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