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