Document.h 182 KB
Newer Older
1
2
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
4
5
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_dom_Document_h___
#define mozilla_dom_Document_h___
kipp's avatar
kipp committed
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
14
15
#include "nsCOMArray.h"           // for member
#include "nsCompatibility.h"      // for member
#include "nsCOMPtr.h"             // for member
16
#include "nsICookieJarSettings.h"
17
18
#include "nsGkAtoms.h"           // for static class members
#include "nsNameSpaceManager.h"  // for static class members
19
20
21
#include "nsIApplicationCache.h"
#include "nsIApplicationCacheContainer.h"
#include "nsIContentViewer.h"
22
#include "nsIDOMXULCommandDispatcher.h"
23
24
#include "nsIInterfaceRequestor.h"
#include "nsILoadContext.h"
25
26
#include "nsILoadGroup.h"  // for member (in nsCOMPtr)
#include "nsINode.h"       // for base class
27
#include "nsIParser.h"
28
29
#include "nsIChannelEventSink.h"
#include "nsIProgressEventSink.h"
30
31
#include "nsIRadioGroupContainer.h"
#include "nsIScriptObjectPrincipal.h"
32
33
#include "nsIScriptGlobalObject.h"   // for member (in nsCOMPtr)
#include "nsIURI.h"                  // for use in inline functions
34
35
36
37
#include "nsIWebProgressListener.h"  // for nsIWebProgressListener
#include "nsIWeakReferenceUtils.h"   // for nsWeakPtr
#include "nsPIDOMWindow.h"           // for use in inline functions
#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
48
#include "nsExpirationTracker.h"
#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
69
// windows.h #defines CreateEvent
#ifdef CreateEvent
70
#  undef CreateEvent
71
72
#endif

73
#ifdef MOZILLA_INTERNAL_API
74
#  include "mozilla/dom/DocumentBinding.h"
75
76
77
78
#else
namespace mozilla {
namespace dom {
class ElementCreationOptionsOrString;
79
80
81
}  // namespace dom
}  // namespace mozilla
#endif  // MOZILLA_INTERNAL_API
82

83
class gfxUserFontSet;
84
class imgIRequest;
85
class nsCachableElementsByNameNodeList;
86
class nsCommandManager;
87
class nsContentList;
88
class nsDocShell;
89
90
class nsDOMNavigationTiming;
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;
kipp's avatar
kipp committed
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
112
113
114
class nsIObjectLoadingContent;
class nsIObserver;
class nsIPrincipal;
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;
kipp's avatar
kipp committed
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
157
template <typename>
class OwningNonNull;
158
struct URLExtraData;
159

160
161
namespace css {
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
173
class ClientInfo;
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
226
class BrowsingContext;

227
228
template <typename>
class Sequence;
229

230
231
232
class nsDocumentOnStack;
class nsUnblockOnloadEvent;

233
234
template <typename, typename>
class CallbackObjectHolder;
235

236
237
enum class CallerType : uint32_t;

238
239
240
241
242
243
244
245
246
247
248
249
enum BFCacheStatus {
  NOT_ALLOWED = 1 << 0,                  // Status 0
  EVENT_HANDLING_SUPPRESSED = 1 << 1,    // Status 1
  SUSPENDED = 1 << 2,                    // Status 2
  UNLOAD_LISTENER = 1 << 3,              // Status 3
  REQUEST = 1 << 4,                      // Status 4
  ACTIVE_GET_USER_MEDIA = 1 << 5,        // Status 5
  ACTIVE_PEER_CONNECTION = 1 << 6,       // Status 6
  CONTAINS_EME_CONTENT = 1 << 7,         // Status 7
  CONTAINS_MSE_CONTENT = 1 << 8,         // Status 8
  HAS_ACTIVE_SPEECH_SYNTHESIS = 1 << 9,  // Status 9
  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
255
}  // namespace dom
}  // namespace mozilla
256

257
258
259
namespace mozilla {
namespace net {
class ChannelEventQueue;
260
261
}  // namespace net
}  // namespace mozilla
262

