Bug 1665252 - remove allowpaymentrequest attribute from HTMLIFrameElement r=dom-worke...
[gecko.git] / dom / base / ShadowRoot.h
blob0308bd9ef9f14ef5df8593f0bfa373c6a32a8a94
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 mozilla_dom_shadowroot_h__
8 #define mozilla_dom_shadowroot_h__
10 #include "mozilla/dom/DocumentBinding.h"
11 #include "mozilla/dom/DocumentFragment.h"
12 #include "mozilla/dom/DocumentOrShadowRoot.h"
13 #include "mozilla/dom/NameSpaceConstants.h"
14 #include "mozilla/dom/ShadowRootBinding.h"
15 #include "mozilla/ServoBindings.h"
16 #include "nsCOMPtr.h"
17 #include "nsCycleCollectionParticipant.h"
18 #include "nsIRadioGroupContainer.h"
19 #include "nsStubMutationObserver.h"
20 #include "nsTHashtable.h"
22 class nsAtom;
23 class nsIContent;
24 class nsXBLPrototypeBinding;
26 namespace mozilla {
28 class EventChainPreVisitor;
29 class ServoStyleRuleMap;
31 enum class StyleRuleChangeKind : uint32_t;
33 namespace css {
34 class Rule;
37 namespace dom {
39 class CSSImportRule;
40 class Element;
41 class HTMLInputElement;
43 class ShadowRoot final : public DocumentFragment,
44 public DocumentOrShadowRoot,
45 public nsIRadioGroupContainer {
46 friend class DocumentOrShadowRoot;
48 public:
49 NS_IMPL_FROMNODE_HELPER(ShadowRoot, IsShadowRoot());
51 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ShadowRoot, DocumentFragment)
52 NS_DECL_ISUPPORTS_INHERITED
54 ShadowRoot(Element* aElement, ShadowRootMode aMode,
55 already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo);
57 void AddSizeOfExcludingThis(nsWindowSizes&, size_t* aNodeSize) const final;
59 // Try to reassign an element to a slot.
60 void MaybeReassignElement(Element&);
61 // Called when an element is inserted as a direct child of our host. Tries to
62 // slot the child in one of our slots.
63 void MaybeSlotHostChild(nsIContent&);
64 // Called when a direct child of our host is removed. Tries to un-slot the
65 // child from the currently-assigned slot, if any.
66 void MaybeUnslotHostChild(nsIContent&);
68 // Shadow DOM v1
69 Element* Host() const {
70 MOZ_ASSERT(GetHost(),
71 "ShadowRoot always has a host, how did we create "
72 "this ShadowRoot?");
73 return GetHost();
76 ShadowRootMode Mode() const { return mMode; }
77 bool IsClosed() const { return mMode == ShadowRootMode::Closed; }
79 void RemoveSheetFromStyles(StyleSheet&);
80 void RuleAdded(StyleSheet&, css::Rule&);
81 void RuleRemoved(StyleSheet&, css::Rule&);
82 void RuleChanged(StyleSheet&, css::Rule*, StyleRuleChangeKind);
83 void ImportRuleLoaded(CSSImportRule&, StyleSheet&);
84 void SheetCloned(StyleSheet&);
85 void StyleSheetApplicableStateChanged(StyleSheet&);
87 /**
88 * Clones internal state, for example stylesheets, of aOther to 'this'.
90 void CloneInternalDataFrom(ShadowRoot* aOther);
91 void InsertSheetAt(size_t aIndex, StyleSheet&);
93 // Calls UnbindFromTree for each of our kids, and also flags us as no longer
94 // being connected.
95 void Unbind();
97 // Only intended for UA widgets / special shadow roots, or for handling
98 // failure cases when adopting (see BlastSubtreeToPieces).
100 // Forgets our shadow host and unbinds all our kids.
101 void Unattach();
103 // Calls BindToTree on each of our kids, and also maybe flags us as being
104 // connected.
105 nsresult Bind();
107 private:
108 void InsertSheetIntoAuthorData(size_t aIndex, StyleSheet&,
109 const nsTArray<RefPtr<StyleSheet>>&);
111 void AppendStyleSheet(StyleSheet& aSheet) {
112 InsertSheetAt(SheetCount(), aSheet);
116 * Represents the insertion point in a slot for a given node.
118 struct SlotAssignment {
119 HTMLSlotElement* mSlot = nullptr;
120 Maybe<uint32_t> mIndex;
122 SlotAssignment() = default;
123 SlotAssignment(HTMLSlotElement* aSlot, const Maybe<uint32_t>& aIndex)
124 : mSlot(aSlot), mIndex(aIndex) {}
128 * Return the assignment corresponding to the content node at this particular
129 * point in time.
131 * It's the caller's responsibility to actually call InsertAssignedNode /
132 * AppendAssignedNode in the slot as needed.
134 SlotAssignment SlotAssignmentFor(nsIContent&);
137 * Explicitly invalidates the style and layout of the flattened-tree subtree
138 * rooted at the element.
140 * You need to use this whenever the flat tree is going to be shuffled in a
141 * way that layout doesn't understand via the usual ContentInserted /
142 * ContentAppended / ContentRemoved notifications. For example, if removing an
143 * element will cause a change in the flat tree such that other element will
144 * start showing up (like fallback content), this method needs to be called on
145 * an ancestor of that element.
147 * It is important that this runs _before_ actually shuffling the flat tree
148 * around, so that layout knows the actual tree that it needs to invalidate.
150 void InvalidateStyleAndLayoutOnSubtree(Element*);
152 public:
153 void AddSlot(HTMLSlotElement* aSlot);
154 void RemoveSlot(HTMLSlotElement* aSlot);
155 bool HasSlots() const { return !mSlotMap.IsEmpty(); };
156 HTMLSlotElement* GetDefaultSlot() const {
157 SlotArray* list = mSlotMap.Get(u""_ns);
158 return list ? (*list)->ElementAt(0) : nullptr;
161 void PartAdded(const Element&);
162 void PartRemoved(const Element&);
164 const nsTArray<const Element*>& Parts() const { return mParts; }
166 const RawServoAuthorStyles* GetServoStyles() const {
167 return mServoStyles.get();
170 RawServoAuthorStyles* GetServoStyles() { return mServoStyles.get(); }
172 mozilla::ServoStyleRuleMap& ServoStyleRuleMap();
174 JSObject* WrapNode(JSContext*, JS::Handle<JSObject*> aGivenProto) final;
176 void NodeInfoChanged(Document* aOldDoc) override {
177 DocumentFragment::NodeInfoChanged(aOldDoc);
178 ClearAdoptedStyleSheets();
181 void AddToIdTable(Element* aElement, nsAtom* aId);
182 void RemoveFromIdTable(Element* aElement, nsAtom* aId);
184 // WebIDL methods.
185 using mozilla::dom::DocumentOrShadowRoot::GetElementById;
187 Element* GetActiveElement();
190 * These methods allow UA Widget to insert DOM elements into the Shadow ROM
191 * without putting their DOM reflectors to content scope first.
192 * The inserted DOM will have their reflectors in the UA Widget scope.
194 nsINode* ImportNodeAndAppendChildAt(nsINode& aParentNode, nsINode& aNode,
195 bool aDeep, mozilla::ErrorResult& rv);
197 nsINode* CreateElementAndAppendChildAt(nsINode& aParentNode,
198 const nsAString& aTagName,
199 mozilla::ErrorResult& rv);
201 bool IsUAWidget() const { return mIsUAWidget; }
203 void SetIsUAWidget() {
204 MOZ_ASSERT(!HasChildren());
205 SetFlags(NODE_HAS_BEEN_IN_UA_WIDGET);
206 mIsUAWidget = true;
209 void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
211 // nsIRadioGroupContainer
212 NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor,
213 bool aFlushContent) override {
214 return DocumentOrShadowRoot::WalkRadioGroup(aName, aVisitor, aFlushContent);
216 virtual void SetCurrentRadioButton(const nsAString& aName,
217 HTMLInputElement* aRadio) override {
218 DocumentOrShadowRoot::SetCurrentRadioButton(aName, aRadio);
220 virtual HTMLInputElement* GetCurrentRadioButton(
221 const nsAString& aName) override {
222 return DocumentOrShadowRoot::GetCurrentRadioButton(aName);
224 NS_IMETHOD
225 GetNextRadioButton(const nsAString& aName, const bool aPrevious,
226 HTMLInputElement* aFocusedRadio,
227 HTMLInputElement** aRadioOut) override {
228 return DocumentOrShadowRoot::GetNextRadioButton(aName, aPrevious,
229 aFocusedRadio, aRadioOut);
231 virtual void AddToRadioGroup(const nsAString& aName,
232 HTMLInputElement* aRadio) override {
233 DocumentOrShadowRoot::AddToRadioGroup(aName, aRadio);
235 virtual void RemoveFromRadioGroup(const nsAString& aName,
236 HTMLInputElement* aRadio) override {
237 DocumentOrShadowRoot::RemoveFromRadioGroup(aName, aRadio);
239 virtual uint32_t GetRequiredRadioCount(
240 const nsAString& aName) const override {
241 return DocumentOrShadowRoot::GetRequiredRadioCount(aName);
243 virtual void RadioRequiredWillChange(const nsAString& aName,
244 bool aRequiredAdded) override {
245 DocumentOrShadowRoot::RadioRequiredWillChange(aName, aRequiredAdded);
247 virtual bool GetValueMissingState(const nsAString& aName) const override {
248 return DocumentOrShadowRoot::GetValueMissingState(aName);
250 virtual void SetValueMissingState(const nsAString& aName,
251 bool aValue) override {
252 return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
255 protected:
256 // FIXME(emilio): This will need to become more fine-grained.
257 void ApplicableRulesChanged();
259 virtual ~ShadowRoot();
261 const ShadowRootMode mMode;
263 // The computed data from the style sheets.
264 UniquePtr<RawServoAuthorStyles> mServoStyles;
265 UniquePtr<mozilla::ServoStyleRuleMap> mStyleRuleMap;
267 using SlotArray = TreeOrderedArray<HTMLSlotElement>;
268 // Map from name of slot to an array of all slots in the shadow DOM with with
269 // the given name. The slots are stored as a weak pointer because the elements
270 // are in the shadow tree and should be kept alive by its parent.
271 nsClassHashtable<nsStringHashKey, SlotArray> mSlotMap;
273 // Unordered array of all elements that have a part attribute in this shadow
274 // tree.
275 nsTArray<const Element*> mParts;
277 bool mIsUAWidget : 1;
279 nsresult Clone(dom::NodeInfo*, nsINode** aResult) const override;
282 } // namespace dom
283 } // namespace mozilla
285 #endif // mozilla_dom_shadowroot_h__