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 the transforms from the coordinate space established by this
139 * element for its children to this element's userspace. This includes any
140 * offsets due to e.g. 'x'/'y' attributes, and any transform due to a
141 * 'viewBox' attribute.
143 virtual gfxMatrix
ChildToUserSpaceTransform() const;
145 // Setter for to set the current <animateMotion> transformation
146 // Only visible for SVGGraphicElement, so it's a no-op here, and that
147 // subclass has the useful implementation.
148 virtual void SetAnimateMotionTransform(
149 const mozilla::gfx::Matrix
* aMatrix
) { /*no-op*/ }
150 virtual const mozilla::gfx::Matrix
* GetAnimateMotionTransform() const {
154 bool IsStringAnimatable(uint8_t aAttrEnum
) {
155 return GetStringInfo().mInfos
[aAttrEnum
].mIsAnimatable
;
157 bool NumberAttrAllowsPercentage(uint8_t aAttrEnum
) {
158 return IsSVGElement(nsGkAtoms::stop
) &&
159 GetNumberInfo().mInfos
[aAttrEnum
].mName
== nsGkAtoms::offset
;
161 virtual bool HasValidDimensions() const { return true; }
162 void SetLength(nsAtom
* aName
, const SVGAnimatedLength
& aLength
);
164 enum class ValToUse
{ Base
, Anim
};
165 static bool UpdateDeclarationBlockFromLength(StyleLockedDeclarationBlock
&,
167 const SVGAnimatedLength
&,
169 static bool UpdateDeclarationBlockFromPath(StyleLockedDeclarationBlock
&,
170 const SVGAnimatedPathSegList
&,
172 static bool UpdateDeclarationBlockFromTransform(
173 StyleLockedDeclarationBlock
&, const SVGAnimatedTransformList
*,
174 const gfx::Matrix
* aAnimateMotionTransform
, ValToUse
);
176 nsAttrValue
WillChangeLength(uint8_t aAttrEnum
,
177 const mozAutoDocUpdate
& aProofOfUpdate
);
178 nsAttrValue
WillChangeNumberPair(uint8_t aAttrEnum
);
179 nsAttrValue
WillChangeIntegerPair(uint8_t aAttrEnum
,
180 const mozAutoDocUpdate
& aProofOfUpdate
);
181 nsAttrValue
WillChangeOrient(const mozAutoDocUpdate
& aProofOfUpdate
);
182 nsAttrValue
WillChangeViewBox(const mozAutoDocUpdate
& aProofOfUpdate
);
183 nsAttrValue
WillChangePreserveAspectRatio(
184 const mozAutoDocUpdate
& aProofOfUpdate
);
185 nsAttrValue
WillChangeNumberList(uint8_t aAttrEnum
,
186 const mozAutoDocUpdate
& aProofOfUpdate
);
187 nsAttrValue
WillChangeLengthList(uint8_t aAttrEnum
,
188 const mozAutoDocUpdate
& aProofOfUpdate
);
189 nsAttrValue
WillChangePointList(const mozAutoDocUpdate
& aProofOfUpdate
);
190 nsAttrValue
WillChangePathSegList(const mozAutoDocUpdate
& aProofOfUpdate
);
191 nsAttrValue
WillChangeTransformList(const mozAutoDocUpdate
& aProofOfUpdate
);
192 nsAttrValue
WillChangeStringList(bool aIsConditionalProcessingAttribute
,
194 const mozAutoDocUpdate
& aProofOfUpdate
);
196 void DidChangeLength(uint8_t aAttrEnum
, const nsAttrValue
& aEmptyOrOldValue
,
197 const mozAutoDocUpdate
& aProofOfUpdate
);
198 void DidChangeNumber(uint8_t aAttrEnum
);
199 void DidChangeNumberPair(uint8_t aAttrEnum
,
200 const nsAttrValue
& aEmptyOrOldValue
);
201 void DidChangeInteger(uint8_t aAttrEnum
);
202 void DidChangeIntegerPair(uint8_t aAttrEnum
,
203 const nsAttrValue
& aEmptyOrOldValue
,
204 const mozAutoDocUpdate
& aProofOfUpdate
);
205 void DidChangeBoolean(uint8_t aAttrEnum
);
206 void DidChangeEnum(uint8_t aAttrEnum
);
207 void DidChangeOrient(const nsAttrValue
& aEmptyOrOldValue
,
208 const mozAutoDocUpdate
& aProofOfUpdate
);
209 void DidChangeViewBox(const nsAttrValue
& aEmptyOrOldValue
,
210 const mozAutoDocUpdate
& aProofOfUpdate
);
211 void DidChangePreserveAspectRatio(const nsAttrValue
& aEmptyOrOldValue
,
212 const mozAutoDocUpdate
& aProofOfUpdate
);
213 void DidChangeNumberList(uint8_t aAttrEnum
,
214 const nsAttrValue
& aEmptyOrOldValue
,
215 const mozAutoDocUpdate
& aProofOfUpdate
);
216 void DidChangeLengthList(uint8_t aAttrEnum
,
217 const nsAttrValue
& aEmptyOrOldValue
,
218 const mozAutoDocUpdate
& aProofOfUpdate
);
219 void DidChangePointList(const nsAttrValue
& aEmptyOrOldValue
,
220 const mozAutoDocUpdate
& aProofOfUpdate
);
221 void DidChangePathSegList(const nsAttrValue
& aEmptyOrOldValue
,
222 const mozAutoDocUpdate
& aProofOfUpdate
);
223 void DidChangeTransformList(const nsAttrValue
& aEmptyOrOldValue
,
224 const mozAutoDocUpdate
& aProofOfUpdate
);
225 void DidChangeString(uint8_t aAttrEnum
) {}
226 void DidChangeStringList(bool aIsConditionalProcessingAttribute
,
228 const nsAttrValue
& aEmptyOrOldValue
,
229 const mozAutoDocUpdate
& aProofOfUpdate
);
231 void DidAnimateLength(uint8_t aAttrEnum
);
232 void DidAnimateNumber(uint8_t aAttrEnum
) {
233 auto info
= GetNumberInfo();
234 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
236 void DidAnimateNumberPair(uint8_t aAttrEnum
) {
237 auto info
= GetNumberPairInfo();
238 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
240 void DidAnimateInteger(uint8_t aAttrEnum
) {
241 auto info
= GetIntegerInfo();
242 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
244 void DidAnimateIntegerPair(uint8_t aAttrEnum
) {
245 auto info
= GetIntegerPairInfo();
246 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
248 void DidAnimateBoolean(uint8_t aAttrEnum
) {
249 auto info
= GetBooleanInfo();
250 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
252 void DidAnimateEnum(uint8_t aAttrEnum
) {
253 auto info
= GetEnumInfo();
254 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
256 void DidAnimateOrient() {
257 DidAnimateAttribute(kNameSpaceID_None
, nsGkAtoms::orient
);
259 void DidAnimateViewBox() {
260 DidAnimateAttribute(kNameSpaceID_None
, nsGkAtoms::viewBox
);
262 void DidAnimatePreserveAspectRatio() {
263 DidAnimateAttribute(kNameSpaceID_None
, nsGkAtoms::preserveAspectRatio
);
265 void DidAnimateNumberList(uint8_t aAttrEnum
) {
266 auto info
= GetNumberListInfo();
267 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
269 void DidAnimateLengthList(uint8_t aAttrEnum
) {
270 auto info
= GetLengthListInfo();
271 DidAnimateAttribute(kNameSpaceID_None
, info
.mInfos
[aAttrEnum
].mName
);
273 void DidAnimatePointList();
274 void DidAnimatePathSegList();
275 void DidAnimateTransformList(int32_t aModType
);
276 void DidAnimateString(uint8_t aAttrEnum
) {
277 auto info
= GetStringInfo();
278 DidAnimateAttribute(info
.mInfos
[aAttrEnum
].mNamespaceID
,
279 info
.mInfos
[aAttrEnum
].mName
);
284 * Flag to indicate to GetAnimatedXxx() methods that the object being
285 * requested should be allocated if it hasn't already been allocated, and
286 * that the method should not return null. Only applicable to methods that
287 * need to allocate the object that they return.
292 SVGAnimatedLength
* GetAnimatedLength(uint8_t aAttrEnum
);
293 SVGAnimatedLength
* GetAnimatedLength(const nsAtom
* aAttrName
);
294 void GetAnimatedLengthValues(float* aFirst
, ...);
295 void GetAnimatedNumberValues(float* aFirst
, ...);
296 void GetAnimatedIntegerValues(int32_t* aFirst
, ...);
297 SVGAnimatedNumberList
* GetAnimatedNumberList(uint8_t aAttrEnum
);
298 SVGAnimatedNumberList
* GetAnimatedNumberList(nsAtom
* aAttrName
);
299 void GetAnimatedLengthListValues(SVGUserUnitList
* aFirst
, ...);
300 SVGAnimatedLengthList
* GetAnimatedLengthList(uint8_t aAttrEnum
);
301 virtual SVGAnimatedPointList
* GetAnimatedPointList() { return nullptr; }
302 virtual SVGAnimatedPathSegList
* GetAnimPathSegList() {
303 // DOM interface 'SVGAnimatedPathData' (*inherited* by SVGPathElement)
304 // has a member called 'animatedPathSegList' member, so we have a shorter
305 // name so we don't get hidden by the GetAnimatedPathSegList declared by
306 // NS_DECL_NSIDOMSVGANIMATEDPATHDATA.
310 * Get the SVGAnimatedTransformList for this element.
312 * Despite the fact that animated transform lists are used for a variety of
313 * attributes, no SVG element uses more than one.
315 * It's relatively uncommon for elements to have their transform attribute
316 * set, so to save memory the SVGAnimatedTransformList is not allocated
317 * until the attribute is set/animated or its DOM wrapper is created. Callers
318 * that require the SVGAnimatedTransformList to be allocated and for this
319 * method to return non-null must pass the DO_ALLOCATE flag.
321 virtual SVGAnimatedTransformList
* GetAnimatedTransformList(
322 uint32_t aFlags
= 0) {
326 mozilla::UniquePtr
<SMILAttr
> GetAnimatedAttr(int32_t aNamespaceID
,
327 nsAtom
* aName
) override
;
328 void AnimationNeedsResample();
329 void FlushAnimations();
331 void GetStringBaseValue(uint8_t aAttrEnum
, nsAString
& aResult
) const;
332 void SetStringBaseValue(uint8_t aAttrEnum
, const nsAString
& aValue
);
334 virtual nsStaticAtom
* GetPointListAttrName() const { return nullptr; }
335 virtual nsStaticAtom
* GetPathDataAttrName() const { return nullptr; }
336 virtual nsStaticAtom
* GetTransformListAttrName() const { return nullptr; }
337 const nsAttrValue
* GetAnimatedClassName() const {
338 if (!mClassAttribute
.IsAnimated()) {
341 return mClassAnimAttr
.get();
344 virtual void ClearAnyCachedPath() {}
345 virtual bool IsTransformable() { return false; }
348 mozilla::dom::SVGSVGElement
* GetOwnerSVGElement();
349 SVGElement
* GetViewportElement();
350 already_AddRefed
<mozilla::dom::DOMSVGAnimatedString
> ClassName();
352 bool Autofocus() const { return GetBoolAttr(nsGkAtoms::autofocus
); }
353 void SetAutofocus(bool aAutofocus
, ErrorResult
& aRv
) {
355 SetAttr(nsGkAtoms::autofocus
, u
""_ns
, aRv
);
357 UnsetAttr(nsGkAtoms::autofocus
, aRv
);
362 JSObject
* WrapNode(JSContext
* cx
, JS::Handle
<JSObject
*> aGivenProto
) override
;
364 // We define BeforeSetAttr here and mark it final to ensure it is NOT used
366 // This is because we're not currently passing the correct value for aValue to
367 // BeforeSetAttr since it would involve allocating extra SVG value types.
368 // See the comment in SVGElement::WillChangeValue.
369 void BeforeSetAttr(int32_t aNamespaceID
, nsAtom
* aName
,
370 const nsAttrValue
* aValue
, bool aNotify
) final
;
371 void AfterSetAttr(int32_t aNamespaceID
, nsAtom
* aName
,
372 const nsAttrValue
* aValue
, const nsAttrValue
* aOldValue
,
373 nsIPrincipal
* aSubjectPrincipal
, bool aNotify
) override
;
374 bool ParseAttribute(int32_t aNamespaceID
, nsAtom
* aAttribute
,
375 const nsAString
& aValue
,
376 nsIPrincipal
* aMaybeScriptedPrincipal
,
377 nsAttrValue
& aResult
) override
;
378 static nsresult
ReportAttributeParseFailure(Document
* aDocument
,
380 const nsAString
& aValue
);
382 nsAttrValue
WillChangeValue(nsAtom
* aName
,
383 const mozAutoDocUpdate
& aProofOfUpdate
);
384 // aNewValue is set to the old value. This value may be invalid if
386 void DidChangeValue(nsAtom
* aName
, const nsAttrValue
& aEmptyOrOldValue
,
387 nsAttrValue
& aNewValue
,
388 const mozAutoDocUpdate
& aProofOfUpdate
);
389 void MaybeSerializeAttrBeforeRemoval(nsAtom
* aName
, bool aNotify
);
391 nsAtom
* GetEventNameForAttr(nsAtom
* aAttr
) override
;
394 nsStaticAtom
* const mName
;
395 const float mDefaultValue
;
396 const uint8_t mDefaultUnitType
;
397 const uint8_t mCtxType
;
400 template <typename Value
, typename InfoValue
>
401 struct AttributesInfo
{
402 Value
* const mValues
;
403 const InfoValue
* const mInfos
;
404 const uint32_t mCount
;
406 AttributesInfo(Value
* aValues
, const InfoValue
* aInfos
, uint32_t aCount
)
407 : mValues(aValues
), mInfos(aInfos
), mCount(aCount
) {}
409 void CopyAllFrom(const AttributesInfo
&);
411 void Reset(uint8_t aEnum
);
414 using LengthAttributesInfo
= AttributesInfo
<SVGAnimatedLength
, LengthInfo
>;
417 nsStaticAtom
* const mName
;
418 const float mDefaultValue
;
421 using NumberAttributesInfo
= AttributesInfo
<SVGAnimatedNumber
, NumberInfo
>;
423 struct NumberPairInfo
{
424 nsStaticAtom
* const mName
;
425 const float mDefaultValue1
;
426 const float mDefaultValue2
;
429 using NumberPairAttributesInfo
=
430 AttributesInfo
<SVGAnimatedNumberPair
, NumberPairInfo
>;
433 nsStaticAtom
* const mName
;
434 const int32_t mDefaultValue
;
437 using IntegerAttributesInfo
= AttributesInfo
<SVGAnimatedInteger
, IntegerInfo
>;
439 struct IntegerPairInfo
{
440 nsStaticAtom
* const mName
;
441 const int32_t mDefaultValue1
;
442 const int32_t mDefaultValue2
;
445 using IntegerPairAttributesInfo
=
446 AttributesInfo
<SVGAnimatedIntegerPair
, IntegerPairInfo
>;
449 nsStaticAtom
* const mName
;
450 const bool mDefaultValue
;
453 using BooleanAttributesInfo
= AttributesInfo
<SVGAnimatedBoolean
, BooleanInfo
>;
455 friend class mozilla::SVGAnimatedEnumeration
;
458 nsStaticAtom
* const mName
;
459 const SVGEnumMapping
* const mMapping
;
460 const uint16_t mDefaultValue
;
463 using EnumAttributesInfo
= AttributesInfo
<SVGAnimatedEnumeration
, EnumInfo
>;
465 struct NumberListInfo
{
466 nsStaticAtom
* const mName
;
469 using NumberListAttributesInfo
=
470 AttributesInfo
<SVGAnimatedNumberList
, NumberListInfo
>;
472 struct LengthListInfo
{
473 nsStaticAtom
* const mName
;
476 * Flag to indicate whether appending zeros to the end of the list would
477 * change the rendering of the SVG for the attribute in question. For x and
478 * y on the <text> element this is true, but for dx and dy on <text> this
479 * is false. This flag is fed down to SVGLengthListSMILType so it can
480 * determine if it can sensibly animate from-to lists of different lengths,
481 * which is desirable in the case of dx and dy.
483 const bool mCouldZeroPadList
;
486 using LengthListAttributesInfo
=
487 AttributesInfo
<SVGAnimatedLengthList
, LengthListInfo
>;
490 nsStaticAtom
* const mName
;
491 const int32_t mNamespaceID
;
492 const bool mIsAnimatable
;
495 using StringAttributesInfo
= AttributesInfo
<SVGAnimatedString
, StringInfo
>;
497 friend class DOMSVGStringList
;
499 struct StringListInfo
{
500 nsStaticAtom
* const mName
;
503 using StringListAttributesInfo
=
504 AttributesInfo
<SVGStringList
, StringListInfo
>;
506 virtual LengthAttributesInfo
GetLengthInfo();
507 virtual NumberAttributesInfo
GetNumberInfo();
508 virtual NumberPairAttributesInfo
GetNumberPairInfo();
509 virtual IntegerAttributesInfo
GetIntegerInfo();
510 virtual IntegerPairAttributesInfo
GetIntegerPairInfo();
511 virtual BooleanAttributesInfo
GetBooleanInfo();
512 virtual EnumAttributesInfo
GetEnumInfo();
513 // We assume all orients, viewboxes and preserveAspectRatios are alike
514 // so we don't need to wrap the class
515 virtual SVGAnimatedOrient
* GetAnimatedOrient();
516 virtual SVGAnimatedPreserveAspectRatio
* GetAnimatedPreserveAspectRatio();
517 virtual SVGAnimatedViewBox
* GetAnimatedViewBox();
518 virtual NumberListAttributesInfo
GetNumberListInfo();
519 virtual LengthListAttributesInfo
GetLengthListInfo();
520 virtual StringAttributesInfo
GetStringInfo();
521 virtual StringListAttributesInfo
GetStringListInfo();
523 static SVGEnumMapping sSVGUnitTypesMap
[];
525 virtual void DidAnimateAttribute(int32_t aNameSpaceID
, nsAtom
* aAttribute
);
528 void UnsetAttrInternal(int32_t aNameSpaceID
, nsAtom
* aName
, bool aNotify
);
530 SVGAnimatedClass mClassAttribute
;
531 UniquePtr
<nsAttrValue
> mClassAnimAttr
;
534 NS_DEFINE_STATIC_IID_ACCESSOR(SVGElement
, MOZILLA_SVGELEMENT_IID
)
537 * A macro to implement the NS_NewSVGXXXElement() functions.
539 #define NS_IMPL_NS_NEW_SVG_ELEMENT(_elementName) \
540 nsresult NS_NewSVG##_elementName##Element( \
541 nsIContent** aResult, \
542 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo) { \
543 RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo); \
544 auto* nim = nodeInfo->NodeInfoManager(); \
545 RefPtr<mozilla::dom::SVG##_elementName##Element> it = \
546 new (nim) mozilla::dom::SVG##_elementName##Element(nodeInfo.forget()); \
548 nsresult rv = it->Init(); \
550 if (NS_FAILED(rv)) { \
554 it.forget(aResult); \
559 #define NS_IMPL_NS_NEW_SVG_ELEMENT_CHECK_PARSER(_elementName) \
560 nsresult NS_NewSVG##_elementName##Element( \
561 nsIContent** aResult, \
562 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo, \
563 mozilla::dom::FromParser aFromParser) { \
564 RefPtr<mozilla::dom::NodeInfo> nodeInfo(aNodeInfo); \
565 auto* nim = nodeInfo->NodeInfoManager(); \
566 RefPtr<mozilla::dom::SVG##_elementName##Element> it = \
567 new (nim) mozilla::dom::SVG##_elementName##Element(nodeInfo.forget(), \
570 nsresult rv = it->Init(); \
572 if (NS_FAILED(rv)) { \
576 it.forget(aResult); \
581 // No unlinking, we'd need to null out the value pointer (the object it
582 // points to is held by the element) and null-check it everywhere.
583 #define NS_SVG_VAL_IMPL_CYCLE_COLLECTION(_val, _element) \
584 NS_IMPL_CYCLE_COLLECTION_CLASS(_val) \
585 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_val) \
586 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_element) \
587 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
588 NS_IMPL_CYCLE_COLLECTION_UNLINK_0(_val)
590 #define NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(_val, _element) \
591 NS_IMPL_CYCLE_COLLECTION_CLASS(_val) \
592 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_val) \
593 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \
594 NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
595 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_val) \
596 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_element) \
597 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \
598 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(_val) \
599 NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER \
600 NS_IMPL_CYCLE_COLLECTION_TRACE_END
603 } // namespace mozilla
605 #endif // DOM_SVG_SVGELEMENT_H_