263
// Must be kept in sync with xpcom/rust/xpcom/src/interfaces/nonidl.rs
264
265
266
267
268
269
#define NS_IDOCUMENT_IID                             \
  {                                                  \
    0xce1f7627, 0x7109, 0x4977, {                    \
      0xba, 0x77, 0x49, 0x0f, 0xfd, 0xe0, 0x7a, 0xaa \
    }                                                \
  }
270

271
272
273
274
275
namespace mozilla {
namespace dom {

class Document;
class DOMStyleSheetSetList;
276
277
class ResizeObserver;
class ResizeObserverController;
278
class PostMessageEvent;
279

280
281
282
// Document states

// 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:
289
  DocHeaderData(nsAtom* aField, const nsAString& aData)
290
      : mField(aField), mData(aData), mNext(nullptr) {}
291

292
  ~DocHeaderData(void) { delete mNext; }
293
294
295

  RefPtr<nsAtom> mField;
  nsString mData;
296
  DocHeaderData* mNext;
297
298
};

299
class ExternalResourceMap {
300
  using SubDocEnumFunc = FunctionRef<CallState(Document&)>;
301

302
 public:
303
304
305
306
307
308
309
310
311
312
  /**
   * A class that represents an external resource load that has begun but
   * doesn't have a document yet.  Observers can be registered on this object,
   * and will be notified after the document is created.  Observers registered
   * after the document has been created will NOT be notified.  When observers
   * are notified, the subject will be the newly-created document, the topic
   * will be "external-resource-document-created", and the data will be null.
   * If document creation fails for some reason, observers will still be
   * notified, with a null document pointer.
   */
313
314
  class ExternalResourceLoad : public nsISupports {
   public:
315
    virtual ~ExternalResourceLoad() = default;
316

317
    void AddObserver(nsIObserver* aObserver) {
318
319
320
321
      MOZ_ASSERT(aObserver, "Must have observer");
      mObservers.AppendElement(aObserver);
    }

322
323
324
    const nsTArray<nsCOMPtr<nsIObserver>>& Observers() { return mObservers; }

   protected:
325
326
327
    AutoTArray<nsCOMPtr<nsIObserver>, 8> mObservers;
  };

328
  ExternalResourceMap();
329
330
331

  /**
   * Request an external resource document.  This does exactly what
332
   * Document::RequestExternalResource is documented to do.
333
   */
334
335
  Document* RequestResource(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
                            nsINode* aRequestingNode,
336
337
                            Document* aDisplayDocument,
                            ExternalResourceLoad** aPendingLoad);
338
339
340

  /**
   * Enumerate the resource documents.  See
341
   * Document::EnumerateExternalResources.
342
   */
343
  void EnumerateResources(SubDocEnumFunc aCallback);
344
345
346
347
348
349
350
351
352
353

  /**
   * Traverse ourselves for cycle-collection
   */
  void Traverse(nsCycleCollectionTraversalCallback* aCallback) const;

  /**
   * Shut ourselves down (used for cycle-collection unlink), as well
   * as for document destruction.
   */
354
  void Shutdown() {
355
356
357
358
359
    mPendingLoads.Clear();
    mMap.Clear();
    mHaveShutDown = true;
  }

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
367
368
369
370
371
372
373
374
375
    nsCOMPtr<nsIContentViewer> mViewer;
    nsCOMPtr<nsILoadGroup> mLoadGroup;
  };

  // Hide all our viewers
  void HideViewers();

  // Show all our viewers
  void ShowViewers();

376
377
 protected:
  class PendingLoad : public ExternalResourceLoad, public nsIStreamListener {
378
    ~PendingLoad() = default;
379

380
   public:
381
    explicit PendingLoad(Document* aDisplayDocument)
382
        : mDisplayDocument(aDisplayDocument) {}
383
384
385
386
387
388
389
390
391

    NS_DECL_ISUPPORTS
    NS_DECL_NSISTREAMLISTENER
    NS_DECL_NSIREQUESTOBSERVER

