Bug 1922904 - Fix bug 1780701 in a different approach. r=botond
[gecko.git] / dom / svg / SVGSVGElement.h
blob4efda482109e99045c12453e8a457f48063aa2d7
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 \
20 { \
21 0x4b83982c, 0xe5e9, 0x4ca1, { \
22 0xab, 0xd4, 0x14, 0xd2, 0x7e, 0x8b, 0x35, 0x31 \
23 } \
26 namespace mozilla {
27 class AutoSVGViewHandler;
28 class SMILTimeContainer;
29 class SVGFragmentIdentifier;
30 class EventChainPreVisitor;
32 namespace dom {
33 struct DOMMatrix2DInit;
34 class DOMSVGAngle;
35 class DOMSVGLength;
36 class DOMSVGNumber;
37 class DOMSVGPoint;
38 class SVGMatrix;
39 class SVGRect;
40 class SVGSVGElement;
42 // Stores svgView arguments of SVG fragment identifiers.
43 class SVGView {
44 public:
45 SVGView();
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;
62 protected:
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(
69 nsIContent** aResult,
70 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
71 mozilla::dom::FromParser aFromParser));
73 ~SVGSVGElement() = default;
75 public:
76 NS_IMPL_FROMNODE_WITH_TAG(SVGSVGElement, kNameSpaceID_SVG, svg)
78 // interfaces:
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
85 * has changed.
87 MOZ_CAN_RUN_SCRIPT
88 void DidChangeTranslate();
90 // nsIContent interface
91 void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
92 bool IsEventAttributeNameInternal(nsAtom* aName) override;
94 // nsINode methods:
95 nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
97 // WebIDL
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();
109 void ForceRedraw();
110 void PauseAnimations();
111 void UnpauseAnimations();
112 bool AnimationsPaused();
113 float GetCurrentTimeAsFloat();
114 void SetCurrentTime(float seconds);
115 void DeselectAll();
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();
146 // public helpers:
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();
161 private:
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;
205 enum { ZOOMANDPAN };
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;
215 float mCurrentScale;
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)
233 } // namespace dom
235 class MOZ_RAII AutoSVGTimeSetRestore {
236 public:
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); }
246 private:
247 const RefPtr<dom::SVGSVGElement> mRootElem;
248 const float mOriginalTime;
251 class MOZ_RAII AutoPreserveAspectRatioOverride {
252 public:
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());
264 mDidOverride = true;
268 ~AutoPreserveAspectRatioOverride() {
269 if (mDidOverride) {
270 mRootElem->ClearImageOverridePreserveAspectRatio();
274 private:
275 const RefPtr<dom::SVGSVGElement> mRootElem;
276 bool mDidOverride;
279 } // namespace mozilla
281 #endif // DOM_SVG_SVGSVGELEMENT_H_