tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

SVGElement.h (24092B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef DOM_SVG_SVGELEMENT_H_
      8 #define DOM_SVG_SVGELEMENT_H_
      9 
     10 /*
     11  SVGElement is the base class for all SVG content elements.
     12  It implements all the common DOM interfaces and handles attributes.
     13 */
     14 
     15 #include "NonCustomCSSPropertyId.h"
     16 #include "gfxMatrix.h"
     17 #include "mozilla/Attributes.h"
     18 #include "mozilla/RefPtr.h"
     19 #include "mozilla/SVGAnimatedClass.h"
     20 #include "mozilla/SVGContentUtils.h"
     21 #include "mozilla/UniquePtr.h"
     22 #include "mozilla/dom/DOMRect.h"
     23 #include "mozilla/dom/Element.h"
     24 #include "mozilla/gfx/MatrixFwd.h"
     25 #include "nsChangeHint.h"
     26 #include "nsCycleCollectionParticipant.h"
     27 #include "nsError.h"
     28 #include "nsISupportsImpl.h"
     29 #include "nsStyledElement.h"
     30 
     31 // {70db954d-e452-4be3-83aa-f54a51cf7890}
     32 #define MOZILLA_SVGELEMENT_IID \
     33  {0x70db954d, 0xe452, 0x4be3, {0x82, 0xaa, 0xf5, 0x4a, 0x51, 0xcf, 0x78, 0x90}}
     34 
     35 nsresult NS_NewSVGElement(mozilla::dom::Element** aResult,
     36                          already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
     37 
     38 class mozAutoDocUpdate;
     39 
     40 namespace mozilla {
     41 
     42 class SVGAnimatedBoolean;
     43 class SVGAnimatedEnumeration;
     44 class SVGAnimatedInteger;
     45 class SVGAnimatedIntegerPair;
     46 class SVGAnimatedLength;
     47 class SVGAnimatedLengthList;
     48 class SVGAnimatedNumber;
     49 class SVGAnimatedNumberList;
     50 class SVGAnimatedNumberPair;
     51 class SVGAnimatedOrient;
     52 class SVGAnimatedPathSegList;
     53 class SVGAnimatedPointList;
     54 class SVGAnimatedString;
     55 class SVGAnimatedPreserveAspectRatio;
     56 class SVGAnimatedTransformList;
     57 class SVGAnimatedViewBox;
     58 class SVGNumberList;
     59 class SVGStringList;
     60 class SVGUserUnitList;
     61 
     62 struct SVGEnumMapping;
     63 
     64 namespace dom {
     65 class DOMSVGStringList;
     66 class SVGSVGElement;
     67 class SVGViewportElement;
     68 
     69 using SVGElementBase = nsStyledElement;
     70 
     71 class SVGElement : public SVGElementBase  // nsIContent
     72 {
     73 protected:
     74  explicit SVGElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
     75  friend nsresult(
     76      ::NS_NewSVGElement(mozilla::dom::Element** aResult,
     77                         already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
     78  nsresult Init();
     79  virtual ~SVGElement();
     80 
     81 public:
     82  nsresult Clone(mozilla::dom::NodeInfo*,
     83                 nsINode** aResult) const MOZ_MUST_OVERRIDE override;
     84 
     85  // From Element
     86  nsresult CopyInnerTo(mozilla::dom::Element* aDest);
     87 
     88  NS_INLINE_DECL_STATIC_IID(MOZILLA_SVGELEMENT_IID)
     89  // nsISupports
     90  NS_INLINE_DECL_REFCOUNTING_INHERITED(SVGElement, SVGElementBase)
     91 
     92  NS_DECL_ADDSIZEOFEXCLUDINGTHIS
     93 
     94  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
     95 
     96  void DidAnimateClass();
     97 
     98  void SetNonce(const nsAString& aNonce) {
     99    SetProperty(nsGkAtoms::nonce, new nsString(aNonce),
    100                nsINode::DeleteProperty<nsString>, /* aTransfer = */ true);
    101  }
    102  void RemoveNonce() { RemoveProperty(nsGkAtoms::nonce); }
    103  void GetNonce(nsAString& aNonce) const {
    104    nsString* cspNonce = static_cast<nsString*>(GetProperty(nsGkAtoms::nonce));
    105    if (cspNonce) {
    106      aNonce = *cspNonce;
    107    }
    108  }
    109 
    110  // nsIContent interface methods
    111 
    112  nsresult BindToTree(BindContext&, nsINode& aParent) override;
    113 
    114  nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
    115                                      AttrModType aModType) const override;
    116 
    117  /**
    118   * We override the default to unschedule computation of Servo declaration
    119   * blocks when adopted across documents.
    120   */
    121  void NodeInfoChanged(Document* aOldDoc) override;
    122 
    123  NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
    124  void UpdateMappedDeclarationBlock();
    125 
    126  NS_IMPL_FROMNODE(SVGElement, kNameSpaceID_SVG)
    127 
    128  // Gets the element that establishes the rectangular viewport against which
    129  // we should resolve percentage lengths (our "coordinate context"). Returns
    130  // nullptr for outer <svg> or SVG without an <svg> parent (invalid SVG).
    131  mozilla::dom::SVGViewportElement* GetCtx() const;
    132 
    133  /**
    134   * Returns the transforms from the coordinate space established by this
    135   * element for its children to this element's userspace. This includes any
    136   * offsets due to e.g. 'x'/'y' attributes, and any transform due to a
    137   * 'viewBox' attribute.
    138   */
    139  virtual gfxMatrix ChildToUserSpaceTransform() const;
    140 
    141  // Setter for to set the current <animateMotion> transformation
    142  // Only visible for SVGGraphicElement, so it's a no-op here, and that
    143  // subclass has the useful implementation.
    144  virtual void SetAnimateMotionTransform(
    145      const mozilla::gfx::Matrix* aMatrix) { /*no-op*/ }
    146  virtual const mozilla::gfx::Matrix* GetAnimateMotionTransform() const {
    147    return nullptr;
    148  }
    149 
    150  bool IsStringAnimatable(uint8_t aAttrEnum) {
    151    return GetStringInfo().mInfos[aAttrEnum].mIsAnimatable;
    152  }
    153  bool LengthAttrIsNonNegative(uint8_t aAttrEnum) {
    154    const nsStaticAtom* name = GetLengthInfo().mInfos[aAttrEnum].mName;
    155    return name == nsGkAtoms::width || name == nsGkAtoms::height ||
    156           name == nsGkAtoms::r || name == nsGkAtoms::rx ||
    157           name == nsGkAtoms::ry || name == nsGkAtoms::markerWidth ||
    158           name == nsGkAtoms::markerHeight || name == nsGkAtoms::textLength;
    159  }
    160  bool NumberAttrAllowsPercentage(uint8_t aAttrEnum) {
    161    return IsSVGElement(nsGkAtoms::stop) &&
    162           GetNumberInfo().mInfos[aAttrEnum].mName == nsGkAtoms::offset;
    163  }
    164  virtual bool HasValidDimensions() const { return true; }
    165  void SetLength(nsAtom* aName, const SVGAnimatedLength& aLength);
    166 
    167  enum class ValToUse { Base, Anim };
    168  static bool UpdateDeclarationBlockFromLength(
    169      const StyleLockedDeclarationBlock&, NonCustomCSSPropertyId,
    170      const SVGAnimatedLength&, ValToUse);
    171  static bool UpdateDeclarationBlockFromPath(const StyleLockedDeclarationBlock&,
    172                                             const SVGAnimatedPathSegList&,
    173                                             ValToUse);
    174  static bool UpdateDeclarationBlockFromTransform(
    175      const StyleLockedDeclarationBlock&, const SVGAnimatedTransformList*,
    176      const gfx::Matrix* aAnimateMotionTransform, ValToUse);
    177 
    178  void WillChangeLength(uint8_t aAttrEnum,
    179                        const mozAutoDocUpdate& aProofOfUpdate);
    180  void WillChangeNumberPair(uint8_t aAttrEnum);
    181  void WillChangeIntegerPair(uint8_t aAttrEnum,
    182                             const mozAutoDocUpdate& aProofOfUpdate);
    183  void WillChangeOrient(const mozAutoDocUpdate& aProofOfUpdate);
    184  void WillChangeViewBox(const mozAutoDocUpdate& aProofOfUpdate);
    185  void WillChangePreserveAspectRatio(const mozAutoDocUpdate& aProofOfUpdate);
    186  void WillChangeNumberList(uint8_t aAttrEnum,
    187                            const mozAutoDocUpdate& aProofOfUpdate);
    188  void WillChangeLengthList(uint8_t aAttrEnum,
    189                            const mozAutoDocUpdate& aProofOfUpdate);
    190  void WillChangePointList(const mozAutoDocUpdate& aProofOfUpdate);
    191  void WillChangePathSegList(const mozAutoDocUpdate& aProofOfUpdate);
    192  void WillChangeTransformList(const mozAutoDocUpdate& aProofOfUpdate);
    193  void WillChangeStringList(bool aIsConditionalProcessingAttribute,
    194                            uint8_t aAttrEnum,
    195                            const mozAutoDocUpdate& aProofOfUpdate);
    196 
    197  void DidChangeLength(uint8_t aAttrEnum,
    198                       const mozAutoDocUpdate& aProofOfUpdate);
    199  void DidChangeNumber(uint8_t aAttrEnum);
    200  void DidChangeNumberPair(uint8_t aAttrEnum);
    201  void DidChangeInteger(uint8_t aAttrEnum);
    202  void DidChangeIntegerPair(uint8_t aAttrEnum,
    203                            const mozAutoDocUpdate& aProofOfUpdate);
    204  void DidChangeBoolean(uint8_t aAttrEnum);
    205  void DidChangeEnum(uint8_t aAttrEnum);
    206  void DidChangeOrient(const mozAutoDocUpdate& aProofOfUpdate);
    207  void DidChangeViewBox(const mozAutoDocUpdate& aProofOfUpdate);
    208  void DidChangePreserveAspectRatio(const mozAutoDocUpdate& aProofOfUpdate);
    209  void DidChangeNumberList(uint8_t aAttrEnum,
    210                           const mozAutoDocUpdate& aProofOfUpdate);
    211  void DidChangeLengthList(uint8_t aAttrEnum,
    212                           const mozAutoDocUpdate& aProofOfUpdate);
    213  void DidChangePointList(const mozAutoDocUpdate& aProofOfUpdate);
    214  void DidChangePathSegList(const mozAutoDocUpdate& aProofOfUpdate);
    215  void DidChangeTransformList(const mozAutoDocUpdate& aProofOfUpdate);
    216  void DidChangeString(uint8_t aAttrEnum) {}
    217  void DidChangeStringList(bool aIsConditionalProcessingAttribute,
    218                           uint8_t aAttrEnum,
    219                           const mozAutoDocUpdate& aProofOfUpdate);
    220 
    221  void DidAnimateLength(uint8_t aAttrEnum);
    222  void DidAnimateNumber(uint8_t aAttrEnum) {
    223    auto info = GetNumberInfo();
    224    DidAnimateAttribute(kNameSpaceID_None, info.mInfos[aAttrEnum].mName);
    225  }
    226  void DidAnimateNumberPair(uint8_t aAttrEnum) {
    227    auto info = GetNumberPairInfo();
    228    DidAnimateAttribute(kNameSpaceID_None, info.mInfos[aAttrEnum].mName);
    229  }
    230  void DidAnimateInteger(uint8_t aAttrEnum) {
    231    auto info = GetIntegerInfo();
    232    DidAnimateAttribute(kNameSpaceID_None, info.mInfos[aAttrEnum].mName);
    233  }
    234  void DidAnimateIntegerPair(uint8_t aAttrEnum) {
    235    auto info = GetIntegerPairInfo();
    236    DidAnimateAttribute(kNameSpaceID_None, info.mInfos[aAttrEnum].mName);
    237  }
    238  void DidAnimateBoolean(uint8_t aAttrEnum) {
    239    auto info = GetBooleanInfo();
    240    DidAnimateAttribute(kNameSpaceID_None, info.mInfos[aAttrEnum].mName);
    241  }
    242  void DidAnimateEnum(uint8_t aAttrEnum) {
    243    auto info = GetEnumInfo();
    244    DidAnimateAttribute(kNameSpaceID_None, info.mInfos[aAttrEnum].mName);
    245  }
    246  void DidAnimateOrient() {
    247    DidAnimateAttribute(kNameSpaceID_None, nsGkAtoms::orient);
    248  }
    249  void DidAnimateViewBox() {
    250    DidAnimateAttribute(kNameSpaceID_None, nsGkAtoms::viewBox);
    251  }
    252  void DidAnimatePreserveAspectRatio() {
    253    DidAnimateAttribute(kNameSpaceID_None, nsGkAtoms::preserveAspectRatio);
    254  }
    255  void DidAnimateNumberList(uint8_t aAttrEnum) {
    256    auto info = GetNumberListInfo();
    257    DidAnimateAttribute(kNameSpaceID_None, info.mInfos[aAttrEnum].mName);
    258  }
    259  void DidAnimateLengthList(uint8_t aAttrEnum) {
    260    auto info = GetLengthListInfo();
    261    DidAnimateAttribute(kNameSpaceID_None, info.mInfos[aAttrEnum].mName);
    262  }
    263  void DidAnimatePointList();
    264  void DidAnimatePathSegList();
    265  void DidAnimateTransformList();
    266  void DidAnimateString(uint8_t aAttrEnum) {
    267    auto info = GetStringInfo();
    268    DidAnimateAttribute(info.mInfos[aAttrEnum].mNamespaceID,
    269                        info.mInfos[aAttrEnum].mName);
    270  }
    271 
    272  enum {
    273    /**
    274     * Flag to indicate to GetAnimatedXxx() methods that the object being
    275     * requested should be allocated if it hasn't already been allocated, and
    276     * that the method should not return null. Only applicable to methods that
    277     * need to allocate the object that they return.
    278     */
    279    DO_ALLOCATE = 0x1
    280  };
    281 
    282  SVGAnimatedLength* GetAnimatedLength(uint8_t aAttrEnum);
    283  SVGAnimatedLength* GetAnimatedLength(const nsAtom* aAttrName);
    284  void GetAnimatedLengthValues(float* aFirst, ...);
    285  void GetAnimatedNumberValues(float* aFirst, ...);
    286  void GetAnimatedIntegerValues(int32_t* aFirst, ...);
    287  SVGAnimatedNumberList* GetAnimatedNumberList(uint8_t aAttrEnum);
    288  SVGAnimatedNumberList* GetAnimatedNumberList(nsAtom* aAttrName);
    289  void GetAnimatedLengthListValues(SVGUserUnitList* aFirst, ...);
    290  SVGAnimatedLengthList* GetAnimatedLengthList(uint8_t aAttrEnum);
    291  virtual SVGAnimatedPointList* GetAnimatedPointList() { return nullptr; }
    292  virtual SVGAnimatedPathSegList* GetAnimPathSegList() {
    293    // DOM interface 'SVGAnimatedPathData' (*inherited* by SVGPathElement)
    294    // has a member called 'animatedPathSegList' member, so we have a shorter
    295    // name so we don't get hidden by the GetAnimatedPathSegList declared by
    296    // NS_DECL_NSIDOMSVGANIMATEDPATHDATA.
    297    return nullptr;
    298  }
    299  /**
    300   * Get the SVGAnimatedTransformList for this element.
    301   *
    302   * Despite the fact that animated transform lists are used for a variety of
    303   * attributes, no SVG element uses more than one.
    304   *
    305   * It's relatively uncommon for elements to have their transform attribute
    306   * set, so to save memory the SVGAnimatedTransformList is not allocated
    307   * until the attribute is set/animated or its DOM wrapper is created. Callers
    308   * that require the SVGAnimatedTransformList to be allocated and for this
    309   * method to return non-null must pass the DO_ALLOCATE flag.
    310   */
    311  virtual SVGAnimatedTransformList* GetAnimatedTransformList(
    312      uint32_t aFlags = 0) {
    313    return nullptr;
    314  }
    315 
    316  mozilla::UniquePtr<SMILAttr> GetAnimatedAttr(int32_t aNamespaceID,
    317                                               nsAtom* aName) override;
    318  void AnimationNeedsResample();
    319  void FlushAnimations();
    320 
    321  void GetStringBaseValue(uint8_t aAttrEnum, nsAString& aResult) const;
    322  void SetStringBaseValue(uint8_t aAttrEnum, const nsAString& aValue);
    323 
    324  virtual nsStaticAtom* GetPointListAttrName() const { return nullptr; }
    325  virtual nsStaticAtom* GetPathDataAttrName() const { return nullptr; }
    326  virtual nsStaticAtom* GetTransformListAttrName() const { return nullptr; }
    327  const nsAttrValue* GetAnimatedClassName() const {
    328    if (!mClassAttribute.IsAnimated()) {
    329      return nullptr;
    330    }
    331    return mClassAnimAttr.get();
    332  }
    333 
    334  virtual void ClearAnyCachedPath() {}
    335  virtual bool IsTransformable() { return false; }
    336 
    337  // WebIDL
    338  mozilla::dom::SVGSVGElement* GetOwnerSVGElement();
    339  SVGElement* GetViewportElement();
    340  already_AddRefed<mozilla::dom::DOMSVGAnimatedString> ClassName();
    341 
    342  bool Autofocus() const { return GetBoolAttr(nsGkAtoms::autofocus); }
    343  void SetAutofocus(bool aAutofocus, ErrorResult& aRv) {
    344    if (aAutofocus) {
    345      SetAttr(nsGkAtoms::autofocus, u""_ns, aRv);
    346    } else {
    347      UnsetAttr(nsGkAtoms::autofocus, aRv);
    348    }
    349  }
    350 
    351 protected:
    352  JSObject* WrapNode(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
    353 
    354  // We define BeforeSetAttr here and mark it final to ensure it is NOT used
    355  // by SVG elements.
    356  // This is because we're not currently passing the correct value for aValue to
    357  // BeforeSetAttr since it would involve allocating extra SVG value types.
    358  // See the comment in SVGElement::WillChangeValue.
    359  void BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
    360                     const nsAttrValue* aValue, bool aNotify) final;
    361  void AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
    362                    const nsAttrValue* aValue, const nsAttrValue* aOldValue,
    363                    nsIPrincipal* aSubjectPrincipal, bool aNotify) override;
    364  bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
    365                      const nsAString& aValue,
    366                      nsIPrincipal* aMaybeScriptedPrincipal,
    367                      nsAttrValue& aResult) override;
    368  static nsresult ReportAttributeParseFailure(Document* aDocument,
    369                                              nsAtom* aAttribute,
    370                                              const nsAString& aValue);
    371 
    372  void WillChangeValue(nsAtom* aName, const mozAutoDocUpdate& aProofOfUpdate);
    373  // aNewValue is set to the old value. This value may be invalid if
    374  // !StoresOwnData.
    375  void DidChangeValue(nsAtom* aName, nsAttrValue& aNewValue,
    376                      const mozAutoDocUpdate& aProofOfUpdate);
    377 
    378  nsAtom* GetEventNameForAttr(nsAtom* aAttr) override;
    379 
    380  struct LengthInfo {
    381    nsStaticAtom* const mName;
    382    const float mDefaultValue;
    383    const uint8_t mDefaultUnitType;
    384    const uint8_t mCtxType;
    385  };
    386 
    387  template <typename Value, typename InfoValue>
    388  struct AttributesInfo {
    389    Value* const mValues;
    390    const InfoValue* const mInfos;
    391    const uint32_t mCount;
    392 
    393    AttributesInfo(Value* aValues, const InfoValue* aInfos, uint32_t aCount)
    394        : mValues(aValues), mInfos(aInfos), mCount(aCount) {}
    395 
    396    void CopyAllFrom(const AttributesInfo&);
    397    void ResetAll();
    398    void Reset(uint8_t aEnum);
    399  };
    400 
    401  using LengthAttributesInfo = AttributesInfo<SVGAnimatedLength, LengthInfo>;
    402 
    403  struct NumberInfo {
    404    nsStaticAtom* const mName;
    405    const float mDefaultValue;
    406  };
    407 
    408  using NumberAttributesInfo = AttributesInfo<SVGAnimatedNumber, NumberInfo>;
    409 
    410  struct NumberPairInfo {
    411    nsStaticAtom* const mName;
    412    const float mDefaultValue1;
    413    const float mDefaultValue2;
    414  };
    415 
    416  using NumberPairAttributesInfo =
    417      AttributesInfo<SVGAnimatedNumberPair, NumberPairInfo>;
    418 
    419  struct IntegerInfo {
    420    nsStaticAtom* const mName;
    421    const int32_t mDefaultValue;
    422  };
    423 
    424  using IntegerAttributesInfo = AttributesInfo<SVGAnimatedInteger, IntegerInfo>;
    425 
    426  struct IntegerPairInfo {
    427    nsStaticAtom* const mName;
    428    const int32_t mDefaultValue1;
    429    const int32_t mDefaultValue2;
    430  };
    431 
    432  using IntegerPairAttributesInfo =
    433      AttributesInfo<SVGAnimatedIntegerPair, IntegerPairInfo>;
    434 
    435  struct BooleanInfo {
    436    nsStaticAtom* const mName;
    437    const bool mDefaultValue;
    438  };
    439 
    440  using BooleanAttributesInfo = AttributesInfo<SVGAnimatedBoolean, BooleanInfo>;
    441 
    442  friend class mozilla::SVGAnimatedEnumeration;
    443 
    444  struct EnumInfo {
    445    nsStaticAtom* const mName;
    446    const SVGEnumMapping* const mMapping;
    447    const uint16_t mDefaultValue;
    448  };
    449 
    450  using EnumAttributesInfo = AttributesInfo<SVGAnimatedEnumeration, EnumInfo>;
    451 
    452  struct NumberListInfo {
    453    nsStaticAtom* const mName;
    454  };
    455 
    456  using NumberListAttributesInfo =
    457      AttributesInfo<SVGAnimatedNumberList, NumberListInfo>;
    458 
    459  struct LengthListInfo {
    460    nsStaticAtom* const mName;
    461    const uint8_t mAxis;
    462    /**
    463     * Flag to indicate whether appending zeros to the end of the list would
    464     * change the rendering of the SVG for the attribute in question. For x and
    465     * y on the <text> element this is true, but for dx and dy on <text> this
    466     * is false. This flag is fed down to SVGLengthListSMILType so it can
    467     * determine if it can sensibly animate from-to lists of different lengths,
    468     * which is desirable in the case of dx and dy.
    469     */
    470    const bool mCouldZeroPadList;
    471  };
    472 
    473  using LengthListAttributesInfo =
    474      AttributesInfo<SVGAnimatedLengthList, LengthListInfo>;
    475 
    476  struct StringInfo {
    477    nsStaticAtom* const mName;
    478    const int32_t mNamespaceID;
    479    const bool mIsAnimatable;
    480  };
    481 
    482  using StringAttributesInfo = AttributesInfo<SVGAnimatedString, StringInfo>;
    483 
    484  friend class DOMSVGStringList;
    485 
    486  struct StringListInfo {
    487    nsStaticAtom* const mName;
    488  };
    489 
    490  using StringListAttributesInfo =
    491      AttributesInfo<SVGStringList, StringListInfo>;
    492 
    493  virtual LengthAttributesInfo GetLengthInfo();
    494  virtual NumberAttributesInfo GetNumberInfo();
    495  virtual NumberPairAttributesInfo GetNumberPairInfo();
    496  virtual IntegerAttributesInfo GetIntegerInfo();
    497  virtual IntegerPairAttributesInfo GetIntegerPairInfo();
    498  virtual BooleanAttributesInfo GetBooleanInfo();
    499  virtual EnumAttributesInfo GetEnumInfo();
    500  // We assume all orients, viewboxes and preserveAspectRatios are alike
    501  // so we don't need to wrap the class
    502  virtual SVGAnimatedOrient* GetAnimatedOrient();
    503  virtual SVGAnimatedPreserveAspectRatio* GetAnimatedPreserveAspectRatio();
    504  virtual SVGAnimatedViewBox* GetAnimatedViewBox();
    505  virtual NumberListAttributesInfo GetNumberListInfo();
    506  virtual LengthListAttributesInfo GetLengthListInfo();
    507  virtual StringAttributesInfo GetStringInfo();
    508  virtual StringListAttributesInfo GetStringListInfo();
    509 
    510  static SVGEnumMapping sSVGUnitTypesMap[];
    511 
    512  virtual void DidAnimateAttribute(int32_t aNameSpaceID, nsAtom* aAttribute);
    513 
    514 private:
    515  void UnsetAttrInternal(int32_t aNameSpaceID, nsAtom* aName, bool aNotify);
    516 
    517  SVGAnimatedClass mClassAttribute;
    518  UniquePtr<nsAttrValue> mClassAnimAttr;
    519 };
    520 
    521 /**
    522 * A macro to implement the NS_NewSVGXXXElement() functions.
    523 */
    524 #define NS_IMPL_NS_NEW_SVG_ELEMENT(_elementName)                               \
    525  nsresult NS_NewSVG##_elementName##Element(                                   \
    526      nsIContent** aResult,                                                    \
    527      already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) {                  \
    528    RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo);                        \
    529    auto* nim = nodeInfo->NodeInfoManager();                                   \
    530    RefPtr<mozilla::dom::SVG##_elementName##Element> it =                      \
    531        new (nim) mozilla::dom::SVG##_elementName##Element(nodeInfo.forget()); \
    532                                                                               \
    533    nsresult rv = it->Init();                                                  \
    534                                                                               \
    535    if (NS_FAILED(rv)) {                                                       \
    536      return rv;                                                               \
    537    }                                                                          \
    538                                                                               \
    539    it.forget(aResult);                                                        \
    540                                                                               \
    541    return rv;                                                                 \
    542  }
    543 
    544 #define NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(_elementName)                 \
    545  nsresult NS_NewSVG##_elementName##Element(                                  \
    546      nsIContent** aResult,                                                   \
    547      already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,                   \
    548      mozilla::dom::FromParser aFromParser) {                                 \
    549    RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo);                       \
    550    auto* nim = nodeInfo->NodeInfoManager();                                  \
    551    RefPtr<mozilla::dom::SVG##_elementName##Element> it =                     \
    552        new (nim) mozilla::dom::SVG##_elementName##Element(nodeInfo.forget(), \
    553                                                           aFromParser);      \
    554                                                                              \
    555    nsresult rv = it->Init();                                                 \
    556                                                                              \
    557    if (NS_FAILED(rv)) {                                                      \
    558      return rv;                                                              \
    559    }                                                                         \
    560                                                                              \
    561    it.forget(aResult);                                                       \
    562                                                                              \
    563    return rv;                                                                \
    564  }
    565 
    566 // No unlinking, we'd need to null out the value pointer (the object it
    567 // points to is held by the element) and null-check it everywhere.
    568 #define NS_SVG_VAL_IMPL_CYCLE_COLLECTION(_val, _element) \
    569  NS_IMPL_CYCLE_COLLECTION_CLASS(_val)                   \
    570  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_val)          \
    571    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_element)          \
    572  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                  \
    573  NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_val)
    574 
    575 #define NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(_val, _element) \
    576  NS_IMPL_CYCLE_COLLECTION_CLASS(_val)                                 \
    577  NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_val)                          \
    578    NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER                  \
    579  NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                  \
    580  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_val)                        \
    581    NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_element)                        \
    582  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                                \
    583  NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_val)                           \
    584    NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER                   \
    585  NS_IMPL_CYCLE_COLLECTION_TRACE_END
    586 
    587 }  // namespace dom
    588 }  // namespace mozilla
    589 
    590 #endif  // DOM_SVG_SVGELEMENT_H_