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/. */
7 #ifndef DOM_SVG_SVGELEMENT_H_
8 #define DOM_SVG_SVGELEMENT_H_
11 SVGElement is the base class for all SVG content elements.
12 It implements all the common DOM interfaces and handles attributes.
15 #include "mozilla/Attributes.h"
16 #include "mozilla/RefPtr.h"
17 #include "mozilla/SVGAnimatedClass.h"
18 #include "mozilla/SVGContentUtils.h"
19 #include "mozilla/dom/DOMRect.h"
20 #include "mozilla/dom/Element.h"
21 #include "mozilla/gfx/MatrixFwd.h"
22 #include "mozilla/UniquePtr.h"
23 #include "nsCSSPropertyID.h"
24 #include "nsChangeHint.h"
25 #include "nsCycleCollectionParticipant.h"
27 #include "nsISupportsImpl.h"
28 #include "nsStyledElement.h"
29 #include "gfxMatrix.h"
31 // {70db954d-e452-4be3-83aa-f54a51cf7890}
32 #define MOZILLA_SVGELEMENT_IID \
34 0x70db954d, 0xe452, 0x4be3, { \
35 0x82, 0xaa, 0xf5, 0x4a, 0x51, 0xcf, 0x78, 0x90 \
39 nsresult
NS_NewSVGElement(mozilla::dom::Element
** aResult
,
40 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
);
42 class mozAutoDocUpdate
;
46 class SVGAnimatedBoolean
;
47 class SVGAnimatedEnumeration
;
48 class SVGAnimatedInteger
;
49 class SVGAnimatedIntegerPair
;
50 class SVGAnimatedLength
;
51 class SVGAnimatedLengthList
;
52 class SVGAnimatedNumber
;
53 class SVGAnimatedNumberList
;
54 class SVGAnimatedNumberPair
;
55 class SVGAnimatedOrient
;
56 class SVGAnimatedPathSegList
;
57 class SVGAnimatedPointList
;
58 class SVGAnimatedString
;
59 class SVGAnimatedPreserveAspectRatio
;
60 class SVGAnimatedTransformList
;
61 class SVGAnimatedViewBox
;
64 class SVGUserUnitList
;
66 struct SVGEnumMapping
;
69 class DOMSVGStringList
;
71 class SVGViewportElement
;
73 using SVGElementBase
= nsStyledElement
;
75 class SVGElement
: public SVGElementBase
// nsIContent
78 explicit SVGElement(already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
);
80 ::NS_NewSVGElement(mozilla::dom::Element
** aResult
,
81 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
));
83 virtual ~SVGElement();
86 nsresult
Clone(mozilla::dom::NodeInfo
*,
87 nsINode
** aResult
) const MOZ_MUST_OVERRIDE override
;
90 nsresult
CopyInnerTo(mozilla::dom::Element
* aDest
);
92 NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_SVGELEMENT_IID
)
94 NS_INLINE_DECL_REFCOUNTING_INHERITED(SVGElement
, SVGElementBase
)
96 NS_DECL_ADDSIZEOFEXCLUDINGTHIS
98 NS_IMETHOD
QueryInterface(REFNSIID aIID
, void** aInstancePtr
) override
;
100 void DidAnimateClass();
102 void SetNonce(const nsAString
& aNonce
) {
103 SetProperty(nsGkAtoms::nonce
, new nsString(aNonce
),
104 nsINode::DeleteProperty
<nsString
>, /* aTransfer = */ true);
106 void RemoveNonce() { RemoveProperty(nsGkAtoms::nonce
); }
107 void GetNonce(nsAString
& aNonce
) const {
108 nsString
* cspNonce
= static_cast<nsString
*>(GetProperty(nsGkAtoms::nonce
));
114 // nsIContent interface methods
116 nsresult
BindToTree(BindContext
&, nsINode
& aParent
) override
;
118 nsChangeHint
GetAttributeChangeHint(const nsAtom
* aAttribute
,
119 int32_t aModType
) const override
;
122 * We override the default to unschedule computation of Servo declaration
123 * blocks when adopted across documents.
125 void NodeInfoChanged(Document
* aOldDoc
) override
;
127 NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom
* aAttribute
) const override
;
128 void UpdateMappedDeclarationBlock();
130 NS_IMPL_FROMNODE(SVGElement
, kNameSpaceID_SVG
)
132 // Gets the element that establishes the rectangular viewport against which
133 // we should resolve percentage lengths (our "coordinate context"). Returns
134 // nullptr for outer <svg> or SVG without an <svg> parent (invalid SVG).
135 mozilla::dom::SVGViewportElement
* GetCtx() const;
138 * Returns aMatrix pre-multiplied by (explicit or implicit) transforms that
139 * are introduced by attributes on this element.
141 * If aWhich is eAllTransforms, then all the transforms from the coordinate
142 * space established by this element for its children to the coordinate
143 * space established by this element's parent element for this element, are
146 * If aWhich is eUserSpaceToParent, then only the transforms from this
147 * element's userspace to the coordinate space established by its parent is
148 * included. This includes any transforms introduced by the 'transform'
149 * attribute, transform animations and animateMotion, but not any offsets
150 * due to e.g. 'x'/'y' attributes, or any transform due to a 'viewBox'
151 * attribute. (SVG userspace is defined to be the coordinate space in which
152 * coordinates on an element apply.)
154 * If aWhich is eChildToUserSpace, then only the transforms from the
155 * coordinate space established by this element for its childre to this
156 * elements userspace are included. This includes any offsets due to e.g.
157 * 'x'/'y' attributes, and any transform due to a 'viewBox' attribute, but
158 * does not include any transforms due to the 'transform' attribute.
160 virtual gfxMatrix
PrependLocalTransformsTo(
161 const gfxMatrix
& aMatrix
,
162 SVGTransformTypes aWhich
= eAllTransforms
) const;
164 // Setter for to set the current <animateMotion> transformation
165 // Only visible for SVGGraphicElement, so it's a no-op here, and that
166 // subclass has the useful implementation.
167 virtual void SetAnimateMotionTransform(
168 const mozilla::gfx::Matrix
* aMatrix
) { /*no-op*/
170 virtual const mozilla::gfx::Matrix
* GetAnimateMotionTransform() const {
174 bool IsStringAnimatable(uint8_t aAttrEnum
) {
175 return GetStringInfo().mInfos
[aAttrEnum
].mIsAnimatable
;
177 bool NumberAttrAllowsPercentage(uint8_t aAttrEnum
) {
178 return IsSVGElement(nsGkAtoms::stop
) &&
179 GetNumberInfo().mInfos
[aAttrEnum
].mName
== nsGkAtoms::offset
;
181 virtual bool HasValidDimensions() const { return true; }
182 void SetLength(nsAtom
* aName
, const SVGAnimatedLength
& aLength
);
184 enum class ValToUse
{ Base
, Anim
};
185 static bool UpdateDeclarationBlockFromLength(
186 StyleLockedDeclarationBlock
& aBlock
, nsCSSPropertyID aPropId
,
187 const SVGAnimatedLength
& aLength
, ValToUse aValToUse
);
188 static bool UpdateDeclarationBlockFromPath(
189 StyleLockedDeclarationBlock
& aBlock
, const SVGAnimatedPathSegList
& aPath
,
192 nsAttrValue
WillChangeLength(uint8_t aAttrEnum
,
193 const mozAutoDocUpdate
& aProofOfUpdate
);
194 nsAttrValue
WillChangeNumberPair(uint8_t aAttrEnum
);
195 nsAttrValue
WillChangeIntegerPair(uint8_t aAttrEnum
,
196 const mozAutoDocUpdate
& aProofOfUpdate
);
197 nsAttrValue
WillChangeOrient(const mozAutoDocUpdate
& aProofOfUpdate
);
198 nsAttrValue
WillChangeViewBox(const mozAutoDocUpdate
& aProofOfUpdate
);
199 nsAttrValue
WillChangePreserveAspectRatio(
200 const mozAutoDocUpdate
& aProofOfUpdate
);
201 nsAttrValue
WillChangeNumberList(uint8_t aAttrEnum
,
202 const mozAutoDocUpdate
& aProofOfUpdate
);
203 nsAttrValue
WillChangeLengthList(uint8_t aAttrEnum
,
204 const mozAutoDocUpdate
& aProofOfUpdate
);
205 nsAttrValue
WillChangePointList(const mozAutoDocUpdate
& aProofOfUpdate
);
206 nsAttrValue
WillChangePathSegList(const mozAutoDocUpdate
& aProofOfUpdate
);
207 nsAttrValue
WillChangeTransformList(const mozAutoDocUpdate
& aProofOfUpdate
);
208 nsAttrValue
WillChangeStringList(bool aIsConditionalProcessingAttribute
,
210 const mozAutoDocUpdate
& aProofOfUpdate
);
212 void DidChangeLength(uint8_t aAttrEnum
, const nsAttrValue
& aEmptyOrOldValue
,
213 const mozAutoDocUpdate
& aProofOfUpdate
);
214 void DidChangeNumber(uint8_t aAttrEnum
);
215 void DidChangeNumberPair(uint8_t aAttrEnum
,
216 const nsAttrValue
& aEmptyOrOldValue
);
217 void DidChangeInteger(uint8_t aAttrEnum
);
218 void DidChangeIntegerPair(uint8_t aAttrEnum
,
219 const nsAttrValue
& aEmptyOrOldValue
,
220 const mozAutoDocUpdate
& aProofOfUpdate
);
221 void DidChangeBoolean(uint8_t aAttrEnum
);
222 void DidChangeEnum(uint8_t aAttrEnum
);
223 void DidChangeOrient(const nsAttrValue
& aEmptyOrOldValue
,
224 const mozAutoDocUpdate
& aProofOfUpdate
);
225 void DidChangeViewBox(const nsAttrValue
& aEmptyOrOldValue
,
226 const mozAutoDocUpdate
& aProofOfUpdate
);
227 void DidChangePreserveAspectRatio(const nsAttrValue
& aEmptyOrOldValue
,
228 const mozAutoDocUpdate
& aProofOfUpdate
);
229 void DidChangeNumberList(uint8_t aAttrEnum
,
230 const nsAttrValue
& aEmptyOrOldValue
,
231 const mozAutoDocUpdate
& aProofOfUpdate
);
232 void DidChangeLengthList(uint8_t aAttrEnum
,
233 const nsAttrValue
& aEmptyOrOldValue
,
234 const mozAutoDocUpdate
& aProofOfUpdate
);
235 void DidChangePointList(const nsAttrValue
& aEmptyOrOldValue
,
236 const mozAutoDocUpdate
& aProofOfUpdate
);
237 void DidChangePathSegList(const nsAttrValue
& aEmptyOrOldValue
,
238 const mozAutoDocUpdate
& aProofOfUpdate
);
239 void DidChangeTransformList(const nsAttrValue
& aEmptyOrOldValue
,
240 const mozAutoDocUpdate
& aProofOfUpdate
);
241 void DidChangeString(uint8_t aAttrEnum
) {}
242 void DidChangeStringList(bool aIsConditionalProcessingAttribute
,
244 const nsAttrValue
& aEmptyOrOldValue
,
245 const mozAutoDocUpdate
& aProofOfUpdate
);
247 void DidAnimateLength(uint8_t aAttrEnum
);
248 void DidAnimateNumber(uint8_t aAttrEnum
) {
249 auto info
= GetNumberInfo();
250 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
252 void DidAnimateNumberPair(uint8_t aAttrEnum
) {
253 auto info
= GetNumberPairInfo();
254 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
256 void DidAnimateInteger(uint8_t aAttrEnum
) {
257 auto info
= GetIntegerInfo();
258 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
260 void DidAnimateIntegerPair(uint8_t aAttrEnum
) {
261 auto info
= GetIntegerPairInfo();
262 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
264 void DidAnimateBoolean(uint8_t aAttrEnum
) {
265 auto info
= GetBooleanInfo();
266 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
268 void DidAnimateEnum(uint8_t aAttrEnum
) {
269 auto info
= GetEnumInfo();
270 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
272 void DidAnimateOrient() {
273 DidAnimateAttribute(kNameSpaceID_None
, nsGkAtoms::orient
);
275 void DidAnimateViewBox() {
276 DidAnimateAttribute(kNameSpaceID_None
, nsGkAtoms::viewBox
);
278 void DidAnimatePreserveAspectRatio() {
279 DidAnimateAttribute(kNameSpaceID_None
, nsGkAtoms::preserveAspectRatio
);
281 void DidAnimateNumberList(uint8_t aAttrEnum
) {
282 auto info
= GetNumberListInfo();
283 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
285 void DidAnimateLengthList(uint8_t aAttrEnum
) {
286 auto info
= GetLengthListInfo();
287 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
289 void DidAnimatePointList();
290 void DidAnimatePathSegList();
291 void DidAnimateTransformList(int32_t aModType
);
292 void DidAnimateString(uint8_t aAttrEnum
) {
293 auto info
= GetStringInfo();
294 DidAnimateAttribute(info
.mInfos
[aAttrEnum
].mNamespaceID
,
295 info
.mInfos
[aAttrEnum
].mName
);
300 * Flag to indicate to GetAnimatedXxx() methods that the object being
301 * requested should be allocated if it hasn't already been allocated, and
302 * that the method should not return null. Only applicable to methods that
303 * need to allocate the object that they return.
308 SVGAnimatedLength
* GetAnimatedLength(uint8_t aAttrEnum
);
309 SVGAnimatedLength
* GetAnimatedLength(const nsAtom
* aAttrName
);
310 void GetAnimatedLengthValues(float* aFirst
, ...);
311 void GetAnimatedNumberValues(float* aFirst
, ...);
312 void GetAnimatedIntegerValues(int32_t* aFirst
, ...);
313 SVGAnimatedNumberList
* GetAnimatedNumberList(uint8_t aAttrEnum
);
314 SVGAnimatedNumberList
* GetAnimatedNumberList(nsAtom
* aAttrName
);
315 void GetAnimatedLengthListValues(SVGUserUnitList
* aFirst
, ...);
316 SVGAnimatedLengthList
* GetAnimatedLengthList(uint8_t aAttrEnum
);
317 virtual SVGAnimatedPointList
* GetAnimatedPointList() { return nullptr; }
318 virtual SVGAnimatedPathSegList
* GetAnimPathSegList() {
319 // DOM interface 'SVGAnimatedPathData' (*inherited* by SVGPathElement)
320 // has a member called 'animatedPathSegList' member, so we have a shorter
321 // name so we don't get hidden by the GetAnimatedPathSegList declared by
322 // NS_DECL_NSIDOMSVGANIMATEDPATHDATA.
326 * Get the SVGAnimatedTransformList for this element.
328 * Despite the fact that animated transform lists are used for a variety of
329 * attributes, no SVG element uses more than one.
331 * It's relatively uncommon for elements to have their transform attribute
332 * set, so to save memory the SVGAnimatedTransformList is not allocated
333 * until the attribute is set/animated or its DOM wrapper is created. Callers
334 * that require the SVGAnimatedTransformList to be allocated and for this
335 * method to return non-null must pass the DO_ALLOCATE flag.
337 virtual SVGAnimatedTransformList
* GetAnimatedTransformList(
338 uint32_t aFlags
= 0) {
342 mozilla::UniquePtr
<SMILAttr
> GetAnimatedAttr(int32_t aNamespaceID
,
343 nsAtom
* aName
) override
;
344 void AnimationNeedsResample();
345 void FlushAnimations();
347 void GetStringBaseValue(uint8_t aAttrEnum
, nsAString
& aResult
) const;
348 void SetStringBaseValue(uint8_t aAttrEnum
, const nsAString
& aValue
);
350 virtual nsStaticAtom
* GetPointListAttrName() const { return nullptr; }
351 virtual nsStaticAtom
* GetPathDataAttrName() const { return nullptr; }
352 virtual nsStaticAtom
* GetTransformListAttrName() const { return nullptr; }
353 const nsAttrValue
* GetAnimatedClassName() const {
354 if (!mClassAttribute
.IsAnimated()) {
357 return mClassAnimAttr
.get();
360 virtual void ClearAnyCachedPath() {}
361 virtual bool IsTransformable() { return false; }
364 mozilla::dom::SVGSVGElement
* GetOwnerSVGElement();
365 SVGElement
* GetViewportElement();
366 already_AddRefed
<mozilla::dom::DOMSVGAnimatedString
> ClassName();
368 bool Autofocus() const { return GetBoolAttr(nsGkAtoms::autofocus
); }
369 void SetAutofocus(bool aAutofocus
, ErrorResult
& aRv
) {
371 SetAttr(nsGkAtoms::autofocus
, u
""_ns
, aRv
);
373 UnsetAttr(nsGkAtoms::autofocus
, aRv
);
378 JSObject
* WrapNode(JSContext
* cx
, JS::Handle
<JSObject
*> aGivenProto
) override
;
380 // We define BeforeSetAttr here and mark it final to ensure it is NOT used
382 // This is because we're not currently passing the correct value for aValue to
383 // BeforeSetAttr since it would involve allocating extra SVG value types.
384 // See the comment in SVGElement::WillChangeValue.
385 void BeforeSetAttr(int32_t aNamespaceID
, nsAtom
* aName
,
386 const nsAttrValue
* aValue
, bool aNotify
) final
;
387 void AfterSetAttr(int32_t aNamespaceID
, nsAtom
* aName
,
388 const nsAttrValue
* aValue
, const nsAttrValue
* aOldValue
,
389 nsIPrincipal
* aSubjectPrincipal
, bool aNotify
) override
;
390 bool ParseAttribute(int32_t aNamespaceID
, nsAtom
* aAttribute
,
391 const nsAString
& aValue
,
392 nsIPrincipal
* aMaybeScriptedPrincipal
,
393 nsAttrValue
& aResult
) override
;
394 static nsresult
ReportAttributeParseFailure(Document
* aDocument
,
396 const nsAString
& aValue
);
398 nsAttrValue
WillChangeValue(nsAtom
* aName
,
399 const mozAutoDocUpdate
& aProofOfUpdate
);
400 // aNewValue is set to the old value. This value may be invalid if
402 void DidChangeValue(nsAtom
* aName
, const nsAttrValue
& aEmptyOrOldValue
,
403 nsAttrValue
& aNewValue
,
404 const mozAutoDocUpdate
& aProofOfUpdate
);
405 void MaybeSerializeAttrBeforeRemoval(nsAtom
* aName
, bool aNotify
);
407 nsAtom
* GetEventNameForAttr(nsAtom
* aAttr
) override
;
410 nsStaticAtom
* const mName
;
411 const float mDefaultValue
;
412 const uint8_t mDefaultUnitType
;
413 const uint8_t mCtxType
;
416 template <typename Value
, typename InfoValue
>
417 struct AttributesInfo
{
418 Value
* const mValues
;
419 const InfoValue
* const mInfos
;
420 const uint32_t mCount
;
422 AttributesInfo(Value
* aValues
, const InfoValue
* aInfos
, uint32_t aCount
)
423 : mValues(aValues
), mInfos(aInfos
), mCount(aCount
) {}
425 void CopyAllFrom(const AttributesInfo
&);
427 void Reset(uint8_t aEnum
);
430 using LengthAttributesInfo
= AttributesInfo
<SVGAnimatedLength
, LengthInfo
>;
433 nsStaticAtom
* const mName
;
434 const float mDefaultValue
;
437 using NumberAttributesInfo
= AttributesInfo
<SVGAnimatedNumber
, NumberInfo
>;
439 struct NumberPairInfo
{
440 nsStaticAtom
* const mName
;
441 const float mDefaultValue1
;
442 const float mDefaultValue2
;
445 using NumberPairAttributesInfo
=
446 AttributesInfo
<SVGAnimatedNumberPair
, NumberPairInfo
>;
449 nsStaticAtom
* const mName
;
450 const int32_t mDefaultValue
;
453 using IntegerAttributesInfo
= AttributesInfo
<SVGAnimatedInteger
, IntegerInfo
>;
455 struct IntegerPairInfo
{
456 nsStaticAtom
* const mName
;
457 const int32_t mDefaultValue1
;
458 const int32_t mDefaultValue2
;
461 using IntegerPairAttributesInfo
=
462 AttributesInfo
<SVGAnimatedIntegerPair
, IntegerPairInfo
>;
465 nsStaticAtom
* const mName
;
466 const bool mDefaultValue
;
469 using BooleanAttributesInfo
= AttributesInfo
<SVGAnimatedBoolean
, BooleanInfo
>;
471 friend class mozilla::SVGAnimatedEnumeration
;
474 nsStaticAtom
* const mName
;
475 const SVGEnumMapping
* const mMapping
;
476 const uint16_t mDefaultValue
;
479 using EnumAttributesInfo
= AttributesInfo
<SVGAnimatedEnumeration
, EnumInfo
>;
481 struct NumberListInfo
{
482 nsStaticAtom
* const mName
;
485 using NumberListAttributesInfo
=
486 AttributesInfo
<SVGAnimatedNumberList
, NumberListInfo
>;
488 struct LengthListInfo
{
489 nsStaticAtom
* const mName
;
492 * Flag to indicate whether appending zeros to the end of the list would
493 * change the rendering of the SVG for the attribute in question. For x and
494 * y on the <text> element this is true, but for dx and dy on <text> this
495 * is false. This flag is fed down to SVGLengthListSMILType so it can
496 * determine if it can sensibly animate from-to lists of different lengths,
497 * which is desirable in the case of dx and dy.
499 const bool mCouldZeroPadList
;
502 using LengthListAttributesInfo
=
503 AttributesInfo
<SVGAnimatedLengthList
, LengthListInfo
>;
506 nsStaticAtom
* const mName
;
507 const int32_t mNamespaceID
;
508 const bool mIsAnimatable
;
511 using StringAttributesInfo
= AttributesInfo
<SVGAnimatedString
, StringInfo
>;
513 friend class DOMSVGStringList
;
515 struct StringListInfo
{
516 nsStaticAtom
* const mName
;
519 using StringListAttributesInfo
=
520 AttributesInfo
<SVGStringList
, StringListInfo
>;
522 virtual LengthAttributesInfo
GetLengthInfo();
523 virtual NumberAttributesInfo
GetNumberInfo();
524 virtual NumberPairAttributesInfo
GetNumberPairInfo();
525 virtual IntegerAttributesInfo
GetIntegerInfo();
526 virtual IntegerPairAttributesInfo
GetIntegerPairInfo();
527 virtual BooleanAttributesInfo
GetBooleanInfo();
528 virtual EnumAttributesInfo
GetEnumInfo();
529 // We assume all orients, viewboxes and preserveAspectRatios are alike
530 // so we don't need to wrap the class
531 virtual SVGAnimatedOrient
* GetAnimatedOrient();
532 virtual SVGAnimatedPreserveAspectRatio
* GetAnimatedPreserveAspectRatio();
533 virtual SVGAnimatedViewBox
* GetAnimatedViewBox();
534 virtual NumberListAttributesInfo
GetNumberListInfo();
535 virtual LengthListAttributesInfo
GetLengthListInfo();
536 virtual StringAttributesInfo
GetStringInfo();
537 virtual StringListAttributesInfo
GetStringListInfo();
539 static SVGEnumMapping sSVGUnitTypesMap
[];
542 void DidAnimateAttribute(int32_t aNameSpaceID
, nsAtom
* aAttribute
);
544 void UnsetAttrInternal(int32_t aNameSpaceID
, nsAtom
* aName
, bool aNotify
);
546 SVGAnimatedClass mClassAttribute
;
547 UniquePtr
<nsAttrValue
> mClassAnimAttr
;
550 NS_DEFINE_STATIC_IID_ACCESSOR(SVGElement
, MOZILLA_SVGELEMENT_IID
)
553 * A macro to implement the NS_NewSVGXXXElement() functions.
555 #define NS_IMPL_NS_NEW_SVG_ELEMENT(_elementName) \
556 nsresult NS_NewSVG##_elementName##Element( \
557 nsIContent** aResult, \
558 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) { \
559 RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo); \
560 auto* nim = nodeInfo->NodeInfoManager(); \
561 RefPtr<mozilla::dom::SVG##_elementName##Element> it = \
562 new (nim) mozilla::dom::SVG##_elementName##Element(nodeInfo.forget()); \
564 nsresult rv = it->Init(); \
566 if (NS_FAILED(rv)) { \
570 it.forget(aResult); \
575 #define NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(_elementName) \
576 nsresult NS_NewSVG##_elementName##Element( \
577 nsIContent** aResult, \
578 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
579 mozilla::dom::FromParser aFromParser) { \
580 RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo); \
581 auto* nim = nodeInfo->NodeInfoManager(); \
582 RefPtr<mozilla::dom::SVG##_elementName##Element> it = \
583 new (nim) mozilla::dom::SVG##_elementName##Element(nodeInfo.forget(), \
586 nsresult rv = it->Init(); \
588 if (NS_FAILED(rv)) { \
592 it.forget(aResult); \
597 // No unlinking, we'd need to null out the value pointer (the object it
598 // points to is held by the element) and null-check it everywhere.
599 #define NS_SVG_VAL_IMPL_CYCLE_COLLECTION(_val, _element) \
600 NS_IMPL_CYCLE_COLLECTION_CLASS(_val) \
601 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_val) \
602 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_element) \
603 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
604 NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_val)
606 #define NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(_val, _element) \
607 NS_IMPL_CYCLE_COLLECTION_CLASS(_val) \
608 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_val) \
609 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
610 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
611 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_val) \
612 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_element) \
613 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
614 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_val) \
615 NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
616 NS_IMPL_CYCLE_COLLECTION_TRACE_END
619 } // namespace mozilla
621 #endif // DOM_SVG_SVGELEMENT_H_