    /**
     * Start aURI loading.  This will perform the necessary security checks and
     * so forth.
     */
392
393
    nsresult StartLoad(nsIURI* aURI, nsIReferrerInfo* aReferrerInfo,
                       nsINode* aRequestingNode);
394
395
396
397
398
399
400
    /**
     * Set up an nsIContentViewer based on aRequest.  This is guaranteed to
     * put null in *aViewer and *aLoadGroup on all failures.
     */
    nsresult SetupViewer(nsIRequest* aRequest, nsIContentViewer** aViewer,
                         nsILoadGroup** aLoadGroup);

401
   private:
402
    RefPtr<Document> mDisplayDocument;
403
404
405
406
407
    nsCOMPtr<nsIStreamListener> mTargetListener;
    nsCOMPtr<nsIURI> mURI;
  };
  friend class PendingLoad;

408
  class LoadgroupCallbacks final : public nsIInterfaceRequestor {
409
    ~LoadgroupCallbacks() = default;
410
411

   public:
412
    explicit LoadgroupCallbacks(nsIInterfaceRequestor* aOtherCallbacks)
413
        : mCallbacks(aOtherCallbacks) {}
414
415
    NS_DECL_ISUPPORTS
    NS_DECL_NSIINTERFACEREQUESTOR
416
   private:
417
418
419
420
421
422
423
424
425
426
427
    // The only reason it's safe to hold a strong ref here without leaking is
    // that the notificationCallbacks on a loadgroup aren't the docshell itself
    // but a shim that holds a weak reference to the docshell.
    nsCOMPtr<nsIInterfaceRequestor> mCallbacks;

    // Use shims for interfaces that docshell implements directly so that we
    // don't hand out references to the docshell.  The shims should all allow
    // getInterface back on us, but other than that each one should only
    // implement one interface.

    // XXXbz I wish we could just derive the _allcaps thing from _i
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
#define DECL_SHIM(_i, _allcaps)                                    \
  class _i##Shim final : public nsIInterfaceRequestor, public _i { \
    ~_i##Shim() {}                                                 \
                                                                   \
   public:                                                         \
    _i##Shim(nsIInterfaceRequestor* aIfreq, _i* aRealPtr)          \
        : mIfReq(aIfreq), mRealPtr(aRealPtr) {                     \
      NS_ASSERTION(mIfReq, "Expected non-null here");              \
      NS_ASSERTION(mRealPtr, "Expected non-null here");            \
    }                                                              \
    NS_DECL_ISUPPORTS                                              \
    NS_FORWARD_NSIINTERFACEREQUESTOR(mIfReq->)                     \
    NS_FORWARD_##_allcaps(mRealPtr->) private                      \
        : nsCOMPtr<nsIInterfaceRequestor> mIfReq;                  \
    nsCOMPtr<_i> mRealPtr;                                         \
  };
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

    DECL_SHIM(nsILoadContext, NSILOADCONTEXT)
    DECL_SHIM(nsIProgressEventSink, NSIPROGRESSEVENTSINK)
    DECL_SHIM(nsIChannelEventSink, NSICHANNELEVENTSINK)
    DECL_SHIM(nsIApplicationCacheContainer, NSIAPPLICATIONCACHECONTAINER)
#undef DECL_SHIM
  };

  /**
   * Add an ExternalResource for aURI.  aViewer and aLoadGroup might be null
   * when this is called if the URI didn't result in an XML document.  This
   * function makes sure to remove the pending load for aURI, if any, from our
   * hashtable, and to notify its observers, if any.
   */
  nsresult AddExternalResource(nsIURI* aURI, nsIContentViewer* aViewer,
                               nsILoadGroup* aLoadGroup,
460
                               Document* aDisplayDocument);
461
462
463
464
465
466

  nsClassHashtable<nsURIHashKey, ExternalResource> mMap;
  nsRefPtrHashtable<nsURIHashKey, PendingLoad> mPendingLoads;
  bool mHaveShutDown;
};

kipp's avatar
kipp committed
467
468
//----------------------------------------------------------------------

469
470
// Document interface.  This is implemented by all document objects in
// Gecko.
471
472
473
474
475
476
477
class Document : public nsINode,
                 public DocumentOrShadowRoot,
                 public nsSupportsWeakReference,
                 public nsIRadioGroupContainer,
                 public nsIScriptObjectPrincipal,
                 public nsIApplicationCacheContainer,
                 public nsStubMutationObserver,
