Line data Source code
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/. */
6 :
7 : #ifndef mozilla_dom_shadowroot_h__
8 : #define mozilla_dom_shadowroot_h__
9 :
10 : #include "mozilla/dom/DocumentFragment.h"
11 : #include "mozilla/dom/StyleSheetList.h"
12 : #include "mozilla/StyleSheet.h"
13 : #include "nsCOMPtr.h"
14 : #include "nsCycleCollectionParticipant.h"
15 : #include "nsIContentInlines.h"
16 : #include "nsIdentifierMapEntry.h"
17 : #include "nsTHashtable.h"
18 :
19 : class nsIAtom;
20 : class nsIContent;
21 : class nsXBLPrototypeBinding;
22 :
23 : namespace mozilla {
24 : namespace dom {
25 :
26 : class Element;
27 : class HTMLContentElement;
28 : class HTMLShadowElement;
29 : class ShadowRootStyleSheetList;
30 :
31 : class ShadowRoot final : public DocumentFragment,
32 : public nsStubMutationObserver
33 : {
34 : friend class ShadowRootStyleSheetList;
35 : public:
36 0 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot,
37 : DocumentFragment)
38 : NS_DECL_ISUPPORTS_INHERITED
39 :
40 : NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
41 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
42 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
43 : NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
44 :
45 : ShadowRoot(nsIContent* aContent, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
46 : nsXBLPrototypeBinding* aProtoBinding);
47 :
48 : void AddToIdTable(Element* aElement, nsIAtom* aId);
49 : void RemoveFromIdTable(Element* aElement, nsIAtom* aId);
50 : void InsertSheet(StyleSheet* aSheet, nsIContent* aLinkingContent);
51 : void RemoveSheet(StyleSheet* aSheet);
52 : bool ApplyAuthorStyles();
53 : void SetApplyAuthorStyles(bool aApplyAuthorStyles);
54 : StyleSheetList* StyleSheets();
55 0 : HTMLShadowElement* GetShadowElement() { return mShadowElement; }
56 :
57 : /**
58 : * Sets the current shadow insertion point where the older
59 : * ShadowRoot will be projected.
60 : */
61 : void SetShadowElement(HTMLShadowElement* aShadowElement);
62 :
63 : /**
64 : * Change the node that populates the distribution pool with
65 : * its children. This is distinct from the ShadowRoot host described
66 : * in the specifications. The ShadowRoot host is the element
67 : * which created this ShadowRoot and does not change. The pool host
68 : * is the same as the ShadowRoot host if this is the youngest
69 : * ShadowRoot. If this is an older ShadowRoot, the pool host is
70 : * the <shadow> element in the younger ShadowRoot (if it exists).
71 : */
72 : void ChangePoolHost(nsIContent* aNewHost);
73 :
74 : /**
75 : * Distributes a single explicit child of the pool host to the content
76 : * insertion points in this ShadowRoot.
77 : */
78 : void DistributeSingleNode(nsIContent* aContent);
79 :
80 : /**
81 : * Removes a single explicit child of the pool host from the content
82 : * insertion points in this ShadowRoot.
83 : */
84 : void RemoveDistributedNode(nsIContent* aContent);
85 :
86 : /**
87 : * Distributes all the explicit children of the pool host to the content
88 : * insertion points in this ShadowRoot.
89 : */
90 : void DistributeAllNodes();
91 :
92 : void AddInsertionPoint(HTMLContentElement* aInsertionPoint);
93 : void RemoveInsertionPoint(HTMLContentElement* aInsertionPoint);
94 :
95 : void SetYoungerShadow(ShadowRoot* aYoungerShadow);
96 0 : ShadowRoot* GetYoungerShadowRoot() { return mYoungerShadow; }
97 0 : void SetInsertionPointChanged() { mInsertionPointChanged = true; }
98 :
99 0 : void SetAssociatedBinding(nsXBLBinding* aBinding) { mAssociatedBinding = aBinding; }
100 :
101 0 : nsISupports* GetParentObject() const { return mPoolHost; }
102 :
103 0 : nsIContent* GetPoolHost() { return mPoolHost; }
104 0 : nsTArray<HTMLShadowElement*>& ShadowDescendants() { return mShadowDescendants; }
105 :
106 : JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
107 :
108 : static bool IsPooledNode(nsIContent* aChild, nsIContent* aContainer,
109 : nsIContent* aHost);
110 : static ShadowRoot* FromNode(nsINode* aNode);
111 : static bool IsShadowInsertionPoint(nsIContent* aContent);
112 :
113 : static void RemoveDestInsertionPoint(nsIContent* aInsertionPoint,
114 : nsTArray<nsIContent*>& aDestInsertionPoints);
115 :
116 : // WebIDL methods.
117 : Element* GetElementById(const nsAString& aElementId);
118 : already_AddRefed<nsContentList>
119 : GetElementsByTagName(const nsAString& aNamespaceURI);
120 : already_AddRefed<nsContentList>
121 : GetElementsByTagNameNS(const nsAString& aNamespaceURI,
122 : const nsAString& aLocalName);
123 : already_AddRefed<nsContentList>
124 : GetElementsByClassName(const nsAString& aClasses);
125 : void GetInnerHTML(nsAString& aInnerHTML);
126 : void SetInnerHTML(const nsAString& aInnerHTML, ErrorResult& aError);
127 : Element* Host();
128 0 : ShadowRoot* GetOlderShadowRoot() { return mOlderShadow; }
129 : void StyleSheetChanged();
130 :
131 0 : bool IsComposedDocParticipant() { return mIsComposedDocParticipant; }
132 0 : void SetIsComposedDocParticipant(bool aIsComposedDocParticipant)
133 : {
134 0 : mIsComposedDocParticipant = aIsComposedDocParticipant;
135 0 : }
136 :
137 : virtual void DestroyContent() override;
138 : protected:
139 : virtual ~ShadowRoot();
140 :
141 : // The pool host is the parent of the nodes that will be distributed
142 : // into the insertion points in this ShadowRoot. See |ChangeShadowRoot|.
143 : nsCOMPtr<nsIContent> mPoolHost;
144 :
145 : // An array of content insertion points that are a descendant of the ShadowRoot
146 : // sorted in tree order. Insertion points are responsible for notifying
147 : // the ShadowRoot when they are removed or added as a descendant. The insertion
148 : // points are kept alive by the parent node, thus weak references are held
149 : // by the array.
150 : nsTArray<HTMLContentElement*> mInsertionPoints;
151 :
152 : // An array of the <shadow> elements that are descendant of the ShadowRoot
153 : // sorted in tree order. Only the first may be a shadow insertion point.
154 : nsTArray<HTMLShadowElement*> mShadowDescendants;
155 :
156 : nsTHashtable<nsIdentifierMapEntry> mIdentifierMap;
157 : nsXBLPrototypeBinding* mProtoBinding;
158 :
159 : // It is necessary to hold a reference to the associated nsXBLBinding
160 : // because the binding holds a reference on the nsXBLDocumentInfo that
161 : // owns |mProtoBinding|.
162 : RefPtr<nsXBLBinding> mAssociatedBinding;
163 :
164 : RefPtr<ShadowRootStyleSheetList> mStyleSheetList;
165 :
166 : // The current shadow insertion point of this ShadowRoot.
167 : HTMLShadowElement* mShadowElement;
168 :
169 : // The ShadowRoot that was created by the host element before
170 : // this ShadowRoot was created.
171 : RefPtr<ShadowRoot> mOlderShadow;
172 :
173 : // The ShadowRoot that was created by the host element after
174 : // this ShadowRoot was created.
175 : RefPtr<ShadowRoot> mYoungerShadow;
176 :
177 : // A boolean that indicates that an insertion point was added or removed
178 : // from this ShadowRoot and that the nodes need to be redistributed into
179 : // the insertion points. After this flag is set, nodes will be distributed
180 : // on the next mutation event.
181 : bool mInsertionPointChanged;
182 :
183 : // Flag to indicate whether the descendants of this shadow root are part of the
184 : // composed document. Ideally, we would use a node flag on nodes to
185 : // mark whether it is in the composed document, but we have run out of flags
186 : // so instead we track it here.
187 : bool mIsComposedDocParticipant;
188 :
189 : nsresult Clone(mozilla::dom::NodeInfo *aNodeInfo, nsINode **aResult,
190 : bool aPreallocateChildren) const override;
191 : };
192 :
193 : class ShadowRootStyleSheetList : public StyleSheetList
194 : {
195 : public:
196 : explicit ShadowRootStyleSheetList(ShadowRoot* aShadowRoot);
197 :
198 : NS_DECL_ISUPPORTS_INHERITED
199 0 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRootStyleSheetList, StyleSheetList)
200 :
201 0 : virtual nsINode* GetParentObject() const override
202 : {
203 0 : return mShadowRoot;
204 : }
205 :
206 : uint32_t Length() override;
207 : StyleSheet* IndexedGetter(uint32_t aIndex, bool& aFound) override;
208 :
209 : protected:
210 : virtual ~ShadowRootStyleSheetList();
211 :
212 : RefPtr<ShadowRoot> mShadowRoot;
213 : };
214 :
215 : } // namespace dom
216 : } // namespace mozilla
217 :
218 : #endif // mozilla_dom_shadowroot_h__
219 :
|