/src/mozilla-central/dom/base/nsDocument.h
Line | Count | Source (jump to first uncovered line) |
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 | | /* |
8 | | * Base class for all our document implementations. |
9 | | */ |
10 | | |
11 | | #ifndef nsDocument_h___ |
12 | | #define nsDocument_h___ |
13 | | |
14 | | #include "nsIDocument.h" |
15 | | |
16 | | #include "jsfriendapi.h" |
17 | | #include "nsCOMPtr.h" |
18 | | #include "nsAutoPtr.h" |
19 | | #include "nsCRT.h" |
20 | | #include "nsWeakReference.h" |
21 | | #include "nsWeakPtr.h" |
22 | | #include "nsTArray.h" |
23 | | #include "nsIdentifierMapEntry.h" |
24 | | #include "nsStubDocumentObserver.h" |
25 | | #include "nsIScriptGlobalObject.h" |
26 | | #include "nsIContent.h" |
27 | | #include "nsIPrincipal.h" |
28 | | #include "nsIParser.h" |
29 | | #include "nsBindingManager.h" |
30 | | #include "nsRefPtrHashtable.h" |
31 | | #include "nsJSThingHashtable.h" |
32 | | #include "nsIScriptObjectPrincipal.h" |
33 | | #include "nsIRadioGroupContainer.h" |
34 | | #include "nsILayoutHistoryState.h" |
35 | | #include "nsIRequest.h" |
36 | | #include "nsILoadGroup.h" |
37 | | #include "nsTObserverArray.h" |
38 | | #include "nsStubMutationObserver.h" |
39 | | #include "nsIChannel.h" |
40 | | #include "nsCycleCollectionParticipant.h" |
41 | | #include "nsContentList.h" |
42 | | #include "nsGkAtoms.h" |
43 | | #include "PLDHashTable.h" |
44 | | #include "nsDOMAttributeMap.h" |
45 | | #include "imgIRequest.h" |
46 | | #include "mozilla/EventStates.h" |
47 | | #include "mozilla/MemoryReporting.h" |
48 | | #include "mozilla/PendingAnimationTracker.h" |
49 | | #include "mozilla/dom/BoxObject.h" |
50 | | #include "mozilla/dom/DOMImplementation.h" |
51 | | #include "mozilla/dom/ScriptLoader.h" |
52 | | #include "mozilla/dom/StyleSheetList.h" |
53 | | #include "nsDataHashtable.h" |
54 | | #include "mozilla/TimeStamp.h" |
55 | | #include "mozilla/Attributes.h" |
56 | | #include "CustomElementRegistry.h" |
57 | | #include "mozilla/dom/Performance.h" |
58 | | #include "mozilla/Maybe.h" |
59 | | #include "nsIURIClassifier.h" |
60 | | |
61 | 0 | #define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0) |
62 | 0 | #define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1) |
63 | 0 | #define XML_DECLARATION_BITS_STANDALONE_EXISTS (1 << 2) |
64 | 0 | #define XML_DECLARATION_BITS_STANDALONE_YES (1 << 3) |
65 | | |
66 | | |
67 | | class nsDOMStyleSheetSetList; |
68 | | class nsDocument; |
69 | | class nsIFormControl; |
70 | | class nsOnloadBlocker; |
71 | | class nsDOMNavigationTiming; |
72 | | class nsWindowSizes; |
73 | | class nsHtml5TreeOpExecutor; |
74 | | class nsDocumentOnStack; |
75 | | class nsISecurityConsoleMessage; |
76 | | |
77 | | namespace mozilla { |
78 | | class EventChainPreVisitor; |
79 | | namespace dom { |
80 | | class ImageTracker; |
81 | | struct LifecycleCallbacks; |
82 | | class CallbackFunction; |
83 | | class DOMIntersectionObserver; |
84 | | class Performance; |
85 | | } // namespace dom |
86 | | } // namespace mozilla |
87 | | |
88 | | class nsOnloadBlocker final : public nsIRequest |
89 | | { |
90 | | public: |
91 | 0 | nsOnloadBlocker() {} |
92 | | |
93 | | NS_DECL_ISUPPORTS |
94 | | NS_DECL_NSIREQUEST |
95 | | |
96 | | private: |
97 | 0 | ~nsOnloadBlocker() {} |
98 | | }; |
99 | | |
100 | | // Base class for our document implementations. |
101 | | class nsDocument : public nsIDocument, |
102 | | public nsSupportsWeakReference, |
103 | | public nsIScriptObjectPrincipal, |
104 | | public nsIRadioGroupContainer, |
105 | | public nsIApplicationCacheContainer, |
106 | | public nsStubMutationObserver |
107 | | { |
108 | | friend class nsIDocument; |
109 | | |
110 | | public: |
111 | | typedef mozilla::dom::Element Element; |
112 | | typedef mozilla::net::ReferrerPolicy ReferrerPolicy; |
113 | | |
114 | | NS_DECL_CYCLE_COLLECTING_ISUPPORTS |
115 | | |
116 | | NS_DECL_ADDSIZEOFEXCLUDINGTHIS |
117 | | |
118 | | // StartDocumentLoad is pure virtual so that subclasses must override it. |
119 | | // The nsDocument StartDocumentLoad does some setup, but does NOT set |
120 | | // *aDocListener; this is the job of subclasses. |
121 | | virtual nsresult StartDocumentLoad(const char* aCommand, |
122 | | nsIChannel* aChannel, |
123 | | nsILoadGroup* aLoadGroup, |
124 | | nsISupports* aContainer, |
125 | | nsIStreamListener **aDocListener, |
126 | | bool aReset = true, |
127 | | nsIContentSink* aContentSink = nullptr) override = 0; |
128 | | |
129 | | virtual void StopDocumentLoad() override; |
130 | | |
131 | | static bool DocumentSupportsL10n(JSContext* aCx, JSObject* aObject); |
132 | | static bool IsWebAnimationsEnabled(JSContext* aCx, JSObject* aObject); |
133 | | static bool IsWebAnimationsEnabled(mozilla::dom::CallerType aCallerType); |
134 | | static bool IsWebAnimationsGetAnimationsEnabled(JSContext* aCx, |
135 | | JSObject* aObject); |
136 | | static bool AreWebAnimationsImplicitKeyframesEnabled(JSContext* aCx, |
137 | | JSObject* aObject); |
138 | | static bool AreWebAnimationsTimelinesEnabled(JSContext* aCx, |
139 | | JSObject* aObject); |
140 | | |
141 | | virtual void EndUpdate() override; |
142 | | virtual void BeginLoad() override; |
143 | | virtual void EndLoad() override; |
144 | | |
145 | | // nsIRadioGroupContainer |
146 | | NS_IMETHOD WalkRadioGroup(const nsAString& aName, |
147 | | nsIRadioVisitor* aVisitor, |
148 | | bool aFlushContent) override |
149 | 0 | { |
150 | 0 | return DocumentOrShadowRoot::WalkRadioGroup(aName, aVisitor, aFlushContent); |
151 | 0 | } |
152 | | virtual void |
153 | | SetCurrentRadioButton(const nsAString& aName, |
154 | | mozilla::dom::HTMLInputElement* aRadio) override |
155 | 0 | { |
156 | 0 | DocumentOrShadowRoot::SetCurrentRadioButton(aName, aRadio); |
157 | 0 | } |
158 | | virtual mozilla::dom::HTMLInputElement* |
159 | | GetCurrentRadioButton(const nsAString& aName) override |
160 | 0 | { |
161 | 0 | return DocumentOrShadowRoot::GetCurrentRadioButton(aName); |
162 | 0 | } |
163 | | NS_IMETHOD |
164 | | GetNextRadioButton(const nsAString& aName, |
165 | | const bool aPrevious, |
166 | | mozilla::dom::HTMLInputElement* aFocusedRadio, |
167 | | mozilla::dom::HTMLInputElement** aRadioOut) override |
168 | 0 | { |
169 | 0 | return DocumentOrShadowRoot::GetNextRadioButton(aName, aPrevious, |
170 | 0 | aFocusedRadio, aRadioOut); |
171 | 0 | } |
172 | | virtual void AddToRadioGroup(const nsAString& aName, |
173 | | mozilla::dom::HTMLInputElement* aRadio) override |
174 | 0 | { |
175 | 0 | DocumentOrShadowRoot::AddToRadioGroup(aName, aRadio); |
176 | 0 | } |
177 | | virtual void RemoveFromRadioGroup(const nsAString& aName, |
178 | | mozilla::dom::HTMLInputElement* aRadio) override |
179 | 0 | { |
180 | 0 | DocumentOrShadowRoot::RemoveFromRadioGroup(aName, aRadio); |
181 | 0 | } |
182 | | virtual uint32_t GetRequiredRadioCount(const nsAString& aName) const override |
183 | 0 | { |
184 | 0 | return DocumentOrShadowRoot::GetRequiredRadioCount(aName); |
185 | 0 | } |
186 | | virtual void RadioRequiredWillChange(const nsAString& aName, |
187 | | bool aRequiredAdded) override |
188 | 0 | { |
189 | 0 | DocumentOrShadowRoot::RadioRequiredWillChange(aName, aRequiredAdded); |
190 | 0 | } |
191 | | virtual bool GetValueMissingState(const nsAString& aName) const override |
192 | 0 | { |
193 | 0 | return DocumentOrShadowRoot::GetValueMissingState(aName); |
194 | 0 | } |
195 | | virtual void SetValueMissingState(const nsAString& aName, bool aValue) override |
196 | 0 | { |
197 | 0 | return DocumentOrShadowRoot::SetValueMissingState(aName, aValue); |
198 | 0 | } |
199 | | |
200 | | // Check whether shadow DOM is enabled for aGlobal. |
201 | | static bool IsShadowDOMEnabled(JSContext* aCx, JSObject* aGlobal); |
202 | | // Check whether shadow DOM is enabled for the document this node belongs to. |
203 | | // Same as above, but also checks that the caller is either chrome or some addon. |
204 | | static bool IsShadowDOMEnabledAndCallerIsChromeOrAddon(JSContext* aCx, JSObject* aObject); |
205 | | static bool IsShadowDOMEnabled(const nsINode* aNode); |
206 | | |
207 | | public: |
208 | | using mozilla::dom::DocumentOrShadowRoot::GetElementById; |
209 | | using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagName; |
210 | | using mozilla::dom::DocumentOrShadowRoot::GetElementsByTagNameNS; |
211 | | using mozilla::dom::DocumentOrShadowRoot::GetElementsByClassName; |
212 | | |
213 | | // EventTarget |
214 | | void GetEventTargetParent(mozilla::EventChainPreVisitor& aVisitor) override; |
215 | | virtual mozilla::EventListenerManager* |
216 | | GetOrCreateListenerManager() override; |
217 | | virtual mozilla::EventListenerManager* |
218 | | GetExistingListenerManager() const override; |
219 | | |
220 | | // nsIScriptObjectPrincipal |
221 | | virtual nsIPrincipal* GetPrincipal() override; |
222 | | |
223 | | // nsIApplicationCacheContainer |
224 | | NS_DECL_NSIAPPLICATIONCACHECONTAINER |
225 | | |
226 | | virtual nsresult Init(); |
227 | | |
228 | | virtual void Destroy() override; |
229 | | virtual void RemovedFromDocShell() override; |
230 | | |
231 | | virtual void BlockOnload() override; |
232 | | virtual void UnblockOnload(bool aFireSync) override; |
233 | | |
234 | | NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDocument, |
235 | | nsIDocument) |
236 | | |
237 | 0 | void SetLoadedAsData(bool aLoadedAsData) { mLoadedAsData = aLoadedAsData; } |
238 | | void SetLoadedAsInteractiveData(bool aLoadedAsInteractiveData) |
239 | 0 | { |
240 | 0 | mLoadedAsInteractiveData = aLoadedAsInteractiveData; |
241 | 0 | } |
242 | | |
243 | | nsresult CloneDocHelper(nsDocument* clone) const; |
244 | | |
245 | | // Only BlockOnload should call this! |
246 | | void AsyncBlockOnload(); |
247 | | |
248 | | virtual void DocAddSizeOfExcludingThis(nsWindowSizes& aWindowSizes) const override; |
249 | | // DocAddSizeOfIncludingThis is inherited from nsIDocument. |
250 | | |
251 | | protected: |
252 | | friend class nsNodeUtils; |
253 | | |
254 | | void RetrieveRelevantHeaders(nsIChannel *aChannel); |
255 | | |
256 | | void TryChannelCharset(nsIChannel *aChannel, |
257 | | int32_t& aCharsetSource, |
258 | | NotNull<const Encoding*>& aEncoding, |
259 | | nsHtml5TreeOpExecutor* aExecutor); |
260 | | |
261 | | nsIContent* GetFirstBaseNodeWithHref(); |
262 | | nsresult SetFirstBaseNodeWithHref(nsIContent *node); |
263 | | |
264 | 0 | #define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_) do { \ |
265 | 0 | NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers, nsIDocumentObserver, \ |
266 | 0 | func_, params_); \ |
267 | 0 | /* FIXME(emilio): Apparently we can keep observing from the BFCache? That \ |
268 | 0 | looks bogus. */ \ |
269 | 0 | if (nsIPresShell* shell = GetObservingShell()) { \ |
270 | 0 | shell->func_ params_; \ |
271 | 0 | } \ |
272 | 0 | } while(0) |
273 | | |
274 | | #ifdef DEBUG |
275 | | void VerifyRootContentState(); |
276 | | #endif |
277 | | |
278 | | explicit nsDocument(const char* aContentType); |
279 | | virtual ~nsDocument(); |
280 | | |
281 | | public: |
282 | | // FIXME(emilio): This needs to be here instead of in nsIDocument because Rust |
283 | | // can't represent alignas(8) values on 32-bit architectures, which would |
284 | | // cause nsIDocument's layout to be wrong in the Rust side. |
285 | | // |
286 | | // This can be fixed after updating to rust 1.25 and updating bindgen to |
287 | | // include https://github.com/rust-lang-nursery/rust-bindgen/pull/1271. |
288 | | js::ExpandoAndGeneration mExpandoAndGeneration; |
289 | | |
290 | | friend class nsCallRequestFullscreen; |
291 | | |
292 | | // The application cache that this document is associated with, if |
293 | | // any. This can change during the lifetime of the document. |
294 | | nsCOMPtr<nsIApplicationCache> mApplicationCache; |
295 | | |
296 | | nsCOMPtr<nsIContent> mFirstBaseNodeWithHref; |
297 | | private: |
298 | | friend class nsUnblockOnloadEvent; |
299 | | |
300 | | // These are not implemented and not supported. |
301 | | nsDocument(const nsDocument& aOther); |
302 | | nsDocument& operator=(const nsDocument& aOther); |
303 | | }; |
304 | | |
305 | | class nsDocumentOnStack |
306 | | { |
307 | | public: |
308 | | explicit nsDocumentOnStack(nsIDocument* aDoc) : mDoc(aDoc) |
309 | 0 | { |
310 | 0 | mDoc->IncreaseStackRefCnt(); |
311 | 0 | } |
312 | | ~nsDocumentOnStack() |
313 | 0 | { |
314 | 0 | mDoc->DecreaseStackRefCnt(); |
315 | 0 | } |
316 | | private: |
317 | | nsIDocument* mDoc; |
318 | | }; |
319 | | |
320 | | #endif /* nsDocument_h___ */ |