478
479
                 public DispatcherTrait,
                 public SupportsWeakPtr<Document> {
480
481
  friend class DocumentOrShadowRoot;

482
 protected:
483
484
  explicit Document(const char* aContentType);
  virtual ~Document();
485

486
487
  Document(const Document&) = delete;
  Document& operator=(const Document&) = delete;
488

489
 public:
490
  typedef dom::ExternalResourceMap::ExternalResourceLoad ExternalResourceLoad;
491
  typedef dom::ReferrerPolicy ReferrerPolicyEnum;
492
493
  using AdoptedStyleSheetCloneCache =
      nsRefPtrHashtable<nsPtrHashKey<const StyleSheet>, StyleSheet>;
494

495
496
497
498
  // nsINode overrides the new operator for DOM Arena allocation.
  // to use the default one, we need to bring it back again
  void* operator new(size_t aSize) { return ::operator new(aSize); }

499
500
501
502
503
  /**
   * Called when XPCOM shutdown.
   */
  static void Shutdown();

504
505
  MOZ_DECLARE_WEAKREFERENCE_TYPENAME(Document)

506
  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IDOCUMENT_IID)
507
508

  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
509

510
511
  NS_DECL_ADDSIZEOFEXCLUDINGTHIS

512
  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Document,
513
514
                                                                   nsINode)

515
516
517
518
519
520
#define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_)                          \
  do {                                                                        \
    NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers, nsIDocumentObserver, \
                                             func_, params_);                 \
    /* FIXME(emilio): Apparently we can keep observing from the BFCache? That \
       looks bogus. */                                                        \
521
522
    if (PresShell* presShell = GetObservingPresShell()) {                     \
      presShell->func_ params_;                                               \
523
524
525
    }                                                                         \
  } while (0)

526
527
528
529
530
531
532
533
534
535
  // nsIApplicationCacheContainer
  NS_DECL_NSIAPPLICATIONCACHECONTAINER

  // nsIRadioGroupContainer
  NS_IMETHOD WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor,
                            bool aFlushContent) final {
    return DocumentOrShadowRoot::WalkRadioGroup(aName, aVisitor, aFlushContent);
  }

  void SetCurrentRadioButton(const nsAString& aName,
536
                             HTMLInputElement* aRadio) final {
537
538
539
    DocumentOrShadowRoot::SetCurrentRadioButton(aName, aRadio);
  }

540
  HTMLInputElement* GetCurrentRadioButton(const nsAString& aName) final {
541
542
543
544
545
    return DocumentOrShadowRoot::GetCurrentRadioButton(aName);
  }

  NS_IMETHOD
  GetNextRadioButton(const nsAString& aName, const bool aPrevious,
546
547
                     HTMLInputElement* aFocusedRadio,
                     HTMLInputElement** aRadioOut) final {
548
549
550
    return DocumentOrShadowRoot::GetNextRadioButton(aName, aPrevious,
                                                    aFocusedRadio, aRadioOut);
  }
551
  void AddToRadioGroup(const nsAString& aName, HTMLInputElement* aRadio) final {
552
553
554
    DocumentOrShadowRoot::AddToRadioGroup(aName, aRadio);
  }
  void RemoveFromRadioGroup(const nsAString& aName,
555
                            HTMLInputElement* aRadio) final {
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
    DocumentOrShadowRoot::RemoveFromRadioGroup(aName, aRadio);
  }
  uint32_t GetRequiredRadioCount(const nsAString& aName) const final {
    return DocumentOrShadowRoot::GetRequiredRadioCount(aName);
  }
  void RadioRequiredWillChange(const nsAString& aName,
                               bool aRequiredAdded) final {
    DocumentOrShadowRoot::RadioRequiredWillChange(aName, aRequiredAdded);
  }
  bool GetValueMissingState(const nsAString& aName) const final {
    return DocumentOrShadowRoot::GetValueMissingState(aName);
  }
  void SetValueMissingState(const nsAString& aName, bool aValue) final {
    return DocumentOrShadowRoot::SetValueMissingState(aName, aValue);
  }

572
573
  nsIPrincipal* EffectiveStoragePrincipal() const;

574
575
576
  // nsIScriptObjectPrincipal
  nsIPrincipal* GetPrincipal() final { return NodePrincipal(); }

