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"
17 #include "nsTHashSet.h"
20 class nsCycleCollectionTraversalCallback
;
35 class DocumentOrShadowRoot
;
36 class HTMLInputElement
;
43 * A class meant to be shared by ShadowRoot and Document, that holds a list of
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
{
56 // These should always be non-null, but can't use a reference because
57 // dereferencing `this` on initializer lists is UB, apparently, see
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
;
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;
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
,
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
160 typedef bool (*IDTargetObserver
)(Element
* aOldElement
, Element
* aNewelement
,
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
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
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
196 * @returns true if aId looks correct, false otherwise.
198 inline bool CheckGetElementByIdArg(const nsAString
& aId
) {
200 ReportEmptyGetElementByIdArg();
206 void ReportEmptyGetElementByIdArg() const;
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
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
))) {
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
280 nsTHashtable
<IdentifierMapEntry
> mIdentifierMap
;
282 // Always non-null, see comment in the constructor as to why a pointer instead
290 } // namespace mozilla