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 __NS_SVGELEMENT_H__
8 #define __NS_SVGELEMENT_H__
9 
10 /*
11   nsSVGElement is the base class for all SVG content elements.
12   It implements all the common DOM interfaces and handles attributes.
13 */
14 
15 #include "mozilla/Attributes.h"
16 #include "nsAutoPtr.h"
17 #include "nsChangeHint.h"
18 #include "nsCOMPtr.h"
19 #include "nsCycleCollectionParticipant.h"
20 #include "nsError.h"
21 #include "mozilla/dom/DOMRect.h"
22 #include "mozilla/dom/Element.h"
23 #include "mozilla/gfx/MatrixFwd.h"
24 #include "nsISupportsImpl.h"
25 #include "nsStyledElement.h"
26 #include "nsSVGClass.h"
27 #include "nsIDOMElement.h"
28 #include "SVGContentUtils.h"
29 #include "gfxMatrix.h"
30 
31 class nsSVGAngle;
32 class nsSVGBoolean;
33 class nsSVGEnum;
34 class nsSVGInteger;
35 class nsSVGIntegerPair;
36 class nsSVGLength2;
37 class nsSVGNumber2;
38 class nsSVGNumberPair;
39 class nsSVGString;
40 class nsSVGViewBox;
41 
42 namespace mozilla {
43 class DeclarationBlock;
44 
45 namespace dom {
46 class SVGSVGElement;
47 class SVGViewportElement;
48 
49 }  // namespace dom
50 
51 class SVGAnimatedNumberList;
52 class SVGNumberList;
53 class SVGAnimatedLengthList;
54 class SVGUserUnitList;
55 class SVGAnimatedPointList;
56 class SVGAnimatedPathSegList;
57 class SVGAnimatedPreserveAspectRatio;
58 class nsSVGAnimatedTransformList;
59 class SVGStringList;
60 class DOMSVGStringList;
61 
62 }  // namespace mozilla
63 
64 struct nsSVGEnumMapping;
65 
66 typedef nsStyledElement nsSVGElementBase;
67 
68 class nsSVGElement : public nsSVGElementBase  // nsIContent
69     ,
70                      public nsIDOMElement {
71  protected:
72   explicit nsSVGElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo);
73   friend nsresult NS_NewSVGElement(
74       mozilla::dom::Element** aResult,
75       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
76   nsresult Init();
77   virtual ~nsSVGElement();
78 
79  public:
80   virtual nsresult Clone(mozilla::dom::NodeInfo* aNodeInfo, nsINode** aResult,
81                          bool aPreallocateChildren) const
82       MOZ_MUST_OVERRIDE override;
83 
84   typedef mozilla::SVGNumberList SVGNumberList;
85   typedef mozilla::SVGAnimatedNumberList SVGAnimatedNumberList;
86   typedef mozilla::SVGUserUnitList SVGUserUnitList;
87   typedef mozilla::SVGAnimatedLengthList SVGAnimatedLengthList;
88   typedef mozilla::SVGAnimatedPointList SVGAnimatedPointList;
89   typedef mozilla::SVGAnimatedPathSegList SVGAnimatedPathSegList;
90   typedef mozilla::SVGAnimatedPreserveAspectRatio
91       SVGAnimatedPreserveAspectRatio;
92   typedef mozilla::nsSVGAnimatedTransformList nsSVGAnimatedTransformList;
93   typedef mozilla::SVGStringList SVGStringList;
94 
95   // nsISupports
96   NS_DECL_ISUPPORTS_INHERITED
97 
98   void DidAnimateClass();
99 
100   // nsIContent interface methods
101 
102   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
103                               nsIContent* aBindingParent,
104                               bool aCompileEventHandlers) override;
105 
106   virtual nsChangeHint GetAttributeChangeHint(const nsAtom* aAttribute,
107                                               int32_t aModType) const override;
108 
109   virtual bool IsNodeOfType(uint32_t aFlags) const override;
110 
111   /**
112    * We override the default to unschedule computation of Servo declaration
113    * blocks when adopted across documents.
114    */
115   virtual void NodeInfoChanged(nsIDocument* aOldDoc) override;
116 
117 #ifdef MOZ_OLD_STYLE
118   NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) override;
119   void WalkAnimatedContentStyleRules(nsRuleWalker* aRuleWalker);
120 #endif
121 
122   NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
123 
124   static const MappedAttributeEntry sFillStrokeMap[];
125   static const MappedAttributeEntry sGraphicsMap[];
126   static const MappedAttributeEntry sTextContentElementsMap[];
127   static const MappedAttributeEntry sFontSpecificationMap[];
128   static const MappedAttributeEntry sGradientStopMap[];
129   static const MappedAttributeEntry sViewportsMap[];
130   static const MappedAttributeEntry sMarkersMap[];
131   static const MappedAttributeEntry sColorMap[];
132   static const MappedAttributeEntry sFiltersMap[];
133   static const MappedAttributeEntry sFEFloodMap[];
134   static const MappedAttributeEntry sLightingEffectsMap[];
135   static const MappedAttributeEntry sMaskMap[];
136 
137   NS_DECL_NSIDOMELEMENT
138 
139   NS_IMPL_FROMCONTENT(nsSVGElement, kNameSpaceID_SVG)
140 
141   // Gets the element that establishes the rectangular viewport against which
142   // we should resolve percentage lengths (our "coordinate context"). Returns
143   // nullptr for outer <svg> or SVG without an <svg> parent (invalid SVG).
144   mozilla::dom::SVGViewportElement* GetCtx() const;
145 
146   /**
147    * Returns aMatrix pre-multiplied by (explicit or implicit) transforms that
148    * are introduced by attributes on this element.
149    *
150    * If aWhich is eAllTransforms, then all the transforms from the coordinate
151    * space established by this element for its children to the coordinate
152    * space established by this element's parent element for this element, are
153    * included.
154    *
155    * If aWhich is eUserSpaceToParent, then only the transforms from this
156    * element's userspace to the coordinate space established by its parent is
157    * included. This includes any transforms introduced by the 'transform'
158    * attribute, transform animations and animateMotion, but not any offsets
159    * due to e.g. 'x'/'y' attributes, or any transform due to a 'viewBox'
160    * attribute. (SVG userspace is defined to be the coordinate space in which
161    * coordinates on an element apply.)
162    *
163    * If aWhich is eChildToUserSpace, then only the transforms from the
164    * coordinate space established by this element for its childre to this
165    * elements userspace are included. This includes any offsets due to e.g.
166    * 'x'/'y' attributes, and any transform due to a 'viewBox' attribute, but
167    * does not include any transforms due to the 'transform' attribute.
168    */
169   virtual gfxMatrix PrependLocalTransformsTo(
170       const gfxMatrix& aMatrix,
171       SVGTransformTypes aWhich = eAllTransforms) const;
172 
173   // Setter for to set the current <animateMotion> transformation
174   // Only visible for nsSVGGraphicElement, so it's a no-op here, and that
175   // subclass has the useful implementation.
SetAnimateMotionTransform(const mozilla::gfx::Matrix * aMatrix)176   virtual void SetAnimateMotionTransform(
177       const mozilla::gfx::Matrix* aMatrix) { /*no-op*/
178   }
GetAnimateMotionTransform()179   virtual const mozilla::gfx::Matrix* GetAnimateMotionTransform() const {
180     return nullptr;
181   }
182 
IsStringAnimatable(uint8_t aAttrEnum)183   bool IsStringAnimatable(uint8_t aAttrEnum) {
184     return GetStringInfo().mStringInfo[aAttrEnum].mIsAnimatable;
185   }
NumberAttrAllowsPercentage(uint8_t aAttrEnum)186   bool NumberAttrAllowsPercentage(uint8_t aAttrEnum) {
187     return GetNumberInfo().mNumberInfo[aAttrEnum].mPercentagesAllowed;
188   }
HasValidDimensions()189   virtual bool HasValidDimensions() const { return true; }
190   void SetLength(nsAtom* aName, const nsSVGLength2& aLength);
191 
192   nsAttrValue WillChangeLength(uint8_t aAttrEnum);
193   nsAttrValue WillChangeNumberPair(uint8_t aAttrEnum);
194   nsAttrValue WillChangeIntegerPair(uint8_t aAttrEnum);
195   nsAttrValue WillChangeAngle(uint8_t aAttrEnum);
196   nsAttrValue WillChangeViewBox();
197   nsAttrValue WillChangePreserveAspectRatio();
198   nsAttrValue WillChangeNumberList(uint8_t aAttrEnum);
199   nsAttrValue WillChangeLengthList(uint8_t aAttrEnum);
200   nsAttrValue WillChangePointList();
201   nsAttrValue WillChangePathSegList();
202   nsAttrValue WillChangeTransformList();
203   nsAttrValue WillChangeStringList(bool aIsConditionalProcessingAttribute,
204                                    uint8_t aAttrEnum);
205 
206   void DidChangeLength(uint8_t aAttrEnum, const nsAttrValue& aEmptyOrOldValue);
207   void DidChangeNumber(uint8_t aAttrEnum);
208   void DidChangeNumberPair(uint8_t aAttrEnum,
209                            const nsAttrValue& aEmptyOrOldValue);
210   void DidChangeInteger(uint8_t aAttrEnum);
211   void DidChangeIntegerPair(uint8_t aAttrEnum,
212                             const nsAttrValue& aEmptyOrOldValue);
213   void DidChangeAngle(uint8_t aAttrEnum, const nsAttrValue& aEmptyOrOldValue);
214   void DidChangeBoolean(uint8_t aAttrEnum);
215   void DidChangeEnum(uint8_t aAttrEnum);
216   void DidChangeViewBox(const nsAttrValue& aEmptyOrOldValue);
217   void DidChangePreserveAspectRatio(const nsAttrValue& aEmptyOrOldValue);
218   void DidChangeNumberList(uint8_t aAttrEnum,
219                            const nsAttrValue& aEmptyOrOldValue);
220   void DidChangeLengthList(uint8_t aAttrEnum,
221                            const nsAttrValue& aEmptyOrOldValue);
222   void DidChangePointList(const nsAttrValue& aEmptyOrOldValue);
223   void DidChangePathSegList(const nsAttrValue& aEmptyOrOldValue);
224   void DidChangeTransformList(const nsAttrValue& aEmptyOrOldValue);
DidChangeString(uint8_t aAttrEnum)225   void DidChangeString(uint8_t aAttrEnum) {}
226   void DidChangeStringList(bool aIsConditionalProcessingAttribute,
227                            uint8_t aAttrEnum,
228                            const nsAttrValue& aEmptyOrOldValue);
229 
230   void DidAnimateLength(uint8_t aAttrEnum);
231   void DidAnimateNumber(uint8_t aAttrEnum);
232   void DidAnimateNumberPair(uint8_t aAttrEnum);
233   void DidAnimateInteger(uint8_t aAttrEnum);
234   void DidAnimateIntegerPair(uint8_t aAttrEnum);
235   void DidAnimateAngle(uint8_t aAttrEnum);
236   void DidAnimateBoolean(uint8_t aAttrEnum);
237   void DidAnimateEnum(uint8_t aAttrEnum);
238   void DidAnimateViewBox();
239   void DidAnimatePreserveAspectRatio();
240   void DidAnimateNumberList(uint8_t aAttrEnum);
241   void DidAnimateLengthList(uint8_t aAttrEnum);
242   void DidAnimatePointList();
243   void DidAnimatePathSegList();
244   void DidAnimateTransformList(int32_t aModType);
245   void DidAnimateString(uint8_t aAttrEnum);
246 
247   enum {
248     /**
249      * Flag to indicate to GetAnimatedXxx() methods that the object being
250      * requested should be allocated if it hasn't already been allocated, and
251      * that the method should not return null. Only applicable to methods that
252      * need to allocate the object that they return.
253      */
254     DO_ALLOCATE = 0x1
255   };
256 
257   nsSVGLength2* GetAnimatedLength(const nsAtom* aAttrName);
258   void GetAnimatedLengthValues(float* aFirst, ...);
259   void GetAnimatedNumberValues(float* aFirst, ...);
260   void GetAnimatedIntegerValues(int32_t* aFirst, ...);
261   SVGAnimatedNumberList* GetAnimatedNumberList(uint8_t aAttrEnum);
262   SVGAnimatedNumberList* GetAnimatedNumberList(nsAtom* aAttrName);
263   void GetAnimatedLengthListValues(SVGUserUnitList* aFirst, ...);
264   SVGAnimatedLengthList* GetAnimatedLengthList(uint8_t aAttrEnum);
GetAnimatedPointList()265   virtual SVGAnimatedPointList* GetAnimatedPointList() { return nullptr; }
GetAnimPathSegList()266   virtual SVGAnimatedPathSegList* GetAnimPathSegList() {
267     // DOM interface 'SVGAnimatedPathData' (*inherited* by nsSVGPathElement)
268     // has a member called 'animatedPathSegList' member, so we have a shorter
269     // name so we don't get hidden by the GetAnimatedPathSegList declared by
270     // NS_DECL_NSIDOMSVGANIMATEDPATHDATA.
271     return nullptr;
272   }
273   /**
274    * Get the nsSVGAnimatedTransformList for this element.
275    *
276    * Despite the fact that animated transform lists are used for a variety of
277    * attributes, no SVG element uses more than one.
278    *
279    * It's relatively uncommon for elements to have their transform attribute
280    * set, so to save memory the nsSVGAnimatedTransformList is not allocated
281    * until the attribute is set/animated or its DOM wrapper is created. Callers
282    * that require the nsSVGAnimatedTransformList to be allocated and for this
283    * method to return non-null must pass the DO_ALLOCATE flag.
284    */
285   virtual nsSVGAnimatedTransformList* GetAnimatedTransformList(
286       uint32_t aFlags = 0) {
287     return nullptr;
288   }
289 
290   mozilla::UniquePtr<nsISMILAttr> GetAnimatedAttr(int32_t aNamespaceID,
291                                                   nsAtom* aName) override;
292   void AnimationNeedsResample();
293   void FlushAnimations();
294 
295   virtual void RecompileScriptEventListeners() override;
296 
297   void GetStringBaseValue(uint8_t aAttrEnum, nsAString& aResult) const;
298   void SetStringBaseValue(uint8_t aAttrEnum, const nsAString& aValue);
299 
GetPointListAttrName()300   virtual nsAtom* GetPointListAttrName() const { return nullptr; }
GetPathDataAttrName()301   virtual nsAtom* GetPathDataAttrName() const { return nullptr; }
GetTransformListAttrName()302   virtual nsAtom* GetTransformListAttrName() const { return nullptr; }
GetAnimatedClassName()303   const nsAttrValue* GetAnimatedClassName() const {
304     if (!mClassAttribute.IsAnimated()) {
305       return nullptr;
306     }
307     return mClassAnimAttr;
308   }
309 
ClearAnyCachedPath()310   virtual void ClearAnyCachedPath() {}
AsDOMNode()311   nsIDOMNode* AsDOMNode() final { return this; }
IsTransformable()312   virtual bool IsTransformable() { return false; }
313 
314   // WebIDL
315   mozilla::dom::SVGSVGElement* GetOwnerSVGElement();
316   nsSVGElement* GetViewportElement();
317   already_AddRefed<mozilla::dom::SVGAnimatedString> ClassName();
318 
319   virtual bool IsSVGFocusable(bool* aIsFocusable, int32_t* aTabIndex);
320   virtual bool IsFocusableInternal(int32_t* aTabIndex,
321                                    bool aWithMouse) override;
322 
323   void UpdateContentDeclarationBlock(mozilla::StyleBackendType aBackend);
324   const mozilla::DeclarationBlock* GetContentDeclarationBlock() const;
325 
326  protected:
327   virtual JSObject* WrapNode(JSContext* cx,
328                              JS::Handle<JSObject*> aGivenProto) override;
329 
330   // We define BeforeSetAttr here and mark it final to ensure it is NOT used
331   // by SVG elements.
332   // This is because we're not currently passing the correct value for aValue to
333   // BeforeSetAttr since it would involve allocating extra SVG value types.
334   // See the comment in nsSVGElement::WillChangeValue.
335   nsresult BeforeSetAttr(int32_t aNamespaceID, nsAtom* aName,
336                          const nsAttrValueOrString* aValue, bool aNotify) final;
337   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsAtom* aName,
338                                 const nsAttrValue* aValue,
339                                 const nsAttrValue* aOldValue,
340                                 nsIPrincipal* aSubjectPrincipal,
341                                 bool aNotify) override;
342   virtual bool ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
343                               const nsAString& aValue,
344                               nsIPrincipal* aMaybeScriptedPrincipal,
345                               nsAttrValue& aResult) override;
346   static nsresult ReportAttributeParseFailure(nsIDocument* aDocument,
347                                               nsAtom* aAttribute,
348                                               const nsAString& aValue);
349 
350   nsAttrValue WillChangeValue(nsAtom* aName);
351   // aNewValue is set to the old value. This value may be invalid if
352   // !StoresOwnData.
353   void DidChangeValue(nsAtom* aName, const nsAttrValue& aEmptyOrOldValue,
354                       nsAttrValue& aNewValue);
355   void MaybeSerializeAttrBeforeRemoval(nsAtom* aName, bool aNotify);
356 
357   static nsAtom* GetEventNameForAttr(nsAtom* aAttr);
358 
359   struct LengthInfo {
360     nsStaticAtom** mName;
361     float mDefaultValue;
362     uint8_t mDefaultUnitType;
363     uint8_t mCtxType;
364   };
365 
366   struct LengthAttributesInfo {
367     nsSVGLength2* mLengths;
368     LengthInfo* mLengthInfo;
369     uint32_t mLengthCount;
370 
LengthAttributesInfoLengthAttributesInfo371     LengthAttributesInfo(nsSVGLength2* aLengths, LengthInfo* aLengthInfo,
372                          uint32_t aLengthCount)
373         : mLengths(aLengths),
374           mLengthInfo(aLengthInfo),
375           mLengthCount(aLengthCount) {}
376 
377     void Reset(uint8_t aAttrEnum);
378   };
379 
380   struct NumberInfo {
381     nsStaticAtom** mName;
382     float mDefaultValue;
383     bool mPercentagesAllowed;
384   };
385 
386   struct NumberAttributesInfo {
387     nsSVGNumber2* mNumbers;
388     NumberInfo* mNumberInfo;
389     uint32_t mNumberCount;
390 
NumberAttributesInfoNumberAttributesInfo391     NumberAttributesInfo(nsSVGNumber2* aNumbers, NumberInfo* aNumberInfo,
392                          uint32_t aNumberCount)
393         : mNumbers(aNumbers),
394           mNumberInfo(aNumberInfo),
395           mNumberCount(aNumberCount) {}
396 
397     void Reset(uint8_t aAttrEnum);
398   };
399 
400   struct NumberPairInfo {
401     nsStaticAtom** mName;
402     float mDefaultValue1;
403     float mDefaultValue2;
404   };
405 
406   struct NumberPairAttributesInfo {
407     nsSVGNumberPair* mNumberPairs;
408     NumberPairInfo* mNumberPairInfo;
409     uint32_t mNumberPairCount;
410 
NumberPairAttributesInfoNumberPairAttributesInfo411     NumberPairAttributesInfo(nsSVGNumberPair* aNumberPairs,
412                              NumberPairInfo* aNumberPairInfo,
413                              uint32_t aNumberPairCount)
414         : mNumberPairs(aNumberPairs),
415           mNumberPairInfo(aNumberPairInfo),
416           mNumberPairCount(aNumberPairCount) {}
417 
418     void Reset(uint8_t aAttrEnum);
419   };
420 
421   struct IntegerInfo {
422     nsStaticAtom** mName;
423     int32_t mDefaultValue;
424   };
425 
426   struct IntegerAttributesInfo {
427     nsSVGInteger* mIntegers;
428     IntegerInfo* mIntegerInfo;
429     uint32_t mIntegerCount;
430 
IntegerAttributesInfoIntegerAttributesInfo431     IntegerAttributesInfo(nsSVGInteger* aIntegers, IntegerInfo* aIntegerInfo,
432                           uint32_t aIntegerCount)
433         : mIntegers(aIntegers),
434           mIntegerInfo(aIntegerInfo),
435           mIntegerCount(aIntegerCount) {}
436 
437     void Reset(uint8_t aAttrEnum);
438   };
439 
440   struct IntegerPairInfo {
441     nsStaticAtom** mName;
442     int32_t mDefaultValue1;
443     int32_t mDefaultValue2;
444   };
445 
446   struct IntegerPairAttributesInfo {
447     nsSVGIntegerPair* mIntegerPairs;
448     IntegerPairInfo* mIntegerPairInfo;
449     uint32_t mIntegerPairCount;
450 
IntegerPairAttributesInfoIntegerPairAttributesInfo451     IntegerPairAttributesInfo(nsSVGIntegerPair* aIntegerPairs,
452                               IntegerPairInfo* aIntegerPairInfo,
453                               uint32_t aIntegerPairCount)
454         : mIntegerPairs(aIntegerPairs),
455           mIntegerPairInfo(aIntegerPairInfo),
456           mIntegerPairCount(aIntegerPairCount) {}
457 
458     void Reset(uint8_t aAttrEnum);
459   };
460 
461   struct AngleInfo {
462     nsStaticAtom** mName;
463     float mDefaultValue;
464     uint8_t mDefaultUnitType;
465   };
466 
467   struct AngleAttributesInfo {
468     nsSVGAngle* mAngles;
469     AngleInfo* mAngleInfo;
470     uint32_t mAngleCount;
471 
AngleAttributesInfoAngleAttributesInfo472     AngleAttributesInfo(nsSVGAngle* aAngles, AngleInfo* aAngleInfo,
473                         uint32_t aAngleCount)
474         : mAngles(aAngles), mAngleInfo(aAngleInfo), mAngleCount(aAngleCount) {}
475 
476     void Reset(uint8_t aAttrEnum);
477   };
478 
479   struct BooleanInfo {
480     nsStaticAtom** mName;
481     bool mDefaultValue;
482   };
483 
484   struct BooleanAttributesInfo {
485     nsSVGBoolean* mBooleans;
486     BooleanInfo* mBooleanInfo;
487     uint32_t mBooleanCount;
488 
BooleanAttributesInfoBooleanAttributesInfo489     BooleanAttributesInfo(nsSVGBoolean* aBooleans, BooleanInfo* aBooleanInfo,
490                           uint32_t aBooleanCount)
491         : mBooleans(aBooleans),
492           mBooleanInfo(aBooleanInfo),
493           mBooleanCount(aBooleanCount) {}
494 
495     void Reset(uint8_t aAttrEnum);
496   };
497 
498   friend class nsSVGEnum;
499 
500   struct EnumInfo {
501     nsStaticAtom** mName;
502     nsSVGEnumMapping* mMapping;
503     uint16_t mDefaultValue;
504   };
505 
506   struct EnumAttributesInfo {
507     nsSVGEnum* mEnums;
508     EnumInfo* mEnumInfo;
509     uint32_t mEnumCount;
510 
EnumAttributesInfoEnumAttributesInfo511     EnumAttributesInfo(nsSVGEnum* aEnums, EnumInfo* aEnumInfo,
512                        uint32_t aEnumCount)
513         : mEnums(aEnums), mEnumInfo(aEnumInfo), mEnumCount(aEnumCount) {}
514 
515     void Reset(uint8_t aAttrEnum);
516   };
517 
518   struct NumberListInfo {
519     nsStaticAtom** mName;
520   };
521 
522   struct NumberListAttributesInfo {
523     SVGAnimatedNumberList* mNumberLists;
524     NumberListInfo* mNumberListInfo;
525     uint32_t mNumberListCount;
526 
NumberListAttributesInfoNumberListAttributesInfo527     NumberListAttributesInfo(SVGAnimatedNumberList* aNumberLists,
528                              NumberListInfo* aNumberListInfo,
529                              uint32_t aNumberListCount)
530         : mNumberLists(aNumberLists),
531           mNumberListInfo(aNumberListInfo),
532           mNumberListCount(aNumberListCount) {}
533 
534     void Reset(uint8_t aAttrEnum);
535   };
536 
537   struct LengthListInfo {
538     nsStaticAtom** mName;
539     uint8_t mAxis;
540     /**
541      * Flag to indicate whether appending zeros to the end of the list would
542      * change the rendering of the SVG for the attribute in question. For x and
543      * y on the <text> element this is true, but for dx and dy on <text> this
544      * is false. This flag is fed down to SVGLengthListSMILType so it can
545      * determine if it can sensibly animate from-to lists of different lengths,
546      * which is desirable in the case of dx and dy.
547      */
548     bool mCouldZeroPadList;
549   };
550 
551   struct LengthListAttributesInfo {
552     SVGAnimatedLengthList* mLengthLists;
553     LengthListInfo* mLengthListInfo;
554     uint32_t mLengthListCount;
555 
LengthListAttributesInfoLengthListAttributesInfo556     LengthListAttributesInfo(SVGAnimatedLengthList* aLengthLists,
557                              LengthListInfo* aLengthListInfo,
558                              uint32_t aLengthListCount)
559         : mLengthLists(aLengthLists),
560           mLengthListInfo(aLengthListInfo),
561           mLengthListCount(aLengthListCount) {}
562 
563     void Reset(uint8_t aAttrEnum);
564   };
565 
566   struct StringInfo {
567     nsStaticAtom** mName;
568     int32_t mNamespaceID;
569     bool mIsAnimatable;
570   };
571 
572   struct StringAttributesInfo {
573     nsSVGString* mStrings;
574     StringInfo* mStringInfo;
575     uint32_t mStringCount;
576 
StringAttributesInfoStringAttributesInfo577     StringAttributesInfo(nsSVGString* aStrings, StringInfo* aStringInfo,
578                          uint32_t aStringCount)
579         : mStrings(aStrings),
580           mStringInfo(aStringInfo),
581           mStringCount(aStringCount) {}
582 
583     void Reset(uint8_t aAttrEnum);
584   };
585 
586   friend class mozilla::DOMSVGStringList;
587 
588   struct StringListInfo {
589     nsStaticAtom** mName;
590   };
591 
592   struct StringListAttributesInfo {
593     SVGStringList* mStringLists;
594     StringListInfo* mStringListInfo;
595     uint32_t mStringListCount;
596 
StringListAttributesInfoStringListAttributesInfo597     StringListAttributesInfo(SVGStringList* aStringLists,
598                              StringListInfo* aStringListInfo,
599                              uint32_t aStringListCount)
600         : mStringLists(aStringLists),
601           mStringListInfo(aStringListInfo),
602           mStringListCount(aStringListCount) {}
603 
604     void Reset(uint8_t aAttrEnum);
605   };
606 
607   virtual LengthAttributesInfo GetLengthInfo();
608   virtual NumberAttributesInfo GetNumberInfo();
609   virtual NumberPairAttributesInfo GetNumberPairInfo();
610   virtual IntegerAttributesInfo GetIntegerInfo();
611   virtual IntegerPairAttributesInfo GetIntegerPairInfo();
612   virtual AngleAttributesInfo GetAngleInfo();
613   virtual BooleanAttributesInfo GetBooleanInfo();
614   virtual EnumAttributesInfo GetEnumInfo();
615   // We assume all viewboxes and preserveAspectRatios are alike
616   // so we don't need to wrap the class
617   virtual nsSVGViewBox* GetViewBox();
618   virtual SVGAnimatedPreserveAspectRatio* GetPreserveAspectRatio();
619   virtual NumberListAttributesInfo GetNumberListInfo();
620   virtual LengthListAttributesInfo GetLengthListInfo();
621   virtual StringAttributesInfo GetStringInfo();
622   virtual StringListAttributesInfo GetStringListInfo();
623 
624   static nsSVGEnumMapping sSVGUnitTypesMap[];
625 
626  private:
627   void UnsetAttrInternal(int32_t aNameSpaceID, nsAtom* aAttribute,
628                          bool aNotify);
629 
630   nsSVGClass mClassAttribute;
631   nsAutoPtr<nsAttrValue> mClassAnimAttr;
632   RefPtr<mozilla::DeclarationBlock> mContentDeclarationBlock;
633 };
634 
635 /**
636  * A macro to implement the NS_NewSVGXXXElement() functions.
637  */
638 #define NS_IMPL_NS_NEW_SVG_ELEMENT(_elementName)              \
639   nsresult NS_NewSVG##_elementName##Element(                  \
640       nsIContent** aResult,                                   \
641       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) { \
642     RefPtr<nsSVG##_elementName##Element> it =                 \
643         new nsSVG##_elementName##Element(aNodeInfo);          \
644                                                               \
645     nsresult rv = it->Init();                                 \
646                                                               \
647     if (NS_FAILED(rv)) {                                      \
648       return rv;                                              \
649     }                                                         \
650                                                               \
651     it.forget(aResult);                                       \
652                                                               \
653     return rv;                                                \
654   }
655 
656 #define NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(_elementName)      \
657   nsresult NS_NewSVG##_elementName##Element(                     \
658       nsIContent** aResult,                                      \
659       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) {    \
660     RefPtr<mozilla::dom::SVG##_elementName##Element> it =        \
661         new mozilla::dom::SVG##_elementName##Element(aNodeInfo); \
662                                                                  \
663     nsresult rv = it->Init();                                    \
664                                                                  \
665     if (NS_FAILED(rv)) {                                         \
666       return rv;                                                 \
667     }                                                            \
668                                                                  \
669     it.forget(aResult);                                          \
670                                                                  \
671     return rv;                                                   \
672   }
673 
674 #define NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT_CHECK_PARSER(_elementName)      \
675   nsresult NS_NewSVG##_elementName##Element(                                  \
676       nsIContent** aResult,                                                   \
677       already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,                   \
678       mozilla::dom::FromParser aFromParser) {                                 \
679     RefPtr<mozilla::dom::SVG##_elementName##Element> it =                     \
680         new mozilla::dom::SVG##_elementName##Element(aNodeInfo, aFromParser); \
681                                                                               \
682     nsresult rv = it->Init();                                                 \
683                                                                               \
684     if (NS_FAILED(rv)) {                                                      \
685       return rv;                                                              \
686     }                                                                         \
687                                                                               \
688     it.forget(aResult);                                                       \
689                                                                               \
690     return rv;                                                                \
691   }
692 
693 // No unlinking, we'd need to null out the value pointer (the object it
694 // points to is held by the element) and null-check it everywhere.
695 #define NS_SVG_VAL_IMPL_CYCLE_COLLECTION(_val, _element) \
696   NS_IMPL_CYCLE_COLLECTION_CLASS(_val)                   \
697   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_val)          \
698     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_element)          \
699   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                  \
700   NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_val)
701 
702 #define NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(_val, _element) \
703   NS_IMPL_CYCLE_COLLECTION_CLASS(_val)                                 \
704   NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_val)                          \
705     NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER                  \
706   NS_IMPL_CYCLE_COLLECTION_UNLINK_END                                  \
707   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_val)                        \
708     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_element)                        \
709   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END                                \
710   NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_val)                           \
711     NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER                   \
712   NS_IMPL_CYCLE_COLLECTION_TRACE_END
713 
714 #endif  // __NS_SVGELEMENT_H__
715