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 #ifndef mozilla_dom_Document_h___
8 #define mozilla_dom_Document_h___
9 
10 #include <bitset>
11 #include <cstddef>
12 #include <cstdint>
13 #include <new>
14 #include <utility>
15 #include "ErrorList.h"
16 #include "MainThreadUtils.h"
17 #include "ReferrerInfo.h"
18 #include "Units.h"
19 #include "imgIRequest.h"
20 #include "js/RootingAPI.h"
21 #include "js/friend/DOMProxy.h"
22 #include "mozilla/AlreadyAddRefed.h"
23 #include "mozilla/Assertions.h"
24 #include "mozilla/Attributes.h"
25 #include "mozilla/BasicEvents.h"
26 #include "mozilla/BitSet.h"
27 #include "mozilla/OriginTrials.h"
28 #include "mozilla/CORSMode.h"
29 #include "mozilla/CallState.h"
30 #include "mozilla/EventStates.h"
31 #include "mozilla/FlushType.h"
32 #include "mozilla/FunctionRef.h"
33 #include "mozilla/HashTable.h"
34 #include "mozilla/LinkedList.h"
35 #include "mozilla/Maybe.h"
36 #include "mozilla/MozPromise.h"
37 #include "mozilla/NotNull.h"
38 #include "mozilla/PointerLockManager.h"
39 #include "mozilla/PreloadService.h"
40 #include "mozilla/RefPtr.h"
41 #include "mozilla/Result.h"
42 #include "mozilla/SegmentedVector.h"
43 #include "mozilla/TaskCategory.h"
44 #include "mozilla/TimeStamp.h"
45 #include "mozilla/UniquePtr.h"
46 #include "mozilla/UseCounter.h"
47 #include "mozilla/WeakPtr.h"
48 #include "mozilla/css/StylePreloadKind.h"
49 #include "mozilla/dom/AnimationFrameProvider.h"
50 #include "mozilla/dom/DispatcherTrait.h"
51 #include "mozilla/dom/DocumentOrShadowRoot.h"
52 #include "mozilla/dom/Element.h"
53 #include "mozilla/dom/EventTarget.h"
54 #include "mozilla/dom/Nullable.h"
55 #include "mozilla/dom/TreeOrderedArray.h"
56 #include "mozilla/dom/ViewportMetaData.h"
57 #include "nsAtom.h"
58 #include "nsCOMArray.h"
59 #include "nsCOMPtr.h"
60 #include "nsClassHashtable.h"
61 #include "nsCompatibility.h"
62 #include "nsContentListDeclarations.h"
63 #include "nsCycleCollectionParticipant.h"
64 #include "nsTHashMap.h"
65 #include "nsDebug.h"
66 #include "nsExpirationTracker.h"
67 #include "nsGkAtoms.h"
68 #include "nsHashKeys.h"
69 #include "nsIChannel.h"
70 #include "nsIChannelEventSink.h"
71 #include "nsIContentViewer.h"
72 #include "nsID.h"
73 #include "nsIInterfaceRequestor.h"
74 #include "nsILoadContext.h"
75 #include "nsILoadGroup.h"
76 #include "nsILoadInfo.h"
77 #include "nsINode.h"
78 #include "nsIObserver.h"
79 #include "nsIParser.h"
80 #include "nsIPrincipal.h"
81 #include "nsIProgressEventSink.h"
82 #include "nsIRadioGroupContainer.h"
83 #include "nsIReferrerInfo.h"
84 #include "nsIRequestObserver.h"
85 #include "nsIScriptObjectPrincipal.h"
86 #include "nsIStreamListener.h"
87 #include "nsISupports.h"
88 #include "nsISupportsUtils.h"
89 #include "nsIURI.h"
90 #include "nsIWeakReferenceUtils.h"
91 #include "nsLiteralString.h"
92 #include "nsPIDOMWindow.h"
93 #include "nsPropertyTable.h"
94 #include "nsRefPtrHashtable.h"
95 #include "nsString.h"
96 #include "nsTArray.h"
97 #include "nsTHashSet.h"
98 #include "nsTLiteralString.h"
99 #include "nsTObserverArray.h"
100 #include "nsThreadUtils.h"
101 #include "nsURIHashKey.h"
102 #include "nsViewportInfo.h"
103 #include "nsWeakReference.h"
104 #include "nsWindowSizes.h"
105 #include "nsXULElement.h"
106 #include "nscore.h"
107 
108 // XXX We need to include this here to ensure that DefaultDeleter for Servo
109 // types is specialized before the template is instantiated. Probably, this
110 // should be included at some other place already that's generated by cbindgen.
111 #include "mozilla/ServoBindingTypes.h"
112 
113 // windows.h #defines CreateEvent
114 #ifdef CreateEvent
115 #  undef CreateEvent
116 #endif
117 
118 #ifdef MOZILLA_INTERNAL_API
119 #  include "mozilla/dom/DocumentBinding.h"
120 #else
121 namespace mozilla {
122 namespace dom {
123 class ElementCreationOptionsOrString;
124 }  // namespace dom
125 }  // namespace mozilla
126 #endif  // MOZILLA_INTERNAL_API
127 
128 class InfallibleAllocPolicy;
129 class JSObject;
130 class JSTracer;
131 class PLDHashTable;
132 class gfxUserFontSet;
133 class mozIDOMWindowProxy;
134 class nsCachableElementsByNameNodeList;
135 class nsCommandManager;
136 class nsContentList;
137 class nsCycleCollectionTraversalCallback;
138 class nsDOMCaretPosition;
139 class nsDOMNavigationTiming;
140 class nsDocShell;
141 class nsFrameLoader;
142 class nsFrameLoaderOwner;
143 class nsGenericHTMLElement;
144 class nsGlobalWindowInner;
145 class nsHTMLCSSStyleSheet;
146 class nsHTMLDocument;
147 class nsHTMLStyleSheet;
148 class nsHtml5TreeOpExecutor;
149 class nsIAppWindow;
150 class nsIAsyncVerifyRedirectCallback;
151 class nsIBFCacheEntry;
152 class nsIContent;
153 class nsIContentSecurityPolicy;
154 class nsIContentSink;
155 class nsICookieJarSettings;
156 class nsIDOMXULCommandDispatcher;
157 class nsIDocShell;
158 class nsIDocShellTreeItem;
159 class nsIDocumentEncoder;
160 class nsIDocumentObserver;
161 class nsIEventTarget;
162 class nsIFrame;
163 class nsIGlobalObject;
164 class nsIHTMLCollection;
165 class nsIInputStream;
166 class nsILayoutHistoryState;
167 class nsIObjectLoadingContent;
168 class nsIPermissionDelegateHandler;
169 class nsIRadioVisitor;
170 class nsIRequest;
171 class nsIRunnable;
172 class nsIScriptGlobalObject;
173 class nsISecurityConsoleMessage;
174 class nsISerialEventTarget;
175 class nsIStructuredCloneContainer;
176 class nsIVariant;
177 class nsNodeInfoManager;
178 class nsPIWindowRoot;
179 class nsPresContext;
180 class nsRange;
181 class nsSimpleContentList;
182 class nsTextNode;
183 class nsViewManager;
184 class nsXULPrototypeDocument;
185 struct JSContext;
186 struct RawServoSelectorList;
187 struct StyleUseCounters;
188 struct nsFont;
189 
190 namespace mozilla {
191 class AbstractThread;
192 class StyleSheet;
193 class EditorBase;
194 class EditorCommand;
195 class Encoding;
196 class ErrorResult;
197 class EventListenerManager;
198 class FullscreenExit;
199 class FullscreenRequest;
200 class HTMLEditor;
201 struct LangGroupFontPrefs;
202 class PendingAnimationTracker;
203 class PermissionDelegateHandler;
204 class PresShell;
205 class ServoStyleSet;
206 enum class StyleOrigin : uint8_t;
207 class SMILAnimationController;
208 enum class StyleCursorKind : uint8_t;
209 enum class ColorScheme : uint8_t;
210 enum class StyleRuleChangeKind : uint32_t;
211 template <typename>
212 class OwningNonNull;
213 struct URLExtraData;
214 
215 namespace css {
216 class Loader;
217 class ImageLoader;
218 class Rule;
219 }  // namespace css
220 
221 namespace dom {
222 class AnonymousContent;
223 class Attr;
224 class XULBroadcastManager;
225 class XULPersist;
226 class BrowserBridgeChild;
227 class ChromeObserver;
228 class ClientInfo;
229 class ClientState;
230 class CDATASection;
231 class Comment;
232 class CSSImportRule;
233 class DocumentL10n;
234 class DocumentFragment;
235 class DocumentTimeline;
236 class DocumentType;
237 class DOMImplementation;
238 class DOMIntersectionObserver;
239 class DOMStringList;
240 class Event;
241 class EventListener;
242 struct FailedCertSecurityInfo;
243 class FeaturePolicy;
244 class FontFaceSet;
245 class FrameRequestCallback;
246 class ImageTracker;
247 class HTMLAllCollection;
248 class HTMLBodyElement;
249 class HTMLInputElement;
250 class HTMLMetaElement;
251 class HTMLDialogElement;
252 class HTMLSharedElement;
253 class HTMLImageElement;
254 struct LifecycleCallbackArgs;
255 class Link;
256 class Location;
257 class MediaQueryList;
258 struct NetErrorInfo;
259 class NodeFilter;
260 class NodeInfo;
261 class NodeIterator;
262 enum class OrientationType : uint8_t;
263 class ProcessingInstruction;
264 class Promise;
265 class ScriptLoader;
266 class Selection;
267 class ServiceWorkerDescriptor;
268 class ShadowRoot;
269 class SVGDocument;
270 class SVGElement;
271 class SVGSVGElement;
272 class SVGUseElement;
273 class Touch;
274 class TouchList;
275 class TreeWalker;
276 enum class ViewportFitType : uint8_t;
277 class WindowContext;
278 class WindowGlobalChild;
279 class WindowProxyHolder;
280 struct Wireframe;
281 class WorkerDocumentListener;
282 class XPathEvaluator;
283 class XPathExpression;
284 class XPathNSResolver;
285 class XPathResult;
286 class BrowsingContext;
287 
288 class nsDocumentOnStack;
289 class nsUnblockOnloadEvent;
290 
291 template <typename, typename>
292 class CallbackObjectHolder;
293 
294 enum class CallerType : uint32_t;
295 
296 enum BFCacheStatus {
297   NOT_ALLOWED = 1 << 0,                  // Status 0
298   EVENT_HANDLING_SUPPRESSED = 1 << 1,    // Status 1
299   SUSPENDED = 1 << 2,                    // Status 2
300   UNLOAD_LISTENER = 1 << 3,              // Status 3
301   REQUEST = 1 << 4,                      // Status 4
302   ACTIVE_GET_USER_MEDIA = 1 << 5,        // Status 5
303   ACTIVE_PEER_CONNECTION = 1 << 6,       // Status 6
304   CONTAINS_EME_CONTENT = 1 << 7,         // Status 7
305   CONTAINS_MSE_CONTENT = 1 << 8,         // Status 8
306   HAS_ACTIVE_SPEECH_SYNTHESIS = 1 << 9,  // Status 9
307   HAS_USED_VR = 1 << 10,                 // Status 10
308   CONTAINS_REMOTE_SUBFRAMES = 1 << 11,   // Status 11
309   NOT_ONLY_TOPLEVEL_IN_BCG = 1 << 12,    // Status 12
310   ABOUT_PAGE = 1 << 13,                  // Status 13
311   RESTORING = 1 << 14,                   // Status 14
312   BEFOREUNLOAD_LISTENER = 1 << 15,       // Status 15
313   ACTIVE_LOCK = 1 << 16,                 // Status 16
314 };
315 
316 }  // namespace dom
317 }  // namespace mozilla
318 
319 namespace mozilla {
320 namespace net {
321 class ChannelEventQueue;
322 }  // namespace net
323 }  // namespace mozilla
324 
325 // Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs
326 #define NS_IDOCUMENT_IID                             \
327   {                                                  \
328     0xce1f7627, 0x7109, 0x4977, {                    \
329       0xba, 0x77, 0x49, 0x0f, 0xfd, 0xe0, 0x7a, 0xaa \
330     }                                                \
331   }
332 
333 namespace mozilla {
334 namespace dom {
335 
336 class Document;
337 class DOMStyleSheetSetList;
338 class ResizeObserver;
339 class ResizeObserverController;
340 class PostMessageEvent;
341 
342 #define DEPRECATED_OPERATION(_op) e##_op,
343 enum class DeprecatedOperations : uint16_t {
344 #include "nsDeprecatedOperationList.h"
345   eDeprecatedOperationCount
346 };
347 #undef DEPRECATED_OPERATION
348 
349 // Document states
350 
351 // Window activation status
352 #define NS_DOCUMENT_STATE_WINDOW_INACTIVE NS_DEFINE_EVENT_STATE_MACRO(0)
353 // RTL locale: specific to the XUL localedir attribute.
354 #define NS_DOCUMENT_STATE_RTL_LOCALE NS_DEFINE_EVENT_STATE_MACRO(1)
355 // LTR locale: specific to the XUL localedir attribute. This is mutually
356 // exclusive with the RTL bit, but the style system invalidation code is simpler
357 // if we differentiate between the two states.
358 #define NS_DOCUMENT_STATE_LTR_LOCALE NS_DEFINE_EVENT_STATE_MACRO(2)
359 // Lightweight-theme status.
360 #define NS_DOCUMENT_STATE_LWTHEME NS_DEFINE_EVENT_STATE_MACRO(3)
361 #define NS_DOCUMENT_STATE_LWTHEME_BRIGHTTEXT NS_DEFINE_EVENT_STATE_MACRO(4)
362 #define NS_DOCUMENT_STATE_LWTHEME_DARKTEXT NS_DEFINE_EVENT_STATE_MACRO(5)
363 
364 #define NS_DOCUMENT_STATE_ALL_LOCALEDIR_BITS \
365   (NS_DOCUMENT_STATE_RTL_LOCALE | NS_DOCUMENT_STATE_LTR_LOCALE)
366 #define NS_DOCUMENT_STATE_ALL_LWTHEME_BITS                            \
367   (NS_DOCUMENT_STATE_LWTHEME | NS_DOCUMENT_STATE_LWTHEME_BRIGHTTEXT | \
368    NS_DOCUMENT_STATE_LWTHEME_DARKTEXT)
369 
370 class ExternalResourceMap {
371   using SubDocEnumFunc = FunctionRef<CallState(Document&)>;
372 
373  public:
374   /**
375    * A class that represents an external resource load that has begun but
376    * doesn't have a document yet.  Observers can be registered on this object,
377    * and will be notified after the document is created.  Observers registered
378    * after the document has been created will NOT be notified.  When observers
379    * are notified, the subject will be the newly-created document, the topic
380    * will be "external-resource-document-created", and the data will be null.
381    * If document creation fails for some reason, observers will still be
382    * notified, with a null document pointer.
383    */
384   class ExternalResourceLoad : public nsISupports {
385    public:
386     virtual ~ExternalResourceLoad() = default;
387 
AddObserver(nsIObserver * aObserver)388     void AddObserver(nsIObserver* aObserver) {
389       MOZ_ASSERT(aObserver, "Must have observer");
390       mObservers.AppendElement(aObserver);
391     }
392 
Observers()393     const nsTArray<nsCOMPtr<nsIObserver>>& Observers() { return mObservers; }
394 
395    protected:
396     AutoTArray<nsCOMPtr<nsIObserver>, 8> mObservers;
397   };
398 
399   ExternalResourceMap();
400 
401   /**
402    * Request an external resource document.  This does exactly what
403    * Document::RequestExternalResource is documented to do.
404    */
405   Document* RequestResource(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
406                             nsINode* aRequestingNode,
407                             Document* aDisplayDocument,
408                             ExternalResourceLoad** aPendingLoad);
409 
410   /**
411    * Enumerate the resource documents.  See
412    * Document::EnumerateExternalResources.
413    */
414   void EnumerateResources(SubDocEnumFunc aCallback);
415 
416   /**
417    * Traverse ourselves for cycle-collection
418    */
419   void Traverse(nsCycleCollectionTraversalCallback* aCallback) const;
420 
421   /**
422    * Shut ourselves down (used for cycle-collection unlink), as well
423    * as for document destruction.
424    */
Shutdown()425   void Shutdown() {
426     mPendingLoads.Clear();
427     mMap.Clear();
428     mHaveShutDown = true;
429   }
430 
HaveShutDown()431   bool HaveShutDown() const { return mHaveShutDown; }
432 
433   // Needs to be public so we can traverse them sanely
434   struct ExternalResource {
435     ~ExternalResource();
436     RefPtr<Document> mDocument;
437     nsCOMPtr<nsIContentViewer> mViewer;
438     nsCOMPtr<nsILoadGroup> mLoadGroup;
439   };
440 
441   // Hide all our viewers
442   void HideViewers();
443 
444   // Show all our viewers
445   void ShowViewers();
446 
447  protected:
448   class PendingLoad : public ExternalResourceLoad, public nsIStreamListener {
449     ~PendingLoad() = default;
450 
451    public:
PendingLoad(Document * aDisplayDocument)452     explicit PendingLoad(Document* aDisplayDocument)
453         : mDisplayDocument(aDisplayDocument) {}
454 
455     NS_DECL_ISUPPORTS
456     NS_DECL_NSISTREAMLISTENER
457     NS_DECL_NSIREQUESTOBSERVER
458 
459     /**
460      * Start aURI loading.  This will perform the necessary security checks and
461      * so forth.
462      */
463     nsresult StartLoad(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
464                        nsINode* aRequestingNode);
465     /**
466      * Set up an nsIContentViewer based on aRequest.  This is guaranteed to
467      * put null in *aViewer and *aLoadGroup on all failures.
468      */
469     nsresult SetupViewer(nsIRequest* aRequest, nsIContentViewer** aViewer,
470                          nsILoadGroup** aLoadGroup);
471 
472    private:
473     RefPtr<Document> mDisplayDocument;
474     nsCOMPtr<nsIStreamListener> mTargetListener;
475     nsCOMPtr<nsIURI> mURI;
476   };
477   friend class PendingLoad;
478 
479   class LoadgroupCallbacks final : public nsIInterfaceRequestor {
480     ~LoadgroupCallbacks() = default;
481 
482    public:
LoadgroupCallbacks(nsIInterfaceRequestor * aOtherCallbacks)483     explicit LoadgroupCallbacks(nsIInterfaceRequestor* aOtherCallbacks)
484         : mCallbacks(aOtherCallbacks) {}
485     NS_DECL_ISUPPORTS
486     NS_DECL_NSIINTERFACEREQUESTOR
487    private:
488     // The only reason it's safe to hold a strong ref here without leaking is
489     // that the notificationCallbacks on a loadgroup aren't the docshell itself
490     // but a shim that holds a weak reference to the docshell.
491     nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
492 
493     // Use shims for interfaces that docshell implements directly so that we
494     // don't hand out references to the docshell.  The shims should all allow
495     // getInterface back on us, but other than that each one should only
496     // implement one interface.
497 
498     // XXXbz I wish we could just derive the _allcaps thing from _i
499 #define DECL_SHIM(_i, _allcaps)                                    \
500   class _i##Shim final : public nsIInterfaceRequestor, public _i { \
501     ~_i##Shim() {}                                                 \
502                                                                    \
503    public:                                                         \
504     _i##Shim(nsIInterfaceRequestor* aIfreq, _i* aRealPtr)          \
505         : mIfReq(aIfreq), mRealPtr(aRealPtr) {                     \
506       NS_ASSERTION(mIfReq, "Expected non-null here");              \
507       NS_ASSERTION(mRealPtr, "Expected non-null here");            \
508     }                                                              \
509     NS_DECL_ISUPPORTS                                              \
510     NS_FORWARD_NSIINTERFACEREQUESTOR(mIfReq->)                     \
511     NS_FORWARD_##_allcaps(mRealPtr->) private                      \
512         : nsCOMPtr<nsIInterfaceRequestor> mIfReq;                  \
513     nsCOMPtr<_i> mRealPtr;                                         \
514   };
515 
516     DECL_SHIM(nsILoadContext, NSILOADCONTEXT)
517     DECL_SHIM(nsIProgressEventSink, NSIPROGRESSEVENTSINK)
518     DECL_SHIM(nsIChannelEventSink, NSICHANNELEVENTSINK)
519 #undef DECL_SHIM
520   };
521 
522   /**
523    * Add an ExternalResource for aURI.  aViewer and aLoadGroup might be null
524    * when this is called if the URI didn't result in an XML document.  This
525    * function makes sure to remove the pending load for aURI, if any, from our
526    * hashtable, and to notify its observers, if any.
527    */
528   nsresult AddExternalResource(nsIURI* aURI, nsIContentViewer* aViewer,
529                                nsILoadGroup* aLoadGroup,
530                                Document* aDisplayDocument);
531 
532   nsClassHashtable<nsURIHashKey, ExternalResource> mMap;
533   nsRefPtrHashtable<nsURIHashKey, PendingLoad> mPendingLoads;
534   bool mHaveShutDown;
535 };
536 
537 // The current status for a preload.
538 enum class SheetPreloadStatus : uint8_t {
539   // There's no need to preload anything, the sheet is already in-memory.
540   AlreadyComplete,
541   // The load is in-progress. There's no guarantee that a load was started, it
542   // could be coalesced with other redundant loads.
543   InProgress,
544   // Something went wrong, and we errored out.
545   Errored,
546 };
547 
548 //----------------------------------------------------------------------
549 
550 // Document interface.  This is implemented by all document objects in
551 // Gecko.
552 class Document : public nsINode,
553                  public DocumentOrShadowRoot,
554                  public nsSupportsWeakReference,
555                  public nsIRadioGroupContainer,
556                  public nsIScriptObjectPrincipal,
557                  public DispatcherTrait,
558                  public SupportsWeakPtr {
559   friend class DocumentOrShadowRoot;
560 
561  protected:
562   explicit Document(const char* aContentType);
563   virtual ~Document();
564 
565   Document(const Document&) = delete;
566   Document& operator=(const Document&) = delete;
567 
568  public:
569   using ExternalResourceLoad = dom::ExternalResourceMap::ExternalResourceLoad;
570   using ReferrerPolicyEnum = dom::ReferrerPolicy;
571   using AdoptedStyleSheetCloneCache =
572       nsRefPtrHashtable<nsPtrHashKey<const StyleSheet>, StyleSheet>;
573 
574   // nsINode overrides the new operator for DOM Arena allocation.
575   // to use the default one, we need to bring it back again
new(size_t aSize)576   void* operator new(size_t aSize) { return ::operator new(aSize); }
577 
578   /**
579    * Called when XPCOM shutdown.
580    */
581   static void Shutdown();
582 
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)583   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)
584 
585   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
586 
587   NS_DECL_ADDSIZEOFEXCLUDINGTHIS
588 
589   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Document,
590                                                                    nsINode)
591 
592 #define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_)                          \
593   do {                                                                        \
594     NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers, func_, params_);     \
595     /* FIXME(emilio): Apparently we can keep observing from the BFCache? That \
596        looks bogus. */                                                        \
597     if (PresShell* presShell = GetObservingPresShell()) {                     \
598       presShell->func_ params_;                                               \
599     }                                                                         \
600   } while (0)
601 
602   // nsIRadioGroupContainer
603   NS_IMETHOD WalkRadioGroup(const nsAString& aName,
604                             nsIRadioVisitor* aVisitor) final {
605     return DocumentOrShadowRoot::WalkRadioGroup(aName, aVisitor);
606   }
607 
SetCurrentRadioButton(const nsAString & aName,HTMLInputElement * aRadio)608   void SetCurrentRadioButton(const nsAString& aName,
609                              HTMLInputElement* aRadio) final {
610     DocumentOrShadowRoot::SetCurrentRadioButton(aName, aRadio);
611   }
612 
GetCurrentRadioButton(const nsAString & aName)613   HTMLInputElement* GetCurrentRadioButton(const nsAString& aName) final {
614     return DocumentOrShadowRoot::GetCurrentRadioButton(aName);
615   }
616 
617   NS_IMETHOD
GetNextRadioButton(const nsAString & aName,const bool aPrevious,HTMLInputElement * aFocusedRadio,HTMLInputElement ** aRadioOut)618   GetNextRadioButton(const nsAString& aName, const bool aPrevious,
619                      HTMLInputElement* aFocusedRadio,
620                      HTMLInputElement** aRadioOut) final {
621     return DocumentOrShadowRoot::GetNextRadioButton(aName, aPrevious,
622                                                     aFocusedRadio, aRadioOut);
623   }
AddToRadioGroup(const nsAString & aName,HTMLInputElement * aRadio)624   void AddToRadioGroup(const nsAString& aName, HTMLInputElement* aRadio) final {
625     DocumentOrShadowRoot::AddToRadioGroup(aName, aRadio);
626   }
RemoveFromRadioGroup(const nsAString & aName,HTMLInputElement * aRadio)627   void RemoveFromRadioGroup(const nsAString& aName,
628                             HTMLInputElement* aRadio) final {
629     DocumentOrShadowRoot::RemoveFromRadioGroup(aName, aRadio);
630   }
GetRequiredRadioCount(const nsAString & aName)631   uint32_t GetRequiredRadioCount(const nsAString& aName) const final {
632     return DocumentOrShadowRoot::GetRequiredRadioCount(aName);
633   }
RadioRequiredWillChange(const nsAString & aName,bool aRequiredAdded)634   void RadioRequiredWillChange(const nsAString& aName,
635                                bool aRequiredAdded) final {
636     DocumentOrShadowRoot::RadioRequiredWillChange(aName, aRequiredAdded);
637   }
GetValueMissingState(const nsAString & aName)638   bool GetValueMissingState(const nsAString& aName) const final {
639     return DocumentOrShadowRoot::GetValueMissingState(aName);
640   }
SetValueMissingState(const nsAString & aName,bool aValue)641   void SetValueMissingState(const nsAString& aName, bool aValue) final {
642     return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
643   }
644 
645   nsIPrincipal* EffectiveStoragePrincipal() const;
646 
647   // nsIScriptObjectPrincipal
GetPrincipal()648   nsIPrincipal* GetPrincipal() final { return NodePrincipal(); }
649 
GetEffectiveStoragePrincipal()650   nsIPrincipal* GetEffectiveStoragePrincipal() final {
651     return EffectiveStoragePrincipal();
652   }
653 
654   // You should probably not be using this function, since it performs no checks
655   // to ensure that the partitioned principal should really be used here.  It is
656   // only designed to be used in very specific circumstances, such as when
657   // inheriting the document/storage principal.
PartitionedPrincipal()658   nsIPrincipal* PartitionedPrincipal() final { return mPartitionedPrincipal; }
659 
660   // Gets the appropriate principal to check the URI against a blocklist /
661   // allowlist.
662   nsIPrincipal* GetPrincipalForPrefBasedHacks() const;
663 
ClearActiveStoragePrincipal()664   void ClearActiveStoragePrincipal() { mActiveStoragePrincipal = nullptr; }
665 
666   // EventTarget
667   void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
668   EventListenerManager* GetOrCreateListenerManager() override;
669   EventListenerManager* GetExistingListenerManager() const override;
670 
671   // This helper class must be set when we dispatch beforeunload and unload
672   // events in order to avoid unterminate sync XHRs.
673   class MOZ_RAII PageUnloadingEventTimeStamp {
674     RefPtr<Document> mDocument;
675     bool mSet;
676 
677    public:
PageUnloadingEventTimeStamp(Document * aDocument)678     explicit PageUnloadingEventTimeStamp(Document* aDocument)
679         : mDocument(aDocument), mSet(false) {
680       MOZ_ASSERT(aDocument);
681       if (mDocument->mPageUnloadingEventTimeStamp.IsNull()) {
682         mDocument->SetPageUnloadingEventTimeStamp();
683         mSet = true;
684       }
685     }
686 
~PageUnloadingEventTimeStamp()687     ~PageUnloadingEventTimeStamp() {
688       if (mSet) {
689         mDocument->CleanUnloadEventsTimeStamp();
690       }
691     }
692   };
693 
694   /**
695    * Let the document know that we're starting to load data into it.
696    * @param aCommand The parser command. Must not be null.
697    *                 XXXbz It's odd to have that here.
698    * @param aChannel The channel the data will come from. The channel must be
699    *                 able to report its Content-Type.
700    * @param aLoadGroup The loadgroup this document should use from now on.
701    *                   Note that the document might not be the only thing using
702    *                   this loadgroup.
703    * @param aContainer The container this document is in.  This may be null.
704    *                   XXXbz maybe we should make it more explicit (eg make the
705    *                   container an nsIWebNavigation or nsIDocShell or
706    *                   something)?
707    * @param [out] aDocListener the listener to pump data from the channel into.
708    *                           Generally this will be the parser this document
709    *                           sets up, or some sort of data-handler for media
710    *                           documents.
711    * @param aReset whether the document should call Reset() on itself.  If this
712    *               is false, the document will NOT set its principal to the
713    *               channel's owner, will not clear any event listeners that are
714    *               already set on it, etc.
715    *
716    * Once this has been called, the document will return false for
717    * MayStartLayout() until SetMayStartLayout(true) is called on it.  Making
718    * sure this happens is the responsibility of the caller of
719    * StartDocumentLoad().
720    *
721    * This function has an implementation, and does some setup, but does NOT set
722    * *aDocListener; this is the job of subclasses.
723    */
724   virtual nsresult StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
725                                      nsILoadGroup* aLoadGroup,
726                                      nsISupports* aContainer,
727                                      nsIStreamListener** aDocListener,
728                                      bool aReset) = 0;
729   void StopDocumentLoad();
730 
SetSuppressParserErrorElement(bool aSuppress)731   virtual void SetSuppressParserErrorElement(bool aSuppress) {}
SuppressParserErrorElement()732   virtual bool SuppressParserErrorElement() { return false; }
733 
SetSuppressParserErrorConsoleMessages(bool aSuppress)734   virtual void SetSuppressParserErrorConsoleMessages(bool aSuppress) {}
SuppressParserErrorConsoleMessages()735   virtual bool SuppressParserErrorConsoleMessages() { return false; }
736 
737   // nsINode
738   bool IsNodeOfType(uint32_t aFlags) const final;
739   void InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
740                          bool aNotify, ErrorResult& aRv) override;
741   void RemoveChildNode(nsIContent* aKid, bool aNotify) final;
Clone(dom::NodeInfo * aNodeInfo,nsINode ** aResult)742   nsresult Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const override {
743     return NS_ERROR_NOT_IMPLEMENTED;
744   }
745   nsresult CloneDocHelper(Document* clone) const;
746 
GetLatestStaticClone()747   Document* GetLatestStaticClone() const { return mLatestStaticClone; }
748 
749   /**
750    * Signal that the document title may have changed
751    * (see Document::GetTitle).
752    * @param aBoundTitleElement true if an HTML or SVG <title> element
753    * has just been bound to the document.
754    */
755   virtual void NotifyPossibleTitleChange(bool aBoundTitleElement);
756 
757   /**
758    * Return the URI for the document. May return null.  If it ever stops being
759    * able to return null, we can make sure nsINode::GetBaseURI/GetBaseURIObject
760    * also never return null.
761    *
762    * The value returned corresponds to the "document's address" in
763    * HTML5.  As such, it may change over the lifetime of the document, for
764    * instance as a result of the user navigating to a fragment identifier on
765    * the page, or as a result to a call to pushState() or replaceState().
766    *
767    * https://html.spec.whatwg.org/multipage/dom.html#the-document%27s-address
768    */
GetDocumentURI()769   nsIURI* GetDocumentURI() const { return mDocumentURI; }
770 
771   /**
772    * Return the original URI of the document.  This is the same as the
773    * document's URI unless that has changed from its original value (for
774    * example, due to history.pushState() or replaceState() being invoked on the
775    * document).
776    *
777    * This method corresponds to the "creation URL" in HTML5 and, once set,
778    * doesn't change over the lifetime of the document.
779    *
780    * https://html.spec.whatwg.org/multipage/webappapis.html#creation-url
781    */
GetOriginalURI()782   nsIURI* GetOriginalURI() const { return mOriginalURI; }
783 
784   /**
785    * Return the base domain of the document.  This has been computed using
786    * mozIThirdPartyUtil::GetBaseDomain() and can be used for third-party
787    * checks.  When the URI of the document changes, this value is recomputed.
788    */
GetBaseDomain()789   nsCString GetBaseDomain() const { return mBaseDomain; }
790 
791   /**
792    * Set the URI for the document.  This also sets the document's original URI,
793    * if it's null.
794    */
795   void SetDocumentURI(nsIURI* aURI);
796 
797   /**
798    * Set the URI for the document loaded via XHR, when accessed from
799    * chrome privileged script.
800    */
SetChromeXHRDocURI(nsIURI * aURI)801   void SetChromeXHRDocURI(nsIURI* aURI) { mChromeXHRDocURI = aURI; }
802 
803   /**
804    * Set the base URI for the document loaded via XHR, when accessed from
805    * chrome privileged script.
806    */
SetChromeXHRDocBaseURI(nsIURI * aURI)807   void SetChromeXHRDocBaseURI(nsIURI* aURI) { mChromeXHRDocBaseURI = aURI; }
808 
809   /**
810    * The CSP in general is stored in the ClientInfo, but we also cache
811    * the CSP on the document so subresources loaded within a document
812    * can query that cached CSP instead of having to deserialize the CSP
813    * from the Client.
814    *
815    * Please note that at the time of CSP parsing the Client is not
816    * available yet, hence we sync CSP of document and Client when the
817    * Client becomes available within nsGlobalWindowInner::EnsureClientSource().
818    */
819   nsIContentSecurityPolicy* GetCsp() const;
820   void SetCsp(nsIContentSecurityPolicy* aCSP);
821 
822   nsIContentSecurityPolicy* GetPreloadCsp() const;
823   void SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP);
824 
825   void GetCspJSON(nsString& aJSON);
826 
827   /**
828    * Set referrer policy and upgrade-insecure-requests flags
829    */
830   void ApplySettingsFromCSP(bool aSpeculative);
831 
CreatorParserOrNull()832   already_AddRefed<nsIParser> CreatorParserOrNull() {
833     nsCOMPtr<nsIParser> parser = mParser;
834     return parser.forget();
835   }
836 
837   /**
838    * ReferrerInfo getter for Document.webidl.
839    */
ReferrerInfo()840   nsIReferrerInfo* ReferrerInfo() const { return GetReferrerInfo(); }
841 
GetReferrerInfo()842   nsIReferrerInfo* GetReferrerInfo() const { return mReferrerInfo; }
843 
GetPreloadReferrerInfo()844   nsIReferrerInfo* GetPreloadReferrerInfo() const {
845     return mPreloadReferrerInfo;
846   }
847   /**
848    * Return the referrer policy of the document. Return "default" if there's no
849    * valid meta referrer tag found in the document.
850    * Referrer policy should be inherited from parent if the iframe is srcdoc
851    */
852   ReferrerPolicyEnum GetReferrerPolicy() const;
853 
854   /**
855    * GetReferrerPolicy() for Document.webidl.
856    */
ReferrerPolicy()857   ReferrerPolicyEnum ReferrerPolicy() const { return GetReferrerPolicy(); }
858 
859   /**
860    * If true, this flag indicates that all mixed content subresource
861    * loads for this document (and also embeded browsing contexts) will
862    * be blocked.
863    */
GetBlockAllMixedContent(bool aPreload)864   bool GetBlockAllMixedContent(bool aPreload) const {
865     if (aPreload) {
866       return mBlockAllMixedContentPreloads;
867     }
868     return mBlockAllMixedContent;
869   }
870 
871   /**
872    * If true, this flag indicates that all subresource loads for this
873    * document need to be upgraded from http to https.
874    * This flag becomes true if the CSP of the document itself, or any
875    * of the document's ancestors up to the toplevel document makes use
876    * of the CSP directive 'upgrade-insecure-requests'.
877    */
GetUpgradeInsecureRequests(bool aPreload)878   bool GetUpgradeInsecureRequests(bool aPreload) const {
879     if (aPreload) {
880       return mUpgradeInsecurePreloads;
881     }
882     return mUpgradeInsecureRequests;
883   }
884 
SetReferrerInfo(nsIReferrerInfo * aReferrerInfo)885   void SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
886     mReferrerInfo = aReferrerInfo;
887   }
888 
889   /*
890    * Referrer policy from <meta name="referrer" content=`policy`>
891    * will have higher priority than referrer policy from Referrer-Policy
892    * header. So override the old ReferrerInfo if we get one from meta
893    */
894   void UpdateReferrerInfoFromMeta(const nsAString& aMetaReferrer,
895                                   bool aPreload);
896 
897   /**
898    * Set the principals responsible for this document.  Chances are, you do not
899    * want to be using this.
900    */
901   void SetPrincipals(nsIPrincipal* aPrincipal,
902                      nsIPrincipal* aPartitionedPrincipal);
903 
904   /**
905    * Returns true if exempt from HTTPS-Only Mode upgrade.
906    */
HttpsOnlyStatus()907   uint32_t HttpsOnlyStatus() const { return mHttpsOnlyStatus; }
908 
909   /**
910    * Return the LoadGroup for the document. May return null.
911    */
GetDocumentLoadGroup()912   already_AddRefed<nsILoadGroup> GetDocumentLoadGroup() const {
913     nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
914     return group.forget();
915   }
916 
917   /**
918    * Return the fallback base URL for this document, as defined in the HTML
919    * specification.  Note that this can return null if there is no document URI.
920    *
921    * XXXbz: This doesn't implement the bits for about:blank yet.
922    */
GetFallbackBaseURI()923   nsIURI* GetFallbackBaseURI() const {
924     if (mIsSrcdocDocument && mParentDocument) {
925       return mParentDocument->GetDocBaseURI();
926     }
927     return mDocumentURI;
928   }
929 
930   /**
931    * Return the referrer from document URI as defined in the Referrer Policy
932    * specification.
933    * https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
934    * While document is an iframe srcdoc document, let document be document's
935    * browsing context's browsing context container's node document.
936    * Then referrer should be document's URL
937    */
938 
GetDocumentURIAsReferrer()939   nsIURI* GetDocumentURIAsReferrer() const {
940     if (mIsSrcdocDocument && mParentDocument) {
941       return mParentDocument->GetDocumentURIAsReferrer();
942     }
943     return mDocumentURI;
944   }
945 
946   /**
947    * Return the base URI for relative URIs in the document (the document uri
948    * unless it's overridden by SetBaseURI, HTML <base> tags, etc.).  The
949    * returned URI could be null if there is no document URI.  If the document is
950    * a srcdoc document and has no explicit base URL, return the parent
951    * document's base URL.
952    */
GetDocBaseURI()953   nsIURI* GetDocBaseURI() const {
954     if (mDocumentBaseURI) {
955       return mDocumentBaseURI;
956     }
957     return GetFallbackBaseURI();
958   }
959 
960   nsIURI* GetBaseURI(bool aTryUseXHRDocBaseURI = false) const final;
961 
962   void SetBaseURI(nsIURI* aURI);
963 
964   /**
965    * Resolves a URI based on the document's base URI.
966    */
967   Result<OwningNonNull<nsIURI>, nsresult> ResolveWithBaseURI(
968       const nsAString& aURI);
969 
970   /**
971    * Return the URL data which style system needs for resolving url value.
972    * This method attempts to use the cached object in mCachedURLData, but
973    * if the base URI, document URI, or principal has changed since last
974    * call to this function, or the function is called the first time for
975    * the document, a new one is created.
976    */
977   URLExtraData* DefaultStyleAttrURLData();
978 
979   /**
980    * Get/Set the base target of a link in a document.
981    */
GetBaseTarget(nsAString & aBaseTarget)982   void GetBaseTarget(nsAString& aBaseTarget) const {
983     aBaseTarget = mBaseTarget;
984   }
985 
SetBaseTarget(const nsString & aBaseTarget)986   void SetBaseTarget(const nsString& aBaseTarget) { mBaseTarget = aBaseTarget; }
987 
988   /**
989    * Return a standard name for the document's character set.
990    */
GetDocumentCharacterSet()991   NotNull<const Encoding*> GetDocumentCharacterSet() const {
992     return mCharacterSet;
993   }
994 
995   /**
996    * Set the document's character encoding.
997    */
998   void SetDocumentCharacterSet(NotNull<const Encoding*> aEncoding);
999 
GetDocumentCharacterSetSource()1000   int32_t GetDocumentCharacterSetSource() const { return mCharacterSetSource; }
1001 
1002   // This method MUST be called before SetDocumentCharacterSet if
1003   // you're planning to call both.
SetDocumentCharacterSetSource(int32_t aCharsetSource)1004   void SetDocumentCharacterSetSource(int32_t aCharsetSource) {
1005     mCharacterSetSource = aCharsetSource;
1006   }
1007 
1008   /**
1009    * Get the Content-Type of this document.
1010    */
1011   void GetContentType(nsAString& aContentType);
1012 
1013   /**
1014    * Set the Content-Type of this document.
1015    */
1016   void SetContentType(const nsACString& aContentType);
1017 
1018   /**
1019    * Return the language of this document.
1020    */
GetContentLanguage(nsAString & aContentLanguage)1021   void GetContentLanguage(nsAString& aContentLanguage) const {
1022     CopyASCIItoUTF16(mContentLanguage, aContentLanguage);
1023   }
1024 
1025   // The states BidiEnabled and MathMLEnabled should persist across multiple
1026   // views (screen, print) of the same document.
1027 
1028   /**
1029    * Check if the document contains bidi data.
1030    * If so, we have to apply the Unicode Bidi Algorithm.
1031    */
GetBidiEnabled()1032   bool GetBidiEnabled() const { return mBidiEnabled; }
1033 
1034   /**
1035    * Indicate the document contains bidi data.
1036    * Currently, we cannot disable bidi, because once bidi is enabled,
1037    * it affects a frame model irreversibly, and plays even though
1038    * the document no longer contains bidi data.
1039    */
SetBidiEnabled()1040   void SetBidiEnabled() { mBidiEnabled = true; }
1041 
SetMathMLEnabled()1042   void SetMathMLEnabled() { mMathMLEnabled = true; }
1043 
1044   /**
1045    * Ask this document whether it's the initial document in its window.
1046    */
IsInitialDocument()1047   bool IsInitialDocument() const { return mIsInitialDocumentInWindow; }
1048 
1049   /**
1050    * Tell this document that it's the initial document in its window.  See
1051    * comments on mIsInitialDocumentInWindow for when this should be called.
1052    */
1053   void SetIsInitialDocument(bool aIsInitialDocument);
1054 
1055   void SetLoadedAsData(bool aLoadedAsData, bool aConsiderForMemoryReporting);
1056 
1057   /**
1058    * Normally we assert if a runnable labeled with one DocGroup touches data
1059    * from another DocGroup. Calling IgnoreDocGroupMismatches() on a document
1060    * means that we can touch that document from any DocGroup without asserting.
1061    */
IgnoreDocGroupMismatches()1062   void IgnoreDocGroupMismatches() { mIgnoreDocGroupMismatches = true; }
1063 
1064   /**
1065    * Get the bidi options for this document.
1066    * @see nsBidiUtils.h
1067    */
GetBidiOptions()1068   uint32_t GetBidiOptions() const { return mBidiOptions; }
1069 
1070   /**
1071    * Set the bidi options for this document.  This just sets the bits;
1072    * callers are expected to take action as needed if they want this
1073    * change to actually change anything immediately.
1074    * @see nsBidiUtils.h
1075    */
SetBidiOptions(uint32_t aBidiOptions)1076   void SetBidiOptions(uint32_t aBidiOptions) { mBidiOptions = aBidiOptions; }
1077 
1078   /**
1079    * Set CSP flag for this document.
1080    */
SetHasCSP(bool aHasCSP)1081   void SetHasCSP(bool aHasCSP) { mHasCSP = aHasCSP; }
1082 
1083   /**
1084    * Set unsafe-inline CSP flag for this document.
1085    */
SetHasUnsafeInlineCSP(bool aHasUnsafeInlineCSP)1086   void SetHasUnsafeInlineCSP(bool aHasUnsafeInlineCSP) {
1087     mHasUnsafeInlineCSP = aHasUnsafeInlineCSP;
1088   }
1089 
1090   /**
1091    * Set unsafe-eval CSP flag for this document.
1092    */
SetHasUnsafeEvalCSP(bool aHasUnsafeEvalCSP)1093   void SetHasUnsafeEvalCSP(bool aHasUnsafeEvalCSP) {
1094     mHasUnsafeEvalCSP = aHasUnsafeEvalCSP;
1095   }
1096 
1097   /**
1098    * Returns true if the document holds a CSP
1099    * delivered through an HTTP Header.
1100    */
GetHasCSPDeliveredThroughHeader()1101   bool GetHasCSPDeliveredThroughHeader() {
1102     return mHasCSPDeliveredThroughHeader;
1103   }
1104 
1105   /**
1106    * Return a promise which resolves to the content blocking events.
1107    */
1108   using GetContentBlockingEventsPromise = MozPromise<uint32_t, bool, true>;
1109   [[nodiscard]] RefPtr<GetContentBlockingEventsPromise>
1110   GetContentBlockingEvents();
1111 
1112   /**
1113    * Get the sandbox flags for this document.
1114    * @see nsSandboxFlags.h for the possible flags
1115    */
GetSandboxFlags()1116   uint32_t GetSandboxFlags() const { return mSandboxFlags; }
1117 
GetEmbedderPolicy()1118   Maybe<nsILoadInfo::CrossOriginEmbedderPolicy> GetEmbedderPolicy() const {
1119     return mEmbedderPolicy;
1120   }
1121 
SetEmbedderPolicy(const Maybe<nsILoadInfo::CrossOriginEmbedderPolicy> & aCOEP)1122   void SetEmbedderPolicy(
1123       const Maybe<nsILoadInfo::CrossOriginEmbedderPolicy>& aCOEP) {
1124     mEmbedderPolicy = aCOEP;
1125   }
1126 
1127   /**
1128    * Get string representation of sandbox flags (null if no flags are set)
1129    */
1130   void GetSandboxFlagsAsString(nsAString& aFlags);
1131 
1132   /**
1133    * Set the sandbox flags for this document.
1134    * @see nsSandboxFlags.h for the possible flags
1135    */
SetSandboxFlags(uint32_t sandboxFlags)1136   void SetSandboxFlags(uint32_t sandboxFlags) { mSandboxFlags = sandboxFlags; }
1137 
1138   /**
1139    * Called when the document was decoded as UTF-8 and decoder encountered no
1140    * errors.
1141    */
EnableEncodingMenu()1142   void EnableEncodingMenu() { mEncodingMenuDisabled = false; }
1143 
1144   /**
1145    * Called to disable client access to cookies through the document.cookie API
1146    * from user JavaScript code.
1147    */
DisableCookieAccess()1148   void DisableCookieAccess() { mDisableCookieAccess = true; }
1149 
SetLinkHandlingEnabled(bool aValue)1150   void SetLinkHandlingEnabled(bool aValue) { mLinksEnabled = aValue; }
LinkHandlingEnabled()1151   bool LinkHandlingEnabled() { return mLinksEnabled; }
1152 
1153   /**
1154    * Set compatibility mode for this document
1155    */
1156   void SetCompatibilityMode(nsCompatibility aMode);
1157 
1158   /**
1159    * Called to disable client access to document.write() API from user
1160    * JavaScript code.
1161    */
SetDocWriteDisabled(bool aDisabled)1162   void SetDocWriteDisabled(bool aDisabled) { mDisableDocWrite = aDisabled; }
1163 
1164   /**
1165    * Whether a document.write() call is in progress.
1166    */
IsWriting()1167   bool IsWriting() const { return mWriteLevel != uint32_t(0); }
1168 
1169   /**
1170    * Access HTTP header data (this may also get set from other
1171    * sources, like HTML META tags).
1172    */
1173   void GetHeaderData(nsAtom* aHeaderField, nsAString& aData) const;
1174   void SetHeaderData(nsAtom* aheaderField, const nsAString& aData);
1175 
1176   /**
1177    * Create a new presentation shell that will use aContext for its
1178    * presentation context (presentation contexts <b>must not</b> be
1179    * shared among multiple presentation shells). The caller of this
1180    * method is responsible for calling BeginObservingDocument() on the
1181    * presshell if the presshell should observe document mutations.
1182    */
1183   already_AddRefed<PresShell> CreatePresShell(nsPresContext* aContext,
1184                                               nsViewManager* aViewManager);
1185   void DeletePresShell();
1186 
GetPresShell()1187   PresShell* GetPresShell() const {
1188     return GetBFCacheEntry() ? nullptr : mPresShell;
1189   }
1190 
1191   inline PresShell* GetObservingPresShell() const;
1192 
1193   // Return whether the presshell for this document is safe to flush.
1194   bool IsSafeToFlush() const;
1195 
1196   inline nsPresContext* GetPresContext() const;
1197 
HasShellOrBFCacheEntry()1198   bool HasShellOrBFCacheEntry() const { return mPresShell || mBFCacheEntry; }
1199 
1200   // Instead using this method, what you probably want is
1201   // RemoveFromBFCacheSync() as we do in MessagePort and BroadcastChannel.
1202   void DisallowBFCaching(uint32_t aStatus = BFCacheStatus::NOT_ALLOWED);
1203 
IsBFCachingAllowed()1204   bool IsBFCachingAllowed() const { return !mBFCacheDisallowed; }
1205 
1206   // Accepts null to clear the BFCache entry too.
1207   void SetBFCacheEntry(nsIBFCacheEntry* aEntry);
1208 
GetBFCacheEntry()1209   nsIBFCacheEntry* GetBFCacheEntry() const { return mBFCacheEntry; }
1210 
1211   // Removes this document from the BFCache, if it is cached, and returns
1212   // true if it was.
1213   bool RemoveFromBFCacheSync();
1214 
1215   /**
1216    * Return the parent document of this document. Will return null
1217    * unless this document is within a compound document and has a
1218    * parent. Note that this parent chain may cross chrome boundaries.
1219    */
GetInProcessParentDocument()1220   Document* GetInProcessParentDocument() const { return mParentDocument; }
1221 
1222   /**
1223    * Set the parent document of this document.
1224    */
SetParentDocument(Document * aParent)1225   void SetParentDocument(Document* aParent) {
1226     mParentDocument = aParent;
1227     if (aParent) {
1228       mIgnoreDocGroupMismatches = aParent->mIgnoreDocGroupMismatches;
1229       if (!mIsDevToolsDocument) {
1230         mIsDevToolsDocument = mParentDocument->IsDevToolsDocument();
1231       }
1232     }
1233   }
1234 
1235   /**
1236    * Are plugins allowed in this document ?
1237    */
1238   bool GetAllowPlugins();
1239 
1240   /**
1241    * Set the sub document for aContent to aSubDoc.
1242    */
1243   nsresult SetSubDocumentFor(Element* aContent, Document* aSubDoc);
1244 
1245   /**
1246    * Get the sub document for aContent
1247    */
1248   Document* GetSubDocumentFor(nsIContent* aContent) const;
1249 
1250   /**
1251    * Get the content node for which this document is a sub document.
1252    */
1253   Element* GetEmbedderElement() const;
1254 
1255   /**
1256    * Return the doctype for this document.
1257    */
1258   DocumentType* GetDoctype() const;
1259 
1260   /**
1261    * Return the root element for this document.
1262    */
1263   Element* GetRootElement() const;
1264 
1265   Selection* GetSelection(ErrorResult& aRv);
1266 
1267   nsresult HasStorageAccessSync(bool& aHasStorageAccess);
1268   already_AddRefed<Promise> HasStorageAccess(ErrorResult& aRv);
1269   already_AddRefed<Promise> RequestStorageAccess(ErrorResult& aRv);
1270 
1271   already_AddRefed<Promise> RequestStorageAccessForOrigin(
1272       const nsAString& aThirdPartyOrigin, const bool aRequireUserInteraction,
1273       ErrorResult& aRv);
1274 
1275   bool UseRegularPrincipal() const;
1276 
1277   /**
1278    * Gets the event target to dispatch key events to if there is no focused
1279    * content in the document.
1280    */
1281   virtual Element* GetUnfocusedKeyEventTarget();
1282 
1283   /**
1284    * Retrieve information about the viewport as a data structure.
1285    * This will return information in the viewport META data section
1286    * of the document. This can be used in lieu of ProcessViewportInfo(),
1287    * which places the viewport information in the document header instead
1288    * of returning it directly.
1289    *
1290    * @param aDisplaySize size of the on-screen display area for this
1291    * document, in device pixels.
1292    *
1293    * NOTE: If the site is optimized for mobile (via the doctype), this
1294    * will return viewport information that specifies default information.
1295    */
1296   nsViewportInfo GetViewportInfo(const ScreenIntSize& aDisplaySize);
1297 
1298   void SetMetaViewportData(UniquePtr<ViewportMetaData> aData);
1299 
1300   // Returns a ViewportMetaData for this document.
1301   ViewportMetaData GetViewportMetaData() const;
1302 
1303   /**
1304    * True iff this doc will ignore manual character encoding overrides.
1305    */
WillIgnoreCharsetOverride()1306   virtual bool WillIgnoreCharsetOverride() { return true; }
1307 
1308   /**
1309    * Return whether the document was created by a srcdoc iframe.
1310    */
IsSrcdocDocument()1311   bool IsSrcdocDocument() const { return mIsSrcdocDocument; }
1312 
1313   /**
1314    * Sets whether the document was created by a srcdoc iframe.
1315    */
SetIsSrcdocDocument(bool aIsSrcdocDocument)1316   void SetIsSrcdocDocument(bool aIsSrcdocDocument) {
1317     mIsSrcdocDocument = aIsSrcdocDocument;
1318   }
1319 
1320   /*
1321    * Gets the srcdoc string from within the channel (assuming both exist).
1322    * Returns a void string if this isn't a srcdoc document or if
1323    * the channel has not been set.
1324    */
1325   nsresult GetSrcdocData(nsAString& aSrcdocData);
1326 
1327   already_AddRefed<AnonymousContent> InsertAnonymousContent(
1328       Element& aElement, bool aForce, ErrorResult& aError);
1329   void RemoveAnonymousContent(AnonymousContent& aContent, ErrorResult& aError);
1330   /**
1331    * If aNode is a descendant of anonymous content inserted by
1332    * InsertAnonymousContent, this method returns the root element of the
1333    * inserted anonymous content (in other words, the clone of the aElement
1334    * that was passed to InsertAnonymousContent).
1335    */
1336   Element* GetAnonRootIfInAnonymousContentContainer(nsINode* aNode) const;
GetAnonymousContents()1337   nsTArray<RefPtr<AnonymousContent>>& GetAnonymousContents() {
1338     return mAnonymousContents;
1339   }
1340 
GetPageUnloadingEventTimeStamp()1341   TimeStamp GetPageUnloadingEventTimeStamp() const {
1342     if (!mParentDocument) {
1343       return mPageUnloadingEventTimeStamp;
1344     }
1345 
1346     TimeStamp parentTimeStamp(
1347         mParentDocument->GetPageUnloadingEventTimeStamp());
1348     if (parentTimeStamp.IsNull()) {
1349       return mPageUnloadingEventTimeStamp;
1350     }
1351 
1352     if (!mPageUnloadingEventTimeStamp ||
1353         parentTimeStamp < mPageUnloadingEventTimeStamp) {
1354       return parentTimeStamp;
1355     }
1356 
1357     return mPageUnloadingEventTimeStamp;
1358   }
1359 
1360   void NotifyLayerManagerRecreated();
1361 
1362   /**
1363    * Add an SVG element to the list of elements that need
1364    * their mapped attributes resolved to a Servo declaration block.
1365    *
1366    * These are weak pointers, please manually unschedule them when an element
1367    * is removed.
1368    */
ScheduleSVGForPresAttrEvaluation(SVGElement * aSVG)1369   void ScheduleSVGForPresAttrEvaluation(SVGElement* aSVG) {
1370     mLazySVGPresElements.Insert(aSVG);
1371   }
1372 
1373   // Unschedule an element scheduled by ScheduleFrameRequestCallback (e.g. for
1374   // when it is destroyed)
UnscheduleSVGForPresAttrEvaluation(SVGElement * aSVG)1375   void UnscheduleSVGForPresAttrEvaluation(SVGElement* aSVG) {
1376     mLazySVGPresElements.Remove(aSVG);
1377   }
1378 
1379   // Resolve all SVG pres attrs scheduled in ScheduleSVGForPresAttrEvaluation
1380   void ResolveScheduledSVGPresAttrs();
1381 
1382   Maybe<ClientInfo> GetClientInfo() const;
1383   Maybe<ClientState> GetClientState() const;
1384   Maybe<ServiceWorkerDescriptor> GetController() const;
1385 
1386   // Returns the size of the mBlockedNodesByClassifier array.
1387   //
1388   // This array contains nodes that have been blocked to prevent user tracking,
1389   // fingerprinting, cryptomining, etc. They most likely have had their
1390   // nsIChannel canceled by the URL classifier (Safebrowsing).
1391   //
1392   // A script can subsequently use GetBlockedNodesByClassifier()
1393   // to get a list of references to these nodes.
1394   //
1395   // Note:
1396   // This expresses how many tracking nodes have been blocked for this document
1397   // since its beginning, not how many of them are still around in the DOM tree.
1398   // Weak references to blocked nodes are added in the mBlockedNodesByClassifier
1399   // array but they are not removed when those nodes are removed from the tree
1400   // or even garbage collected.
BlockedNodeByClassifierCount()1401   long BlockedNodeByClassifierCount() const {
1402     return mBlockedNodesByClassifier.Length();
1403   }
1404 
1405   //
1406   // Returns strong references to mBlockedNodesByClassifier. (Document.h)
1407   //
1408   // This array contains nodes that have been blocked to prevent
1409   // user tracking. They most likely have had their nsIChannel
1410   // canceled by the URL classifier (Safebrowsing).
1411   //
1412   already_AddRefed<nsSimpleContentList> BlockedNodesByClassifier() const;
1413 
1414   // Helper method that returns true if the document has storage-access sandbox
1415   // flag.
1416   bool StorageAccessSandboxed() const;
1417 
1418   // Helper method that returns true if storage access API is enabled and
1419   // the passed flag has storage-access sandbox flag.
1420   static bool StorageAccessSandboxed(uint32_t aSandboxFlags);
1421 
1422   // Returns the cookie jar settings for this and sub contexts.
1423   nsICookieJarSettings* CookieJarSettings();
1424 
1425   // Returns whether this document has the storage access permission.
1426   bool HasStorageAccessPermissionGranted();
1427 
1428   // Returns whether the storage access permission of the document is granted by
1429   // the allow list.
1430   bool HasStorageAccessPermissionGrantedByAllowList();
1431 
1432   // Increments the document generation.
Changed()1433   inline void Changed() { ++mGeneration; }
1434 
1435   // Returns the current generation.
GetGeneration()1436   inline int32_t GetGeneration() const { return mGeneration; }
1437 
1438   // Adds cached sizes values to aSizes if there's any
1439   // cached value and if the document generation hasn't
1440   // changed since the cache was created.
1441   // Returns true if sizes were added.
1442   bool GetCachedSizes(nsTabSizes* aSizes);
1443 
1444   // Sets the cache sizes for the current generation.
1445   void SetCachedSizes(nsTabSizes* aSizes);
1446 
1447   /**
1448    * Should be called when an element's editable changes as a result of
1449    * changing its contentEditable attribute/property.
1450    *
1451    * The change should be +1 if the contentEditable attribute/property was
1452    * changed to true, -1 if it was changed to false.
1453    */
1454   void ChangeContentEditableCount(Element*, int32_t aChange);
1455   void DeferredContentEditableCountChange(Element*);
1456 
1457   enum class EditingState : int8_t {
1458     eTearingDown = -2,
1459     eSettingUp = -1,
1460     eOff = 0,
1461     eDesignMode,
1462     eContentEditable
1463   };
1464 
1465   /**
1466    * Returns the editing state of the document (not editable, contentEditable or
1467    * designMode).
1468    */
GetEditingState()1469   EditingState GetEditingState() const { return mEditingState; }
1470 
1471   /**
1472    * Returns whether the document is editable.
1473    */
IsEditingOn()1474   bool IsEditingOn() const {
1475     return GetEditingState() == EditingState::eDesignMode ||
1476            GetEditingState() == EditingState::eContentEditable;
1477   }
1478 
1479   class MOZ_STACK_CLASS nsAutoEditingState {
1480    public:
nsAutoEditingState(Document * aDoc,EditingState aState)1481     nsAutoEditingState(Document* aDoc, EditingState aState)
1482         : mDoc(aDoc), mSavedState(aDoc->mEditingState) {
1483       aDoc->mEditingState = aState;
1484     }
~nsAutoEditingState()1485     ~nsAutoEditingState() { mDoc->mEditingState = mSavedState; }
1486 
1487    private:
1488     RefPtr<Document> mDoc;
1489     EditingState mSavedState;
1490   };
1491   friend class nsAutoEditingState;
1492 
1493   /**
1494    * Set the editing state of the document. Don't use this if you want
1495    * to enable/disable editing, call EditingStateChanged() or
1496    * SetDesignMode().
1497    */
SetEditingState(EditingState aState)1498   void SetEditingState(EditingState aState) { mEditingState = aState; }
1499 
1500   /**
1501    * Called when this Document's editor is destroyed.
1502    */
1503   void TearingDownEditor();
1504 
1505   void SetKeyPressEventModel(uint16_t aKeyPressEventModel);
1506 
1507   // Gets the next form number.
1508   //
1509   // Used by nsContentUtils::GenerateStateKey to get a unique number for each
1510   // parser inserted form element.
GetNextFormNumber()1511   int32_t GetNextFormNumber() { return mNextFormNumber++; }
1512 
1513   // Gets the next form control number.
1514   //
1515   // Used by nsContentUtils::GenerateStateKey to get a unique number for each
1516   // parser inserted form control element.
GetNextControlNumber()1517   int32_t GetNextControlNumber() { return mNextControlNumber++; }
1518 
Preloads()1519   PreloadService& Preloads() { return mPreloadService; }
1520 
1521   bool HasThirdPartyChannel();
1522 
1523   bool ShouldIncludeInTelemetry(bool aAllowExtensionURIs);
1524 
1525   void AddMediaElementWithMSE();
1526   void RemoveMediaElementWithMSE();
1527 
1528   void DoNotifyPossibleTitleChange();
1529 
1530  protected:
1531   friend class nsUnblockOnloadEvent;
1532 
1533   nsresult InitCSP(nsIChannel* aChannel);
1534   nsresult InitCOEP(nsIChannel* aChannel);
1535 
1536   nsresult InitFeaturePolicy(nsIChannel* aChannel);
1537 
1538   nsresult InitReferrerInfo(nsIChannel* aChannel);
1539 
1540   void PostUnblockOnloadEvent();
1541 
1542   void DoUnblockOnload();
1543 
1544   void RetrieveRelevantHeaders(nsIChannel* aChannel);
1545 
1546   void TryChannelCharset(nsIChannel* aChannel, int32_t& aCharsetSource,
1547                          NotNull<const Encoding*>& aEncoding,
1548                          nsHtml5TreeOpExecutor* aExecutor);
1549 
1550   MOZ_CAN_RUN_SCRIPT void DispatchContentLoadedEvents();
1551 
1552   // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
1553   MOZ_CAN_RUN_SCRIPT_BOUNDARY void DispatchPageTransition(
1554       EventTarget* aDispatchTarget, const nsAString& aType, bool aInFrameSwap,
1555       bool aPersisted, bool aOnlySystemGroup);
1556 
1557   // Call this before the document does something that will unbind all content.
1558   // That will stop us from doing a lot of work as each element is removed.
1559   void DestroyElementMaps();
1560 
1561   Element* GetRootElementInternal() const;
1562 
SetPageUnloadingEventTimeStamp()1563   void SetPageUnloadingEventTimeStamp() {
1564     MOZ_ASSERT(!mPageUnloadingEventTimeStamp);
1565     mPageUnloadingEventTimeStamp = TimeStamp::NowLoRes();
1566   }
1567 
CleanUnloadEventsTimeStamp()1568   void CleanUnloadEventsTimeStamp() {
1569     MOZ_ASSERT(mPageUnloadingEventTimeStamp);
1570     mPageUnloadingEventTimeStamp = TimeStamp();
1571   }
1572 
1573   /**
1574    * Clears any Servo element data stored on Elements in the document.
1575    */
1576   void ClearStaleServoData();
1577 
1578   /**
1579    * Do the tree-disconnection that ResetToURI and document.open need to do.
1580    */
1581   void DisconnectNodeTree();
1582 
1583   /**
1584    * MaybeDispatchCheckKeyPressEventModelEvent() dispatches
1585    * "CheckKeyPressEventModel" event to check whether we should dispatch
1586    * keypress events in confluent model or split model.  This should be
1587    * called only when mEditingState is changed to eDesignMode or
1588    * eConentEditable at first time.
1589    */
1590   void MaybeDispatchCheckKeyPressEventModelEvent();
1591 
1592   /* Midas implementation */
1593   nsCommandManager* GetMidasCommandManager();
1594 
1595   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult TurnEditingOff();
1596 
1597   // MOZ_CAN_RUN_SCRIPT_BOUNDARY because this is called from all sorts
1598   // of places, and I'm pretty sure the exact ExecCommand call it
1599   // makes cannot actually run script.
1600   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsresult EditingStateChanged();
1601 
1602   void MaybeEditingStateChanged();
1603 
1604  private:
1605   class SelectorCacheKey {
1606    public:
SelectorCacheKey(const nsACString & aString)1607     explicit SelectorCacheKey(const nsACString& aString) : mKey(aString) {
1608       MOZ_COUNT_CTOR(SelectorCacheKey);
1609     }
1610 
1611     nsCString mKey;
1612     nsExpirationState mState;
1613 
GetExpirationState()1614     nsExpirationState* GetExpirationState() { return &mState; }
1615 
1616     MOZ_COUNTED_DTOR(SelectorCacheKey)
1617   };
1618 
1619   class SelectorCacheKeyDeleter;
1620 
1621  public:
1622   class SelectorCache final : public nsExpirationTracker<SelectorCacheKey, 4> {
1623    public:
1624     using SelectorList = UniquePtr<RawServoSelectorList>;
1625     using Table = nsTHashMap<nsCStringHashKey, SelectorList>;
1626 
1627     explicit SelectorCache(nsIEventTarget* aEventTarget);
1628     void NotifyExpired(SelectorCacheKey*) final;
1629 
1630     // We do not call MarkUsed because it would just slow down lookups and
1631     // because we're OK expiring things after a few seconds even if they're
1632     // being used.  Returns whether we actually had an entry for aSelector.
1633     //
1634     // If we have an entry and the selector list returned has a null
1635     // RawServoSelectorList*, that indicates that aSelector has already been
1636     // parsed and is not a syntactically valid selector.
1637     template <typename F>
GetListOrInsertFrom(const nsACString & aSelector,F && aFrom)1638     RawServoSelectorList* GetListOrInsertFrom(const nsACString& aSelector,
1639                                               F&& aFrom) {
1640       MOZ_ASSERT(NS_IsMainThread());
1641       return mTable.LookupOrInsertWith(aSelector, std::forward<F>(aFrom)).get();
1642     }
1643 
1644     ~SelectorCache();
1645 
1646    private:
1647     Table mTable;
1648   };
1649 
GetSelectorCache()1650   SelectorCache& GetSelectorCache() {
1651     if (!mSelectorCache) {
1652       mSelectorCache =
1653           MakeUnique<SelectorCache>(EventTargetFor(TaskCategory::Other));
1654     }
1655     return *mSelectorCache;
1656   }
1657   // Get the root <html> element, or return null if there isn't one (e.g.
1658   // if the root isn't <html>)
1659   Element* GetHtmlElement() const;
1660   // Returns the first child of GetHtmlContent which has the given tag,
1661   // or nullptr if that doesn't exist.
1662   Element* GetHtmlChildElement(nsAtom* aTag);
1663   // Get the canonical <body> element, or return null if there isn't one (e.g.
1664   // if the root isn't <html> or if the <body> isn't there)
1665   HTMLBodyElement* GetBodyElement();
1666   // Get the canonical <head> element, or return null if there isn't one (e.g.
1667   // if the root isn't <html> or if the <head> isn't there)
GetHeadElement()1668   Element* GetHeadElement() { return GetHtmlChildElement(nsGkAtoms::head); }
1669   // Get the "body" in the sense of document.body: The first <body> or
1670   // <frameset> that's a child of a root <html>
1671   nsGenericHTMLElement* GetBody();
1672   // Set the "body" in the sense of document.body.
1673   void SetBody(nsGenericHTMLElement* aBody, ErrorResult& rv);
1674   // Get the "head" element in the sense of document.head.
1675   HTMLSharedElement* GetHead();
1676 
StyleSetForPresShellOrMediaQueryEvaluation()1677   ServoStyleSet* StyleSetForPresShellOrMediaQueryEvaluation() const {
1678     return mStyleSet.get();
1679   }
1680 
1681   // ShadowRoot has APIs that can change styles. This notifies the shell that
1682   // stlyes applicable in the shadow tree have potentially changed.
1683   void RecordShadowStyleChange(ShadowRoot&);
1684 
1685   // Needs to be called any time the applicable style can has changed, in order
1686   // to schedule a style flush and setup all the relevant state.
1687   void ApplicableStylesChanged();
1688 
1689   // Whether we filled the style set with any style sheet. Only meant to be used
1690   // from DocumentOrShadowRoot::Traverse.
StyleSetFilled()1691   bool StyleSetFilled() const { return mStyleSetFilled; }
1692 
1693   /**
1694    * Accessors to the collection of stylesheets owned by this document.
1695    * Style sheets are ordered, most significant last.
1696    */
1697 
1698   void InsertSheetAt(size_t aIndex, StyleSheet&);
1699 
1700   /**
1701    * Add a stylesheet to the document
1702    *
1703    * TODO(emilio): This is only used by parts of editor that are no longer in
1704    * use by m-c or c-c, so remove.
1705    */
AddStyleSheet(StyleSheet * aSheet)1706   void AddStyleSheet(StyleSheet* aSheet) {
1707     MOZ_ASSERT(aSheet);
1708     InsertSheetAt(SheetCount(), *aSheet);
1709   }
1710 
1711   /**
1712    * Notify the document that the applicable state of the sheet changed
1713    * and that observers should be notified and style sets updated
1714    */
1715   void StyleSheetApplicableStateChanged(StyleSheet&);
1716 
1717   void PostStyleSheetApplicableStateChangeEvent(StyleSheet&);
1718 
1719   enum additionalSheetType {
1720     eAgentSheet,
1721     eUserSheet,
1722     eAuthorSheet,
1723     AdditionalSheetTypeCount
1724   };
1725 
1726   nsresult LoadAdditionalStyleSheet(additionalSheetType aType,
1727                                     nsIURI* aSheetURI);
1728   nsresult AddAdditionalStyleSheet(additionalSheetType aType,
1729                                    StyleSheet* aSheet);
1730   void RemoveAdditionalStyleSheet(additionalSheetType aType, nsIURI* sheetURI);
1731 
GetFirstAdditionalAuthorSheet()1732   StyleSheet* GetFirstAdditionalAuthorSheet() {
1733     return mAdditionalSheets[eAuthorSheet].SafeElementAt(0);
1734   }
1735 
1736   /**
1737    * Returns the index that aSheet should be inserted at to maintain document
1738    * ordering.
1739    */
1740   size_t FindDocStyleSheetInsertionPoint(const StyleSheet& aSheet);
1741 
1742   /**
1743    * Get this document's CSSLoader.  This is guaranteed to not return null.
1744    */
CSSLoader()1745   css::Loader* CSSLoader() const { return mCSSLoader; }
1746 
1747   /**
1748    * Get this document's StyleImageLoader.  This is guaranteed to not return
1749    * null.
1750    */
StyleImageLoader()1751   css::ImageLoader* StyleImageLoader() const { return mStyleImageLoader; }
1752 
1753   /**
1754    * Get the channel that was passed to StartDocumentLoad or Reset for this
1755    * document.  Note that this may be null in some cases (eg if
1756    * StartDocumentLoad or Reset were never called)
1757    */
GetChannel()1758   nsIChannel* GetChannel() const { return mChannel; }
1759 
1760   /**
1761    * Get this document's attribute stylesheet.  May return null if
1762    * there isn't one.
1763    */
GetAttributeStyleSheet()1764   nsHTMLStyleSheet* GetAttributeStyleSheet() const { return mAttrStyleSheet; }
1765 
1766   /**
1767    * Get this document's inline style sheet.  May return null if there
1768    * isn't one
1769    */
GetInlineStyleSheet()1770   nsHTMLCSSStyleSheet* GetInlineStyleSheet() const {
1771     return mStyleAttrStyleSheet;
1772   }
1773 
1774   virtual void SetScriptGlobalObject(nsIScriptGlobalObject* aGlobalObject);
1775 
1776   /**
1777    * Get/set the object from which the context for the event/script handling can
1778    * be got. Normally GetScriptHandlingObject() returns the same object as
1779    * GetScriptGlobalObject(), but if the document is loaded as data,
1780    * non-null may be returned, even if GetScriptGlobalObject() returns null.
1781    * aHasHadScriptHandlingObject is set true if document has had the object
1782    * for event/script handling. Do not process any events/script if the method
1783    * returns null, but aHasHadScriptHandlingObject is true.
1784    */
GetScriptHandlingObject(bool & aHasHadScriptHandlingObject)1785   nsIScriptGlobalObject* GetScriptHandlingObject(
1786       bool& aHasHadScriptHandlingObject) const {
1787     aHasHadScriptHandlingObject = mHasHadScriptHandlingObject;
1788     return mScriptGlobalObject ? mScriptGlobalObject.get()
1789                                : GetScriptHandlingObjectInternal();
1790   }
1791   void SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject);
1792 
1793   /**
1794    * Get the object that is used as the scope for all of the content
1795    * wrappers whose owner document is this document. Unlike the script global
1796    * object, this will only return null when the global object for this
1797    * document is truly gone. Use this object when you're trying to find a
1798    * content wrapper in XPConnect.
1799    */
1800   nsIGlobalObject* GetScopeObject() const;
1801   void SetScopeObject(nsIGlobalObject* aGlobal);
1802 
1803   /**
1804    * Return the cross-origin-isolated state from browsing context. If it's a
1805    * data document, we get its creator's state.
1806    */
1807   bool CrossOriginIsolated() const;
1808 
1809   /**
1810    * Return the window containing the document (the outer window).
1811    */
GetWindow()1812   nsPIDOMWindowOuter* GetWindow() const {
1813     return mWindow ? mWindow->GetOuterWindow() : GetWindowInternal();
1814   }
1815 
IsInBackgroundWindow()1816   bool IsInBackgroundWindow() const {
1817     auto* outer = mWindow ? mWindow->GetOuterWindow() : nullptr;
1818     return outer && outer->IsBackground();
1819   }
1820 
1821   /**
1822    * Return the inner window used as the script compilation scope for
1823    * this document. If you're not absolutely sure you need this, use
1824    * GetWindow().
1825    */
GetInnerWindow()1826   nsPIDOMWindowInner* GetInnerWindow() const {
1827     return mRemovedFromDocShell ? nullptr : mWindow;
1828   }
1829 
1830   /**
1831    * Return the outer window ID.
1832    */
OuterWindowID()1833   uint64_t OuterWindowID() const {
1834     nsPIDOMWindowOuter* window = GetWindow();
1835     return window ? window->WindowID() : 0;
1836   }
1837 
1838   /**
1839    * Return the inner window ID.
1840    */
InnerWindowID()1841   uint64_t InnerWindowID() const {
1842     nsPIDOMWindowInner* window = GetInnerWindow();
1843     return window ? window->WindowID() : 0;
1844   }
1845 
1846   /**
1847    * Return WindowGlobalChild that is associated with the inner window.
1848    */
GetWindowGlobalChild()1849   WindowGlobalChild* GetWindowGlobalChild() {
1850     return GetInnerWindow() ? GetInnerWindow()->GetWindowGlobalChild()
1851                             : nullptr;
1852   }
1853 
1854   /**
1855    * Return WindowContext associated with the inner window.
1856    */
GetWindowContext()1857   WindowContext* GetWindowContext() const {
1858     return GetInnerWindow() ? GetInnerWindow()->GetWindowContext() : nullptr;
1859   }
1860 
1861   bool IsTopLevelWindowInactive() const;
1862 
1863   /**
1864    * Get the script loader for this document
1865    */
ScriptLoader()1866   dom::ScriptLoader* ScriptLoader() { return mScriptLoader; }
1867 
1868   /**
1869    * Add/Remove an element to the document's id and name hashes
1870    */
1871   void AddToIdTable(Element* aElement, nsAtom* aId);
1872   void RemoveFromIdTable(Element* aElement, nsAtom* aId);
1873   void AddToNameTable(Element* aElement, nsAtom* aName);
1874   void RemoveFromNameTable(Element* aElement, nsAtom* aName);
1875 
1876   /**
1877    * Returns all elements in the top layer in the insertion order.
1878    */
1879   nsTArray<Element*> GetTopLayer() const;
1880 
1881   /**
1882    * Asynchronously requests that the document make aElement the fullscreen
1883    * element, and move into fullscreen mode. The current fullscreen element
1884    * (if any) is pushed onto the top layer, and it can be
1885    * returned to fullscreen status by calling RestorePreviousFullscreenState().
1886    *
1887    * Note that requesting fullscreen in a document also makes the element which
1888    * contains this document in this document's parent document fullscreen. i.e.
1889    * the <iframe> or <browser> that contains this document is also mode
1890    * fullscreen. This happens recursively in all ancestor documents.
1891    */
1892   void AsyncRequestFullscreen(UniquePtr<FullscreenRequest>);
1893 
1894   // Do the "fullscreen element ready check" from the fullscreen spec.
1895   // It returns true if the given element is allowed to go into fullscreen.
1896   // It is responsive to dispatch "fullscreenerror" event when necessary.
1897   bool FullscreenElementReadyCheck(FullscreenRequest&);
1898 
1899   // This is called asynchronously by Document::AsyncRequestFullscreen()
1900   // to move this document into fullscreen mode if allowed.
1901   void RequestFullscreen(UniquePtr<FullscreenRequest> aRequest,
1902                          bool applyFullScreenDirectly = false);
1903 
1904  private:
1905   void RequestFullscreenInContentProcess(UniquePtr<FullscreenRequest> aRequest,
1906                                          bool applyFullScreenDirectly);
1907   void RequestFullscreenInParentProcess(UniquePtr<FullscreenRequest> aRequest,
1908                                         bool applyFullScreenDirectly);
1909 
1910  public:
1911   // Removes all the elements with fullscreen flag set from the top layer, and
1912   // clears their fullscreen flag.
1913   void CleanupFullscreenState();
1914 
1915   // Pushes aElement onto the top layer
1916   void TopLayerPush(Element* aElement);
1917 
1918   // Removes the topmost element which have aPredicate return true from the top
1919   // layer. The removed element, if any, is returned.
1920   Element* TopLayerPop(FunctionRef<bool(Element*)> aPredicateFunc);
1921 
1922   // Pops the fullscreen element from the top layer and clears its
1923   // fullscreen flag.
1924   void UnsetFullscreenElement();
1925 
1926   // Pushes the given element into the top of top layer and set fullscreen
1927   // flag.
1928   void SetFullscreenElement(Element* aElement);
1929 
1930   // Cancel the dialog element if the document is blocked by the dialog
1931   void TryCancelDialog();
1932 
1933   void SetBlockedByModalDialog(HTMLDialogElement&);
1934 
1935   void UnsetBlockedByModalDialog(HTMLDialogElement&);
1936 
1937   /**
1938    * Called when a frame in a child process has entered fullscreen or when a
1939    * fullscreen frame in a child process changes to another origin.
1940    * aFrameElement is the frame element which contains the child-process
1941    * fullscreen document.
1942    */
1943   void RemoteFrameFullscreenChanged(Element* aFrameElement);
1944 
1945   /**
1946    * Called when a frame in a remote child document has rolled back fullscreen
1947    * so that all its top layer are empty; we must continue the
1948    * rollback in this parent process' doc tree branch which is fullscreen.
1949    * Note that only one branch of the document tree can have its documents in
1950    * fullscreen state at one time. We're in inconsistent state if a
1951    * fullscreen document has a parent and that parent isn't fullscreen. We
1952    * preserve this property across process boundaries.
1953    */
1954   void RemoteFrameFullscreenReverted();
1955 
1956   /**
1957    * Restores the previous fullscreen element to fullscreen status. If there
1958    * is no former fullscreen element, this exits fullscreen, moving the
1959    * top-level browser window out of fullscreen mode.
1960    */
1961   void RestorePreviousFullscreenState(UniquePtr<FullscreenExit>);
1962 
1963   /**
1964    * Returns true if this document is a fullscreen leaf document, i.e. it
1965    * is in fullscreen mode and has no fullscreen children.
1966    */
1967   bool IsFullscreenLeaf();
1968 
1969   /**
1970    * Returns the document which is at the root of this document's branch
1971    * in the in-process document tree. Returns nullptr if the document isn't
1972    * fullscreen.
1973    */
1974   Document* GetFullscreenRoot();
1975 
1976   size_t CountFullscreenElements() const;
1977 
1978   /**
1979    * Sets the fullscreen root to aRoot. This stores a weak reference to aRoot
1980    * in this document.
1981    */
1982   void SetFullscreenRoot(Document* aRoot);
1983 
1984   /**
1985    * Synchronously cleans up the fullscreen state on the given document.
1986    *
1987    * Calling this without performing fullscreen transition could lead
1988    * to undesired effect (the transition happens after document state
1989    * flips), hence it should only be called either by nsGlobalWindow
1990    * when we have performed the transition, or when it is necessary to
1991    * clean up the state immediately. Otherwise, AsyncExitFullscreen()
1992    * should be called instead.
1993    *
1994    * aDocument must not be null.
1995    */
1996   static void ExitFullscreenInDocTree(Document* aDocument);
1997 
1998   /**
1999    * Ask the document to exit fullscreen state asynchronously.
2000    *
2001    * Different from ExitFullscreenInDocTree(), this allows the window
2002    * to perform fullscreen transition first if any.
2003    *
2004    * If aDocument is null, it will exit fullscreen from all documents
2005    * in all windows.
2006    */
2007   static void AsyncExitFullscreen(Document* aDocument);
2008 
2009   /**
2010    * Handles any pending fullscreen in aDocument or its subdocuments.
2011    *
2012    * Returns whether there is any fullscreen request handled.
2013    */
2014   static bool HandlePendingFullscreenRequests(Document* aDocument);
2015 
2016   // ScreenOrientation related APIs
2017 
2018   void ClearOrientationPendingPromise();
2019   bool SetOrientationPendingPromise(Promise* aPromise);
GetOrientationPendingPromise()2020   Promise* GetOrientationPendingPromise() const {
2021     return mOrientationPendingPromise;
2022   }
2023 
2024   //----------------------------------------------------------------------
2025 
2026   // Document notification API's
2027 
2028   /**
2029    * Add a new observer of document change notifications. Whenever
2030    * content is changed, appended, inserted or removed the observers are
2031    * informed.  An observer that is already observing the document must
2032    * not be added without being removed first.
2033    */
2034   void AddObserver(nsIDocumentObserver* aObserver);
2035 
2036   /**
2037    * Remove an observer of document change notifications. This will
2038    * return false if the observer cannot be found.
2039    */
2040   bool RemoveObserver(nsIDocumentObserver* aObserver);
2041 
2042   // Observation hooks used to propagate notifications to document observers.
2043   // BeginUpdate must be called before any batch of modifications of the
2044   // content model or of style data, EndUpdate must be called afterward.
2045   // To make this easy and painless, use the mozAutoDocUpdate helper class.
2046   void BeginUpdate();
2047   void EndUpdate();
UpdateNestingLevel()2048   uint32_t UpdateNestingLevel() { return mUpdateNestLevel; }
2049 
2050   void BeginLoad();
2051   virtual void EndLoad();
2052 
2053   enum ReadyState {
2054     READYSTATE_UNINITIALIZED = 0,
2055     READYSTATE_LOADING = 1,
2056     READYSTATE_INTERACTIVE = 3,
2057     READYSTATE_COMPLETE = 4
2058   };
2059   // Set the readystate of the document.  If aUpdateTimingInformation is true,
2060   // this will record relevant timestamps in the document's performance timing.
2061   // Some consumers (document.open is the only one right now, actually) don't
2062   // want to do that, though.
2063   void SetReadyStateInternal(ReadyState, bool aUpdateTimingInformation = true);
GetReadyStateEnum()2064   ReadyState GetReadyStateEnum() { return mReadyState; }
2065 
2066   void NotifyLoading(bool aNewParentIsLoading, const ReadyState& aCurrentState,
2067                      ReadyState aNewState);
2068 
2069   void NotifyAbortedLoad();
2070 
2071   // notify that a content node changed state.  This must happen under
2072   // a scriptblocker but NOT within a begin/end update.
2073   void ContentStateChanged(nsIContent* aContent, EventStates aStateMask);
2074 
2075   // Update a set of document states that may have changed.
2076   // This should only be called by callers whose state is also reflected in the
2077   // implementation of Document::GetDocumentState.
2078   //
2079   // aNotify controls whether we notify our DocumentStatesChanged observers.
2080   void UpdateDocumentStates(EventStates aMaybeChangedStates, bool aNotify);
2081 
2082   void ResetDocumentDirection();
2083 
2084   // Observation hooks for style data to propagate notifications
2085   // to document observers
2086   void RuleChanged(StyleSheet&, css::Rule*, StyleRuleChangeKind);
2087   void RuleAdded(StyleSheet&, css::Rule&);
2088   void RuleRemoved(StyleSheet&, css::Rule&);
SheetCloned(StyleSheet &)2089   void SheetCloned(StyleSheet&) {}
2090   void ImportRuleLoaded(CSSImportRule&, StyleSheet&);
2091 
2092   /**
2093    * Flush notifications for this document and its parent documents
2094    * (since those may affect the layout of this one).
2095    */
2096   void FlushPendingNotifications(FlushType aType);
2097 
2098   /**
2099    * Another variant of the above FlushPendingNotifications.  This function
2100    * takes a ChangesToFlush to specify whether throttled animations are flushed
2101    * or not.
2102    * If in doubt, use the above FlushPendingNotifications.
2103    */
2104   MOZ_CAN_RUN_SCRIPT_BOUNDARY
2105   void FlushPendingNotifications(ChangesToFlush aFlush);
2106 
2107   /**
2108    * Calls FlushPendingNotifications on any external resources this document
2109    * has. If this document has no external resources or is an external resource
2110    * itself this does nothing. This should only be called with
2111    * aType >= FlushType::Style.
2112    */
2113   void FlushExternalResources(FlushType aType);
2114 
2115   void AddWorkerDocumentListener(WorkerDocumentListener* aListener);
2116   void RemoveWorkerDocumentListener(WorkerDocumentListener* aListener);
2117 
2118   // Triggers an update of <svg:use> element shadow trees.
UpdateSVGUseElementShadowTrees()2119   void UpdateSVGUseElementShadowTrees() {
2120     if (mSVGUseElementsNeedingShadowTreeUpdate.IsEmpty()) {
2121       return;
2122     }
2123     DoUpdateSVGUseElementShadowTrees();
2124   }
2125 
2126   /**
2127    * Only to be used inside Gecko, you can't really do anything with the
2128    * pointer outside Gecko anyway.
2129    */
NodeInfoManager()2130   nsNodeInfoManager* NodeInfoManager() const { return mNodeInfoManager; }
2131 
2132   /**
2133    * Reset the document using the given channel and loadgroup.  This works
2134    * like ResetToURI, but also sets the document's channel to aChannel.
2135    * The principal of the document will be set from the channel.
2136    */
2137   virtual void Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup);
2138 
2139   /**
2140    * Reset this document to aURI, aLoadGroup, aPrincipal and
2141    * aPartitionedPrincipal.  aURI must not be null.  If aPrincipal is null, a
2142    * content principal based on aURI will be used.
2143    */
2144   virtual void ResetToURI(nsIURI* aURI, nsILoadGroup* aLoadGroup,
2145                           nsIPrincipal* aPrincipal,
2146                           nsIPrincipal* aPartitionedPrincipal);
2147 
2148   /**
2149    * Set the container (docshell) for this document. Virtual so that
2150    * docshell can call it.
2151    */
2152   virtual void SetContainer(nsDocShell* aContainer);
2153 
2154   /**
2155    * Get the container (docshell) for this document.
2156    */
2157   nsISupports* GetContainer() const;
2158 
2159   /**
2160    * Get the container's load context for this document.
2161    */
2162   nsILoadContext* GetLoadContext() const;
2163 
2164   /**
2165    * Get docshell the for this document.
2166    */
2167   nsIDocShell* GetDocShell() const;
2168 
2169   /**
2170    * Set and get XML declaration. If aVersion is null there is no declaration.
2171    * aStandalone takes values -1, 0 and 1 indicating respectively that there
2172    * was no standalone parameter in the declaration, that it was given as no,
2173    * or that it was given as yes.
2174    */
2175   void SetXMLDeclaration(const char16_t* aVersion, const char16_t* aEncoding,
2176                          const int32_t aStandalone);
2177   void GetXMLDeclaration(nsAString& aVersion, nsAString& aEncoding,
2178                          nsAString& Standalone);
2179 
2180   /**
2181    * Returns the bits for the color-scheme specified by the
2182    * <meta name="color-scheme">.
2183    */
GetColorSchemeBits()2184   uint8_t GetColorSchemeBits() const { return mColorSchemeBits; }
2185 
2186   /**
2187    * Traverses the DOM and computes the supported color schemes as per
2188    * https://html.spec.whatwg.org/#meta-color-scheme
2189    */
2190   void RecomputeColorScheme();
2191   void AddColorSchemeMeta(HTMLMetaElement&);
2192   void RemoveColorSchemeMeta(HTMLMetaElement&);
2193 
2194   /**
2195    * Returns true if this is what HTML 5 calls an "HTML document" (for example
2196    * regular HTML document with Content-Type "text/html", image documents and
2197    * media documents).  Returns false for XHTML and any other documents parsed
2198    * by the XML parser.
2199    */
IsHTMLDocument()2200   bool IsHTMLDocument() const { return mType == eHTML; }
IsHTMLOrXHTML()2201   bool IsHTMLOrXHTML() const { return mType == eHTML || mType == eXHTML; }
IsXMLDocument()2202   bool IsXMLDocument() const { return !IsHTMLDocument(); }
IsSVGDocument()2203   bool IsSVGDocument() const { return mType == eSVG; }
IsUnstyledDocument()2204   bool IsUnstyledDocument() { return IsLoadedAsData(); }
LoadsFullXULStyleSheetUpFront()2205   bool LoadsFullXULStyleSheetUpFront() {
2206     if (IsSVGDocument()) {
2207       return false;
2208     }
2209     return AllowXULXBL();
2210   }
2211 
2212   bool IsScriptEnabled();
2213 
2214   /**
2215    * Returns true if this document was created from a nsXULPrototypeDocument.
2216    */
LoadedFromPrototype()2217   bool LoadedFromPrototype() const { return mPrototypeDocument; }
2218   /**
2219    * Returns the prototype the document was created from, or null if it was not
2220    * created from a prototype.
2221    */
GetPrototype()2222   nsXULPrototypeDocument* GetPrototype() const { return mPrototypeDocument; }
2223 
IsTopLevelContentDocument()2224   bool IsTopLevelContentDocument() const { return mIsTopLevelContentDocument; }
SetIsTopLevelContentDocument(bool aIsTopLevelContentDocument)2225   void SetIsTopLevelContentDocument(bool aIsTopLevelContentDocument) {
2226     mIsTopLevelContentDocument = aIsTopLevelContentDocument;
2227   }
2228 
IsContentDocument()2229   bool IsContentDocument() const { return mIsContentDocument; }
SetIsContentDocument(bool aIsContentDocument)2230   void SetIsContentDocument(bool aIsContentDocument) {
2231     mIsContentDocument = aIsContentDocument;
2232   }
2233 
2234   void ProcessMETATag(HTMLMetaElement* aMetaElement);
2235   /**
2236    * Create an element with the specified name, prefix and namespace ID.
2237    * Returns null if element name parsing failed.
2238    */
2239   already_AddRefed<Element> CreateElem(const nsAString& aName, nsAtom* aPrefix,
2240                                        int32_t aNamespaceID,
2241                                        const nsAString* aIs = nullptr);
2242 
2243   /**
2244    * Get the security info (i.e. SSL state etc) that the document got
2245    * from the channel/document that created the content of the
2246    * document.
2247    *
2248    * @see nsIChannel
2249    */
GetSecurityInfo()2250   nsISupports* GetSecurityInfo() { return mSecurityInfo; }
2251 
2252   /**
2253    * Get the channel that failed to load and resulted in an error page, if it
2254    * exists. This is only relevant to error pages.
2255    */
GetFailedChannel()2256   nsIChannel* GetFailedChannel() const { return mFailedChannel; }
2257 
2258   /**
2259    * This function checks if the document that is trying to access
2260    * GetNetErrorInfo is a trusted about net error page or not.
2261    */
2262   static bool CallerIsTrustedAboutNetError(JSContext* aCx, JSObject* aObject);
2263 
2264   /**
2265    * This function checks if the document that is trying to access
2266    * ReloadWithHttpsOnlyException is a trusted HTTPS only error page.
2267    */
2268   static bool CallerIsTrustedAboutHttpsOnlyError(JSContext* aCx,
2269                                                  JSObject* aObject);
2270 
2271   /**
2272    * Get security info like error code for a failed channel. This
2273    * property is only exposed to about:neterror documents.
2274    */
2275   void GetNetErrorInfo(mozilla::dom::NetErrorInfo& aInfo, ErrorResult& aRv);
2276 
2277   /**
2278    * This function checks if the document that is trying to access
2279    * GetFailedCertSecurityInfo is a trusted cert error page or not.
2280    */
2281   static bool CallerIsTrustedAboutCertError(JSContext* aCx, JSObject* aObject);
2282 
2283   /**
2284    * This function checks if the privilege storage access api is available for
2285    * the caller. We only allow privilege SSA to be called by system principal
2286    * and webcompat extension.
2287    */
2288   static bool CallerCanAccessPrivilegeSSA(JSContext* aCx, JSObject* aObject);
2289 
2290   /**
2291    * Get the security info (i.e. certificate validity, errorCode, etc) for a
2292    * failed Channel. This property is only exposed for about:certerror
2293    * documents.
2294    */
2295   void GetFailedCertSecurityInfo(mozilla::dom::FailedCertSecurityInfo& aInfo,
2296                                  ErrorResult& aRv);
2297 
2298   /**
2299    * Controls whether or not we allow TLS 1.0/1.1. Only exposed to error pages.
2300    */
2301   bool AllowDeprecatedTls();
2302   void SetAllowDeprecatedTls(bool aResult);
2303 
2304   /**
2305    * Set the channel that failed to load and resulted in an error page.
2306    * This is only relevant to error pages.
2307    */
SetFailedChannel(nsIChannel * aChannel)2308   void SetFailedChannel(nsIChannel* aChannel) { mFailedChannel = aChannel; }
2309 
2310   /**
2311    * Returns the default namespace ID used for elements created in this
2312    * document.
2313    */
GetDefaultNamespaceID()2314   int32_t GetDefaultNamespaceID() const { return mDefaultElementType; }
2315 
2316   void RemoveAllProperties();
2317   void RemoveAllPropertiesFor(nsINode* aNode);
2318 
PropertyTable()2319   nsPropertyTable& PropertyTable() { return mPropertyTable; }
2320 
2321   /**
2322    * Sets the ID used to identify this part of the multipart document
2323    */
SetPartID(uint32_t aID)2324   void SetPartID(uint32_t aID) { mPartID = aID; }
2325 
2326   /**
2327    * Return the ID used to identify this part of the multipart document
2328    */
GetPartID()2329   uint32_t GetPartID() const { return mPartID; }
2330 
2331   /**
2332    * Sanitize the document by resetting all input elements and forms that have
2333    * autocomplete=off to their default values.
2334    * TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
2335    */
2336   MOZ_CAN_RUN_SCRIPT_BOUNDARY void Sanitize();
2337 
2338   /**
2339    * Enumerate all subdocuments.
2340    * The enumerator callback should return CallState::Continue to continue
2341    * enumerating, or CallState::Stop to stop.  This will never get passed a null
2342    * aDocument.
2343    */
2344   using SubDocEnumFunc = FunctionRef<CallState(Document&)>;
2345   void EnumerateSubDocuments(SubDocEnumFunc aCallback);
2346 
2347   /**
2348    * Collect all the descendant documents for which |aCalback| returns true.
2349    * The callback function must not mutate any state for the given document.
2350    */
2351   using nsDocTestFunc = bool (*)(const Document* aDocument);
2352   void CollectDescendantDocuments(nsTArray<RefPtr<Document>>& aDescendants,
2353                                   nsDocTestFunc aCallback) const;
2354 
2355   /**
2356    * Check whether it is safe to cache the presentation of this document
2357    * and all of its subdocuments (depending on the 3rd param). This method
2358    * checks the following conditions recursively:
2359    *  - Some document types, such as plugin documents, cannot be safely cached.
2360    *  - If there are any pending requests, we don't allow the presentation
2361    *    to be cached.  Ideally these requests would be suspended and resumed,
2362    *    but that is difficult in some cases, such as XMLHttpRequest.
2363    *  - If there are any beforeunload or unload listeners, we must fire them
2364    *    for correctness, but this likely puts the document into a state where
2365    *    it would not function correctly if restored.
2366    *
2367    * |aNewRequest| should be the request for a new document which will
2368    * replace this document in the docshell.  The new document's request
2369    * will be ignored when checking for active requests.  If there is no
2370    * request associated with the new document, this parameter may be null.
2371    *
2372    * |aBFCacheCombo| is used as a bitmask to indicate what the status
2373    * combination is when we try to BFCache aNewRequest
2374    */
2375   virtual bool CanSavePresentation(nsIRequest* aNewRequest,
2376                                    uint32_t& aBFCacheCombo,
2377                                    bool aIncludeSubdocuments,
2378                                    bool aAllowUnloadListeners = true);
2379 
2380   virtual nsresult Init();
2381 
2382   /**
2383    * Notify the document that its associated ContentViewer is being destroyed.
2384    * This releases circular references so that the document can go away.
2385    * Destroy() is only called on documents that have a content viewer.
2386    */
2387   virtual void Destroy();
2388 
2389   /**
2390    * Notify the document that its associated ContentViewer is no longer
2391    * the current viewer for the docshell. The document might still
2392    * be rendered in "zombie state" until the next document is ready.
2393    * The document should save form control state.
2394    */
2395   void RemovedFromDocShell();
2396 
2397   /**
2398    * Get the layout history state that should be used to save and restore state
2399    * for nodes in this document.  This may return null; if that happens state
2400    * saving and restoration is not possible.
2401    */
2402   already_AddRefed<nsILayoutHistoryState> GetLayoutHistoryState() const;
2403 
2404   /**
2405    * Methods that can be used to prevent onload firing while an event that
2406    * should block onload is posted.  onload is guaranteed to not fire until
2407    * either all calls to BlockOnload() have been matched by calls to
2408    * UnblockOnload() or the load has been stopped altogether (by the user
2409    * pressing the Stop button, say).
2410    */
2411   void BlockOnload();
2412   /**
2413    * @param aFireSync whether to fire onload synchronously.  If false,
2414    * onload will fire asynchronously after all onload blocks have been
2415    * removed.  It will NOT fire from inside UnblockOnload.  If true,
2416    * onload may fire from inside UnblockOnload.
2417    */
2418   void UnblockOnload(bool aFireSync);
2419 
2420   // Only BlockOnload should call this!
2421   void AsyncBlockOnload();
2422 
BlockDOMContentLoaded()2423   void BlockDOMContentLoaded() { ++mBlockDOMContentLoaded; }
2424 
2425   MOZ_CAN_RUN_SCRIPT_BOUNDARY void UnblockDOMContentLoaded();
2426 
2427   /**
2428    * Notification that the page has been shown, for documents which are loaded
2429    * into a DOM window.  This corresponds to the completion of document load,
2430    * or to the page's presentation being restored into an existing DOM window.
2431    * This notification fires applicable DOM events to the content window.  See
2432    * PageTransitionEvent.webidl for a description of the |aPersisted|
2433    * parameter. If aDispatchStartTarget is null, the pageshow event is
2434    * dispatched on the ScriptGlobalObject for this document, otherwise it's
2435    * dispatched on aDispatchStartTarget. If |aOnlySystemGroup| is true, the
2436    * event is only dispatched to listeners in the system group.
2437    * Note: if aDispatchStartTarget isn't null, the showing state of the
2438    * document won't be altered.
2439    */
2440   virtual void OnPageShow(bool aPersisted, EventTarget* aDispatchStartTarget,
2441                           bool aOnlySystemGroup = false);
2442 
2443   /**
2444    * Notification that the page has been hidden, for documents which are loaded
2445    * into a DOM window.  This corresponds to the unloading of the document, or
2446    * to the document's presentation being saved but removed from an existing
2447    * DOM window.  This notification fires applicable DOM events to the content
2448    * window.  See PageTransitionEvent.webidl for a description of the
2449    * |aPersisted| parameter. If aDispatchStartTarget is null, the pagehide
2450    * event is dispatched on the ScriptGlobalObject for this document,
2451    * otherwise it's dispatched on aDispatchStartTarget. If |aOnlySystemGroup| is
2452    * true, the event is only dispatched to listeners in the system group.
2453    * Note: if aDispatchStartTarget isn't null, the showing state of the
2454    * document won't be altered.
2455    */
2456   void OnPageHide(bool aPersisted, EventTarget* aDispatchStartTarget,
2457                   bool aOnlySystemGroup = false);
2458 
2459   /*
2460    * We record the set of links in the document that are relevant to
2461    * style.
2462    */
2463   /**
2464    * Notification that an element is a link that is relevant to style.
2465    */
AddStyleRelevantLink(Link * aLink)2466   void AddStyleRelevantLink(Link* aLink) {
2467     NS_ASSERTION(aLink, "Passing in a null link.  Expect crashes RSN!");
2468 #ifdef DEBUG
2469     NS_ASSERTION(!mStyledLinks.Contains(aLink),
2470                  "Document already knows about this Link!");
2471     mStyledLinksCleared = false;
2472 #endif
2473     mStyledLinks.Insert(aLink);
2474   }
2475 
2476   /**
2477    * Notification that an element is a link and its URI might have been
2478    * changed or the element removed. If the element is still a link relevant
2479    * to style, then someone must ensure that AddStyleRelevantLink is
2480    * (eventually) called on it again.
2481    */
ForgetLink(Link * aLink)2482   void ForgetLink(Link* aLink) {
2483     NS_ASSERTION(aLink, "Passing in a null link.  Expect crashes RSN!");
2484 #ifdef DEBUG
2485     bool linkContained = mStyledLinks.Contains(aLink);
2486     NS_ASSERTION(linkContained || mStyledLinksCleared,
2487                  "Document knows nothing about this Link!");
2488 #endif
2489     mStyledLinks.Remove(aLink);
2490   }
2491 
2492   // Refreshes the hrefs of all the links in the document.
2493   void RefreshLinkHrefs();
2494 
2495   /**
2496    * Support for window.matchMedia()
2497    */
2498 
2499   already_AddRefed<MediaQueryList> MatchMedia(const nsACString& aMediaQueryList,
2500                                               CallerType aCallerType);
2501 
MediaQueryLists()2502   LinkedList<MediaQueryList>& MediaQueryLists() { return mDOMMediaQueryLists; }
2503 
2504   /**
2505    * Get the compatibility mode for this document
2506    */
GetCompatibilityMode()2507   nsCompatibility GetCompatibilityMode() const { return mCompatMode; }
2508 
2509   /**
2510    * Check whether we've ever fired a DOMTitleChanged event for this
2511    * document.
2512    */
HaveFiredDOMTitleChange()2513   bool HaveFiredDOMTitleChange() const { return mHaveFiredTitleChange; }
2514 
2515   /**
2516    * To batch DOMSubtreeModified, document needs to be informed when
2517    * a mutation event might be dispatched, even if the event isn't actually
2518    * created because there are no listeners for it.
2519    *
2520    * @param aTarget is the target for the mutation event.
2521    */
MayDispatchMutationEvent(nsINode * aTarget)2522   void MayDispatchMutationEvent(nsINode* aTarget) {
2523     if (mSubtreeModifiedDepth > 0) {
2524       mSubtreeModifiedTargets.AppendObject(aTarget);
2525     }
2526   }
2527 
2528   /**
2529    * Marks as not-going-to-be-collected for the given generation of
2530    * cycle collection.
2531    */
MarkUncollectableForCCGeneration(uint32_t aGeneration)2532   void MarkUncollectableForCCGeneration(uint32_t aGeneration) {
2533     mMarkedCCGeneration = aGeneration;
2534   }
2535 
2536   /**
2537    * Gets the cycle collector generation this document is marked for.
2538    */
GetMarkedCCGeneration()2539   uint32_t GetMarkedCCGeneration() { return mMarkedCCGeneration; }
2540 
2541   /**
2542    * Returns whether this document is cookie averse. See
2543    * https://html.spec.whatwg.org/multipage/dom.html#cookie-averse-document-object
2544    */
IsCookieAverse()2545   bool IsCookieAverse() const {
2546     // If we are a document that "has no browsing context."
2547     if (!GetInnerWindow()) {
2548       return true;
2549     }
2550 
2551     // If we are a document "whose URL's scheme is not a network scheme."
2552     // NB: Explicitly allow file: URIs to store cookies.
2553 
2554     return !NodePrincipal()->SchemeIs("http") &&
2555            !NodePrincipal()->SchemeIs("https") &&
2556            !NodePrincipal()->SchemeIs("file");
2557   }
2558 
IsLoadedAsData()2559   bool IsLoadedAsData() { return mLoadedAsData; }
2560 
SetAddedToMemoryReportAsDataDocument()2561   void SetAddedToMemoryReportAsDataDocument() {
2562     mAddedToMemoryReportingAsDataDocument = true;
2563   }
2564 
2565   void UnregisterFromMemoryReportingForDataDocument();
2566 
MayStartLayout()2567   bool MayStartLayout() { return mMayStartLayout; }
2568 
2569   void SetMayStartLayout(bool aMayStartLayout);
2570 
2571   already_AddRefed<nsIDocumentEncoder> GetCachedEncoder();
2572 
2573   void SetCachedEncoder(already_AddRefed<nsIDocumentEncoder> aEncoder);
2574 
2575   // In case of failure, the document really can't initialize the frame loader.
2576   nsresult InitializeFrameLoader(nsFrameLoader* aLoader);
2577   // In case of failure, the caller must handle the error, for example by
2578   // finalizing frame loader asynchronously.
2579   nsresult FinalizeFrameLoader(nsFrameLoader* aLoader, nsIRunnable* aFinalizer);
2580   // Removes the frame loader of aShell from the initialization list.
2581   void TryCancelFrameLoaderInitialization(nsIDocShell* aShell);
2582 
2583   /**
2584    * Check whether this document is a root document that is not an
2585    * external resource.
2586    */
IsRootDisplayDocument()2587   bool IsRootDisplayDocument() const {
2588     return !mParentDocument && !mDisplayDocument;
2589   }
2590 
IsDocumentURISchemeChrome()2591   bool IsDocumentURISchemeChrome() const { return mDocURISchemeIsChrome; }
2592 
IsInChromeDocShell()2593   bool IsInChromeDocShell() const {
2594     const Document* root = this;
2595     while (const Document* displayDoc = root->GetDisplayDocument()) {
2596       root = displayDoc;
2597     }
2598     return root->mInChromeDocShell;
2599   }
2600 
IsDevToolsDocument()2601   bool IsDevToolsDocument() const { return mIsDevToolsDocument; }
2602 
IsBeingUsedAsImage()2603   bool IsBeingUsedAsImage() const { return mIsBeingUsedAsImage; }
2604 
SetIsBeingUsedAsImage()2605   void SetIsBeingUsedAsImage() { mIsBeingUsedAsImage = true; }
2606 
IsSVGGlyphsDocument()2607   bool IsSVGGlyphsDocument() const { return mIsSVGGlyphsDocument; }
2608 
SetIsSVGGlyphsDocument()2609   void SetIsSVGGlyphsDocument() { mIsSVGGlyphsDocument = true; }
2610 
IsResourceDoc()2611   bool IsResourceDoc() const {
2612     return IsBeingUsedAsImage() ||  // Are we a helper-doc for an SVG image?
2613            mHasDisplayDocument;     // Are we an external resource doc?
2614   }
2615 
2616   /**
2617    * Get the document for which this document is an external resource.  This
2618    * will be null if this document is not an external resource.  Otherwise,
2619    * GetDisplayDocument() will return a non-null document, and
2620    * GetDisplayDocument()->GetDisplayDocument() is guaranteed to be null.
2621    */
GetDisplayDocument()2622   Document* GetDisplayDocument() const { return mDisplayDocument; }
2623 
2624   /**
2625    * Set the display document for this document.  aDisplayDocument must not be
2626    * null.
2627    */
SetDisplayDocument(Document * aDisplayDocument)2628   void SetDisplayDocument(Document* aDisplayDocument) {
2629     MOZ_ASSERT(!GetPresShell() && !GetContainer() && !GetWindow(),
2630                "Shouldn't set mDisplayDocument on documents that already "
2631                "have a presentation or a docshell or a window");
2632     MOZ_ASSERT(aDisplayDocument, "Must not be null");
2633     MOZ_ASSERT(aDisplayDocument != this, "Should be different document");
2634     MOZ_ASSERT(!aDisplayDocument->GetDisplayDocument(),
2635                "Display documents should not nest");
2636     mDisplayDocument = aDisplayDocument;
2637     mHasDisplayDocument = !!aDisplayDocument;
2638   }
2639 
2640   /**
2641    * Request an external resource document for aURI.  This will return the
2642    * resource document if available.  If one is not available yet, it will
2643    * start loading as needed, and the pending load object will be returned in
2644    * aPendingLoad so that the caller can register an observer to wait for the
2645    * load.  If this function returns null and doesn't return a pending load,
2646    * that means that there is no resource document for this URI and won't be
2647    * one in the future.
2648    *
2649    * @param aURI the URI to get
2650    * @param aReferrerInfo the referrerInfo of the request
2651    * @param aRequestingNode the node making the request
2652    * @param aPendingLoad the pending load for this request, if any
2653    */
2654   Document* RequestExternalResource(nsIURI* aURI,
2655                                     nsIReferrerInfo* aReferrerInfo,
2656                                     nsINode* aRequestingNode,
2657                                     ExternalResourceLoad** aPendingLoad);
2658 
2659   /**
2660    * Enumerate the external resource documents associated with this document.
2661    * The enumerator callback should return CallState::Continue to continue
2662    * enumerating, or CallState::Stop to stop.  This callback will never get
2663    * passed a null aDocument.
2664    */
2665   void EnumerateExternalResources(SubDocEnumFunc aCallback);
2666 
ExternalResourceMap()2667   dom::ExternalResourceMap& ExternalResourceMap() {
2668     return mExternalResourceMap;
2669   }
2670 
2671   /**
2672    * Return whether the document is currently showing (in the sense of
2673    * OnPageShow() having been called already and OnPageHide() not having been
2674    * called yet.
2675    */
IsShowing()2676   bool IsShowing() const { return mIsShowing; }
2677   /**
2678    * Return whether the document is currently visible (in the sense of
2679    * OnPageHide having been called and OnPageShow not yet having been called)
2680    */
IsVisible()2681   bool IsVisible() const { return mVisible; }
2682 
2683   void SetSuppressedEventListener(EventListener* aListener);
2684 
GetSuppressedEventListener()2685   EventListener* GetSuppressedEventListener() {
2686     return mSuppressedEventListener;
2687   }
2688 
2689   /**
2690    * Return true when this document is active, i.e., an active document
2691    * in a content viewer and not in the bfcache.
2692    * This does NOT match the "active document" concept in the WHATWG spec -
2693    * see IsCurrentActiveDocument.
2694    */
2695   bool IsActive() const;
2696 
2697   /**
2698    * Return true if this is the current active document for its
2699    * docshell. Note that a docshell may have multiple active documents
2700    * due to the bfcache -- this should be used when you need to
2701    * differentiate the *current* active document from any active
2702    * documents.
2703    */
IsCurrentActiveDocument()2704   bool IsCurrentActiveDocument() const {
2705     nsPIDOMWindowInner* inner = GetInnerWindow();
2706     return inner && inner->IsCurrentInnerWindow() && inner->GetDoc() == this;
2707   }
2708 
2709   /**
2710    * Returns whether this document should perform image loads.
2711    */
ShouldLoadImages()2712   bool ShouldLoadImages() const {
2713     // We check IsBeingUsedAsImage() so that SVG documents loaded as
2714     // images can themselves have data: URL image references.
2715     return IsCurrentActiveDocument() || IsBeingUsedAsImage() ||
2716            IsStaticDocument();
2717   }
2718 
SetHasPrintCallbacks()2719   void SetHasPrintCallbacks() {
2720     MOZ_DIAGNOSTIC_ASSERT(IsStaticDocument());
2721     mHasPrintCallbacks = true;
2722   }
2723 
HasPrintCallbacks()2724   bool HasPrintCallbacks() const { return mHasPrintCallbacks; }
2725 
2726   /**
2727    * Register/Unregister the ActivityObserver into mActivityObservers to listen
2728    * the document's activity changes such as OnPageHide, visibility, activity.
2729    * The ActivityObserver objects can be nsIObjectLoadingContent or
2730    * nsIDocumentActivity or HTMLMEdiaElement.
2731    */
2732   void RegisterActivityObserver(nsISupports* aSupports);
2733   bool UnregisterActivityObserver(nsISupports* aSupports);
2734   // Enumerate all the observers in mActivityObservers by the aEnumerator.
2735   using ActivityObserverEnumerator = FunctionRef<void(nsISupports*)>;
2736   void EnumerateActivityObservers(ActivityObserverEnumerator aEnumerator);
2737 
2738   void NotifyActivityChanged();
2739 
2740   // Indicates whether mAnimationController has been (lazily) initialized.
2741   // If this returns true, we're promising that GetAnimationController()
2742   // will have a non-null return value.
HasAnimationController()2743   bool HasAnimationController() { return !!mAnimationController; }
2744 
2745   // Getter for this document's SMIL Animation Controller. Performs lazy
2746   // initialization, if this document supports animation and if
2747   // mAnimationController isn't yet initialized.
2748   //
2749   // If HasAnimationController is true, this is guaranteed to return non-null.
2750   SMILAnimationController* GetAnimationController();
2751 
2752   // Gets the tracker for animations that are waiting to start.
2753   // Returns nullptr if there is no pending animation tracker for this document
2754   // which will be the case if there have never been any CSS animations or
2755   // transitions on elements in the document.
GetPendingAnimationTracker()2756   PendingAnimationTracker* GetPendingAnimationTracker() {
2757     return mPendingAnimationTracker;
2758   }
2759 
2760   // Gets the tracker for animations that are waiting to start and
2761   // creates it if it doesn't already exist. As a result, the return value
2762   // will never be nullptr.
2763   PendingAnimationTracker* GetOrCreatePendingAnimationTracker();
2764 
2765   /**
2766    * Prevents user initiated events from being dispatched to the document and
2767    * subdocuments.
2768    */
2769   void SuppressEventHandling(uint32_t aIncrease = 1);
2770 
2771   /**
2772    * Unsuppress event handling.
2773    * @param aFireEvents If true, delayed events (focus/blur) will be fired
2774    *                    asynchronously.
2775    */
2776   void UnsuppressEventHandlingAndFireEvents(bool aFireEvents);
2777 
EventHandlingSuppressed()2778   uint32_t EventHandlingSuppressed() const { return mEventsSuppressed; }
2779 
IsEventHandlingEnabled()2780   bool IsEventHandlingEnabled() const {
2781     return !EventHandlingSuppressed() && mScriptGlobalObject;
2782   }
2783 
WouldScheduleFrameRequestCallbacks()2784   bool WouldScheduleFrameRequestCallbacks() const {
2785     // If this function changes to depend on some other variable, make sure to
2786     // call UpdateFrameRequestCallbackSchedulingState() calls to the places
2787     // where that variable can change.
2788     return mPresShell && IsEventHandlingEnabled();
2789   }
2790 
DecreaseEventSuppression()2791   void DecreaseEventSuppression() {
2792     MOZ_ASSERT(mEventsSuppressed);
2793     --mEventsSuppressed;
2794     UpdateFrameRequestCallbackSchedulingState();
2795   }
2796 
2797   /**
2798    * Some clipboard commands are unconditionally enabled on some documents, so
2799    * as to always dispatch copy / paste events even though you'd normally not be
2800    * able to copy.
2801    */
2802   bool AreClipboardCommandsUnconditionallyEnabled() const;
2803 
2804   /**
2805    * Note a ChannelEventQueue which has been suspended on the document's behalf
2806    * to prevent XHRs from running content scripts while event handling is
2807    * suppressed. The document is responsible for resuming the queue after
2808    * event handling is unsuppressed.
2809    */
2810   void AddSuspendedChannelEventQueue(net::ChannelEventQueue* aQueue);
2811 
2812   /**
2813    * Returns true if a postMessage event should be suspended instead of running.
2814    * The document is responsible for running the event later, in the order they
2815    * were received.
2816    */
2817   bool SuspendPostMessageEvent(PostMessageEvent* aEvent);
2818 
2819   /**
2820    * Run any suspended postMessage events, or clear them.
2821    */
2822   void FireOrClearPostMessageEvents(bool aFireEvents);
2823 
SetHasDelayedRefreshEvent()2824   void SetHasDelayedRefreshEvent() { mHasDelayedRefreshEvent = true; }
2825 
2826   /**
2827    * Flag whether we're about to fire the window's load event for this document.
2828    */
SetLoadEventFiring(bool aFiring)2829   void SetLoadEventFiring(bool aFiring) { mLoadEventFiring = aFiring; }
2830 
2831   /**
2832    * Test whether we should be firing a load event for this document after a
2833    * document.close().  This is public and on Document, instead of being private
2834    * to Document, because we need to go through the normal docloader logic
2835    * for the readystate change to READYSTATE_COMPLETE with the normal timing and
2836    * semantics of firing the load event; we just don't want to fire the load
2837    * event if this tests true.  So we need the docloader to be able to access
2838    * this state.
2839    *
2840    * This method should only be called at the point when the load event is about
2841    * to be fired.  It resets the "skip" flag, so it is not idempotent.
2842    */
SkipLoadEventAfterClose()2843   bool SkipLoadEventAfterClose() {
2844     bool skip = mSkipLoadEventAfterClose;
2845     mSkipLoadEventAfterClose = false;
2846     return skip;
2847   }
2848 
2849   /**
2850    * Increment https://html.spec.whatwg.org/#ignore-destructive-writes-counter
2851    */
IncrementIgnoreDestructiveWritesCounter()2852   void IncrementIgnoreDestructiveWritesCounter() {
2853     ++mIgnoreDestructiveWritesCounter;
2854   }
2855 
2856   /**
2857    * Decrement https://html.spec.whatwg.org/#ignore-destructive-writes-counter
2858    */
DecrementIgnoreDestructiveWritesCounter()2859   void DecrementIgnoreDestructiveWritesCounter() {
2860     --mIgnoreDestructiveWritesCounter;
2861   }
2862 
IsDNSPrefetchAllowed()2863   bool IsDNSPrefetchAllowed() const { return mAllowDNSPrefetch; }
2864 
2865   /**
2866    * Returns true if this document is allowed to contain XUL element and
2867    * use non-builtin XBL bindings.
2868    */
AllowXULXBL()2869   bool AllowXULXBL() {
2870     return mAllowXULXBL == eTriTrue    ? true
2871            : mAllowXULXBL == eTriFalse ? false
2872                                        : InternalAllowXULXBL();
2873   }
2874 
2875   /**
2876    * Returns true if this document is allowed to load DTDs from UI resources
2877    * no matter what.
2878    */
SkipDTDSecurityChecks()2879   bool SkipDTDSecurityChecks() { return mSkipDTDSecurityChecks; }
2880 
ForceEnableXULXBL()2881   void ForceEnableXULXBL() { mAllowXULXBL = eTriTrue; }
2882 
ForceSkipDTDSecurityChecks()2883   void ForceSkipDTDSecurityChecks() { mSkipDTDSecurityChecks = true; }
2884 
2885   /**
2886    * Returns the template content owner document that owns the content of
2887    * HTMLTemplateElement.
2888    */
2889   Document* GetTemplateContentsOwner();
2890 
2891   /**
2892    * Returns true if this document is a static clone of a normal document.
2893    *
2894    * We create static clones for print preview and printing (possibly other
2895    * things in future).
2896    *
2897    * Note that static documents are also "loaded as data" (if this method
2898    * returns true, IsLoadedAsData() will also return true).
2899    */
IsStaticDocument()2900   bool IsStaticDocument() const { return mIsStaticDocument; }
2901 
2902   /**
2903    * Clones the document along with any subdocuments, stylesheet, etc.
2904    *
2905    * The resulting document and everything it contains (including any
2906    * sub-documents) are created purely via cloning.  The returned documents and
2907    * any sub-documents are "loaded as data" documents to preserve the state as
2908    * it was during the clone process (we don't want external resources to load
2909    * and replace the cloned resources).
2910    *
2911    * @param aCloneContainer The container for the clone document.
2912    * @param aContentViewer The viewer for the clone document. Must be the viewer
2913    *                       of aCloneContainer, but callers must have a reference
2914    *                       to it already and ensure it's not null.
2915    * @param aPrintSettings The print settings for this clone.
2916    * @param aOutHasInProcessPrintCallbacks Self-descriptive.
2917    */
2918   already_AddRefed<Document> CreateStaticClone(
2919       nsIDocShell* aCloneContainer, nsIContentViewer* aContentViewer,
2920       nsIPrintSettings* aPrintSettings, bool* aOutHasInProcessPrintCallbacks);
2921 
2922   /**
2923    * If this document is a static clone, this returns the original
2924    * document.
2925    */
GetOriginalDocument()2926   Document* GetOriginalDocument() const {
2927     MOZ_ASSERT(!mOriginalDocument || !mOriginalDocument->GetOriginalDocument());
2928     return mOriginalDocument;
2929   }
2930 
2931   /**
2932    * If this document is a static clone, let the original document know that
2933    * we're going away and then release our reference to it.
2934    */
2935   void UnlinkOriginalDocumentIfStatic();
2936 
2937   /**
2938    * These are called by the parser as it encounters <picture> tags, the end of
2939    * said tags, and possible picture <source srcset> sources respectively. These
2940    * are used to inform ResolvePreLoadImage() calls.  Unset attributes are
2941    * expected to be marked void.
2942    *
2943    * NOTE that the parser does not attempt to track the current picture nesting
2944    * level or whether the given <source> tag is within a picture -- it is only
2945    * guaranteed to order these calls properly with respect to
2946    * ResolvePreLoadImage.
2947    */
2948 
PreloadPictureOpened()2949   void PreloadPictureOpened() { mPreloadPictureDepth++; }
2950 
2951   void PreloadPictureClosed();
2952 
2953   void PreloadPictureImageSource(const nsAString& aSrcsetAttr,
2954                                  const nsAString& aSizesAttr,
2955                                  const nsAString& aTypeAttr,
2956                                  const nsAString& aMediaAttr);
2957 
2958   /**
2959    * Called by the parser to resolve an image for preloading. The parser will
2960    * call the PreloadPicture* functions to inform us of possible <picture>
2961    * nesting and possible sources, which are used to inform URL selection
2962    * responsive <picture> or <img srcset> images.  Unset attributes are expected
2963    * to be marked void.
2964    * If this image is for <picture> or <img srcset>, aIsImgSet will be set to
2965    * true, false otherwise.
2966    */
2967   already_AddRefed<nsIURI> ResolvePreloadImage(nsIURI* aBaseURI,
2968                                                const nsAString& aSrcAttr,
2969                                                const nsAString& aSrcsetAttr,
2970                                                const nsAString& aSizesAttr,
2971                                                bool* aIsImgSet);
2972   /**
2973    * Called by nsParser to preload images. Can be removed and code moved
2974    * to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
2975    * parser-module is linked with gklayout-module.  aCrossOriginAttr should
2976    * be a void string if the attr is not present.
2977    * aIsImgSet is the value got from calling ResolvePreloadImage, it is true
2978    * when this image is for loading <picture> or <img srcset> images.
2979    */
2980   void MaybePreLoadImage(nsIURI* uri, const nsAString& aCrossOriginAttr,
2981                          ReferrerPolicyEnum aReferrerPolicy, bool aIsImgSet,
2982                          bool aLinkPreload, const TimeStamp& aInitTimestamp);
2983   void PreLoadImage(nsIURI* uri, const nsAString& aCrossOriginAttr,
2984                     ReferrerPolicyEnum aReferrerPolicy, bool aIsImgSet,
2985                     bool aLinkPreload);
2986 
2987   /**
2988    * Called by images to forget an image preload when they start doing
2989    * the real load.
2990    */
2991   void ForgetImagePreload(nsIURI* aURI);
2992 
2993   /**
2994    * Called by the parser or the preload service to preload style sheets.
2995    * aCrossOriginAttr should be a void string if the attr is not present.
2996    */
2997   SheetPreloadStatus PreloadStyle(nsIURI* aURI, const Encoding* aEncoding,
2998                                   const nsAString& aCrossOriginAttr,
2999                                   ReferrerPolicyEnum aReferrerPolicy,
3000                                   const nsAString& aIntegrity,
3001                                   css::StylePreloadKind);
3002 
3003   /**
3004    * Called by the chrome registry to load style sheets.
3005    *
3006    * This always does a synchronous load, and parses as a normal document sheet.
3007    */
3008   RefPtr<StyleSheet> LoadChromeSheetSync(nsIURI* aURI);
3009 
3010   /**
3011    * Returns true if the locale used for the document specifies a direction of
3012    * right to left. For chrome documents, this comes from the chrome registry.
3013    * This is used to determine the current state for the :-moz-locale-dir
3014    * pseudoclass so once can know whether a document is expected to be rendered
3015    * left-to-right or right-to-left.
3016    */
3017   bool IsDocumentRightToLeft();
3018 
3019   /**
3020    * Called by Parser for link rel=preconnect
3021    */
3022   void MaybePreconnect(nsIURI* uri, CORSMode aCORSMode);
3023 
3024   /**
3025    * Set the document's pending state object (as serialized using structured
3026    * clone).
3027    */
3028   void SetStateObject(nsIStructuredCloneContainer* scContainer);
3029 
3030   /**
3031    * Set the document's pending state object to the same state object as
3032    * aDocument.
3033    */
SetStateObjectFrom(Document * aDocument)3034   void SetStateObjectFrom(Document* aDocument) {
3035     SetStateObject(aDocument->mStateObjectContainer);
3036   }
3037 
3038   enum class DocumentTheme { None, Neutral, Dark, Bright };
3039 
3040   /**
3041    * Returns DocumentTheme::None if there is no lightweight theme specified,
3042    * Dark for a dark theme, Bright for a light theme, and Neutral for any other
3043    * theme. This is used to determine the state of the pseudoclasses
3044    * :-moz-lwtheme and :-moz-lwtheme-*text.
3045    */
3046   DocumentTheme GetDocumentLWTheme() const;
ResetDocumentLWTheme()3047   void ResetDocumentLWTheme() {
3048     UpdateDocumentStates(NS_DOCUMENT_STATE_ALL_LWTHEME_BITS, true);
3049   }
3050 
3051   // Whether we're a media document or not.
3052   enum class MediaDocumentKind {
3053     NotMedia,
3054     Video,
3055     Image,
3056     Plugin,
3057   };
3058 
MediaDocumentKind()3059   virtual enum MediaDocumentKind MediaDocumentKind() const {
3060     return MediaDocumentKind::NotMedia;
3061   }
3062 
3063   /**
3064    * Returns the document state.
3065    * Document state bits have the form NS_DOCUMENT_STATE_* and are declared in
3066    * Document.h.
3067    */
GetDocumentState()3068   EventStates GetDocumentState() const { return mDocumentState; }
3069 
3070   nsISupports* GetCurrentContentSink();
3071 
3072   void SetAutoFocusElement(Element* aAutoFocusElement);
3073   void TriggerAutoFocus();
3074   void SetAutoFocusFired();
3075   bool IsAutoFocusFired();
3076 
3077   void SetScrollToRef(nsIURI* aDocumentURI);
3078   MOZ_CAN_RUN_SCRIPT void ScrollToRef();
ResetScrolledToRefAlready()3079   void ResetScrolledToRefAlready() { mScrolledToRefAlready = false; }
3080 
SetChangeScrollPosWhenScrollingToRef(bool aValue)3081   void SetChangeScrollPosWhenScrollingToRef(bool aValue) {
3082     mChangeScrollPosWhenScrollingToRef = aValue;
3083   }
3084 
3085   using DocumentOrShadowRoot::GetElementById;
3086   using DocumentOrShadowRoot::GetElementsByClassName;
3087   using DocumentOrShadowRoot::GetElementsByTagName;
3088   using DocumentOrShadowRoot::GetElementsByTagNameNS;
3089 
3090   DocumentTimeline* Timeline();
Timelines()3091   LinkedList<DocumentTimeline>& Timelines() { return mTimelines; }
3092 
3093   SVGSVGElement* GetSVGRootElement() const;
3094 
3095   nsresult ScheduleFrameRequestCallback(FrameRequestCallback& aCallback,
3096                                         int32_t* aHandle);
3097   void CancelFrameRequestCallback(int32_t aHandle);
3098 
3099   /**
3100    * Returns true if the handle refers to a callback that was canceled that
3101    * we did not find in our list of callbacks (e.g. because it is one of those
3102    * in the set of callbacks currently queued to be run).
3103    */
3104   bool IsCanceledFrameRequestCallback(int32_t aHandle) const;
3105 
3106   /**
3107    * Put this document's frame request callbacks into the provided
3108    * list, and forget about them.
3109    */
3110   void TakeFrameRequestCallbacks(nsTArray<FrameRequest>& aCallbacks);
3111 
3112   /**
3113    * @return true if this document's frame request callbacks should be
3114    * throttled. We throttle requestAnimationFrame for documents which aren't
3115    * visible (e.g. scrolled out of the viewport).
3116    */
3117   bool ShouldThrottleFrameRequests() const;
3118 
3119   // This returns true when the document tree is being teared down.
InUnlinkOrDeletion()3120   bool InUnlinkOrDeletion() { return mInUnlinkOrDeletion; }
3121 
3122   dom::ImageTracker* ImageTracker();
3123 
3124   // Adds an element to mResponsiveContent when the element is
3125   // added to the tree.
AddResponsiveContent(HTMLImageElement * aContent)3126   void AddResponsiveContent(HTMLImageElement* aContent) {
3127     MOZ_ASSERT(aContent);
3128     mResponsiveContent.Insert(aContent);
3129   }
3130 
3131   // Removes an element from mResponsiveContent when the element is
3132   // removed from the tree.
RemoveResponsiveContent(HTMLImageElement * aContent)3133   void RemoveResponsiveContent(HTMLImageElement* aContent) {
3134     MOZ_ASSERT(aContent);
3135     mResponsiveContent.Remove(aContent);
3136   }
3137 
3138   void ScheduleSVGUseElementShadowTreeUpdate(SVGUseElement&);
UnscheduleSVGUseElementShadowTreeUpdate(SVGUseElement & aElement)3139   void UnscheduleSVGUseElementShadowTreeUpdate(SVGUseElement& aElement) {
3140     mSVGUseElementsNeedingShadowTreeUpdate.Remove(&aElement);
3141   }
3142 
SVGUseElementNeedsShadowTreeUpdate(SVGUseElement & aElement)3143   bool SVGUseElementNeedsShadowTreeUpdate(SVGUseElement& aElement) const {
3144     return mSVGUseElementsNeedingShadowTreeUpdate.Contains(&aElement);
3145   }
3146 
3147   using ShadowRootSet = nsTHashSet<ShadowRoot*>;
3148 
AddComposedDocShadowRoot(ShadowRoot & aShadowRoot)3149   void AddComposedDocShadowRoot(ShadowRoot& aShadowRoot) {
3150     mComposedShadowRoots.Insert(&aShadowRoot);
3151   }
3152 
RemoveComposedDocShadowRoot(ShadowRoot & aShadowRoot)3153   void RemoveComposedDocShadowRoot(ShadowRoot& aShadowRoot) {
3154     mComposedShadowRoots.Remove(&aShadowRoot);
3155   }
3156 
3157   // If you're considering using this, you probably want to use
3158   // ShadowRoot::IsComposedDocParticipant instead. This is just for
3159   // sanity-checking.
IsComposedDocShadowRoot(ShadowRoot & aShadowRoot)3160   bool IsComposedDocShadowRoot(ShadowRoot& aShadowRoot) {
3161     return mComposedShadowRoots.Contains(&aShadowRoot);
3162   }
3163 
ComposedShadowRoots()3164   const ShadowRootSet& ComposedShadowRoots() const {
3165     return mComposedShadowRoots;
3166   }
3167 
3168   // WebIDL method for chrome code.
3169   void GetConnectedShadowRoots(nsTArray<RefPtr<ShadowRoot>>&) const;
3170 
3171   // Notifies any responsive content added by AddResponsiveContent upon media
3172   // features values changing.
3173   void NotifyMediaFeatureValuesChanged();
3174 
3175   nsresult GetStateObject(nsIVariant** aResult);
3176 
GetNavigationTiming()3177   nsDOMNavigationTiming* GetNavigationTiming() const { return mTiming; }
3178 
3179   void SetNavigationTiming(nsDOMNavigationTiming* aTiming);
3180 
3181   nsContentList* ImageMapList();
3182 
3183   // Add aLink to the set of links that need their status resolved.
3184   void RegisterPendingLinkUpdate(Link* aLink);
3185 
3186   // Update state on links in mLinksToUpdate.
3187   void FlushPendingLinkUpdates();
3188 
3189   bool HasWarnedAbout(DeprecatedOperations aOperation) const;
3190   void WarnOnceAbout(
3191       DeprecatedOperations aOperation, bool asError = false,
3192       const nsTArray<nsString>& aParams = nsTArray<nsString>()) const;
3193 
3194 #define DOCUMENT_WARNING(_op) e##_op,
3195   enum DocumentWarnings {
3196 #include "nsDocumentWarningList.h"
3197     eDocumentWarningCount
3198   };
3199 #undef DOCUMENT_WARNING
3200   bool HasWarnedAbout(DocumentWarnings aWarning) const;
3201   void WarnOnceAbout(
3202       DocumentWarnings aWarning, bool asError = false,
3203       const nsTArray<nsString>& aParams = nsTArray<nsString>()) const;
3204 
3205   // This method may fire a DOM event; if it does so it will happen
3206   // synchronously.
3207   //
3208   // Whether the event fires is controlled by the argument.
3209   enum class DispatchVisibilityChange { No, Yes };
3210   void UpdateVisibilityState(
3211       DispatchVisibilityChange = DispatchVisibilityChange::Yes);
3212 
3213   // Posts an event to call UpdateVisibilityState.
3214   void PostVisibilityUpdateEvent();
3215 
IsSyntheticDocument()3216   bool IsSyntheticDocument() const { return mIsSyntheticDocument; }
3217 
3218   // Adds the size of a given node, which must not be a document node, to the
3219   // window sizes passed-in.
3220   static void AddSizeOfNodeTree(nsINode&, nsWindowSizes&);
3221 
3222   // Note: Document is a sub-class of nsINode, which has a
3223   // SizeOfExcludingThis function.  However, because Document objects can
3224   // only appear at the top of the DOM tree, we have a specialized measurement
3225   // function which returns multiple sizes.
3226   virtual void DocAddSizeOfExcludingThis(nsWindowSizes& aWindowSizes) const;
3227   // DocAddSizeOfIncludingThis doesn't need to be overridden by sub-classes
3228   // because Document inherits from nsINode;  see the comment above the
3229   // declaration of nsINode::SizeOfIncludingThis.
3230   virtual void DocAddSizeOfIncludingThis(nsWindowSizes& aWindowSizes) const;
3231 
3232   void ConstructUbiNode(void* storage) override;
3233 
MayHaveDOMMutationObservers()3234   bool MayHaveDOMMutationObservers() { return mMayHaveDOMMutationObservers; }
3235 
SetMayHaveDOMMutationObservers()3236   void SetMayHaveDOMMutationObservers() { mMayHaveDOMMutationObservers = true; }
3237 
MayHaveAnimationObservers()3238   bool MayHaveAnimationObservers() { return mMayHaveAnimationObservers; }
3239 
SetMayHaveAnimationObservers()3240   void SetMayHaveAnimationObservers() { mMayHaveAnimationObservers = true; }
3241 
IsInSyncOperation()3242   bool IsInSyncOperation() { return mInSyncOperationCount != 0; }
3243 
3244   void SetIsInSyncOperation(bool aSync);
3245 
CreatingStaticClone()3246   bool CreatingStaticClone() const { return mCreatingStaticClone; }
3247 
3248   /**
3249    * Creates a new element in the HTML namespace with a local name given by
3250    * aTag.
3251    */
3252   already_AddRefed<Element> CreateHTMLElement(nsAtom* aTag);
3253 
3254   // WebIDL API
GetParentObject()3255   nsIGlobalObject* GetParentObject() const { return GetScopeObject(); }
3256   static already_AddRefed<Document> Constructor(const GlobalObject& aGlobal,
3257                                                 ErrorResult& rv);
3258   DOMImplementation* GetImplementation(ErrorResult& rv);
3259   [[nodiscard]] nsresult GetURL(nsString& retval) const;
3260   [[nodiscard]] nsresult GetDocumentURI(nsString& retval) const;
3261   // Return the URI for the document.
3262   // The returned value may differ if the document is loaded via XHR, and
3263   // when accessed from chrome privileged script and
3264   // from content privileged script for compatibility.
3265   void GetDocumentURIFromJS(nsString& aDocumentURI, CallerType aCallerType,
3266                             ErrorResult& aRv) const;
3267   void GetCompatMode(nsString& retval) const;
3268   void GetCharacterSet(nsAString& retval) const;
3269   // Skip GetContentType, because our NS_IMETHOD version above works fine here.
3270   // GetDoctype defined above
GetDocumentElement()3271   Element* GetDocumentElement() const { return GetRootElement(); }
3272 
3273   WindowContext* GetTopLevelWindowContext() const;
3274 
3275   // If the top-level ancestor content document for this document is in the same
3276   // process, returns it. Otherwise, returns null. This function is not
3277   // Fission-compatible, and should not be used in new code.
3278   Document* GetTopLevelContentDocumentIfSameProcess();
3279   const Document* GetTopLevelContentDocumentIfSameProcess() const;
3280 
3281   // Returns the associated app window if this is a top-level chrome document,
3282   // null otherwise.
3283   already_AddRefed<nsIAppWindow> GetAppWindowIfToplevelChrome() const;
3284 
3285   already_AddRefed<Element> CreateElement(
3286       const nsAString& aTagName, const ElementCreationOptionsOrString& aOptions,
3287       ErrorResult& rv);
3288   already_AddRefed<Element> CreateElementNS(
3289       const nsAString& aNamespaceURI, const nsAString& aQualifiedName,
3290       const ElementCreationOptionsOrString& aOptions, ErrorResult& rv);
3291   already_AddRefed<Element> CreateXULElement(
3292       const nsAString& aTagName, const ElementCreationOptionsOrString& aOptions,
3293       ErrorResult& aRv);
3294   already_AddRefed<DocumentFragment> CreateDocumentFragment() const;
3295   already_AddRefed<nsTextNode> CreateTextNode(const nsAString& aData) const;
3296   already_AddRefed<nsTextNode> CreateEmptyTextNode() const;
3297   already_AddRefed<Comment> CreateComment(const nsAString& aData) const;
3298   already_AddRefed<ProcessingInstruction> CreateProcessingInstruction(
3299       const nsAString& target, const nsAString& data, ErrorResult& rv) const;
3300   already_AddRefed<nsINode> ImportNode(nsINode& aNode, bool aDeep,
3301                                        ErrorResult& rv) const;
3302   // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
3303   MOZ_CAN_RUN_SCRIPT_BOUNDARY nsINode* AdoptNode(nsINode& aNode,
3304                                                  ErrorResult& rv);
3305   already_AddRefed<Event> CreateEvent(const nsAString& aEventType,
3306                                       CallerType aCallerType,
3307                                       ErrorResult& rv) const;
3308   already_AddRefed<nsRange> CreateRange(ErrorResult& rv);
3309   already_AddRefed<NodeIterator> CreateNodeIterator(nsINode& aRoot,
3310                                                     uint32_t aWhatToShow,
3311                                                     NodeFilter* aFilter,
3312                                                     ErrorResult& rv) const;
3313   already_AddRefed<TreeWalker> CreateTreeWalker(nsINode& aRoot,
3314                                                 uint32_t aWhatToShow,
3315                                                 NodeFilter* aFilter,
3316                                                 ErrorResult& rv) const;
3317   // Deprecated WebIDL bits
3318   already_AddRefed<CDATASection> CreateCDATASection(const nsAString& aData,
3319                                                     ErrorResult& rv);
3320   already_AddRefed<Attr> CreateAttribute(const nsAString& aName,
3321                                          ErrorResult& rv);
3322   already_AddRefed<Attr> CreateAttributeNS(const nsAString& aNamespaceURI,
3323                                            const nsAString& aQualifiedName,
3324                                            ErrorResult& rv);
3325   void GetInputEncoding(nsAString& aInputEncoding) const;
3326   already_AddRefed<Location> GetLocation() const;
3327   void GetDomain(nsAString& aDomain);
3328   void SetDomain(const nsAString& aDomain, mozilla::ErrorResult& rv);
3329   void GetCookie(nsAString& aCookie, mozilla::ErrorResult& rv);
3330   void SetCookie(const nsAString& aCookie, mozilla::ErrorResult& rv);
3331   void GetReferrer(nsAString& aReferrer) const;
3332   void GetLastModified(nsAString& aLastModified) const;
3333   void GetReadyState(nsAString& aReadyState) const;
3334 
3335   void GetTitle(nsAString& aTitle);
3336   void SetTitle(const nsAString& aTitle, ErrorResult& rv);
3337   void GetDir(nsAString& aDirection) const;
3338   void SetDir(const nsAString& aDirection);
3339   nsIHTMLCollection* Images();
3340   nsIHTMLCollection* Embeds();
Plugins()3341   nsIHTMLCollection* Plugins() { return Embeds(); }
3342   nsIHTMLCollection* Links();
3343   nsIHTMLCollection* Forms();
3344   nsIHTMLCollection* Scripts();
GetElementsByName(const nsAString & aName)3345   already_AddRefed<nsContentList> GetElementsByName(const nsAString& aName) {
3346     return GetFuncStringContentList<nsCachableElementsByNameNodeList>(
3347         this, MatchNameAttribute, nullptr, UseExistingNameString, aName);
3348   }
3349   Document* Open(const mozilla::dom::Optional<nsAString>& /* unused */,
3350                  const mozilla::dom::Optional<nsAString>& /* unused */,
3351                  mozilla::ErrorResult& aError);
3352   mozilla::dom::Nullable<mozilla::dom::WindowProxyHolder> Open(
3353       const nsAString& aURL, const nsAString& aName, const nsAString& aFeatures,
3354       mozilla::ErrorResult& rv);
3355   void Close(mozilla::ErrorResult& rv);
3356   void Write(const mozilla::dom::Sequence<nsString>& aText,
3357              mozilla::ErrorResult& rv);
3358   void Writeln(const mozilla::dom::Sequence<nsString>& aText,
3359                mozilla::ErrorResult& rv);
3360   Nullable<WindowProxyHolder> GetDefaultView() const;
3361   Element* GetActiveElement();
3362   nsIContent* GetUnretargetedFocusedContent() const;
3363   bool HasFocus(ErrorResult& rv) const;
3364   void GetDesignMode(nsAString& aDesignMode);
3365   void SetDesignMode(const nsAString& aDesignMode,
3366                      nsIPrincipal& aSubjectPrincipal, mozilla::ErrorResult& rv);
3367   void SetDesignMode(const nsAString& aDesignMode,
3368                      const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
3369                      mozilla::ErrorResult& rv);
3370   MOZ_CAN_RUN_SCRIPT
3371   bool ExecCommand(const nsAString& aHTMLCommandName, bool aShowUI,
3372                    const nsAString& aValue, nsIPrincipal& aSubjectPrincipal,
3373                    mozilla::ErrorResult& aRv);
3374   MOZ_CAN_RUN_SCRIPT bool QueryCommandEnabled(const nsAString& aHTMLCommandName,
3375                                               nsIPrincipal& aSubjectPrincipal,
3376                                               mozilla::ErrorResult& aRv);
3377   MOZ_CAN_RUN_SCRIPT bool QueryCommandIndeterm(
3378       const nsAString& aHTMLCommandName, mozilla::ErrorResult& aRv);
3379   MOZ_CAN_RUN_SCRIPT bool QueryCommandState(const nsAString& aHTMLCommandName,
3380                                             mozilla::ErrorResult& aRv);
3381   MOZ_CAN_RUN_SCRIPT bool QueryCommandSupported(
3382       const nsAString& aHTMLCommandName, mozilla::dom::CallerType aCallerType,
3383       mozilla::ErrorResult& aRv);
3384   MOZ_CAN_RUN_SCRIPT void QueryCommandValue(const nsAString& aHTMLCommandName,
3385                                             nsAString& aValue,
3386                                             mozilla::ErrorResult& aRv);
3387   nsIHTMLCollection* Applets();
3388   nsIHTMLCollection* Anchors();
3389   TimeStamp LastFocusTime() const;
3390   void SetLastFocusTime(const TimeStamp& aFocusTime);
3391   // Event handlers are all on nsINode already
MozSyntheticDocument()3392   bool MozSyntheticDocument() const { return IsSyntheticDocument(); }
3393   Element* GetCurrentScript();
3394   void ReleaseCapture() const;
3395   void MozSetImageElement(const nsAString& aImageElementId, Element* aElement);
3396   nsIURI* GetDocumentURIObject() const;
3397   // Not const because all the fullscreen goop is not const
3398   const char* GetFullscreenError(CallerType);
FullscreenEnabled(CallerType aCallerType)3399   bool FullscreenEnabled(CallerType aCallerType) {
3400     return !GetFullscreenError(aCallerType);
3401   }
3402 
3403   void GetWireframeWithoutFlushing(bool aIncludeNodes, Nullable<Wireframe>&);
3404 
3405   MOZ_CAN_RUN_SCRIPT void GetWireframe(bool aIncludeNodes,
3406                                        Nullable<Wireframe>&);
3407 
3408   Element* GetTopLayerTop();
3409   // Return the fullscreen element in the top layer
3410   Element* GetUnretargetedFullScreenElement() const;
Fullscreen()3411   bool Fullscreen() const { return !!GetUnretargetedFullScreenElement(); }
3412   already_AddRefed<Promise> ExitFullscreen(ErrorResult&);
ExitPointerLock()3413   void ExitPointerLock() { PointerLockManager::Unlock(this); }
3414   void GetFgColor(nsAString& aFgColor);
3415   void SetFgColor(const nsAString& aFgColor);
3416   void GetLinkColor(nsAString& aLinkColor);
3417   void SetLinkColor(const nsAString& aLinkColor);
3418   void GetVlinkColor(nsAString& aAvlinkColor);
3419   void SetVlinkColor(const nsAString& aVlinkColor);
3420   void GetAlinkColor(nsAString& aAlinkColor);
3421   void SetAlinkColor(const nsAString& aAlinkColor);
3422   void GetBgColor(nsAString& aBgColor);
3423   void SetBgColor(const nsAString& aBgColor);
Clear()3424   void Clear() const {
3425     // Deprecated
3426   }
3427   void CaptureEvents();
3428   void ReleaseEvents();
3429 
3430   mozilla::dom::HTMLAllCollection* All();
3431 
3432   static bool DocumentSupportsL10n(JSContext* aCx, JSObject* aObject);
3433   static bool IsWebAnimationsEnabled(JSContext* aCx, JSObject* aObject);
3434   static bool IsWebAnimationsEnabled(CallerType aCallerType);
3435   static bool IsWebAnimationsGetAnimationsEnabled(JSContext* aCx,
3436                                                   JSObject* aObject);
3437   static bool AreWebAnimationsImplicitKeyframesEnabled(JSContext* aCx,
3438                                                        JSObject* aObject);
3439   static bool AreWebAnimationsTimelinesEnabled(JSContext* aCx,
3440                                                JSObject* aObject);
3441   // Checks that the caller is either chrome or some addon.
3442   static bool IsCallerChromeOrAddon(JSContext* aCx, JSObject* aObject);
3443 
Hidden()3444   bool Hidden() const { return mVisibilityState != VisibilityState::Visible; }
VisibilityState()3445   dom::VisibilityState VisibilityState() const { return mVisibilityState; }
3446 
3447  private:
3448   int32_t mPictureInPictureChildElementCount = 0;
3449 
3450  public:
3451   void EnableChildElementInPictureInPictureMode();
3452   void DisableChildElementInPictureInPictureMode();
3453 
3454   // True if any child element is being used in picture in picture mode.
3455   bool HasPictureInPictureChildElement() const;
3456 
3457   void GetSelectedStyleSheetSet(nsAString& aSheetSet);
3458   void SetSelectedStyleSheetSet(const nsAString& aSheetSet);
GetLastStyleSheetSet(nsAString & aSheetSet)3459   void GetLastStyleSheetSet(nsAString& aSheetSet) {
3460     aSheetSet = mLastStyleSheetSet;
3461   }
GetCurrentStyleSheetSet()3462   const nsString& GetCurrentStyleSheetSet() const {
3463     return mLastStyleSheetSet.IsEmpty() ? mPreferredStyleSheetSet
3464                                         : mLastStyleSheetSet;
3465   }
3466   void SetPreferredStyleSheetSet(const nsAString&);
GetPreferredStyleSheetSet(nsAString & aSheetSet)3467   void GetPreferredStyleSheetSet(nsAString& aSheetSet) {
3468     aSheetSet = mPreferredStyleSheetSet;
3469   }
3470   DOMStringList* StyleSheetSets();
3471   void EnableStyleSheetsForSet(const nsAString& aSheetSet);
3472 
3473   /**
3474    * Retrieve the location of the caret position (DOM node and character
3475    * offset within that node), given a point.
3476    *
3477    * @param aX Horizontal point at which to determine the caret position, in
3478    *           page coordinates.
3479    * @param aY Vertical point at which to determine the caret position, in
3480    *           page coordinates.
3481    */
3482   already_AddRefed<nsDOMCaretPosition> CaretPositionFromPoint(float aX,
3483                                                               float aY);
3484 
3485   Element* GetScrollingElement();
3486   // A way to check whether a given element is what would get returned from
3487   // GetScrollingElement.  It can be faster than comparing to the return value
3488   // of GetScrollingElement() due to being able to avoid flushes in various
3489   // cases.  This method assumes that null is NOT passed.
3490   bool IsScrollingElement(Element* aElement);
3491 
3492   // QuerySelector and QuerySelectorAll already defined on nsINode
3493 
3494   XPathExpression* CreateExpression(const nsAString& aExpression,
3495                                     XPathNSResolver* aResolver,
3496                                     ErrorResult& rv);
3497   nsINode* CreateNSResolver(nsINode& aNodeResolver);
3498   already_AddRefed<XPathResult> Evaluate(
3499       JSContext* aCx, const nsAString& aExpression, nsINode& aContextNode,
3500       XPathNSResolver* aResolver, uint16_t aType, JS::Handle<JSObject*> aResult,
3501       ErrorResult& rv);
3502   // Touch event handlers already on nsINode
3503   already_AddRefed<Touch> CreateTouch(nsGlobalWindowInner* aView,
3504                                       EventTarget* aTarget, int32_t aIdentifier,
3505                                       int32_t aPageX, int32_t aPageY,
3506                                       int32_t aScreenX, int32_t aScreenY,
3507                                       int32_t aClientX, int32_t aClientY,
3508                                       int32_t aRadiusX, int32_t aRadiusY,
3509                                       float aRotationAngle, float aForce);
3510   already_AddRefed<TouchList> CreateTouchList();
3511   already_AddRefed<TouchList> CreateTouchList(
3512       Touch& aTouch, const Sequence<OwningNonNull<Touch>>& aTouches);
3513   already_AddRefed<TouchList> CreateTouchList(
3514       const Sequence<OwningNonNull<Touch>>& aTouches);
3515 
SetStyleSheetChangeEventsEnabled(bool aValue)3516   void SetStyleSheetChangeEventsEnabled(bool aValue) {
3517     mStyleSheetChangeEventsEnabled = aValue;
3518   }
3519 
StyleSheetChangeEventsEnabled()3520   bool StyleSheetChangeEventsEnabled() const {
3521     return mStyleSheetChangeEventsEnabled;
3522   }
3523 
SetShadowRootAttachedEventEnabled(bool aValue)3524   void SetShadowRootAttachedEventEnabled(bool aValue) {
3525     mShadowRootAttachedEventEnabled = aValue;
3526   }
ShadowRootAttachedEventEnabled()3527   bool ShadowRootAttachedEventEnabled() const {
3528     return mShadowRootAttachedEventEnabled;
3529   }
3530 
3531   already_AddRefed<Promise> BlockParsing(Promise& aPromise,
3532                                          const BlockParsingOptions& aOptions,
3533                                          ErrorResult& aRv);
3534 
3535   already_AddRefed<nsIURI> GetMozDocumentURIIfNotForErrorPages();
3536 
3537   Promise* GetDocumentReadyForIdle(ErrorResult& aRv);
3538 
BlockUnblockOnloadForPDFJS(bool aBlock)3539   void BlockUnblockOnloadForPDFJS(bool aBlock) {
3540     if (aBlock) {
3541       BlockOnload();
3542     } else {
3543       UnblockOnload(/* aFireSync = */ false);
3544     }
3545   }
3546 
3547   nsIDOMXULCommandDispatcher* GetCommandDispatcher();
HasXULBroadcastManager()3548   bool HasXULBroadcastManager() const { return mXULBroadcastManager; };
3549   void InitializeXULBroadcastManager();
GetXULBroadcastManager()3550   XULBroadcastManager* GetXULBroadcastManager() const {
3551     return mXULBroadcastManager;
3552   }
3553   nsINode* GetPopupRangeParent(ErrorResult& aRv);
3554   int32_t GetPopupRangeOffset(ErrorResult& aRv);
3555 
DevToolsWatchingDOMMutations()3556   bool DevToolsWatchingDOMMutations() const {
3557     return mDevToolsWatchingDOMMutations;
3558   }
3559   void SetDevToolsWatchingDOMMutations(bool aValue);
3560 
3561   void MaybeWarnAboutZoom();
3562 
3563   // ParentNode
3564   nsIHTMLCollection* Children();
3565   uint32_t ChildElementCount();
3566 
3567   /**
3568    * Asserts IsHTMLOrXHTML, and can't return null.
3569    * Defined inline in nsHTMLDocument.h
3570    */
3571   inline nsHTMLDocument* AsHTMLDocument();
3572   inline const nsHTMLDocument* AsHTMLDocument() const;
3573 
3574   /**
3575    * Asserts IsSVGDocument, and can't return null.
3576    * Defined inline in SVGDocument.h
3577    */
3578   inline SVGDocument* AsSVGDocument();
3579   inline const SVGDocument* AsSVGDocument() const;
3580 
3581   /*
3582    * Given a node, get a weak reference to it and append that reference to
3583    * mBlockedNodesByClassifier. Can be used later on to look up a node in it.
3584    * (e.g., by the UI)
3585    */
AddBlockedNodeByClassifier(nsINode * node)3586   void AddBlockedNodeByClassifier(nsINode* node) {
3587     if (!node) {
3588       return;
3589     }
3590 
3591     nsWeakPtr weakNode = do_GetWeakReference(node);
3592 
3593     if (weakNode) {
3594       mBlockedNodesByClassifier.AppendElement(weakNode);
3595     }
3596   }
3597 
3598   gfxUserFontSet* GetUserFontSet();
3599   void FlushUserFontSet();
3600   void MarkUserFontSetDirty();
GetFonts()3601   FontFaceSet* GetFonts() { return mFontFaceSet; }
3602 
3603   // FontFaceSource
3604   FontFaceSet* Fonts();
3605 
DidFireDOMContentLoaded()3606   bool DidFireDOMContentLoaded() const { return mDidFireDOMContentLoaded; }
3607 
3608   bool IsSynthesized();
3609 
3610   // Records whether we will track use counters for this document, and if so,
3611   // which top-level document that page counters will be accumulated to.
3612   //
3613   // Informs the parent process that page use counters will be sent once the
3614   // document goes away.
3615   void InitUseCounters();
3616 
3617   // Reports document use counters via telemetry.  This method only has an
3618   // effect once per document, and so is called during document destruction.
3619   void ReportDocumentUseCounters();
3620 
3621   // Report how lazyload performs for this document.
3622   void ReportDocumentLazyLoadCounters();
3623 
3624   // Sends page use counters to the parent process to accumulate against the
3625   // top-level document.  Must be called while we still have access to our
3626   // WindowContext.  This method has an effect each time it is called, and we
3627   // call it just before the document loses its window.
3628   void SendPageUseCounters();
3629 
SetUseCounter(UseCounter aUseCounter)3630   void SetUseCounter(UseCounter aUseCounter) {
3631     mUseCounters[aUseCounter] = true;
3632   }
3633 
GetStyleUseCounters()3634   const StyleUseCounters* GetStyleUseCounters() {
3635     return mStyleUseCounters.get();
3636   }
3637 
3638   // Propagate our use counters explicitly into the specified referencing
3639   // document.
3640   //
3641   // This is used for SVG image documents, which cannot be enumerated in the
3642   // referencing document's ReportUseCounters() like external resource documents
3643   // can.
3644   void PropagateImageUseCounters(Document* aReferencingDocument);
3645 
3646   // Called to track whether this document has had any interaction.
3647   // This is used to track whether we should permit "beforeunload".
3648   void SetUserHasInteracted();
UserHasInteracted()3649   bool UserHasInteracted() { return mUserHasInteracted; }
3650   void ResetUserInteractionTimer();
3651 
3652   // This method would return current autoplay policy, it would be "allowed"
3653   // , "allowed-muted" or "disallowed".
3654   DocumentAutoplayPolicy AutoplayPolicy() const;
3655 
3656   // This should be called when this document receives events which are likely
3657   // to be user interaction with the document, rather than the byproduct of
3658   // interaction with the browser (i.e. a keypress to scroll the view port,
3659   // keyboard shortcuts, etc). This is used to decide whether we should
3660   // permit autoplay audible media. This also gesture activates all other
3661   // content documents in this tab.
3662   void NotifyUserGestureActivation();
3663 
3664   // This function is used for mochitest only.
3665   void ClearUserGestureActivation();
3666 
3667   // Return true if NotifyUserGestureActivation() has been called on any
3668   // document in the document tree.
3669   bool HasBeenUserGestureActivated();
3670 
3671   // Return true if there is transient user gesture activation and it hasn't yet
3672   // timed out.
3673   bool HasValidTransientUserGestureActivation() const;
3674 
3675   // Return true.
3676   bool ConsumeTransientUserGestureActivation();
3677 
3678   BrowsingContext* GetBrowsingContext() const;
3679 
3680   // This document is a WebExtension page, it might be a background page, a
3681   // popup, a visible tab, a visible iframe ...e.t.c.
3682   bool IsExtensionPage() const;
3683 
3684   bool HasScriptsBlockedBySandbox();
3685 
3686   void ReportHasScrollLinkedEffect();
HasScrollLinkedEffect()3687   bool HasScrollLinkedEffect() const { return mHasScrollLinkedEffect; }
3688 
3689 #ifdef DEBUG
3690   void AssertDocGroupMatchesKey() const;
3691 #endif
3692 
GetDocGroup()3693   DocGroup* GetDocGroup() const {
3694 #ifdef DEBUG
3695     AssertDocGroupMatchesKey();
3696 #endif
3697     return mDocGroup;
3698   }
3699 
3700   DocGroup* GetDocGroupOrCreate();
3701 
3702   /**
3703    * If we're a sub-document, the parent document's layout can affect our style
3704    * and layout (due to the viewport size, viewport units, media queries...).
3705    *
3706    * This function returns true if our parent document and our child document
3707    * can observe each other. If they cannot, then we don't need to synchronously
3708    * update the parent document layout every time the child document may need
3709    * up-to-date layout information.
3710    */
StyleOrLayoutObservablyDependsOnParentDocumentLayout()3711   bool StyleOrLayoutObservablyDependsOnParentDocumentLayout() const {
3712     return GetInProcessParentDocument() &&
3713            GetDocGroup() == GetInProcessParentDocument()->GetDocGroup();
3714   }
3715 
AddIntersectionObserver(DOMIntersectionObserver * aObserver)3716   void AddIntersectionObserver(DOMIntersectionObserver* aObserver) {
3717     MOZ_ASSERT(!mIntersectionObservers.Contains(aObserver),
3718                "Intersection observer already in the list");
3719     mIntersectionObservers.Insert(aObserver);
3720   }
3721 
RemoveIntersectionObserver(DOMIntersectionObserver * aObserver)3722   void RemoveIntersectionObserver(DOMIntersectionObserver* aObserver) {
3723     mIntersectionObservers.Remove(aObserver);
3724   }
3725 
HasIntersectionObservers()3726   bool HasIntersectionObservers() const {
3727     return !mIntersectionObservers.IsEmpty();
3728   }
3729 
3730   void UpdateIntersectionObservations(TimeStamp aNowTime);
3731   void ScheduleIntersectionObserverNotification();
3732   MOZ_CAN_RUN_SCRIPT void NotifyIntersectionObservers();
3733 
GetLazyLoadImageObserver()3734   DOMIntersectionObserver* GetLazyLoadImageObserver() {
3735     return mLazyLoadImageObserver;
3736   }
GetLazyLoadImageObserverViewport()3737   DOMIntersectionObserver* GetLazyLoadImageObserverViewport() {
3738     return mLazyLoadImageObserverViewport;
3739   }
3740   DOMIntersectionObserver& EnsureLazyLoadImageObserver();
3741   DOMIntersectionObserver& EnsureLazyLoadImageObserverViewport();
3742   void IncLazyLoadImageCount();
DecLazyLoadImageCount()3743   void DecLazyLoadImageCount() {
3744     MOZ_DIAGNOSTIC_ASSERT(mLazyLoadImageCount > 0);
3745     --mLazyLoadImageCount;
3746   }
IncLazyLoadImageStarted()3747   void IncLazyLoadImageStarted() { ++mLazyLoadImageStarted; }
3748   void IncLazyLoadImageReachViewport(bool aLoading);
3749 
3750   // Dispatch a runnable related to the document.
3751   nsresult Dispatch(TaskCategory aCategory,
3752                     already_AddRefed<nsIRunnable>&& aRunnable) final;
3753 
3754   virtual nsISerialEventTarget* EventTargetFor(
3755       TaskCategory aCategory) const override;
3756 
3757   virtual AbstractThread* AbstractMainThreadFor(
3758       TaskCategory aCategory) override;
3759 
3760   // The URLs passed to this function should match what
3761   // JS::DescribeScriptedCaller() returns, since this API is used to
3762   // determine whether some code is being called from a tracking script.
3763   void NoteScriptTrackingStatus(const nsACString& aURL, bool isTracking);
3764   // The JSContext passed to this method represents the context that we want to
3765   // determine if it belongs to a tracker.
3766   bool IsScriptTracking(JSContext* aCx) const;
3767 
3768   // For more information on Flash classification, see
3769   // toolkit/components/url-classifier/flash-block-lists.rst
3770   FlashClassification DocumentFlashClassification();
3771 
3772   // ResizeObserver usage.
3773   void AddResizeObserver(ResizeObserver&);
3774   void RemoveResizeObserver(ResizeObserver&);
3775   void ScheduleResizeObserversNotification() const;
3776 
3777   // Getter for PermissionDelegateHandler. Performs lazy initialization.
3778   PermissionDelegateHandler* GetPermissionDelegateHandler();
3779 
3780   // Notify the document that a fetch or a XHR request has completed
3781   // succesfully in this document. This is used by the password manager to infer
3782   // whether a form is submitted.
3783   void NotifyFetchOrXHRSuccess();
3784 
3785   // Set whether NotifyFetchOrXHRSuccess should dispatch an event.
3786   void SetNotifyFetchSuccess(bool aShouldNotify);
3787 
3788   // When this is set, removing a form or a password field from DOM
3789   // sends a Chrome-only event. This is now only used by the password manager.
3790   void SetNotifyFormOrPasswordRemoved(bool aShouldNotify);
3791 
3792   // This function is used by HTMLFormElement and HTMLInputElement to determin
3793   // whether to send an event when it is removed from DOM.
ShouldNotifyFormOrPasswordRemoved()3794   bool ShouldNotifyFormOrPasswordRemoved() const {
3795     return mShouldNotifyFormOrPasswordRemoved;
3796   }
3797 
3798   /**
3799    * Localization
3800    *
3801    * For more information on DocumentL10n see
3802    * intl/l10n/docs/fluent_tutorial.rst
3803    */
3804 
3805  public:
3806   /**
3807    * This is a public method exposed on Document WebIDL
3808    * to chrome only documents.
3809    */
3810   DocumentL10n* GetL10n();
3811 
3812   /**
3813    * This method should be called when the container
3814    * of l10n resources parsing is completed.
3815    *
3816    * It triggers initial async fetch of the resources
3817    * as early as possible.
3818    *
3819    * In HTML case this is </head>.
3820    * In XUL case this is </linkset>.
3821    */
3822   void OnL10nResourceContainerParsed();
3823 
3824   /**
3825    * This method should be called when a link element
3826    * with rel="localization" is being added to the
3827    * l10n resource container element.
3828    */
3829   void LocalizationLinkAdded(Element* aLinkElement);
3830 
3831   /**
3832    * This method should be called when a link element
3833    * with rel="localization" is being removed.
3834    */
3835   void LocalizationLinkRemoved(Element* aLinkElement);
3836 
3837   /**
3838    * This method should be called as soon as the
3839    * parsing of the document is completed.
3840    *
3841    * In HTML/XHTML this happens when we finish parsing
3842    * the document element.
3843    * In XUL it happens at `DoneWalking`, during
3844    * `MozBeforeInitialXULLayout`.
3845    */
3846   void OnParsingCompleted();
3847 
3848   /**
3849    * This method is called when the initial translation
3850    * of the document is completed.
3851    *
3852    * It unblocks the load event if translation was blocking it.
3853    *
3854    * If the `aL10nCached` is set to `true`, and the document has
3855    * a prototype, it will set the `isL10nCached` flag on it.
3856    */
3857   void InitialTranslationCompleted(bool aL10nCached);
3858 
3859   /**
3860    * Returns whether the document allows localization.
3861    */
3862   bool AllowsL10n() const;
3863 
3864  protected:
3865   RefPtr<DocumentL10n> mDocumentL10n;
3866 
3867   /**
3868    * Return true when you want a document without explicitly specified viewport
3869    * dimensions/scale to be treated as if "width=device-width" had in fact been
3870    * specified.
3871    */
3872   virtual bool UseWidthDeviceWidthFallbackViewport() const;
3873 
3874  private:
3875   bool IsErrorPage() const;
3876 
3877   // Takes the bits from mStyleUseCounters if appropriate, and sets them in
3878   // mUseCounters.
3879   void SetCssUseCounterBits();
3880 
3881   void ParseWidthAndHeightInMetaViewport(const nsAString& aWidthString,
3882                                          const nsAString& aHeightString,
3883                                          bool aIsAutoScale);
3884 
3885   // Parse scale values in viewport meta tag for a given |aHeaderField| which
3886   // represents the scale property and returns the scale value if it's valid.
3887   Maybe<LayoutDeviceToScreenScale> ParseScaleInHeader(nsAtom* aHeaderField);
3888 
3889   // Parse scale values in |aViewportMetaData| and set the values in
3890   // mScaleMinFloat, mScaleMaxFloat and mScaleFloat respectively.
3891   void ParseScalesInViewportMetaData(const ViewportMetaData& aViewportMetaData);
3892 
3893   // Get parent FeaturePolicy from container. The parent FeaturePolicy is
3894   // stored in parent iframe or container's browsingContext (cross process)
3895   already_AddRefed<mozilla::dom::FeaturePolicy> GetParentFeaturePolicy();
3896 
3897   FlashClassification DocumentFlashClassificationInternal();
3898 
3899  public:
3900   bool IsThirdPartyForFlashClassifier();
3901 
3902  private:
3903   void DoCacheAllKnownLangPrefs();
3904   void RecomputeLanguageFromCharset();
3905   bool GetSHEntryHasUserInteraction();
3906 
3907  public:
SetMayNeedFontPrefsUpdate()3908   void SetMayNeedFontPrefsUpdate() { mMayNeedFontPrefsUpdate = true; }
3909 
MayNeedFontPrefsUpdate()3910   bool MayNeedFontPrefsUpdate() { return mMayNeedFontPrefsUpdate; }
3911 
3912   void SetSHEntryHasUserInteraction(bool aHasInteraction);
3913 
3914   already_AddRefed<nsAtom> GetContentLanguageAsAtomForStyle() const;
3915   already_AddRefed<nsAtom> GetLanguageForStyle() const;
3916 
3917   /**
3918    * Fetch the user's font preferences for the given aLanguage's
3919    * language group.
3920    */
3921   const LangGroupFontPrefs* GetFontPrefsForLang(
3922       nsAtom* aLanguage, bool* aNeedsToCache = nullptr) const;
3923 
ForceCacheLang(nsAtom * aLanguage)3924   void ForceCacheLang(nsAtom* aLanguage) {
3925     if (!mLanguagesUsed.EnsureInserted(aLanguage)) {
3926       return;
3927     }
3928     GetFontPrefsForLang(aLanguage);
3929   }
3930 
CacheAllKnownLangPrefs()3931   void CacheAllKnownLangPrefs() {
3932     if (!mMayNeedFontPrefsUpdate) {
3933       return;
3934     }
3935     DoCacheAllKnownLangPrefs();
3936   }
3937 
GetServoRestyleRoot()3938   nsINode* GetServoRestyleRoot() const { return mServoRestyleRoot; }
3939 
GetServoRestyleRootDirtyBits()3940   uint32_t GetServoRestyleRootDirtyBits() const {
3941     MOZ_ASSERT(mServoRestyleRoot);
3942     MOZ_ASSERT(mServoRestyleRootDirtyBits);
3943     return mServoRestyleRootDirtyBits;
3944   }
3945 
ClearServoRestyleRoot()3946   void ClearServoRestyleRoot() {
3947     mServoRestyleRoot = nullptr;
3948     mServoRestyleRootDirtyBits = 0;
3949   }
3950 
3951   inline void SetServoRestyleRoot(nsINode* aRoot, uint32_t aDirtyBits);
3952   inline void SetServoRestyleRootDirtyBits(uint32_t aDirtyBits);
3953 
ShouldThrowOnDynamicMarkupInsertion()3954   bool ShouldThrowOnDynamicMarkupInsertion() {
3955     return mThrowOnDynamicMarkupInsertionCounter;
3956   }
3957 
IncrementThrowOnDynamicMarkupInsertionCounter()3958   void IncrementThrowOnDynamicMarkupInsertionCounter() {
3959     ++mThrowOnDynamicMarkupInsertionCounter;
3960   }
3961 
DecrementThrowOnDynamicMarkupInsertionCounter()3962   void DecrementThrowOnDynamicMarkupInsertionCounter() {
3963     MOZ_ASSERT(mThrowOnDynamicMarkupInsertionCounter);
3964     --mThrowOnDynamicMarkupInsertionCounter;
3965   }
3966 
ShouldIgnoreOpens()3967   bool ShouldIgnoreOpens() const { return mIgnoreOpensDuringUnloadCounter; }
3968 
IncrementIgnoreOpensDuringUnloadCounter()3969   void IncrementIgnoreOpensDuringUnloadCounter() {
3970     ++mIgnoreOpensDuringUnloadCounter;
3971   }
3972 
DecrementIgnoreOpensDuringUnloadCounter()3973   void DecrementIgnoreOpensDuringUnloadCounter() {
3974     MOZ_ASSERT(mIgnoreOpensDuringUnloadCounter);
3975     --mIgnoreOpensDuringUnloadCounter;
3976   }
3977 
3978   mozilla::dom::FeaturePolicy* FeaturePolicy() const;
3979 
3980   bool ModuleScriptsEnabled();
3981 
3982   /**
3983    * Find the (non-anonymous) content in this document for aFrame. It will
3984    * be aFrame's content node if that content is in this document and not
3985    * anonymous. Otherwise, when aFrame is in a subdocument, we use the frame
3986    * element containing the subdocument containing aFrame, and/or find the
3987    * nearest non-anonymous ancestor in this document.
3988    * Returns null if there is no such element.
3989    */
3990   nsIContent* GetContentInThisDocument(nsIFrame* aFrame) const;
3991 
3992   void ReportShadowDOMUsage();
3993 
3994   // Sets flags for media telemetry.
3995   void SetDocTreeHadMedia();
3996 
3997   dom::XPathEvaluator* XPathEvaluator();
3998 
3999   void MaybeInitializeFinalizeFrameLoaders();
4000 
SetDelayFrameLoaderInitialization(bool aDelayFrameLoaderInitialization)4001   void SetDelayFrameLoaderInitialization(bool aDelayFrameLoaderInitialization) {
4002     mDelayFrameLoaderInitialization = aDelayFrameLoaderInitialization;
4003   }
4004 
4005   void SetPrototypeDocument(nsXULPrototypeDocument* aPrototype);
4006 
4007   nsIPermissionDelegateHandler* PermDelegateHandler();
4008 
4009   // CSS prefers-color-scheme media feature for this document.
4010   enum class IgnoreRFP { No, Yes };
4011   ColorScheme PreferredColorScheme(IgnoreRFP = IgnoreRFP::No) const;
4012   // Returns the initial color-scheme used for this document based on the
4013   // color-scheme meta tag.
4014   ColorScheme DefaultColorScheme() const;
4015 
4016   static bool HasRecentlyStartedForegroundLoads();
4017 
4018   static bool AutomaticStorageAccessPermissionCanBeGranted(
4019       nsIPrincipal* aPrincipal);
4020 
4021   already_AddRefed<Promise> AddCertException(bool aIsTemporary);
4022 
4023   void ReloadWithHttpsOnlyException();
4024 
4025   // Subframes need to be static cloned after the main document has been
4026   // embedded within a script global. A `PendingFrameStaticClone` is a static
4027   // clone which has not yet been performed.
4028   //
4029   // The getter returns a direct reference to an internal array which is
4030   // manipulated from within printing code.
4031   struct PendingFrameStaticClone {
4032     PendingFrameStaticClone() = default;
4033     PendingFrameStaticClone(PendingFrameStaticClone&&) = default;
4034     PendingFrameStaticClone& operator=(PendingFrameStaticClone&&) = default;
4035     ~PendingFrameStaticClone();
4036 
4037     RefPtr<nsFrameLoaderOwner> mElement;
4038     RefPtr<nsFrameLoader> mStaticCloneOf;
4039   };
4040   void AddPendingFrameStaticClone(nsFrameLoaderOwner* aElement,
4041                                   nsFrameLoader* aStaticCloneOf);
4042 
4043   bool ShouldAvoidNativeTheme() const;
4044 
4045   static bool IsValidDomain(nsIURI* aOrigHost, nsIURI* aNewURI);
4046 
4047   // Inform a parent document that a BrowserBridgeChild has been created for
4048   // an OOP sub-document.
4049   // (This is the OOP counterpart to nsDocLoader::ChildEnteringOnload)
4050   void OOPChildLoadStarted(BrowserBridgeChild* aChild);
4051 
4052   // Inform a parent document that the BrowserBridgeChild for one of its
4053   // OOP sub-documents is done calling its onload handler.
4054   // (This is the OOP counterpart to nsDocLoader::ChildDoneWithOnload)
4055   void OOPChildLoadDone(BrowserBridgeChild* aChild);
4056 
4057   void ClearOOPChildrenLoading();
4058 
HasOOPChildrenLoading()4059   bool HasOOPChildrenLoading() { return !mOOPChildrenLoading.IsEmpty(); }
4060 
SetDidHitCompleteSheetCache()4061   void SetDidHitCompleteSheetCache() { mDidHitCompleteSheetCache = true; }
4062 
DidHitCompleteSheetCache()4063   bool DidHitCompleteSheetCache() const { return mDidHitCompleteSheetCache; }
4064 
4065  protected:
4066   // Returns the WindowContext for the document that we will contribute
4067   // page use counters to.
4068   WindowContext* GetWindowContextForPageUseCounters() const;
4069 
4070   void DoUpdateSVGUseElementShadowTrees();
4071 
4072   already_AddRefed<nsIPrincipal> MaybeDowngradePrincipal(
4073       nsIPrincipal* aPrincipal);
4074 
4075   void EnsureOnloadBlocker();
4076 
4077   void SendToConsole(nsCOMArray<nsISecurityConsoleMessage>& aMessages);
4078 
4079   // Returns true if the scheme for the url for this document is "about".
4080   bool IsAboutPage() const;
4081 
4082   bool ContainsEMEContent();
4083   bool ContainsMSEContent();
4084 
4085   /**
4086    * Returns the title element of the document as defined by the HTML
4087    * specification, or null if there isn't one.  For documents whose root
4088    * element is an <svg:svg>, this is the first <svg:title> element that's a
4089    * child of the root.  For other documents, it's the first HTML title element
4090    * in the document.
4091    */
4092   Element* GetTitleElement();
4093 
4094   void RecordNavigationTiming(ReadyState aReadyState);
4095 
4096   // Recomputes the visibility state but doesn't set the new value.
4097   dom::VisibilityState ComputeVisibilityState() const;
4098 
4099   // Since we wouldn't automatically play media from non-visited page, we need
4100   // to notify window when the page was first visited.
4101   void MaybeActiveMediaComponents();
4102 
4103   // Apply the fullscreen state to the document, and trigger related
4104   // events. It returns false if the fullscreen element ready check
4105   // fails and nothing gets changed.
4106   bool ApplyFullscreen(UniquePtr<FullscreenRequest>);
4107 
4108   void RemoveDocStyleSheetsFromStyleSets();
4109   void ResetStylesheetsToURI(nsIURI* aURI);
4110   void FillStyleSet();
4111   void FillStyleSetUserAndUASheets();
4112   void FillStyleSetDocumentSheets();
4113   void CompatibilityModeChanged();
NeedsQuirksSheet()4114   bool NeedsQuirksSheet() const {
4115     // SVG documents never load quirk.css.
4116     // FIXME(emilio): Can SVG documents be in quirks mode anyway?
4117     return mCompatMode == eCompatibility_NavQuirks && !IsSVGDocument();
4118   }
4119   void AddContentEditableStyleSheetsToStyleSet(bool aDesignMode);
4120   void RemoveContentEditableStyleSheets();
4121   void AddStyleSheetToStyleSets(StyleSheet&);
4122   void RemoveStyleSheetFromStyleSets(StyleSheet&);
4123   void NotifyStyleSheetApplicableStateChanged();
4124   // Just like EnableStyleSheetsForSet, but doesn't check whether
4125   // aSheetSet is null and allows the caller to control whether to set
4126   // aSheetSet as the preferred set in the CSSLoader.
4127   void EnableStyleSheetsForSetInternal(const nsAString& aSheetSet,
4128                                        bool aUpdateCSSLoader);
4129 
4130   already_AddRefed<nsIURI> GetDomainURI();
4131   already_AddRefed<nsIURI> CreateInheritingURIForHost(
4132       const nsACString& aHostString);
4133   already_AddRefed<nsIURI> RegistrableDomainSuffixOfInternal(
4134       const nsAString& aHostSuffixString, nsIURI* aOrigHost);
4135 
4136   void WriteCommon(const nsAString& aText, bool aNewlineTerminate,
4137                    mozilla::ErrorResult& aRv);
4138   // A version of WriteCommon used by WebIDL bindings
4139   void WriteCommon(const mozilla::dom::Sequence<nsString>& aText,
4140                    bool aNewlineTerminate, mozilla::ErrorResult& rv);
4141 
4142   void* GenerateParserKey(void);
4143 
4144  private:
4145   // ExecCommandParam indicates how HTMLDocument.execCommand() treats given the
4146   // parameter.
4147   enum class ExecCommandParam : uint8_t {
4148     // Always ignore it.
4149     Ignore,
4150     // Treat the given parameter as-is.  If the command requires it, use it.
4151     // Otherwise, ignore it.
4152     String,
4153     // Always treat it as boolean parameter.
4154     Boolean,
4155     // Always treat it as boolean, but inverted.
4156     InvertedBoolean,
4157   };
4158 
4159   using GetEditorCommandFunc = mozilla::EditorCommand*();
4160 
4161   struct InternalCommandData {
4162     const char* mXULCommandName;
4163     mozilla::Command mCommand;  // uint8_t
4164     // How ConvertToInternalCommand() to treats aValue.
4165     // Its callers don't need to check this.
4166     ExecCommandParam mExecCommandParam;  // uint8_t
4167     GetEditorCommandFunc* mGetEditorCommandFunc;
4168     enum class CommandOnTextEditor : uint8_t {
4169       Disabled,
4170       Enabled,
4171       FallThrough,  // Not disabled, but handled by HTMLEditor if there is one
4172     };
4173     CommandOnTextEditor mCommandOnTextEditor;
4174 
InternalCommandDataInternalCommandData4175     InternalCommandData()
4176         : mXULCommandName(nullptr),
4177           mCommand(mozilla::Command::DoNothing),
4178           mExecCommandParam(ExecCommandParam::Ignore),
4179           mGetEditorCommandFunc(nullptr),
4180           mCommandOnTextEditor(CommandOnTextEditor::Disabled) {}
InternalCommandDataInternalCommandData4181     InternalCommandData(const char* aXULCommandName, mozilla::Command aCommand,
4182                         ExecCommandParam aExecCommandParam,
4183                         GetEditorCommandFunc aGetEditorCommandFunc,
4184                         CommandOnTextEditor aCommandOnTextEditor)
4185         : mXULCommandName(aXULCommandName),
4186           mCommand(aCommand),
4187           mExecCommandParam(aExecCommandParam),
4188           mGetEditorCommandFunc(aGetEditorCommandFunc),
4189           mCommandOnTextEditor(aCommandOnTextEditor) {}
4190 
IsAvailableOnlyWhenEditableInternalCommandData4191     bool IsAvailableOnlyWhenEditable() const {
4192       return mCommand != mozilla::Command::Cut &&
4193              mCommand != mozilla::Command::Copy &&
4194              mCommand != mozilla::Command::Paste &&
4195              mCommand != mozilla::Command::SetDocumentReadOnly &&
4196              mCommand != mozilla::Command::GetHTML &&
4197              mCommand != mozilla::Command::SelectAll;
4198     }
IsCutOrCopyCommandInternalCommandData4199     bool IsCutOrCopyCommand() const {
4200       return mCommand == mozilla::Command::Cut ||
4201              mCommand == mozilla::Command::Copy;
4202     }
IsPasteCommandInternalCommandData4203     bool IsPasteCommand() const { return mCommand == mozilla::Command::Paste; }
4204   };
4205 
4206   /**
4207    * AutoEditorCommandTarget considers which editor or global command manager
4208    * handles given command.
4209    */
4210   class MOZ_RAII AutoEditorCommandTarget {
4211    public:
4212     MOZ_CAN_RUN_SCRIPT AutoEditorCommandTarget(
4213         Document& aDocument, const InternalCommandData& aCommandData);
4214     AutoEditorCommandTarget() = delete;
4215     explicit AutoEditorCommandTarget(const AutoEditorCommandTarget& aOther) =
4216         delete;
4217 
DoNothing()4218     bool DoNothing() const { return mDoNothing; }
4219     MOZ_CAN_RUN_SCRIPT bool IsEditable(Document* aDocument) const;
IsEditor()4220     bool IsEditor() const {
4221       MOZ_ASSERT_IF(mEditorCommand, mActiveEditor || mHTMLEditor);
4222       return !!mEditorCommand;
4223     }
4224 
4225     MOZ_CAN_RUN_SCRIPT bool IsCommandEnabled() const;
4226     MOZ_CAN_RUN_SCRIPT nsresult DoCommand(nsIPrincipal* aPrincipal) const;
4227     template <typename ParamType>
4228     MOZ_CAN_RUN_SCRIPT nsresult DoCommandParam(const ParamType& aParam,
4229                                                nsIPrincipal* aPrincipal) const;
4230     MOZ_CAN_RUN_SCRIPT nsresult
4231     GetCommandStateParams(nsCommandParams& aParams) const;
4232 
4233    private:
4234     // The returned editor's life is guaranteed while this instance is alive.
4235     EditorBase* GetTargetEditor() const;
4236 
4237     RefPtr<EditorBase> mActiveEditor;
4238     RefPtr<HTMLEditor> mHTMLEditor;
4239     RefPtr<EditorCommand> mEditorCommand;
4240     const InternalCommandData& mCommandData;
4241     bool mDoNothing = false;
4242   };
4243 
4244   /**
4245    * Helper method to initialize sInternalCommandDataHashtable.
4246    */
4247   static void EnsureInitializeInternalCommandDataHashtable();
4248 
4249   /**
4250    * ConvertToInternalCommand() returns a copy of InternalCommandData instance.
4251    * Note that if aAdjustedValue is non-nullptr, this method checks whether
4252    * aValue is proper value or not unless InternalCommandData::mExecCommandParam
4253    * is ExecCommandParam::Ignore.  For example, if aHTMLCommandName is
4254    * "defaultParagraphSeparator", the value has to be one of "div", "p" or
4255    * "br".  If aValue is invalid value for InternalCommandData::mCommand, this
4256    * returns a copy of instance created with default constructor.  I.e., its
4257    * mCommand is set to Command::DoNothing.  So, this treats aHTMLCommandName
4258    * is unsupported in such case.
4259    *
4260    * @param aHTMLCommandName    Command name in HTML, e.g., used by
4261    *                            execCommand().
4262    * @param aValue              The value which is set to the 3rd parameter
4263    *                            of execCommand().
4264    * @param aAdjustedValue      [out] Must be empty string if set non-nullptr.
4265    *                            Will be set to adjusted value for executing
4266    *                            the internal command.
4267    * @return                    Returns a copy of instance created with the
4268    *                            default constructor if there is no
4269    *                            corresponding internal command for
4270    *                            aHTMLCommandName or aValue is invalid for
4271    *                            found internal command when aAdjustedValue
4272    *                            is not nullptr.  Otherwise, returns a copy of
4273    *                            instance registered in
4274    *                            sInternalCommandDataHashtable.
4275    */
4276   static InternalCommandData ConvertToInternalCommand(
4277       const nsAString& aHTMLCommandName, const nsAString& aValue = u""_ns,
4278       nsAString* aAdjustedValue = nullptr);
4279 
4280   /**
4281    * AutoRunningExecCommandMarker is AutoRestorer for mIsRunningExecCommand.
4282    * Since it's a bit field, not a bool member, therefore, we cannot use
4283    * AutoRestorer for it.
4284    */
4285   class MOZ_STACK_CLASS AutoRunningExecCommandMarker final {
4286    public:
4287     AutoRunningExecCommandMarker() = delete;
4288     explicit AutoRunningExecCommandMarker(const AutoRunningExecCommandMarker&) =
4289         delete;
4290     // Guaranteeing the document's lifetime with `MOZ_CAN_RUN_SCRIPT`.
AutoRunningExecCommandMarker(Document & aDocument)4291     MOZ_CAN_RUN_SCRIPT explicit AutoRunningExecCommandMarker(
4292         Document& aDocument)
4293         : mDocument(aDocument),
4294           mHasBeenRunning(aDocument.mIsRunningExecCommand) {
4295       aDocument.mIsRunningExecCommand = true;
4296     }
~AutoRunningExecCommandMarker()4297     ~AutoRunningExecCommandMarker() {
4298       if (!mHasBeenRunning) {
4299         mDocument.mIsRunningExecCommand = false;
4300       }
4301     }
4302 
4303    private:
4304     Document& mDocument;
4305     bool mHasBeenRunning;
4306   };
4307 
4308   // Mapping table from HTML command name to internal command.
4309   using InternalCommandDataHashtable =
4310       nsTHashMap<nsStringCaseInsensitiveHashKey, InternalCommandData>;
4311   static InternalCommandDataHashtable* sInternalCommandDataHashtable;
4312 
4313   mutable std::bitset<static_cast<size_t>(
4314       DeprecatedOperations::eDeprecatedOperationCount)>
4315       mDeprecationWarnedAbout;
4316   mutable std::bitset<eDocumentWarningCount> mDocWarningWarnedAbout;
4317 
4318   // Lazy-initialization to have mDocGroup initialized in prior to the
4319   // SelectorCaches.
4320   UniquePtr<SelectorCache> mSelectorCache;
4321   UniquePtr<ServoStyleSet> mStyleSet;
4322 
4323  protected:
4324   friend class nsDocumentOnStack;
4325 
IncreaseStackRefCnt()4326   void IncreaseStackRefCnt() { ++mStackRefCnt; }
4327 
DecreaseStackRefCnt()4328   void DecreaseStackRefCnt() {
4329     if (--mStackRefCnt == 0 && mNeedsReleaseAfterStackRefCntRelease) {
4330       mNeedsReleaseAfterStackRefCntRelease = false;
4331       NS_RELEASE_THIS();
4332     }
4333   }
4334 
4335   // Never ever call this. Only call GetWindow!
4336   nsPIDOMWindowOuter* GetWindowInternal() const;
4337 
4338   // Never ever call this. Only call GetScriptHandlingObject!
4339   nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const;
4340 
4341   // Never ever call this. Only call AllowXULXBL!
4342   bool InternalAllowXULXBL();
4343 
4344   /**
4345    * These methods should be called before and after dispatching
4346    * a mutation event.
4347    * To make this easy and painless, use the mozAutoSubtreeModified helper
4348    * class.
4349    */
4350   void WillDispatchMutationEvent(nsINode* aTarget);
4351   void MutationEventDispatched(nsINode* aTarget);
4352   friend class mozAutoSubtreeModified;
4353 
GetNameSpaceElement()4354   virtual Element* GetNameSpaceElement() override { return GetRootElement(); }
4355 
GetContentTypeInternal()4356   nsCString GetContentTypeInternal() const { return mContentType; }
4357 
4358   // Update our frame request callback scheduling state, if needed.  This will
4359   // schedule or unschedule them, if necessary, and update
4360   // mFrameRequestCallbacksScheduled.  aOldShell should only be passed when
4361   // mPresShell is becoming null; in that case it will be used to get hold of
4362   // the relevant refresh driver.
4363   void UpdateFrameRequestCallbackSchedulingState(
4364       PresShell* aOldPresShell = nullptr);
4365 
4366   // Helper for GetScrollingElement/IsScrollingElement.
4367   bool IsPotentiallyScrollable(HTMLBodyElement* aBody);
4368 
4369   void MaybeAllowStorageForOpenerAfterUserInteraction();
4370 
4371   void MaybeStoreUserInteractionAsPermission();
4372 
4373   // Helpers for GetElementsByName.
4374   static bool MatchNameAttribute(Element* aElement, int32_t aNamespaceID,
4375                                  nsAtom* aAtom, void* aData);
4376   static void* UseExistingNameString(nsINode* aRootNode, const nsString* aName);
4377 
4378   void MaybeResolveReadyForIdle();
4379 
4380   using AutomaticStorageAccessPermissionGrantPromise =
4381       MozPromise<bool, bool, true>;
4382   [[nodiscard]] RefPtr<AutomaticStorageAccessPermissionGrantPromise>
4383   AutomaticStorageAccessPermissionCanBeGranted(bool hasUserActivation);
4384 
4385   static void AddToplevelLoadingDocument(Document* aDoc);
4386   static void RemoveToplevelLoadingDocument(Document* aDoc);
4387   static AutoTArray<Document*, 8>* sLoadingForegroundTopLevelContentDocument;
4388   friend class cycleCollection;
4389 
4390   nsCOMPtr<nsIReferrerInfo> mPreloadReferrerInfo;
4391   nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
4392 
4393   nsString mLastModified;
4394 
4395   nsCOMPtr<nsIURI> mDocumentURI;
4396   nsCOMPtr<nsIURI> mOriginalURI;
4397   nsCOMPtr<nsIURI> mChromeXHRDocURI;
4398   nsCOMPtr<nsIURI> mDocumentBaseURI;
4399   nsCOMPtr<nsIURI> mChromeXHRDocBaseURI;
4400 
4401   // The base domain of the document for third-party checks.
4402   nsCString mBaseDomain;
4403 
4404   // A lazily-constructed URL data for style system to resolve URL value.
4405   RefPtr<URLExtraData> mCachedURLData;
4406   nsCOMPtr<nsIReferrerInfo> mCachedReferrerInfo;
4407 
4408   nsWeakPtr mDocumentLoadGroup;
4409 
4410   WeakPtr<nsDocShell> mDocumentContainer;
4411 
4412   NotNull<const Encoding*> mCharacterSet;
4413   int32_t mCharacterSetSource;
4414 
4415   OriginTrials mTrials;
4416 
4417   // This is just a weak pointer; the parent document owns its children.
4418   Document* mParentDocument;
4419 
4420   // A reference to the element last returned from GetRootElement().
4421   Element* mCachedRootElement;
4422 
4423   // This is a weak reference, but we hold a strong reference to mNodeInfo,
4424   // which in turn holds a strong reference to this mNodeInfoManager.
4425   nsNodeInfoManager* mNodeInfoManager;
4426   RefPtr<css::Loader> mCSSLoader;
4427   RefPtr<css::ImageLoader> mStyleImageLoader;
4428   RefPtr<nsHTMLStyleSheet> mAttrStyleSheet;
4429   RefPtr<nsHTMLCSSStyleSheet> mStyleAttrStyleSheet;
4430 
4431   // Tracking for images in the document.
4432   RefPtr<dom::ImageTracker> mImageTracker;
4433 
4434   // A hashtable of ShadowRoots belonging to the composed doc.
4435   //
4436   // See ShadowRoot::Bind and ShadowRoot::Unbind.
4437   ShadowRootSet mComposedShadowRoots;
4438 
4439   using SVGUseElementSet = nsTHashSet<SVGUseElement*>;
4440 
4441   // The set of <svg:use> elements that need a shadow tree reclone because the
4442   // tree they map to has changed.
4443   SVGUseElementSet mSVGUseElementsNeedingShadowTreeUpdate;
4444 
4445   // The set of all object, embed, video/audio elements or
4446   // nsIObjectLoadingContent or DocumentActivity for which this is
4447   // the owner document. (They might not be in the document.)
4448   //
4449   // These are non-owning pointers, the elements are responsible for removing
4450   // themselves when they go away.
4451   UniquePtr<nsTHashSet<nsISupports*>> mActivityObservers;
4452 
4453   // A hashtable of styled links keyed by address pointer.
4454   nsTHashSet<Link*> mStyledLinks;
4455 #ifdef DEBUG
4456   // Indicates whether mStyledLinks was cleared or not.  This is used to track
4457   // state so we can provide useful assertions to consumers of ForgetLink and
4458   // AddStyleRelevantLink.
4459   bool mStyledLinksCleared;
4460 #endif
4461 
4462   // The array of all links that need their status resolved.  Links must add
4463   // themselves to this set by calling RegisterPendingLinkUpdate when added to a
4464   // document.
4465   static const size_t kSegmentSize = 128;
4466 
4467   using LinksToUpdateList =
4468       SegmentedVector<nsCOMPtr<Link>, kSegmentSize, InfallibleAllocPolicy>;
4469 
4470   LinksToUpdateList mLinksToUpdate;
4471 
4472   // SMIL Animation Controller, lazily-initialized in GetAnimationController
4473   RefPtr<SMILAnimationController> mAnimationController;
4474 
4475   // Table of element properties for this document.
4476   nsPropertyTable mPropertyTable;
4477 
4478   // Our cached .children collection
4479   nsCOMPtr<nsIHTMLCollection> mChildrenCollection;
4480 
4481   // Various DOM lists
4482   RefPtr<nsContentList> mImages;
4483   RefPtr<nsContentList> mEmbeds;
4484   RefPtr<nsContentList> mLinks;
4485   RefPtr<nsContentList> mForms;
4486   RefPtr<nsContentList> mScripts;
4487   nsCOMPtr<nsIHTMLCollection> mApplets;
4488   RefPtr<nsContentList> mAnchors;
4489 
4490   // container for per-context fonts (downloadable, SVG, etc.)
4491   RefPtr<FontFaceSet> mFontFaceSet;
4492 
4493   // Last time this document or a one of its sub-documents was focused.  If
4494   // focus has never occurred then mLastFocusTime.IsNull() will be true.
4495   TimeStamp mLastFocusTime;
4496 
4497   EventStates mDocumentState{NS_DOCUMENT_STATE_LTR_LOCALE};
4498 
4499   RefPtr<Promise> mReadyForIdle;
4500 
4501   RefPtr<mozilla::dom::FeaturePolicy> mFeaturePolicy;
4502 
4503   UniquePtr<ResizeObserverController> mResizeObserverController;
4504 
4505   // Permission Delegate Handler, lazily-initialized in
4506   // GetPermissionDelegateHandler
4507   RefPtr<PermissionDelegateHandler> mPermissionDelegateHandler;
4508 
4509   bool mBlockAllMixedContent : 1;
4510   bool mBlockAllMixedContentPreloads : 1;
4511   bool mUpgradeInsecureRequests : 1;
4512   bool mUpgradeInsecurePreloads : 1;
4513   bool mDevToolsWatchingDOMMutations : 1;
4514 
4515   // True if BIDI is enabled.
4516   bool mBidiEnabled : 1;
4517   // True if we may need to recompute the language prefs for this document.
4518   bool mMayNeedFontPrefsUpdate : 1;
4519   // True if a MathML element has ever been owned by this document.
4520   bool mMathMLEnabled : 1;
4521 
4522   // True if this document is the initial document for a window.  This should
4523   // basically be true only for documents that exist in newly-opened windows or
4524   // documents created to satisfy a GetDocument() on a window when there's no
4525   // document in it.
4526   bool mIsInitialDocumentInWindow : 1;
4527 
4528   bool mIgnoreDocGroupMismatches : 1;
4529 
4530   // True if we're loaded as data and therefor has any dangerous stuff, such
4531   // as scripts and plugins, disabled.
4532   bool mLoadedAsData : 1;
4533 
4534   // True if the document is considered for memory reporting as a
4535   // data document
4536   bool mAddedToMemoryReportingAsDataDocument : 1;
4537 
4538   // If true, whoever is creating the document has gotten it to the
4539   // point where it's safe to start layout on it.
4540   bool mMayStartLayout : 1;
4541 
4542   // True iff we've ever fired a DOMTitleChanged event for this document
4543   bool mHaveFiredTitleChange : 1;
4544 
4545   // State for IsShowing(). mIsShowing starts off false. It becomes true when
4546   // OnPageShow happens and becomes false when OnPageHide happens. So it's false
4547   // before the initial load completes and when we're in bfcache or unloaded,
4548   // true otherwise.
4549   bool mIsShowing : 1;
4550 
4551   // State for IsVisible(). mVisible starts off true. It becomes false when
4552   // OnPageHide happens, and becomes true again when OnPageShow happens.  So
4553   // it's false only when we're in bfcache or unloaded.
4554   bool mVisible : 1;
4555 
4556   // True if our content viewer has been removed from the docshell
4557   // (it may still be displayed, but in zombie state). Form control data
4558   // has been saved.
4559   bool mRemovedFromDocShell : 1;
4560 
4561   // True iff DNS prefetch is allowed for this document.  Note that if the
4562   // document has no window, DNS prefetch won't be performed no matter what.
4563   bool mAllowDNSPrefetch : 1;
4564 
4565   // True when this document is a static clone of a normal document
4566   bool mIsStaticDocument : 1;
4567 
4568   // True while this document is being cloned to a static document.
4569   bool mCreatingStaticClone : 1;
4570 
4571   // True if this static document has any <canvas> element with a
4572   // mozPrintCallback property at the time of the clone.
4573   bool mHasPrintCallbacks : 1;
4574 
4575   // True iff the document is being unlinked or deleted.
4576   bool mInUnlinkOrDeletion : 1;
4577 
4578   // True if document has ever had script handling object.
4579   bool mHasHadScriptHandlingObject : 1;
4580 
4581   // True if we're an SVG document being used as an image.
4582   bool mIsBeingUsedAsImage : 1;
4583 
4584   // True if our current document URI's scheme is chrome://
4585   bool mDocURISchemeIsChrome : 1;
4586 
4587   // True if we're loaded in a chrome docshell.
4588   bool mInChromeDocShell : 1;
4589 
4590   // True if our current document is a DevTools document. Either the url is
4591   // about:devtools-toolbox or the parent document already has
4592   // mIsDevToolsDocument set to true.
4593   // This is used to avoid applying High Contrast mode to DevTools documents.
4594   // See Bug 1575766.
4595   bool mIsDevToolsDocument : 1;
4596 
4597   // True is this document is synthetic : stand alone image, video, audio
4598   // file, etc.
4599   bool mIsSyntheticDocument : 1;
4600 
4601   // True is there is a pending runnable which will call
4602   // FlushPendingLinkUpdates().
4603   bool mHasLinksToUpdateRunnable : 1;
4604 
4605   // True if we're flushing pending link updates.
4606   bool mFlushingPendingLinkUpdates : 1;
4607 
4608   // True if a DOMMutationObserver is perhaps attached to a node in the
4609   // document.
4610   bool mMayHaveDOMMutationObservers : 1;
4611 
4612   // True if an nsIAnimationObserver is perhaps attached to a node in the
4613   // document.
4614   bool mMayHaveAnimationObservers : 1;
4615 
4616   // True if a document load has a CSP attached.
4617   bool mHasCSP : 1;
4618 
4619   // True if a document load has a CSP with unsafe-eval attached.
4620   bool mHasUnsafeEvalCSP : 1;
4621 
4622   // True if a document load has a CSP with unsafe-inline attached.
4623   bool mHasUnsafeInlineCSP : 1;
4624 
4625   // True if the document has a CSP delivered throuh a header
4626   bool mHasCSPDeliveredThroughHeader : 1;
4627 
4628   // True if DisallowBFCaching has been called on this document.
4629   bool mBFCacheDisallowed : 1;
4630 
4631   bool mHasHadDefaultView : 1;
4632 
4633   // Whether style sheet change events will be dispatched for this document
4634   bool mStyleSheetChangeEventsEnabled : 1;
4635 
4636   // Whether shadowrootattached events will be dispatched for this document.
4637   bool mShadowRootAttachedEventEnabled : 1;
4638 
4639   // Whether the document was created by a srcdoc iframe.
4640   bool mIsSrcdocDocument : 1;
4641 
4642   // Whether this document has a display document and thus is considered to
4643   // be a resource document.  Normally this is the same as !!mDisplayDocument,
4644   // but mDisplayDocument is cleared during Unlink.  mHasDisplayDocument is
4645   // valid in the document's destructor.
4646   bool mHasDisplayDocument : 1;
4647 
4648   // Is the current mFontFaceSet valid?
4649   bool mFontFaceSetDirty : 1;
4650 
4651   // True if we have fired the DOMContentLoaded event, or don't plan to fire one
4652   // (e.g. we're not being parsed at all).
4653   bool mDidFireDOMContentLoaded : 1;
4654 
4655   // True if ReportHasScrollLinkedEffect() has been called.
4656   bool mHasScrollLinkedEffect : 1;
4657 
4658   // True if we have frame request callbacks scheduled with the refresh driver.
4659   // This should generally be updated only via
4660   // UpdateFrameRequestCallbackSchedulingState.
4661   bool mFrameRequestCallbacksScheduled : 1;
4662 
4663   bool mIsTopLevelContentDocument : 1;
4664 
4665   bool mIsContentDocument : 1;
4666 
4667   // True if we have called BeginLoad and are expecting a paired EndLoad call.
4668   bool mDidCallBeginLoad : 1;
4669 
4670   // True if the encoding menu should be disabled.
4671   bool mEncodingMenuDisabled : 1;
4672 
4673   // False if we've disabled link handling for elements inside this document,
4674   // true otherwise.
4675   bool mLinksEnabled : 1;
4676 
4677   // True if this document is for an SVG-in-OpenType font.
4678   bool mIsSVGGlyphsDocument : 1;
4679 
4680   // True if the document is being destroyed.
4681   bool mInDestructor : 1;
4682 
4683   // True if the document has been detached from its content viewer.
4684   bool mIsGoingAway : 1;
4685 
4686   bool mInXBLUpdate : 1;
4687 
4688   bool mNeedsReleaseAfterStackRefCntRelease : 1;
4689 
4690   // Whether we have filled our style set with all the stylesheets.
4691   bool mStyleSetFilled : 1;
4692 
4693   // Whether we have a quirks mode stylesheet in the style set.
4694   bool mQuirkSheetAdded : 1;
4695 
4696   // Whether we have a contenteditable.css stylesheet in the style set.
4697   bool mContentEditableSheetAdded : 1;
4698 
4699   // Whether we have a designmode.css stylesheet in the style set.
4700   bool mDesignModeSheetAdded : 1;
4701 
4702   // Keeps track of whether we have a pending
4703   // 'style-sheet-applicable-state-changed' notification.
4704   bool mSSApplicableStateNotificationPending : 1;
4705 
4706   // True if this document has ever had an HTML or SVG <title> element
4707   // bound to it
4708   bool mMayHaveTitleElement : 1;
4709 
4710   bool mDOMLoadingSet : 1;
4711   bool mDOMInteractiveSet : 1;
4712   bool mDOMCompleteSet : 1;
4713   bool mAutoFocusFired : 1;
4714 
4715   bool mScrolledToRefAlready : 1;
4716   bool mChangeScrollPosWhenScrollingToRef : 1;
4717 
4718   bool mDelayFrameLoaderInitialization : 1;
4719 
4720   bool mSynchronousDOMContentLoaded : 1;
4721 
4722   // Set to true when the document is possibly controlled by the ServiceWorker.
4723   // Used to prevent multiple requests to ServiceWorkerManager.
4724   bool mMaybeServiceWorkerControlled : 1;
4725 
4726   // These member variables cache information about the viewport so we don't
4727   // have to recalculate it each time.
4728   bool mAllowZoom : 1;
4729   bool mValidScaleFloat : 1;
4730   bool mValidMinScale : 1;
4731   bool mValidMaxScale : 1;
4732   bool mWidthStrEmpty : 1;
4733 
4734   // Parser aborted. True if the parser of this document was forcibly
4735   // terminated instead of letting it finish at its own pace.
4736   bool mParserAborted : 1;
4737 
4738   // Whether we have reported document use counters for this document with
4739   // Telemetry yet.  Normally this is only done at document destruction time,
4740   // but for image documents (SVG documents) that are not guaranteed to be
4741   // destroyed, we report use counters when the image cache no longer has any
4742   // imgRequestProxys pointing to them.  We track whether we ever reported use
4743   // counters so that we only report them once for the document.
4744   bool mReportedDocumentUseCounters : 1;
4745 
4746   bool mHasReportedShadowDOMUsage : 1;
4747 
4748   // Whether an event triggered by the refresh driver was delayed because this
4749   // document has suppressed events.
4750   bool mHasDelayedRefreshEvent : 1;
4751 
4752   // The HTML spec has a "iframe load in progress" flag, but that doesn't seem
4753   // to have the right semantics.  See
4754   // <https://github.com/whatwg/html/issues/4292>. What we have instead is a
4755   // flag that is set while the window's 'load' event is firing if this document
4756   // is the window's document.
4757   bool mLoadEventFiring : 1;
4758 
4759   // The HTML spec has a "mute iframe load" flag, but that doesn't seem to have
4760   // the right semantics.  See <https://github.com/whatwg/html/issues/4292>.
4761   // What we have instead is a flag that is set if completion of our document
4762   // via document.close() should skip firing the load event.  Note that this
4763   // flag is only relevant for HTML documents, but lives here for reasons that
4764   // are documented above on SkipLoadEventAfterClose().
4765   bool mSkipLoadEventAfterClose : 1;
4766 
4767   // When false, the .cookies property is completely disabled
4768   bool mDisableCookieAccess : 1;
4769 
4770   // When false, the document.write() API is disabled.
4771   bool mDisableDocWrite : 1;
4772 
4773   // Has document.write() been called with a recursion depth higher than
4774   // allowed?
4775   bool mTooDeepWriteRecursion : 1;
4776 
4777   /**
4778    * Temporary flag that is set in EndUpdate() to ignore
4779    * MaybeEditingStateChanged() script runners from a nested scope.
4780    */
4781   bool mPendingMaybeEditingStateChanged : 1;
4782 
4783   // mHasBeenEditable is set to true when mEditingState is firstly set to
4784   // eDesignMode or eContentEditable.
4785   bool mHasBeenEditable : 1;
4786 
4787   // Whether we've warned about the CSS zoom property.
4788   //
4789   // We don't use the general deprecated operation mechanism for this because we
4790   // also record this as a `CountedUnknownProperty`.
4791   bool mHasWarnedAboutZoom : 1;
4792 
4793   // While we're handling an execCommand call, set to true.
4794   bool mIsRunningExecCommand : 1;
4795 
4796   // True if we should change the readystate to complete after we fire
4797   // DOMContentLoaded. This happens when we abort a load and
4798   // nsDocumentViewer::EndLoad runs while we still have things blocking
4799   // DOMContentLoaded. We wait for those to complete, and then update the
4800   // readystate when they finish.
4801   bool mSetCompleteAfterDOMContentLoaded : 1;
4802 
4803   // Set the true if a completed cached stylesheet was created for the document.
4804   bool mDidHitCompleteSheetCache : 1;
4805 
4806   uint8_t mPendingFullscreenRequests;
4807 
4808   uint8_t mXMLDeclarationBits;
4809 
4810   // NOTE(emilio): Technically, this should be a StyleColorSchemeFlags, but we
4811   // use uint8_t to avoid having to include a bunch of style system headers
4812   // everywhere.
4813   uint8_t mColorSchemeBits = 0;
4814 
4815   // Currently active onload blockers.
4816   uint32_t mOnloadBlockCount;
4817 
4818   // Tracks if we are currently processing any document.write calls (either
4819   // implicit or explicit). Note that if a write call writes out something which
4820   // would block the parser, then mWriteLevel will be incorrect until the parser
4821   // finishes processing that script.
4822   uint32_t mWriteLevel;
4823 
4824   // The amount of images that have `loading="lazy"` on the page or have loaded
4825   // lazily already.
4826   uint32_t mLazyLoadImageCount;
4827   // Number of lazy-loaded images that we've started loading as a result of
4828   // triggering the lazy-load observer threshold.
4829   uint32_t mLazyLoadImageStarted;
4830   // Number of lazy-loaded images that reached the viewport which were not done
4831   // loading when they did so.
4832   uint32_t mLazyLoadImageReachViewportLoading;
4833   // Number of lazy-loaded images that reached the viewport and were done
4834   // loading when they did so.
4835   uint32_t mLazyLoadImageReachViewportLoaded;
4836 
4837   uint32_t mContentEditableCount;
4838   EditingState mEditingState;
4839 
4840   // Compatibility mode
4841   nsCompatibility mCompatMode;
4842 
4843   // Our readyState
4844   ReadyState mReadyState;
4845 
4846   // Ancestor's loading state
4847   bool mAncestorIsLoading;
4848 
4849   // Our visibility state
4850   dom::VisibilityState mVisibilityState;
4851 
4852   enum Type {
4853     eUnknown,  // should never be used
4854     eHTML,
4855     eXHTML,
4856     eGenericXML,
4857     eSVG
4858   };
4859 
4860   Type mType;
4861 
4862   uint8_t mDefaultElementType;
4863 
4864   enum Tri { eTriUnset = 0, eTriFalse, eTriTrue };
4865 
4866   Tri mAllowXULXBL;
4867 
4868   bool mSkipDTDSecurityChecks;
4869 
4870   // The document's script global object, the object from which the
4871   // document can get its script context and scope. This is the
4872   // *inner* window object.
4873   nsCOMPtr<nsIScriptGlobalObject> mScriptGlobalObject;
4874 
4875   // If mIsStaticDocument is true, mOriginalDocument points to the original
4876   // document.
4877   RefPtr<Document> mOriginalDocument;
4878 
4879   // The bidi options for this document.  What this bitfield means is
4880   // defined in nsBidiUtils.h
4881   uint32_t mBidiOptions;
4882 
4883   // The sandbox flags on the document. These reflect the value of the sandbox
4884   // attribute of the associated IFRAME or CSP-protectable content, if existent.
4885   // These are set at load time and are immutable - see nsSandboxFlags.h for the
4886   // possible flags.
4887   uint32_t mSandboxFlags;
4888 
4889   // The embedder policy obtained from parsing the HTTP response header or from
4890   // our opener if this is the initial about:blank document.
4891   Maybe<nsILoadInfo::CrossOriginEmbedderPolicy> mEmbedderPolicy;
4892 
4893   nsCString mContentLanguage;
4894 
4895   // The channel that got passed to Document::StartDocumentLoad(), if any.
4896   nsCOMPtr<nsIChannel> mChannel;
4897 
4898   // The CSP for every load lives in the Client within the LoadInfo. For all
4899   // document-initiated subresource loads we can use that cached version of the
4900   // CSP so we do not have to deserialize the CSP from the Client all the time.
4901   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
4902   nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
4903 
4904  private:
4905   nsCString mContentType;
4906 
4907  protected:
4908   // The document's security info
4909   nsCOMPtr<nsISupports> mSecurityInfo;
4910 
4911   // The channel that failed to load and resulted in an error page.
4912   // This only applies to error pages. Might be null.
4913   nsCOMPtr<nsIChannel> mFailedChannel;
4914 
4915   // if this document is part of a multipart document,
4916   // the ID can be used to distinguish it from the other parts.
4917   uint32_t mPartID;
4918 
4919   // Cycle collector generation in which we're certain that this document
4920   // won't be collected
4921   uint32_t mMarkedCCGeneration;
4922 
4923   PresShell* mPresShell;
4924 
4925   nsCOMArray<nsINode> mSubtreeModifiedTargets;
4926   uint32_t mSubtreeModifiedDepth;
4927 
4928   // All images in process of being preloaded.  This is a hashtable so
4929   // we can remove them as the real image loads start; that way we
4930   // make sure to not keep the image load going when no one cares
4931   // about it anymore.
4932   nsRefPtrHashtable<nsURIHashKey, imgIRequest> mPreloadingImages;
4933 
4934   // A list of preconnects initiated by the preloader. This prevents
4935   // the same uri from being used more than once, and allows the dom
4936   // builder to not repeat the work of the preloader.
4937   nsTHashMap<nsURIHashKey, bool> mPreloadedPreconnects;
4938 
4939   // Current depth of picture elements from parser
4940   uint32_t mPreloadPictureDepth;
4941 
4942   // Set if we've found a URL for the current picture
4943   nsString mPreloadPictureFoundSource;
4944 
4945   // If we're an external resource document, this will be non-null and will
4946   // point to our "display document": the one that all resource lookups should
4947   // go to.
4948   RefPtr<Document> mDisplayDocument;
4949 
4950   uint32_t mEventsSuppressed;
4951 
4952   // Any XHR ChannelEventQueues that were suspended on this document while
4953   // events were suppressed.
4954   nsTArray<RefPtr<net::ChannelEventQueue>> mSuspendedQueues;
4955 
4956   // Any postMessage events that were suspended on this document while events
4957   // were suppressed.
4958   nsTArray<RefPtr<PostMessageEvent>> mSuspendedPostMessageEvents;
4959 
4960   RefPtr<EventListener> mSuppressedEventListener;
4961 
4962   /**
4963    * https://html.spec.whatwg.org/#ignore-destructive-writes-counter
4964    */
4965   uint32_t mIgnoreDestructiveWritesCounter;
4966 
4967   // Count of live static clones of this document.
4968   uint32_t mStaticCloneCount;
4969 
4970   // If the document is currently printing (or in print preview) this will point
4971   // to the current static clone of this document. This is weak since the clone
4972   // also has a reference to this document.
4973   WeakPtr<Document> mLatestStaticClone;
4974 
4975   // Array of nodes that have been blocked to prevent user tracking.
4976   // They most likely have had their nsIChannel canceled by the URL
4977   // classifier. (Safebrowsing)
4978   //
4979   // Weak nsINode pointers are used to allow nodes to disappear.
4980   nsTArray<nsWeakPtr> mBlockedNodesByClassifier;
4981 
4982   // Weak reference to mScriptGlobalObject QI:d to nsPIDOMWindow,
4983   // updated on every set of mScriptGlobalObject.
4984   nsPIDOMWindowInner* mWindow;
4985 
4986   nsCOMPtr<nsIDocumentEncoder> mCachedEncoder;
4987 
4988   FrameRequestManager mFrameRequestManager;
4989 
4990   // This object allows us to evict ourself from the back/forward cache.  The
4991   // pointer is non-null iff we're currently in the bfcache.
4992   nsIBFCacheEntry* mBFCacheEntry;
4993 
4994   // Our base target.
4995   nsString mBaseTarget;
4996 
4997   nsCOMPtr<nsIStructuredCloneContainer> mStateObjectContainer;
4998   nsCOMPtr<nsIVariant> mStateObjectCached;
4999 
5000   uint32_t mInSyncOperationCount;
5001 
5002   UniquePtr<dom::XPathEvaluator> mXPathEvaluator;
5003 
5004   nsTArray<RefPtr<AnonymousContent>> mAnonymousContents;
5005 
5006   uint32_t mBlockDOMContentLoaded;
5007 
5008   // Our live MediaQueryLists
5009   LinkedList<MediaQueryList> mDOMMediaQueryLists;
5010 
5011   // Array of observers
5012   nsTObserverArray<nsIDocumentObserver*> mObservers;
5013 
5014   // Flags for use counters used directly by this document.
5015   UseCounters mUseCounters;
5016   // Flags for use counters from resource documents, static clones,
5017   // and SVG images referenced by this document.  Those documents propagate
5018   // their use counters up to here, which then count towards the top-level
5019   // document's page use counters.
5020   UseCounters mChildDocumentUseCounters;
5021 
5022   // The CSS property use counters.
5023   UniquePtr<StyleUseCounters> mStyleUseCounters;
5024 
5025   // Whether we have initialized mShouldReportUseCounters and
5026   // mShouldSendPageUseCounters, and sent any needed message to the parent
5027   // process to indicate that use counter data will be sent at some later point.
5028   bool mUseCountersInitialized : 1;
5029 
5030   // Whether this document should report use counters.
5031   bool mShouldReportUseCounters : 1;
5032 
5033   // Whether this document should send page use counters.  Set to true after
5034   // we've called SendExpectPageUseCounters on the top-level WindowGlobal.
5035   bool mShouldSendPageUseCounters : 1;
5036 
5037   // Whether the user has interacted with the document or not:
5038   bool mUserHasInteracted;
5039 
5040   // We constantly update the user-interaction anti-tracking permission at any
5041   // user-interaction using a timer. This boolean value is set to true when this
5042   // timer is scheduled.
5043   bool mHasUserInteractionTimerScheduled;
5044 
5045   TimeStamp mPageUnloadingEventTimeStamp;
5046 
5047   RefPtr<DocGroup> mDocGroup;
5048 
5049   RefPtr<nsCommandManager> mMidasCommandManager;
5050 
5051   // The set of all the tracking script URLs.  URLs are added to this set by
5052   // calling NoteScriptTrackingStatus().  Currently we assume that a URL not
5053   // existing in the set means the corresponding script isn't a tracking script.
5054   nsTHashSet<nsCString> mTrackingScripts;
5055 
5056   // Pointer to our parser if we're currently in the process of being
5057   // parsed into.
5058   nsCOMPtr<nsIParser> mParser;
5059 
5060   // If the document was created from the the prototype cache there will be a
5061   // reference to the prototype document to allow tracing.
5062   RefPtr<nsXULPrototypeDocument> mPrototypeDocument;
5063 
5064   nsrefcnt mStackRefCnt;
5065 
5066   // Weak reference to our sink for in case we no longer have a parser.  This
5067   // will allow us to flush out any pending stuff from the sink even if
5068   // EndLoad() has already happened.
5069   nsWeakPtr mWeakSink;
5070 
5071   // Our update nesting level
5072   uint32_t mUpdateNestLevel;
5073 
5074   // HTTPS-Only Mode Status
5075   // Constants are defined at nsILoadInfo::HTTPS_ONLY_*
5076   uint32_t mHttpsOnlyStatus;
5077 
5078   enum ViewportType : uint8_t {
5079     DisplayWidthHeight,
5080     Specified,
5081     Unknown,
5082   };
5083 
5084   ViewportType mViewportType;
5085 
5086   // viewport-fit described by
5087   // https://drafts.csswg.org/css-round-display/#viewport-fit-descriptor
5088   ViewportFitType mViewportFit;
5089 
5090   PLDHashTable* mSubDocuments;
5091 
5092   class HeaderData;
5093   UniquePtr<HeaderData> mHeaderData;
5094 
5095   // For determining if this is a flash document which should be
5096   // blocked based on its principal.
5097   FlashClassification mFlashClassification;
5098 
5099   // Do not use this value directly. Call the |IsThirdPartyForFlashClassifier()|
5100   // method, which caches its result here.
5101   Maybe<bool> mIsThirdPartyForFlashClassifier;
5102 
5103   nsRevocableEventPtr<nsRunnableMethod<Document, void, false>>
5104       mPendingTitleChangeEvent;
5105 
5106   RefPtr<nsDOMNavigationTiming> mTiming;
5107 
5108   // Recorded time of change to 'loading' state.
5109   TimeStamp mLoadingTimeStamp;
5110 
5111   nsWeakPtr mAutoFocusElement;
5112 
5113   nsCString mScrollToRef;
5114 
5115   // Weak reference to the scope object (aka the script global object)
5116   // that, unlike mScriptGlobalObject, is never unset once set. This
5117   // is a weak reference to avoid leaks due to circular references.
5118   nsWeakPtr mScopeObject;
5119 
5120   // Array of intersection observers
5121   nsTHashSet<DOMIntersectionObserver*> mIntersectionObservers;
5122 
5123   RefPtr<DOMIntersectionObserver> mLazyLoadImageObserver;
5124   // Used to measure how effective the lazyload thresholds are.
5125   RefPtr<DOMIntersectionObserver> mLazyLoadImageObserverViewport;
5126 
5127   // Stack of top layer elements.
5128   nsTArray<nsWeakPtr> mTopLayer;
5129 
5130   // The root of the doc tree in which this document is in. This is only
5131   // non-null when this document is in fullscreen mode.
5132   nsWeakPtr mFullscreenRoot;
5133 
5134   RefPtr<DOMImplementation> mDOMImplementation;
5135 
5136   RefPtr<nsContentList> mImageMaps;
5137 
5138   // A set of responsive images keyed by address pointer.
5139   nsTHashSet<HTMLImageElement*> mResponsiveContent;
5140 
5141   RefPtr<DocumentTimeline> mDocumentTimeline;
5142   LinkedList<DocumentTimeline> mTimelines;
5143 
5144   RefPtr<dom::ScriptLoader> mScriptLoader;
5145 
5146   // Tracker for animations that are waiting to start.
5147   // nullptr until GetOrCreatePendingAnimationTracker is called.
5148   RefPtr<PendingAnimationTracker> mPendingAnimationTracker;
5149 
5150   // A document "without a browsing context" that owns the content of
5151   // HTMLTemplateElement.
5152   RefPtr<Document> mTemplateContentsOwner;
5153 
5154   dom::ExternalResourceMap mExternalResourceMap;
5155 
5156   // ScreenOrientation "pending promise" as described by
5157   // http://www.w3.org/TR/screen-orientation/
5158   RefPtr<Promise> mOrientationPendingPromise;
5159 
5160   nsTArray<RefPtr<nsFrameLoader>> mInitializableFrameLoaders;
5161   nsTArray<nsCOMPtr<nsIRunnable>> mFrameLoaderFinalizers;
5162   RefPtr<nsRunnableMethod<Document>> mFrameLoaderRunner;
5163 
5164   nsTArray<PendingFrameStaticClone> mPendingFrameStaticClones;
5165 
5166   // The layout history state that should be used by nodes in this
5167   // document.  We only actually store a pointer to it when:
5168   // 1)  We have no script global object.
5169   // 2)  We haven't had Destroy() called on us yet.
5170   nsCOMPtr<nsILayoutHistoryState> mLayoutHistoryState;
5171 
5172   // The parsed viewport metadata of the last modified <meta name=viewport>
5173   // element.
5174   UniquePtr<ViewportMetaData> mLastModifiedViewportMetaData;
5175 
5176   // A tree ordered list of all color-scheme meta tags in this document.
5177   //
5178   // TODO(emilio): There are other meta tags in the spec that have a similar
5179   // processing model to color-scheme. We could store all in-document meta tags
5180   // here to get sane and fast <meta> element processing.
5181   TreeOrderedArray<HTMLMetaElement> mColorSchemeMetaTags;
5182 
5183   // These member variables cache information about the viewport so we don't
5184   // have to recalculate it each time.
5185   LayoutDeviceToScreenScale mScaleMinFloat;
5186   LayoutDeviceToScreenScale mScaleMaxFloat;
5187   LayoutDeviceToScreenScale mScaleFloat;
5188   CSSToLayoutDeviceScale mPixelRatio;
5189 
5190   CSSCoord mMinWidth;
5191   CSSCoord mMaxWidth;
5192   CSSCoord mMinHeight;
5193   CSSCoord mMaxHeight;
5194 
5195   RefPtr<EventListenerManager> mListenerManager;
5196 
5197   nsCOMPtr<nsIRequest> mOnloadBlocker;
5198 
5199   // Gecko-internal sheets used for extensions and such.
5200   // Exposed to privileged script via nsIDOMWindowUtils.loadSheet.
5201   nsTArray<RefPtr<StyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];
5202 
5203   // Member to store out last-selected stylesheet set.
5204   nsString mLastStyleSheetSet;
5205   nsString mPreferredStyleSheetSet;
5206 
5207   RefPtr<DOMStyleSheetSetList> mStyleSheetSetList;
5208 
5209   // We lazily calculate declaration blocks for SVG elements with mapped
5210   // attributes in Servo mode. This list contains all elements which need lazy
5211   // resolution.
5212   nsTHashSet<SVGElement*> mLazySVGPresElements;
5213 
5214   nsTHashSet<RefPtr<nsAtom>> mLanguagesUsed;
5215 
5216   // TODO(emilio): Is this hot enough to warrant to be cached?
5217   RefPtr<nsAtom> mLanguageFromCharset;
5218 
5219   // Restyle root for servo's style system.
5220   //
5221   // We store this as an nsINode, rather than as an Element, so that we can
5222   // store the Document node as the restyle root if the entire document (along
5223   // with all document-level native-anonymous content) needs to be restyled.
5224   //
5225   // We also track which "descendant" bits (normal/animation-only/lazy-fc) the
5226   // root corresponds to.
5227   nsCOMPtr<nsINode> mServoRestyleRoot;
5228   uint32_t mServoRestyleRootDirtyBits;
5229 
5230   // Used in conjunction with the create-an-element-for-the-token algorithm to
5231   // prevent custom element constructors from being able to use document.open(),
5232   // document.close(), and document.write() when they are invoked by the parser.
5233   uint32_t mThrowOnDynamicMarkupInsertionCounter;
5234 
5235   // Count of unload/beforeunload/pagehide operations in progress.
5236   uint32_t mIgnoreOpensDuringUnloadCounter;
5237 
5238   nsCOMPtr<nsIDOMXULCommandDispatcher>
5239       mCommandDispatcher;  // [OWNER] of the focus tracker
5240 
5241   RefPtr<XULBroadcastManager> mXULBroadcastManager;
5242   RefPtr<XULPersist> mXULPersist;
5243   RefPtr<ChromeObserver> mChromeObserver;
5244 
5245   RefPtr<HTMLAllCollection> mAll;
5246 
5247   nsTHashSet<RefPtr<WorkerDocumentListener>> mWorkerListeners;
5248 
5249   // Pres shell resolution saved before entering fullscreen mode.
5250   float mSavedResolution;
5251 
5252   // Pres shell resolution saved before creating a MobileViewportManager.
5253   float mSavedResolutionBeforeMVM;
5254 
5255   nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
5256 
5257   bool mHasStoragePermission;
5258 
5259   // Document generation. Gets incremented everytime it changes.
5260   int32_t mGeneration;
5261 
5262   // Cached TabSizes values for the document.
5263   int32_t mCachedTabSizeGeneration;
5264   nsTabSizes mCachedTabSizes;
5265 
5266   // This is equal to document's principal but with an isolation key. See
5267   // StoragePrincipalHelper.h to know more.
5268   nsCOMPtr<nsIPrincipal> mPartitionedPrincipal;
5269 
5270   // The cached storage principal for this document.
5271   // This is mutable so that we can keep EffectiveStoragePrincipal() const
5272   // which is required due to its CloneDocHelper() call site.  :-(
5273   mutable nsCOMPtr<nsIPrincipal> mActiveStoragePrincipal;
5274 
5275   // See GetNextFormNumber and GetNextControlNumber.
5276   int32_t mNextFormNumber;
5277   int32_t mNextControlNumber;
5278 
5279   uint32_t mMediaElementWithMSECount = 0;
5280 
5281   // Scope preloads per document.  This is used by speculative loading as well.
5282   PreloadService mPreloadService;
5283 
5284   // See NotifyFetchOrXHRSuccess and SetNotifyFetchSuccess.
5285   bool mShouldNotifyFetchSuccess;
5286 
5287   // See SetNotifyFormOrPasswordRemoved and ShouldNotifyFormOrPasswordRemoved.
5288   bool mShouldNotifyFormOrPasswordRemoved;
5289 
5290   // Accumulate JS telemetry collected
5291   void AccumulateJSTelemetry();
5292 
5293   // Accumulate page load metrics
5294   void AccumulatePageLoadTelemetry();
5295 
5296   // The OOP counterpart to nsDocLoader::mChildrenInOnload.
5297   // Not holding strong refs here since we don't actually use the BBCs.
5298   nsTArray<const BrowserBridgeChild*> mOOPChildrenLoading;
5299 
5300  public:
5301   // Needs to be public because the bindings code pokes at it.
5302   JS::ExpandoAndGeneration mExpandoAndGeneration;
5303 
5304   bool HasPendingInitialTranslation();
5305 
5306   nsRefPtrHashtable<nsRefPtrHashKey<Element>, nsXULPrototypeElement>
5307       mL10nProtoElements;
5308 
GetSavedResolutionBeforeMVM()5309   float GetSavedResolutionBeforeMVM() { return mSavedResolutionBeforeMVM; }
SetSavedResolutionBeforeMVM(float aResolution)5310   void SetSavedResolutionBeforeMVM(float aResolution) {
5311     mSavedResolutionBeforeMVM = aResolution;
5312   }
5313 
5314   void LoadEventFired();
5315 };
5316 
NS_DEFINE_STATIC_IID_ACCESSOR(Document,NS_IDOCUMENT_IID)5317 NS_DEFINE_STATIC_IID_ACCESSOR(Document, NS_IDOCUMENT_IID)
5318 
5319 /**
5320  * mozAutoSubtreeModified batches DOM mutations so that a DOMSubtreeModified
5321  * event is dispatched, if necessary, when the outermost mozAutoSubtreeModified
5322  * object is deleted.
5323  */
5324 class MOZ_STACK_CLASS mozAutoSubtreeModified {
5325  public:
5326   /**
5327    * @param aSubTreeOwner The document in which a subtree will be modified.
5328    * @param aTarget       The target of the possible DOMSubtreeModified event.
5329    *                      Can be nullptr, in which case mozAutoSubtreeModified
5330    *                      is just used to batch DOM mutations.
5331    */
5332   mozAutoSubtreeModified(Document* aSubtreeOwner, nsINode* aTarget) {
5333     UpdateTarget(aSubtreeOwner, aTarget);
5334   }
5335 
5336   ~mozAutoSubtreeModified() { UpdateTarget(nullptr, nullptr); }
5337 
5338   void UpdateTarget(Document* aSubtreeOwner, nsINode* aTarget) {
5339     if (mSubtreeOwner) {
5340       mSubtreeOwner->MutationEventDispatched(mTarget);
5341     }
5342 
5343     mTarget = aTarget;
5344     mSubtreeOwner = aSubtreeOwner;
5345     if (mSubtreeOwner) {
5346       mSubtreeOwner->WillDispatchMutationEvent(mTarget);
5347     }
5348   }
5349 
5350  private:
5351   nsCOMPtr<nsINode> mTarget;
5352   RefPtr<Document> mSubtreeOwner;
5353 };
5354 
5355 enum class SyncOperationBehavior { eSuspendInput, eAllowInput };
5356 
5357 class AutoWalkBrowsingContextGroup {
5358  public:
5359   virtual ~AutoWalkBrowsingContextGroup() = default;
5360 
5361  protected:
5362   void SuppressBrowsingContext(BrowsingContext* aContext);
5363   void SuppressBrowsingContextGroup(BrowsingContextGroup* aGroup);
UnsuppressDocuments()5364   void UnsuppressDocuments() {
5365     for (const auto& doc : mDocuments) {
5366       UnsuppressDocument(doc);
5367     }
5368   }
5369   virtual void SuppressDocument(Document* aDocument) = 0;
5370   virtual void UnsuppressDocument(Document* aDocument) = 0;
5371   AutoTArray<RefPtr<Document>, 16> mDocuments;
5372 };
5373 
5374 class MOZ_RAII nsAutoSyncOperation : private AutoWalkBrowsingContextGroup {
5375  public:
5376   explicit nsAutoSyncOperation(Document* aDocument,
5377                                SyncOperationBehavior aSyncBehavior);
5378   ~nsAutoSyncOperation();
5379 
5380  protected:
5381   void SuppressDocument(Document* aDocument) override;
5382   void UnsuppressDocument(Document* aDocument) override;
5383 
5384  private:
5385   uint32_t mMicroTaskLevel;
5386   const SyncOperationBehavior mSyncBehavior;
5387   RefPtr<BrowsingContext> mBrowsingContext;
5388 };
5389 
5390 class MOZ_RAII AutoSetThrowOnDynamicMarkupInsertionCounter final {
5391  public:
AutoSetThrowOnDynamicMarkupInsertionCounter(Document * aDocument)5392   explicit AutoSetThrowOnDynamicMarkupInsertionCounter(Document* aDocument)
5393       : mDocument(aDocument) {
5394     mDocument->IncrementThrowOnDynamicMarkupInsertionCounter();
5395   }
5396 
~AutoSetThrowOnDynamicMarkupInsertionCounter()5397   ~AutoSetThrowOnDynamicMarkupInsertionCounter() {
5398     mDocument->DecrementThrowOnDynamicMarkupInsertionCounter();
5399   }
5400 
5401  private:
5402   Document* mDocument;
5403 };
5404 
5405 class MOZ_RAII IgnoreOpensDuringUnload final {
5406  public:
IgnoreOpensDuringUnload(Document * aDoc)5407   explicit IgnoreOpensDuringUnload(Document* aDoc) : mDoc(aDoc) {
5408     mDoc->IncrementIgnoreOpensDuringUnloadCounter();
5409   }
5410 
~IgnoreOpensDuringUnload()5411   ~IgnoreOpensDuringUnload() {
5412     mDoc->DecrementIgnoreOpensDuringUnloadCounter();
5413   }
5414 
5415  private:
5416   Document* mDoc;
5417 };
5418 
5419 bool IsInActiveTab(Document* aDoc);
5420 
5421 }  // namespace dom
5422 }  // namespace mozilla
5423 
5424 // XXX These belong somewhere else
5425 nsresult NS_NewHTMLDocument(mozilla::dom::Document** aInstancePtrResult,
5426                             bool aLoadedAsData = false);
5427 
5428 nsresult NS_NewXMLDocument(mozilla::dom::Document** aInstancePtrResult,
5429                            bool aLoadedAsData = false,
5430                            bool aIsPlainDocument = false);
5431 
5432 nsresult NS_NewSVGDocument(mozilla::dom::Document** aInstancePtrResult);
5433 
5434 nsresult NS_NewImageDocument(mozilla::dom::Document** aInstancePtrResult);
5435 
5436 nsresult NS_NewVideoDocument(mozilla::dom::Document** aInstancePtrResult);
5437 
5438 // Enum for requesting a particular type of document when creating a doc
5439 enum DocumentFlavor {
5440   DocumentFlavorLegacyGuess,  // compat with old code until made HTML5-compliant
5441   DocumentFlavorHTML,         // HTMLDocument with HTMLness bit set to true
5442   DocumentFlavorSVG,          // SVGDocument
5443   DocumentFlavorXML,          // XMLDocument
5444   DocumentFlavorPlain,        // Just a Document
5445 };
5446 
5447 // Note: it's the caller's responsibility to create or get aPrincipal as needed
5448 // -- this method will not attempt to get a principal based on aDocumentURI.
5449 // Also, both aDocumentURI and aBaseURI must not be null.
5450 nsresult NS_NewDOMDocument(
5451     mozilla::dom::Document** aInstancePtrResult, const nsAString& aNamespaceURI,
5452     const nsAString& aQualifiedName, mozilla::dom::DocumentType* aDoctype,
5453     nsIURI* aDocumentURI, nsIURI* aBaseURI, nsIPrincipal* aPrincipal,
5454     bool aLoadedAsData, nsIGlobalObject* aEventObject, DocumentFlavor aFlavor);
5455 
5456 nsresult NS_NewPluginDocument(mozilla::dom::Document** aInstancePtrResult);
5457 
GetOwnerDocument()5458 inline mozilla::dom::Document* nsINode::GetOwnerDocument() const {
5459   mozilla::dom::Document* ownerDoc = OwnerDoc();
5460 
5461   return ownerDoc != this ? ownerDoc : nullptr;
5462 }
5463 
OwnerDocAsNode()5464 inline nsINode* nsINode::OwnerDocAsNode() const { return OwnerDoc(); }
5465 
AsDocument()5466 inline mozilla::dom::Document* nsINode::AsDocument() {
5467   MOZ_ASSERT(IsDocument());
5468   return static_cast<mozilla::dom::Document*>(this);
5469 }
5470 
AsDocument()5471 inline const mozilla::dom::Document* nsINode::AsDocument() const {
5472   MOZ_ASSERT(IsDocument());
5473   return static_cast<const mozilla::dom::Document*>(this);
5474 }
5475 
ToSupports(mozilla::dom::Document * aDoc)5476 inline nsISupports* ToSupports(mozilla::dom::Document* aDoc) {
5477   return static_cast<nsINode*>(aDoc);
5478 }
5479 
5480 #endif /* mozilla_dom_Document_h___ */
5481