Bug 1852740: add tests for the `fetchpriority` attribute in Link headers. r=necko...
[gecko.git] / dom / base / DocumentOrShadowRoot.h
blob1e77d02ab971639566cbbbe25c61f7526cd88a1d
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 "mozilla/ReverseIterator.h"
14 #include "nsClassHashtable.h"
15 #include "nsContentListDeclarations.h"
16 #include "nsTArray.h"
17 #include "nsTHashSet.h"
19 class nsContentList;
20 class nsCycleCollectionTraversalCallback;
21 class nsINode;
22 class nsINodeList;
23 class nsWindowSizes;
25 namespace mozilla {
26 class ErrorResult;
27 class StyleSheet;
28 class ErrorResult;
30 namespace dom {
32 class Animation;
33 class Element;
34 class Document;
35 class DocumentOrShadowRoot;
36 class HTMLInputElement;
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 const nsTArray<RefPtr<StyleSheet>>& AdoptedStyleSheets() const {
78 return mAdoptedStyleSheets;
81 /**
82 * Returns an index for the sheet in relative style order.
83 * If there are non-applicable sheets, then this index may
84 * not match 1:1 with the sheet's actual index in the style set.
86 * Handles sheets from both mStyleSheets and mAdoptedStyleSheets
88 int32_t StyleOrderIndexOfSheet(const StyleSheet& aSheet) const;
90 StyleSheetList* StyleSheets();
92 void RemoveStyleSheet(StyleSheet&);
94 Element* GetElementById(const nsAString& aElementId) const;
95 Element* GetElementById(nsAtom* aElementId) const;
97 /**
98 * This method returns _all_ the elements in this scope which have id
99 * aElementId, if there are any. Otherwise it returns null.
101 * This is useful for stuff like QuerySelector optimization and such.
103 const nsTArray<Element*>* GetAllElementsForId(
104 const IdentifierMapEntry::DependentAtomOrString& aElementId) const {
105 IdentifierMapEntry* entry = mIdentifierMap.GetEntry(aElementId);
106 return entry ? &entry->GetIdElements() : nullptr;
109 already_AddRefed<nsContentList> GetElementsByTagName(
110 const nsAString& aTagName) {
111 return NS_GetContentList(&AsNode(), kNameSpaceID_Unknown, aTagName);
114 already_AddRefed<nsContentList> GetElementsByTagNameNS(
115 const nsAString& aNamespaceURI, const nsAString& aLocalName);
117 already_AddRefed<nsContentList> GetElementsByTagNameNS(
118 const nsAString& aNamespaceURI, const nsAString& aLocalName,
119 mozilla::ErrorResult&);
121 already_AddRefed<nsContentList> GetElementsByClassName(
122 const nsAString& aClasses);
124 ~DocumentOrShadowRoot();
126 Element* GetPointerLockElement();
127 Element* GetFullscreenElement() const;
129 Element* ElementFromPoint(float aX, float aY);
130 nsINode* NodeFromPoint(float aX, float aY);
132 void ElementsFromPoint(float aX, float aY, nsTArray<RefPtr<Element>>&);
133 void NodesFromPoint(float aX, float aY, nsTArray<RefPtr<nsINode>>&);
136 * Helper for elementFromPoint implementation that allows
137 * ignoring the scroll frame and/or avoiding layout flushes.
139 * @see nsIDOMWindowUtils::elementFromPoint
141 Element* ElementFromPointHelper(float aX, float aY,
142 bool aIgnoreRootScrollFrame,
143 bool aFlushLayout,
144 ViewportType aViewportType);
146 void NodesFromRect(float aX, float aY, float aTopSize, float aRightSize,
147 float aBottomSize, float aLeftSize,
148 bool aIgnoreRootScrollFrame, bool aFlushLayout,
149 bool aOnlyVisible, float aVisibleThreshold,
150 nsTArray<RefPtr<nsINode>>&);
153 * This gets fired when the element that an id refers to changes.
154 * This fires at difficult times. It is generally not safe to do anything
155 * which could modify the DOM in any way. Use
156 * nsContentUtils::AddScriptRunner.
157 * @return true to keep the callback in the callback set, false
158 * to remove it.
160 typedef bool (*IDTargetObserver)(Element* aOldElement, Element* aNewelement,
161 void* aData);
164 * Add an IDTargetObserver for a specific ID. The IDTargetObserver
165 * will be fired whenever the content associated with the ID changes
166 * in the future. If aForImage is true, mozSetImageElement can override
167 * what content is associated with the ID. In that case the IDTargetObserver
168 * will be notified at those times when the result of LookupImageElement
169 * changes.
170 * At most one (aObserver, aData, aForImage) triple can be
171 * registered for each ID.
172 * @return the content currently associated with the ID.
174 Element* AddIDTargetObserver(nsAtom* aID, IDTargetObserver aObserver,
175 void* aData, bool aForImage);
178 * Remove the (aObserver, aData, aForImage) triple for a specific ID, if
179 * registered.
181 void RemoveIDTargetObserver(nsAtom* aID, IDTargetObserver aObserver,
182 void* aData, bool aForImage);
185 * Lookup an image element using its associated ID, which is usually provided
186 * by |-moz-element()|. Similar to GetElementById, with the difference that
187 * elements set using mozSetImageElement have higher priority.
188 * @param aId the ID associated the element we want to lookup
189 * @return the element associated with |aId|
191 Element* LookupImageElement(const nsAString& aElementId);
194 * Check that aId is not empty and log a message to the console
195 * service if it is.
196 * @returns true if aId looks correct, false otherwise.
198 inline bool CheckGetElementByIdArg(const nsAString& aId) {
199 if (aId.IsEmpty()) {
200 ReportEmptyGetElementByIdArg();
201 return false;
203 return true;
206 void ReportEmptyGetElementByIdArg() const;
208 // Web Animations
209 MOZ_CAN_RUN_SCRIPT
210 void GetAnimations(nsTArray<RefPtr<Animation>>& aAnimations);
212 nsINode* Retarget(nsINode*) const;
214 void OnSetAdoptedStyleSheets(StyleSheet&, uint32_t aIndex, ErrorResult&);
215 void OnDeleteAdoptedStyleSheets(StyleSheet&, uint32_t aIndex, ErrorResult&);
217 // This is needed because ServoStyleSet / ServoAuthorData don't deal with
218 // duplicate stylesheets (and it's unclear we'd want to support that as it'd
219 // be a bunch of duplicate work), while adopted stylesheets do need to deal
220 // with them.
221 template <typename Callback>
222 void EnumerateUniqueAdoptedStyleSheetsBackToFront(Callback aCallback) {
223 StyleSheetSet set(mAdoptedStyleSheets.Length());
224 for (StyleSheet* sheet : Reversed(mAdoptedStyleSheets)) {
225 if (MOZ_UNLIKELY(!set.EnsureInserted(sheet))) {
226 continue;
228 aCallback(*sheet);
232 protected:
233 // Cycle collection helper functions
234 void TraverseSheetRefInStylesIfApplicable(
235 StyleSheet&, nsCycleCollectionTraversalCallback&);
236 void TraverseStyleSheets(nsTArray<RefPtr<StyleSheet>>&, const char*,
237 nsCycleCollectionTraversalCallback&);
238 void UnlinkStyleSheets(nsTArray<RefPtr<StyleSheet>>&);
240 using StyleSheetSet = nsTHashSet<const StyleSheet*>;
241 void RemoveSheetFromStylesIfApplicable(StyleSheet&);
242 void ClearAdoptedStyleSheets();
245 * Clone's the argument's adopted style sheets into this.
246 * This should only be used when cloning a static document for printing.
248 void CloneAdoptedSheetsFrom(const DocumentOrShadowRoot&);
250 void InsertSheetAt(size_t aIndex, StyleSheet& aSheet);
252 void AddSizeOfExcludingThis(nsWindowSizes&) const;
253 void AddSizeOfOwnedSheetArrayExcludingThis(
254 nsWindowSizes&, const nsTArray<RefPtr<StyleSheet>>&) const;
257 * If focused element's subtree root is this document or shadow root, return
258 * focused element, otherwise, get the shadow host recursively until the
259 * shadow host's subtree root is this document or shadow root.
261 Element* GetRetargetedFocusedElement();
263 nsTArray<RefPtr<StyleSheet>> mStyleSheets;
264 RefPtr<StyleSheetList> mDOMStyleSheets;
267 * Style sheets that are adopted by assinging to the `adoptedStyleSheets`
268 * WebIDL atribute. These can only be constructed stylesheets.
270 nsTArray<RefPtr<StyleSheet>> mAdoptedStyleSheets;
273 * mIdentifierMap works as follows for IDs:
274 * 1) Attribute changes affect the table immediately (removing and adding
275 * entries as needed).
276 * 2) Removals from the DOM affect the table immediately
277 * 3) Additions to the DOM always update existing entries for names, and add
278 * new ones for IDs.
280 nsTHashtable<IdentifierMapEntry> mIdentifierMap;
282 // Always non-null, see comment in the constructor as to why a pointer instead
283 // of a reference.
284 nsINode* mAsNode;
285 const Kind mKind;
288 } // namespace dom
290 } // namespace mozilla
292 #endif