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_SVGSVGELEMENT_H_
8 #define DOM_SVG_SVGSVGELEMENT_H_
10 #include "SVGAnimatedEnumeration.h"
11 #include "SVGViewportElement.h"
13 nsresult
NS_NewSVGSVGElement(
14 nsIContent
** aResult
, already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
,
15 mozilla::dom::FromParser aFromParser
);
17 // {4b83982c-e5e9-4ca1-abd4-14d27e8b3531}
18 #define MOZILLA_SVGSVGELEMENT_IID \
20 0x4b83982c, 0xe5e9, 0x4ca1, { \
21 0xab, 0xd4, 0x14, 0xd2, 0x7e, 0x8b, 0x35, 0x31 \
26 class AutoSVGViewHandler
;
27 class SMILTimeContainer
;
28 class SVGFragmentIdentifier
;
29 class EventChainPreVisitor
;
32 struct DOMMatrix2DInit
;
41 // Stores svgView arguments of SVG fragment identifiers.
46 SVGAnimatedEnumeration mZoomAndPan
;
47 SVGAnimatedViewBox mViewBox
;
48 SVGAnimatedPreserveAspectRatio mPreserveAspectRatio
;
49 UniquePtr
<SVGAnimatedTransformList
> mTransforms
;
52 using SVGSVGElementBase
= SVGViewportElement
;
54 class SVGSVGElement final
: public SVGSVGElementBase
{
55 friend class mozilla::SVGFragmentIdentifier
;
56 friend class mozilla::SVGOuterSVGFrame
;
57 friend class mozilla::AutoSVGViewHandler
;
58 friend class mozilla::AutoPreserveAspectRatioOverride
;
59 friend class mozilla::dom::SVGView
;
62 SVGSVGElement(already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
,
63 FromParser aFromParser
);
64 JSObject
* WrapNode(JSContext
* aCx
,
65 JS::Handle
<JSObject
*> aGivenProto
) override
;
67 friend nsresult(::NS_NewSVGSVGElement(
69 already_AddRefed
<mozilla::dom::NodeInfo
>&& aNodeInfo
,
70 mozilla::dom::FromParser aFromParser
));
72 ~SVGSVGElement() = default;
75 NS_IMPL_FROMNODE_WITH_TAG(SVGSVGElement
, kNameSpaceID_SVG
, svg
)
78 NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_SVGSVGELEMENT_IID
)
79 NS_DECL_ISUPPORTS_INHERITED
80 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGSVGElement
, SVGSVGElementBase
)
83 * Send appropriate events and updates if our root translate
87 void DidChangeTranslate();
89 // nsIContent interface
90 void GetEventTargetParent(EventChainPreVisitor
& aVisitor
) override
;
91 bool IsEventAttributeNameInternal(nsAtom
* aName
) override
;
94 nsresult
Clone(dom::NodeInfo
*, nsINode
** aResult
) const override
;
97 already_AddRefed
<DOMSVGAnimatedLength
> X();
98 already_AddRefed
<DOMSVGAnimatedLength
> Y();
99 already_AddRefed
<DOMSVGAnimatedLength
> Width();
100 already_AddRefed
<DOMSVGAnimatedLength
> Height();
101 bool UseCurrentView() const;
102 float CurrentScale() const;
103 void SetCurrentScale(float aCurrentScale
);
104 already_AddRefed
<DOMSVGPoint
> CurrentTranslate();
105 uint32_t SuspendRedraw(uint32_t max_wait_milliseconds
);
106 void UnsuspendRedraw(uint32_t suspend_handle_id
);
107 void UnsuspendRedrawAll();
109 void PauseAnimations();
110 void UnpauseAnimations();
111 bool AnimationsPaused();
112 float GetCurrentTimeAsFloat();
113 void SetCurrentTime(float seconds
);
115 already_AddRefed
<DOMSVGNumber
> CreateSVGNumber();
116 already_AddRefed
<DOMSVGLength
> CreateSVGLength();
117 already_AddRefed
<DOMSVGAngle
> CreateSVGAngle();
118 already_AddRefed
<DOMSVGPoint
> CreateSVGPoint();
119 already_AddRefed
<SVGMatrix
> CreateSVGMatrix();
120 already_AddRefed
<SVGRect
> CreateSVGRect();
121 already_AddRefed
<DOMSVGTransform
> CreateSVGTransform();
122 already_AddRefed
<DOMSVGTransform
> CreateSVGTransformFromMatrix(
123 const DOMMatrix2DInit
& matrix
, ErrorResult
& rv
);
124 using nsINode::GetElementById
; // This does what we want
125 uint16_t ZoomAndPan() const;
126 void SetZoomAndPan(uint16_t aZoomAndPan
, ErrorResult
& rv
);
128 // SVGElement overrides
130 nsresult
BindToTree(BindContext
&, nsINode
& aParent
) override
;
131 void UnbindFromTree(UnbindContext
&) override
;
132 SVGAnimatedTransformList
* GetAnimatedTransformList(
133 uint32_t aFlags
= 0) override
;
135 // SVGSVGElement methods:
137 // Returns true IFF our attributes are currently overridden by a <view>
138 // element and that element's ID matches the passed-in string.
139 bool IsOverriddenBy(const nsAString
& aViewID
) const {
140 return mCurrentViewID
&& mCurrentViewID
->Equals(aViewID
);
143 SMILTimeContainer
* GetTimedDocumentRoot();
147 const SVGPoint
& GetCurrentTranslate() const { return mCurrentTranslate
; }
148 bool IsScaledOrTranslated() const {
149 return mCurrentTranslate
!= SVGPoint() || mCurrentScale
!= 1.0f
;
152 LengthPercentage
GetIntrinsicWidth();
153 LengthPercentage
GetIntrinsicHeight();
155 // This services any pending notifications for the transform on on this root
156 // <svg> node needing to be recalculated. (Only applicable in
157 // SVG-as-an-image documents.)
158 virtual void FlushImageTransformInvalidation();
161 // SVGViewportElement methods:
163 virtual SVGViewElement
* GetCurrentViewElement() const;
164 SVGPreserveAspectRatio
GetPreserveAspectRatioWithOverride() const override
;
166 // implementation helpers:
169 * While binding to the tree we need to determine if we will be the outermost
170 * <svg> element _before_ the children are bound (as they want to know what
171 * timed document root to register with) and therefore _before_ our parent is
172 * set (both actions are performed by Element::BindToTree) so we
173 * can't use GetOwnerSVGElement() as it relies on GetParent(). This code is
174 * basically a simplified version of GetOwnerSVGElement that uses the parent
175 * parameters passed in instead.
177 * FIXME(bug 1596690): GetOwnerSVGElement() uses the flattened tree parent
178 * rather than the DOM tree parent nowadays.
180 bool WillBeOutermostSVG(nsINode
& aParent
) const;
182 LengthPercentage
GetIntrinsicWidthOrHeight(int aAttr
);
184 // invalidate viewbox -> viewport xform & inform frames
185 void InvalidateTransformNotifyFrame();
187 // Methods for <image> elements to override my "PreserveAspectRatio" value.
188 // These are private so that only our friends
189 // (AutoPreserveAspectRatioOverride in particular) have access.
190 void SetImageOverridePreserveAspectRatio(const SVGPreserveAspectRatio
& aPAR
);
191 void ClearImageOverridePreserveAspectRatio();
193 // Set/Clear properties to hold old version of preserveAspectRatio
194 // when it's being overridden by an <image> element that we are inside of.
195 bool SetPreserveAspectRatioProperty(const SVGPreserveAspectRatio
& aPAR
);
196 const SVGPreserveAspectRatio
* GetPreserveAspectRatioProperty() const;
197 bool ClearPreserveAspectRatioProperty();
199 const SVGAnimatedViewBox
& GetViewBoxInternal() const override
;
200 SVGAnimatedTransformList
* GetTransformInternal() const override
;
202 EnumAttributesInfo
GetEnumInfo() override
;
205 SVGAnimatedEnumeration mEnumAttributes
[1];
206 static SVGEnumMapping sZoomAndPanMap
[];
207 static EnumInfo sEnumInfo
[1];
209 // The time container for animations within this SVG document fragment. Set
210 // for all outermost <svg> elements (not nested <svg> elements).
211 UniquePtr
<SMILTimeContainer
> mTimedDocumentRoot
;
213 SVGPoint mCurrentTranslate
;
216 // For outermost <svg> elements created from parsing, animation is started by
217 // the onload event in accordance with the SVG spec, but for <svg> elements
218 // created by script or promoted from inner <svg> to outermost <svg> we need
219 // to manually kick off animation when they are bound to the tree.
220 bool mStartAnimationOnBindToTree
;
222 bool mImageNeedsTransformInvalidation
;
224 // mCurrentViewID and mSVGView are mutually exclusive; we can have
225 // at most one non-null.
226 UniquePtr
<nsString
> mCurrentViewID
;
227 UniquePtr
<SVGView
> mSVGView
;
230 NS_DEFINE_STATIC_IID_ACCESSOR(SVGSVGElement
, MOZILLA_SVGSVGELEMENT_IID
)
234 class MOZ_RAII AutoSVGTimeSetRestore
{
236 AutoSVGTimeSetRestore(dom::SVGSVGElement
* aRootElem
, float aFrameTime
)
237 : mRootElem(aRootElem
),
238 mOriginalTime(mRootElem
->GetCurrentTimeAsFloat()) {
239 mRootElem
->SetCurrentTime(
240 aFrameTime
); // Does nothing if there's no change.
243 ~AutoSVGTimeSetRestore() { mRootElem
->SetCurrentTime(mOriginalTime
); }
246 const RefPtr
<dom::SVGSVGElement
> mRootElem
;
247 const float mOriginalTime
;
250 class MOZ_RAII AutoPreserveAspectRatioOverride
{
252 AutoPreserveAspectRatioOverride(const SVGImageContext
& aSVGContext
,
253 dom::SVGSVGElement
* aRootElem
)
254 : mRootElem(aRootElem
), mDidOverride(false) {
255 MOZ_ASSERT(mRootElem
, "No SVG/Symbol node to manage?");
257 if (aSVGContext
.GetPreserveAspectRatio().isSome()) {
258 // Override preserveAspectRatio in our helper document.
259 // XXXdholbert We should technically be overriding the helper doc's clip
260 // and overflow properties here, too. See bug 272288 comment 36.
261 mRootElem
->SetImageOverridePreserveAspectRatio(
262 *aSVGContext
.GetPreserveAspectRatio());
267 ~AutoPreserveAspectRatioOverride() {
269 mRootElem
->ClearImageOverridePreserveAspectRatio();
274 const RefPtr
<dom::SVGSVGElement
> mRootElem
;
278 } // namespace mozilla
280 #endif // DOM_SVG_SVGSVGELEMENT_H_