Bug 1665252 - remove allowpaymentrequest attribute from HTMLIFrameElement r=dom-worke...
[gecko.git] / dom / base / DocumentOrShadowRoot.h
blobfea333989b187e2c76ac45e7f7e95de8eb6a621c
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_DocumentOrShadowRoot_h__
8 #define mozilla_dom_DocumentOrShadowRoot_h__
10 #include "mozilla/dom/NameSpaceConstants.h"
11 #include "mozilla/IdentifierMapEntry.h"
12 #include "mozilla/RelativeTo.h"
13 #include "nsClassHashtable.h"
14 #include "nsContentListDeclarations.h"
15 #include "nsTArray.h"
17 class nsContentList;
18 class nsCycleCollectionTraversalCallback;
19 class nsINode;
20 class nsINodeList;
21 class nsIRadioVisitor;
22 class nsWindowSizes;
24 namespace mozilla {
25 class ErrorResult;
26 class StyleSheet;
27 class ErrorResult;
29 namespace dom {
31 class Animation;
32 class Element;
33 class Document;
34 class DocumentOrShadowRoot;
35 class HTMLInputElement;
36 struct nsRadioGroupStruct;
37 class StyleSheetList;
38 class ShadowRoot;
39 template <typename T>
40 class Sequence;
42 /**
43 * A class meant to be shared by ShadowRoot and Document, that holds a list of
44 * stylesheets.
46 * TODO(emilio, bug 1418159): In the future this should hold most of the
47 * relevant style state, this should allow us to fix bug 548397.
49 class DocumentOrShadowRoot {
50 enum class Kind {
51 Document,
52 ShadowRoot,
55 public:
56 // These should always be non-null, but can't use a reference because
57 // dereferencing `this` on initializer lists is UB, apparently, see
58 // bug 1596499.
59 explicit DocumentOrShadowRoot(Document*);
60 explicit DocumentOrShadowRoot(ShadowRoot*);
62 // Unusual argument naming is because of cycle collection macros.
63 static void Traverse(DocumentOrShadowRoot* tmp,
64 nsCycleCollectionTraversalCallback& cb);
65 static void Unlink(DocumentOrShadowRoot* tmp);
67 nsINode& AsNode() { return *mAsNode; }
69 const nsINode& AsNode() const { return *mAsNode; }
71 StyleSheet* SheetAt(size_t aIndex) const {
72 return mStyleSheets.SafeElementAt(aIndex);
75 size_t SheetCount() const { return mStyleSheets.Length(); }
77 size_t AdoptedSheetCount() const { return mAdoptedStyleSheets.Length(); }
79 /**
80 * Returns an index for the sheet in relative style order.
81 * If there are non-applicable sheets, then this index may
82 * not match 1:1 with the sheet's actual index in the style set.
84 * Handles sheets from both mStyleSheets and mAdoptedStyleSheets
86 int32_t StyleOrderIndexOfSheet(const StyleSheet& aSheet) const;
88 StyleSheetList* StyleSheets();
90 void GetAdoptedStyleSheets(nsTArray<RefPtr<StyleSheet>>&) const;
92 void RemoveStyleSheet(StyleSheet&);
94 Element* GetElementById(const nsAString& aElementId);
96 /**
97 * This method returns _all_ the elements in this scope which have id
98 * aElementId, if there are any. Otherwise it returns null.
100 * This is useful for stuff like QuerySelector optimization and such.
102 inline const nsTArray<Element*>* GetAllElementsForId(
103 const nsAString& aElementId) const;
105 already_AddRefed<nsContentList> GetElementsByTagName(
106 const nsAString& aTagName) {
107 return NS_GetContentList(&AsNode(), kNameSpaceID_Unknown, aTagName);
110 already_AddRefed<nsContentList> GetElementsByTagNameNS(
111 const nsAString& aNamespaceURI, const nsAString& aLocalName);
113 already_AddRefed<nsContentList> GetElementsByTagNameNS(
114 const nsAString& aNamespaceURI, const nsAString& aLocalName,
115 mozilla::ErrorResult&);
117 already_AddRefed<nsContentList> GetElementsByClassName(
118 const nsAString& aClasses);
120 ~DocumentOrShadowRoot();
122 Element* GetPointerLockElement();
123 Element* GetFullscreenElement();
125 Element* ElementFromPoint(float aX, float aY);
126 nsINode* NodeFromPoint(float aX, float aY);
128 void ElementsFromPoint(float aX, float aY, nsTArray<RefPtr<Element>>&);
129 void NodesFromPoint(float aX, float aY, nsTArray<RefPtr<nsINode>>&);
132 * Helper for elementFromPoint implementation that allows
133 * ignoring the scroll frame and/or avoiding layout flushes.
135 * @see nsIDOMWindowUtils::elementFromPoint
137 Element* ElementFromPointHelper(float aX, float aY,
138 bool aIgnoreRootScrollFrame,
139 bool aFlushLayout,
140 ViewportType aViewportType);
142 void NodesFromRect(float aX, float aY, float aTopSize, float aRightSize,
143 float aBottomSize, float aLeftSize,
144 bool aIgnoreRootScrollFrame, bool aFlushLayout,
145 bool aOnlyVisible, nsTArray<RefPtr<nsINode>>&);
148 * This gets fired when the element that an id refers to changes.
149 * This fires at difficult times. It is generally not safe to do anything
150 * which could modify the DOM in any way. Use
151 * nsContentUtils::AddScriptRunner.
152 * @return true to keep the callback in the callback set, false
153 * to remove it.
155 typedef bool (*IDTargetObserver)(Element* aOldElement, Element* aNewelement,
156 void* aData);
159 * Add an IDTargetObserver for a specific ID. The IDTargetObserver
160 * will be fired whenever the content associated with the ID changes
161 * in the future. If aForImage is true, mozSetImageElement can override
162 * what content is associated with the ID. In that case the IDTargetObserver
163 * will be notified at those times when the result of LookupImageElement
164 * changes.
165 * At most one (aObserver, aData, aForImage) triple can be
166 * registered for each ID.
167 * @return the content currently associated with the ID.
169 Element* AddIDTargetObserver(nsAtom* aID, IDTargetObserver aObserver,
170 void* aData, bool aForImage);
173 * Remove the (aObserver, aData, aForImage) triple for a specific ID, if
174 * registered.
176 void RemoveIDTargetObserver(nsAtom* aID, IDTargetObserver aObserver,
177 void* aData, bool aForImage);
180 * Lookup an image element using its associated ID, which is usually provided
181 * by |-moz-element()|. Similar to GetElementById, with the difference that
182 * elements set using mozSetImageElement have higher priority.
183 * @param aId the ID associated the element we want to lookup
184 * @return the element associated with |aId|
186 Element* LookupImageElement(const nsAString& aElementId);
189 * Check that aId is not empty and log a message to the console
190 * service if it is.
191 * @returns true if aId looks correct, false otherwise.
193 inline bool CheckGetElementByIdArg(const nsAString& aId) {
194 if (aId.IsEmpty()) {
195 ReportEmptyGetElementByIdArg();
196 return false;
198 return true;
201 void ReportEmptyGetElementByIdArg();
203 // Web Animations
204 MOZ_CAN_RUN_SCRIPT
205 void GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations);
207 // nsIRadioGroupContainer
208 NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor,
209 bool aFlushContent);
210 void SetCurrentRadioButton(const nsAString& aName, HTMLInputElement* aRadio);
211 HTMLInputElement* GetCurrentRadioButton(const nsAString& aName);
212 nsresult GetNextRadioButton(const nsAString& aName, const bool aPrevious,
213 HTMLInputElement* aFocusedRadio,
214 HTMLInputElement** aRadioOut);
215 void AddToRadioGroup(const nsAString& aName, HTMLInputElement* aRadio);
216 void RemoveFromRadioGroup(const nsAString& aName, HTMLInputElement* aRadio);
217 uint32_t GetRequiredRadioCount(const nsAString& aName) const;
218 void RadioRequiredWillChange(const nsAString& aName, bool aRequiredAdded);
219 bool GetValueMissingState(const nsAString& aName) const;
220 void SetValueMissingState(const nsAString& aName, bool aValue);
222 // for radio group
223 nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const;
224 nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName);
226 nsIContent* Retarget(nsIContent* aContent) const;
228 void SetAdoptedStyleSheets(
229 const Sequence<OwningNonNull<StyleSheet>>& aAdoptedStyleSheets,
230 ErrorResult& aRv);
232 // This is needed because ServoStyleSet / ServoAuthorData don't deal with
233 // duplicate stylesheets (and it's unclear we'd want to support that as it'd
234 // be a bunch of duplicate work), while adopted stylesheets do need to deal
235 // with them.
236 template <typename Callback>
237 void EnumerateUniqueAdoptedStyleSheetsBackToFront(Callback aCallback) {
238 StyleSheetSet set(mAdoptedStyleSheets.Length());
239 for (StyleSheet* sheet : Reversed(mAdoptedStyleSheets)) {
240 if (MOZ_UNLIKELY(!set.EnsureInserted(sheet))) {
241 continue;
243 aCallback(*sheet);
247 protected:
248 // Cycle collection helper functions
249 void TraverseSheetRefInStylesIfApplicable(
250 StyleSheet&, nsCycleCollectionTraversalCallback&);
251 void TraverseStyleSheets(nsTArray<RefPtr<StyleSheet>>&, const char*,
252 nsCycleCollectionTraversalCallback&);
253 void UnlinkStyleSheets(nsTArray<RefPtr<StyleSheet>>&);
255 using StyleSheetSet = nsTHashtable<nsPtrHashKey<const StyleSheet>>;
256 void RemoveSheetFromStylesIfApplicable(StyleSheet&);
257 void ClearAdoptedStyleSheets();
260 * Clone's the argument's adopted style sheets into this.
261 * This should only be used when cloning a static document for printing.
263 void CloneAdoptedSheetsFrom(const DocumentOrShadowRoot&);
265 void InsertSheetAt(size_t aIndex, StyleSheet& aSheet);
267 void AddSizeOfExcludingThis(nsWindowSizes&) const;
268 void AddSizeOfOwnedSheetArrayExcludingThis(
269 nsWindowSizes&, const nsTArray<RefPtr<StyleSheet>>&) const;
272 * If focused element's subtree root is this document or shadow root, return
273 * focused element, otherwise, get the shadow host recursively until the
274 * shadow host's subtree root is this document or shadow root.
276 Element* GetRetargetedFocusedElement();
278 nsTArray<RefPtr<StyleSheet>> mStyleSheets;
279 RefPtr<StyleSheetList> mDOMStyleSheets;
282 * Style sheets that are adopted by assinging to the `adoptedStyleSheets`
283 * WebIDL atribute. These can only be constructed stylesheets.
285 nsTArray<RefPtr<StyleSheet>> mAdoptedStyleSheets;
288 * mIdentifierMap works as follows for IDs:
289 * 1) Attribute changes affect the table immediately (removing and adding
290 * entries as needed).
291 * 2) Removals from the DOM affect the table immediately
292 * 3) Additions to the DOM always update existing entries for names, and add
293 * new ones for IDs.
295 nsTHashtable<IdentifierMapEntry> mIdentifierMap;
297 nsClassHashtable<nsStringHashKey, nsRadioGroupStruct> mRadioGroups;
299 // Always non-null, see comment in the constructor as to why a pointer instead
300 // of a reference.
301 nsINode* mAsNode;
302 const Kind mKind;
305 inline const nsTArray<Element*>* DocumentOrShadowRoot::GetAllElementsForId(
306 const nsAString& aElementId) const {
307 if (aElementId.IsEmpty()) {
308 return nullptr;
311 IdentifierMapEntry* entry = mIdentifierMap.GetEntry(aElementId);
312 return entry ? &entry->GetIdElements() : nullptr;
315 } // namespace dom
317 } // namespace mozilla
319 #endif