577
578
579
580
  nsIPrincipal* GetEffectiveStoragePrincipal() final {
    return EffectiveStoragePrincipal();
  }

581
582
583
584
  // You should probably not be using this function, since it performs no
  // checks to ensure that the intrinsic storage principal should really be
  // used here.  It is only designed to be used in very specific circumstances,
  // such as when inheriting the document/storage principal.
585
  nsIPrincipal* IntrinsicStoragePrincipal() final {
586
587
588
    return mIntrinsicStoragePrincipal;
  }

589
590
  void ClearActiveStoragePrincipal() { mActiveStoragePrincipal = nullptr; }

591
592
593
594
  nsIPrincipal* GetContentBlockingAllowListPrincipal() const {
    return mContentBlockingAllowListPrincipal;
  }

595
  // EventTarget
596
597
598
  void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
  EventListenerManager* GetOrCreateListenerManager() override;
  EventListenerManager* GetExistingListenerManager() const override;
599

600
601
  // This helper class must be set when we dispatch beforeunload and unload
  // events in order to avoid unterminate sync XHRs.
602
  class MOZ_RAII PageUnloadingEventTimeStamp {
603
    RefPtr<Document> mDocument;
604
605
    bool mSet;

606
   public:
607
    explicit PageUnloadingEventTimeStamp(Document* aDocument)
608
        : mDocument(aDocument), mSet(false) {
609
610
611
612
613
614
615
      MOZ_ASSERT(aDocument);
      if (mDocument->mPageUnloadingEventTimeStamp.IsNull()) {
        mDocument->SetPageUnloadingEventTimeStamp();
        mSet = true;
      }
    }

616
    ~PageUnloadingEventTimeStamp() {
617
618
619
620
621
622
      if (mSet) {
        mDocument->CleanUnloadEventsTimeStamp();
      }
    }
  };

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
628
   * @param aChannel The channel the data will come from. The channel must be
   *                 able to report its Content-Type.
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
   * @param aLoadGroup The loadgroup this document should use from now on.
   *                   Note that the document might not be the only thing using
   *                   this loadgroup.
   * @param aContainer The container this document is in.  This may be null.
   *                   XXXbz maybe we should make it more explicit (eg make the
   *                   container an nsIWebNavigation or nsIDocShell or
   *                   something)?
   * @param [out] aDocListener the listener to pump data from the channel into.
   *                           Generally this will be the parser this document
   *                           sets up, or some sort of data-handler for media
   *                           documents.
   * @param aReset whether the document should call Reset() on itself.  If this
   *               is false, the document will NOT set its principal to the
   *               channel's owner, will not clear any event listeners that are
   *               already set on it, etc.
   * @param aSink The content sink to use for the data.  If this is null and
   *              the document needs a content sink, it will create one based
   *              on whatever it knows about the data it's going to load.
647
648
649
   *              This MUST be null if the underlying document is an HTML
   *              document. Even in the XML case, please don't add new calls
   *              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
654
   * sure this happens is the responsibility of the caller of
   * StartDocumentLoad().
655
656
657
   *
   * This function has an implementation, and does some setup, but does NOT set
   * *aDocListener; this is the job of subclasses.
658
   */
659
  virtual nsresult StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
660
661
                                     nsILoadGroup* aLoadGroup,
                                     nsISupports* aContainer,
662
                                     nsIStreamListener** aDocListener,
663
                                     bool aReset,
664
                                     nsIContentSink* aSink = nullptr) = 0;
665
  void StopDocumentLoad();
666

667
668
669
  virtual void SetSuppressParserErrorElement(bool aSuppress) {}
  virtual bool SuppressParserErrorElement() { return false; }

670
671
672
  virtual void SetSuppressParserErrorConsoleMessages(bool aSuppress) {}
  virtual bool SuppressParserErrorConsoleMessages() { return false; }

673
674
675
676
677
  // nsINode
  bool IsNodeOfType(uint32_t aFlags) const final;
  nsresult InsertChildBefore(nsIContent* aKid, nsIContent* aBeforeThis,
                             bool aNotify) override;
  void RemoveChildNode(nsIContent* aKid, bool aNotify) final;
