Bug 1889091 - Part 6: Remove "scratch" register parameter from emitPushArguments...
[gecko.git] / dom / svg / SVGUseElement.h
blob3bdf3fc5bb620c677d0bda490b2fd7a341614351
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_SVGUSEELEMENT_H_
8 #define DOM_SVG_SVGUSEELEMENT_H_
10 #include "mozilla/dom/FromParser.h"
11 #include "mozilla/dom/IDTracker.h"
12 #include "mozilla/dom/SVGGraphicsElement.h"
13 #include "mozilla/RefPtr.h"
14 #include "nsCOMPtr.h"
15 #include "nsStubMutationObserver.h"
16 #include "SVGAnimatedLength.h"
17 #include "SVGAnimatedString.h"
18 #include "nsTArray.h"
20 class nsIContent;
22 nsresult NS_NewSVGSVGElement(
23 nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
24 mozilla::dom::FromParser aFromParser);
25 nsresult NS_NewSVGUseElement(
26 nsIContent** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
28 namespace mozilla {
29 class Encoding;
30 class SVGUseFrame;
31 struct URLExtraData;
33 namespace dom {
35 using SVGUseElementBase = SVGGraphicsElement;
37 class SVGUseElement final : public SVGUseElementBase,
38 public nsStubMutationObserver {
39 friend class mozilla::SVGUseFrame;
41 protected:
42 friend nsresult(::NS_NewSVGUseElement(
43 nsIContent** aResult,
44 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo));
45 explicit SVGUseElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
46 virtual ~SVGUseElement();
47 JSObject* WrapNode(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
49 public:
50 NS_IMPL_FROMNODE_WITH_TAG(SVGUseElement, kNameSpaceID_SVG, use)
52 nsresult BindToTree(BindContext&, nsINode& aParent) override;
53 void UnbindFromTree(UnbindContext&) override;
55 // interfaces:
56 NS_DECL_ISUPPORTS_INHERITED
57 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGUseElement, SVGUseElementBase)
59 NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
60 NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
61 NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
62 NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
63 NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
64 NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED
66 // SVGElement specializations:
67 gfxMatrix PrependLocalTransformsTo(
68 const gfxMatrix& aMatrix,
69 SVGTransformTypes aWhich = eAllTransforms) const override;
70 bool HasValidDimensions() const override;
72 // nsIContent interface
73 nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
74 NS_IMETHOD_(bool) IsAttributeMapped(const nsAtom* aAttribute) const override;
76 static nsCSSPropertyID GetCSSPropertyIdForAttrEnum(uint8_t aAttrEnum);
78 // WebIDL
79 already_AddRefed<DOMSVGAnimatedString> Href();
80 already_AddRefed<DOMSVGAnimatedLength> X();
81 already_AddRefed<DOMSVGAnimatedLength> Y();
82 already_AddRefed<DOMSVGAnimatedLength> Width();
83 already_AddRefed<DOMSVGAnimatedLength> Height();
85 nsIURI* GetSourceDocURI();
86 const Encoding* GetSourceDocCharacterSet();
87 URLExtraData* GetContentURLData() const { return mContentURLData; }
89 // Updates the internal shadow tree to be an up-to-date clone of the
90 // referenced element.
91 void UpdateShadowTree();
93 // Shared code between AfterSetAttr and SVGUseFrame::AttributeChanged.
95 // This is needed because SMIL doesn't go through AfterSetAttr unfortunately.
96 void ProcessAttributeChange(int32_t aNamespaceID, nsAtom* aAttribute);
98 void AfterSetAttr(int32_t aNamespaceID, nsAtom* aAttribute,
99 const nsAttrValue* aValue, const nsAttrValue* aOldValue,
100 nsIPrincipal* aSubjectPrincipal, bool aNotify) final;
102 protected:
103 // Information from walking our ancestors and a given target.
104 enum class ScanResult {
105 // Nothing that should stop us from rendering the shadow tree.
107 // We're never going to be displayed, so no point in updating the shadow
108 // tree.
110 // However if we're referenced from another tree that tree may need to be
111 // rendered.
112 Invisible,
113 // We're a cyclic reference to either an ancestor or another shadow tree. We
114 // shouldn't render this <use> element.
115 CyclicReference,
116 // We're too deep in our clone chain, we shouldn't be rendered.
117 TooDeep,
119 ScanResult ScanAncestors(const Element& aTarget) const;
120 ScanResult ScanAncestorsInternal(const Element& aTarget,
121 uint32_t& aCount) const;
124 * Helper that provides a reference to the element with the ID that is
125 * referenced by the 'use' element's 'href' attribute, and that will update
126 * the 'use' element if the element that that ID identifies changes to a
127 * different element (or none).
129 class ElementTracker final : public IDTracker {
130 public:
131 explicit ElementTracker(SVGUseElement* aOwningUseElement)
132 : mOwningUseElement(aOwningUseElement) {}
134 private:
135 void ElementChanged(Element* aFrom, Element* aTo) override {
136 IDTracker::ElementChanged(aFrom, aTo);
137 if (aFrom) {
138 aFrom->RemoveMutationObserver(mOwningUseElement);
140 mOwningUseElement->TriggerReclone();
143 SVGUseElement* mOwningUseElement;
146 SVGUseFrame* GetFrame() const;
148 LengthAttributesInfo GetLengthInfo() override;
149 StringAttributesInfo GetStringInfo() override;
152 * Returns true if our width and height should be used, or false if they
153 * should be ignored. As per the spec, this depends on the type of the
154 * element that we're referencing.
156 bool OurWidthAndHeightAreUsed() const;
157 void SyncWidthOrHeight(nsAtom* aName);
158 void LookupHref();
159 void TriggerReclone();
160 void UnlinkSource();
162 enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
163 SVGAnimatedLength mLengthAttributes[4];
164 static LengthInfo sLengthInfo[4];
166 enum { HREF, XLINK_HREF };
167 SVGAnimatedString mStringAttributes[2];
168 static StringInfo sStringInfo[2];
170 RefPtr<SVGUseElement> mOriginal; // if we've been cloned, our "real" copy
171 ElementTracker mReferencedElementTracker;
172 RefPtr<URLExtraData> mContentURLData; // URL data for its anonymous content
175 } // namespace dom
176 } // namespace mozilla
178 #endif // DOM_SVG_SVGUSEELEMENT_H_