678
  nsresult Clone(dom::NodeInfo* aNodeInfo, nsINode** aResult) const override {
679
680
    return NS_ERROR_NOT_IMPLEMENTED;
  }
681
  nsresult CloneDocHelper(Document* clone) const;
682

683
684
  Document* GetLatestStaticClone() const { return mLatestStaticClone; }

kipp's avatar
kipp committed
685
  /**
686
   * Signal that the document title may have changed
687
   * (see Document::GetTitle).
688
689
   * @param aBoundTitleElement true if an HTML or SVG <title> element
   * has just been bound to the document.
kipp's avatar
kipp committed
690
   */
691
  virtual void NotifyPossibleTitleChange(bool aBoundTitleElement);
692

kipp's avatar
kipp committed
693
  /**
694
695
696
   * Return the URI for the document. May return null.  If it ever stops being
   * able to return null, we can make sure nsINode::GetBaseURI/GetBaseURIObject
   * 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
701
702
703
   * instance as a result of the user navigating to a fragment identifier on
   * the page, or as a result to a call to pushState() or replaceState().
   *
   * https://html.spec.whatwg.org/multipage/dom.html#the-document%27s-address
kipp's avatar
kipp committed
704
   */
705
  nsIURI* GetDocumentURI() const { return mDocumentURI; }
706
707

  /**
708
   * Return the original URI of the document.  This is the same as the
709
710
711
712
713
714
   * document's URI unless that has changed from its original value (for
   * example, due to history.pushState() or replaceState() being invoked on the
   * document).
   *
   * This method corresponds to the "creation URL" in HTML5 and, once set,
   * doesn't change over the lifetime of the document.
715
   *
716
   * https://html.spec.whatwg.org/multipage/webappapis.html#creation-url
717
   */
718
  nsIURI* GetOriginalURI() const { return mOriginalURI; }
719

720
721
722
723
724
725
726
  /**
   * Return the base domain of the document.  This has been computed using
   * mozIThirdPartyUtil::GetBaseDomain() and can be used for third-party
   * checks.  When the URI of the document changes, this value is recomputed.
   */
  nsCString GetBaseDomain() const { return mBaseDomain; }

727
728
729
  /**
   * Set the URI for the document.  This also sets the document's original URI,
   * if it's null.
730
   */
731
  void SetDocumentURI(nsIURI* aURI);
kipp's avatar
kipp committed
732

733
734
735
736
  /**
   * Set the URI for the document loaded via XHR, when accessed from
   * chrome privileged script.
   */
737
  void SetChromeXHRDocURI(nsIURI* aURI) { mChromeXHRDocURI = aURI; }
738
739
740
741
742

  /**
   * Set the base URI for the document loaded via XHR, when accessed from
   * chrome privileged script.
   */
743
  void SetChromeXHRDocBaseURI(nsIURI* aURI) { mChromeXHRDocBaseURI = aURI; }
744

745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
  /**
   * The CSP in general is stored in the ClientInfo, but we also cache
   * the CSP on the document so subresources loaded within a document
   * can query that cached CSP instead of having to deserialize the CSP
   * from the Client.
   *
   * Please note that at the time of CSP parsing the Client is not
   * available yet, hence we sync CSP of document and Client when the
   * Client becomes available within nsGlobalWindowInner::EnsureClientSource().
   */
  nsIContentSecurityPolicy* GetCsp() const;
  void SetCsp(nsIContentSecurityPolicy* aCSP);

  nsIContentSecurityPolicy* GetPreloadCsp() const;
  void SetPreloadCsp(nsIContentSecurityPolicy* aPreloadCSP);

  void GetCspJSON(nsString& aJSON);

763
764
765
  /**
   * Set referrer policy and upgrade-insecure-requests flags
   */
766
  void ApplySettingsFromCSP(bool aSpeculative);
767

768
  already_AddRefed<nsIParser> CreatorParserOrNull() {
769
770
771
    nsCOMPtr<nsIParser> parser = mParser;
    return parser.forget();
  }
772

773
774
775
776
777
778
779
780
781
782
  /**
   * ReferrerInfo getter for Document.webidl.
   */
  nsIReferrerInfo* ReferrerInfo() const { return GetReferrerInfo(); }

  nsIReferrerInfo* GetReferrerInfo() const { return mReferrerInfo; }

  nsIReferrerInfo* GetPreloadReferrerInfo() const {
    return mPreloadReferrerInfo;
  }
783
784
785
  /**
   * Return the referrer policy of the document. Return "default" if there's no
   * 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
792
  /**
   * GetReferrerPolicy() for Document.webidl.
   */
793
  ReferrerPolicyEnum ReferrerPolicy() const { return GetReferrerPolicy(); }
794

795
796
797
798
799
  /**
   * If true, this flag indicates that all mixed content subresource
   * loads for this document (and also embeded browsing contexts) will
   * be blocked.
   */
800
  bool GetBlockAllMixedContent(bool aPreload) const {
801
802
803
804
805
806
    if (aPreload) {
      return mBlockAllMixedContentPreloads;
    }
    return mBlockAllMixedContent;
  }

807
808
809
810
811
812
813
  /**
   * If true, this flag indicates that all subresource loads for this
   * document need to be upgraded from http to https.
   * This flag becomes true if the CSP of the document itself, or any
   * of the document's ancestors up to the toplevel document makes use
   * of the CSP directive 'upgrade-insecure-requests'.
   */
814
  bool GetUpgradeInsecureRequests(bool aPreload) const {
815
816
817
    if (aPreload) {
      return mUpgradeInsecurePreloads;
    }
818
819
820
    return mUpgradeInsecureRequests;
  }

821
822
823
824
825
826
827
828
829
830
831
  void SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
    mReferrerInfo = aReferrerInfo;
  }

  /*
   * Referrer policy from <meta name="referrer" content=`policy`>
   * will have higher priority than referrer policy from Referrer-Policy
   * header. So override the old ReferrerInfo if we get one from meta
   */
  void UpdateReferrerInfoFromMeta(const nsAString& aMetaReferrer,
                                  bool aPreload) {
832
    ReferrerPolicyEnum policy =
833
        ReferrerInfo::ReferrerPolicyFromMetaString(aMetaReferrer);
834
835
    // The empty string "" corresponds to no referrer policy, causing a fallback
    // to a referrer policy defined elsewhere.
836
    if (policy == ReferrerPolicy::_empty) {
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
      return;
    }

    MOZ_ASSERT(mReferrerInfo);
    MOZ_ASSERT(mPreloadReferrerInfo);

    if (aPreload) {
      mPreloadReferrerInfo =
          static_cast<mozilla::dom::ReferrerInfo*>((mPreloadReferrerInfo).get())
              ->CloneWithNewPolicy(policy);
    } else {
      mReferrerInfo =
          static_cast<mozilla::dom::ReferrerInfo*>((mReferrerInfo).get())
              ->CloneWithNewPolicy(policy);
    }
  }
853

854
  /**
855
856
   * Set the principals responsible for this document.  Chances are, you do not
   * want to be using this.
857
   */
858
  void SetPrincipals(nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal);
859

860
861
862
863
864
865
866
867
  /**
   * Get the list of ancestor principals for a document.  This is the same as
   * the ancestor list for the document's docshell the last time SetContainer()
   * was called with a non-null argument. See the documentation for the
   * corresponding getter in docshell for how this list is determined.  We store
   * a copy of the list, because we may lose the ability to reach our docshell
   * before people stop asking us for this information.
   */
868
  const nsTArray<nsCOMPtr<nsIPrincipal>>& AncestorPrincipals() const {
869
870
871
    return mAncestorPrincipals;
  }

872
873
874
875
876
  /**
   * Returns true if exempt from HTTPS-Only Mode upgrade.
   */
  uint32_t HttpsOnlyStatus() const { return mHttpsOnlyStatus; }

877
878
879
880
  /**
   * Get the list of ancestor outerWindowIDs for a document that correspond to
   * the ancestor principals (see above for more details).
   */
881
  const nsTArray<uint64_t>& AncestorOuterWindowIDs() const {
882
883
884
    return mAncestorOuterWindowIDs;
  }

warren%netscape.com's avatar
warren%netscape.com committed
885
  /**
886
   * Return the LoadGroup for the document. May return null.
warren%netscape.com's avatar
warren%netscape.com committed
887
   */
Sylvestre Ledru's avatar