Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 143941e

Browse files
committed
Bug 1523638 - Part 9: Use provided 'WindowGlobalChild' actors to create the initial about:blank document, r=kmag
Differential Revision: https://phabricator.services.mozilla.com/D37656 --HG-- extra : moz-landing-system : lando
1 parent 15f2abf commit 143941e

19 files changed

Lines changed: 169 additions & 62 deletions

docshell/base/nsDocShell.cpp

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,10 @@ static void DecreasePrivateDocShellCount() {
306306
}
307307
}
308308

309-
nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext)
309+
nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext,
310+
uint64_t aContentWindowID)
310311
: nsDocLoader(),
311-
mContentWindowID(nsContentUtils::GenerateWindowId()),
312+
mContentWindowID(aContentWindowID),
312313
mBrowsingContext(aBrowsingContext),
313314
mForcedCharset(nullptr),
314315
mParentCharset(nullptr),
@@ -394,6 +395,11 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext)
394395

395396
nsContentUtils::GenerateUUIDInPlace(mHistoryID);
396397

398+
// If no outer window ID was provided, generate a new one.
399+
if (aContentWindowID == 0) {
400+
mContentWindowID = nsContentUtils::GenerateWindowId();
401+
}
402+
397403
if (gDocShellCount++ == 0) {
398404
NS_ASSERTION(sURIFixup == nullptr,
399405
"Huh, sURIFixup not null in first nsDocShell ctor!");
@@ -460,11 +466,11 @@ nsDocShell::~nsDocShell() {
460466

461467
/* static */
462468
already_AddRefed<nsDocShell> nsDocShell::Create(
463-
BrowsingContext* aBrowsingContext) {
469+
BrowsingContext* aBrowsingContext, uint64_t aContentWindowID) {
464470
MOZ_ASSERT(aBrowsingContext, "DocShell without a BrowsingContext!");
465471

466472
nsresult rv;
467-
RefPtr<nsDocShell> ds = new nsDocShell(aBrowsingContext);
473+
RefPtr<nsDocShell> ds = new nsDocShell(aBrowsingContext, aContentWindowID);
468474

469475
// Initialize the underlying nsDocLoader.
470476
rv = ds->nsDocLoader::Init();
@@ -518,6 +524,7 @@ already_AddRefed<nsDocShell> nsDocShell::Create(
518524

519525
// Make |ds| the primary DocShell for the given context.
520526
aBrowsingContext->SetDocShell(ds);
527+
521528
return ds.forget();
522529
}
523530

@@ -6243,12 +6250,13 @@ nsresult nsDocShell::RefreshURIFromQueue() {
62436250
return NS_OK;
62446251
}
62456252

6246-
nsresult nsDocShell::Embed(nsIContentViewer* aContentViewer) {
6253+
nsresult nsDocShell::Embed(nsIContentViewer* aContentViewer,
6254+
WindowGlobalChild* aWindowActor) {
62476255
// Save the LayoutHistoryState of the previous document, before
62486256
// setting up new document
62496257
PersistLayoutHistoryState();
62506258

6251-
nsresult rv = SetupNewViewer(aContentViewer);
6259+
nsresult rv = SetupNewViewer(aContentViewer, aWindowActor);
62526260
NS_ENSURE_SUCCESS(rv, rv);
62536261

62546262
// XXX What if SetupNewViewer fails?
@@ -6884,6 +6892,7 @@ nsresult nsDocShell::EnsureContentViewer() {
68846892
nsCOMPtr<nsIURI> baseURI;
68856893
nsIPrincipal* principal = GetInheritedPrincipal(false);
68866894
nsIPrincipal* storagePrincipal = GetInheritedPrincipal(false, true);
6895+
68876896
nsCOMPtr<nsIDocShellTreeItem> parentItem;
68886897
GetInProcessSameTypeParent(getter_AddRefs(parentItem));
68896898
if (parentItem) {
@@ -6925,11 +6934,14 @@ nsresult nsDocShell::EnsureContentViewer() {
69256934
nsresult nsDocShell::CreateAboutBlankContentViewer(
69266935
nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal,
69276936
nsIContentSecurityPolicy* aCSP, nsIURI* aBaseURI,
6928-
bool aTryToSaveOldPresentation, bool aCheckPermitUnload) {
6937+
bool aTryToSaveOldPresentation, bool aCheckPermitUnload,
6938+
WindowGlobalChild* aActor) {
69296939
RefPtr<Document> blankDoc;
69306940
nsCOMPtr<nsIContentViewer> viewer;
69316941
nsresult rv = NS_ERROR_FAILURE;
69326942

6943+
MOZ_ASSERT_IF(aActor, aActor->DocumentPrincipal() == aPrincipal);
6944+
69336945
/* mCreatingDocument should never be true at this point. However, it's
69346946
a theoretical possibility. We want to know about it and make it stop,
69356947
and this sounds like a job for an assertion. */
@@ -7058,7 +7070,7 @@ nsresult nsDocShell::CreateAboutBlankContentViewer(
70587070
// hook 'em up
70597071
if (viewer) {
70607072
viewer->SetContainer(this);
7061-
rv = Embed(viewer);
7073+
rv = Embed(viewer, aActor);
70627074
NS_ENSURE_SUCCESS(rv, rv);
70637075

70647076
SetCurrentURI(blankDoc->GetDocumentURI(), nullptr, true, 0);
@@ -7088,6 +7100,32 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
70887100
nullptr);
70897101
}
70907102

7103+
nsresult nsDocShell::CreateContentViewerForActor(
7104+
WindowGlobalChild* aWindowActor) {
7105+
MOZ_ASSERT(aWindowActor);
7106+
7107+
// FIXME: WindowGlobalChild should provide the StoragePrincipal.
7108+
nsresult rv = CreateAboutBlankContentViewer(
7109+
aWindowActor->DocumentPrincipal(), aWindowActor->DocumentPrincipal(),
7110+
/* aCsp */ nullptr,
7111+
/* aBaseURI */ nullptr,
7112+
/* aTryToSaveOldPresentation */ true,
7113+
/* aCheckPermitUnload */ true, aWindowActor);
7114+
if (NS_SUCCEEDED(rv)) {
7115+
RefPtr<Document> doc(GetDocument());
7116+
MOZ_ASSERT(
7117+
doc,
7118+
"Should have a document if CreateAboutBlankContentViewer succeeded");
7119+
MOZ_ASSERT(doc->GetOwnerGlobal() == aWindowActor->WindowGlobal(),
7120+
"New document should be in the same global as our actor");
7121+
7122+
// FIXME: We may want to support non-initial documents here.
7123+
doc->SetIsInitialDocument(true);
7124+
}
7125+
7126+
return rv;
7127+
}
7128+
70917129
bool nsDocShell::CanSavePresentation(uint32_t aLoadType,
70927130
nsIRequest* aNewRequest,
70937131
Document* aNewDocument) {
@@ -8293,7 +8331,8 @@ nsresult nsDocShell::NewContentViewerObj(const nsACString& aContentType,
82938331
return NS_OK;
82948332
}
82958333

8296-
nsresult nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer) {
8334+
nsresult nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer,
8335+
WindowGlobalChild* aWindowActor) {
82978336
MOZ_ASSERT(!mIsBeingDestroyed);
82988337

82998338
//
@@ -8417,7 +8456,7 @@ nsresult nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer) {
84178456

84188457
mContentViewer->SetNavigationTiming(mTiming);
84198458

8420-
if (NS_FAILED(mContentViewer->Init(widget, bounds))) {
8459+
if (NS_FAILED(mContentViewer->Init(widget, bounds, aWindowActor))) {
84218460
mContentViewer = nullptr;
84228461
NS_WARNING("ContentViewer Initialization failed");
84238462
return NS_ERROR_FAILURE;

docshell/base/nsDocShell.h

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ class nsDocShell final : public nsDocLoader,
201201

202202
// Create a new nsDocShell object, initializing it.
203203
static already_AddRefed<nsDocShell> Create(
204-
mozilla::dom::BrowsingContext* aBrowsingContext);
204+
mozilla::dom::BrowsingContext* aBrowsingContext,
205+
uint64_t aContentWindowID = 0);
205206

206207
NS_IMETHOD Stop() override {
207208
// Need this here because otherwise nsIWebNavigation::Stop
@@ -470,6 +471,11 @@ class nsDocShell final : public nsDocLoader,
470471
mSkipBrowsingContextDetachOnDestroy = true;
471472
}
472473

474+
// Create a content viewer within this nsDocShell for the given
475+
// `WindowGlobalChild` actor.
476+
nsresult CreateContentViewerForActor(
477+
mozilla::dom::WindowGlobalChild* aWindowActor);
478+
473479
private: // member functions
474480
friend class nsDSURIContentListener;
475481
friend class FramingChecker;
@@ -494,7 +500,8 @@ class nsDocShell final : public nsDocLoader,
494500
friend void mozilla::TimelineConsumers::PopMarkers(
495501
nsDocShell*, JSContext*, nsTArray<dom::ProfileTimelineMarker>&);
496502

497-
explicit nsDocShell(mozilla::dom::BrowsingContext* aBrowsingContext);
503+
nsDocShell(mozilla::dom::BrowsingContext* aBrowsingContext,
504+
uint64_t aContentWindowID);
498505

499506
// Security checks to prevent frameset spoofing. See comments at
500507
// implementation sites.
@@ -548,12 +555,11 @@ class nsDocShell final : public nsDocLoader,
548555
// aPrincipal can be passed in if the caller wants. If null is
549556
// passed in, the about:blank principal will end up being used.
550557
// aCSP, if any, will be used for the new about:blank load.
551-
nsresult CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
552-
nsIPrincipal* aStoragePrincipal,
553-
nsIContentSecurityPolicy* aCSP,
554-
nsIURI* aBaseURI,
555-
bool aTryToSaveOldPresentation = true,
556-
bool aCheckPermitUnload = true);
558+
nsresult CreateAboutBlankContentViewer(
559+
nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal,
560+
nsIContentSecurityPolicy* aCSP, nsIURI* aBaseURI,
561+
bool aTryToSaveOldPresentation = true, bool aCheckPermitUnload = true,
562+
mozilla::dom::WindowGlobalChild* aActor = nullptr);
557563

558564
nsresult CreateContentViewer(const nsACString& aContentType,
559565
nsIRequest* aRequest,
@@ -564,7 +570,9 @@ class nsDocShell final : public nsDocLoader,
564570
nsIStreamListener** aContentHandler,
565571
nsIContentViewer** aViewer);
566572

567-
nsresult SetupNewViewer(nsIContentViewer* aNewViewer);
573+
nsresult SetupNewViewer(
574+
nsIContentViewer* aNewViewer,
575+
mozilla::dom::WindowGlobalChild* aWindowActor = nullptr);
568576

569577
//
570578
// Session History
@@ -977,7 +985,8 @@ class nsDocShell final : public nsDocLoader,
977985
nsresult EnsureFind();
978986
nsresult EnsureCommandHandler();
979987
nsresult RefreshURIFromQueue();
980-
nsresult Embed(nsIContentViewer* aContentViewer);
988+
nsresult Embed(nsIContentViewer* aContentViewer,
989+
mozilla::dom::WindowGlobalChild* aWindowActor = nullptr);
981990
nsPresContext* GetEldestPresContext();
982991
nsresult CheckLoadingPermissions();
983992
nsresult PersistLayoutHistoryState();

docshell/base/nsIContentViewer.idl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ class nsDOMNavigationTiming;
2121
namespace mozilla {
2222
class Encoding;
2323
class PresShell;
24-
}
24+
namespace dom {
25+
class WindowGlobalChild;
26+
} // namespace dom
27+
} // namespace mozilla
2528
%}
2629

2730
[ptr] native nsIWidgetPtr(nsIWidget);
@@ -32,12 +35,14 @@ class PresShell;
3235
[ref] native nsIContentViewerTArray(nsTArray<nsCOMPtr<nsIContentViewer> >);
3336
[ptr] native Encoding(const mozilla::Encoding);
3437
[ptr] native PresShellPtr(mozilla::PresShell);
38+
[ptr] native WindowGlobalChildPtr(mozilla::dom::WindowGlobalChild);
3539

3640
[scriptable, builtinclass, uuid(2da17016-7851-4a45-a7a8-00b360e01595)]
3741
interface nsIContentViewer : nsISupports
3842
{
3943
[noscript] void init(in nsIWidgetPtr aParentWidget,
40-
[const] in nsIntRectRef aBounds);
44+
[const] in nsIntRectRef aBounds,
45+
in WindowGlobalChildPtr aWindowActor);
4146

4247
attribute nsIDocShell container;
4348

dom/base/Document.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -843,7 +843,7 @@ nsresult ExternalResourceMap::AddExternalResource(nsIURI* aURI,
843843
// Make sure that hiding our viewer will tear down its presentation.
844844
aViewer->SetSticky(false);
845845

846-
rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0));
846+
rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0), nullptr);
847847
if (NS_SUCCEEDED(rv)) {
848848
rv = aViewer->Open(nullptr, nullptr);
849849
}

dom/base/nsGlobalWindowInner.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -839,8 +839,9 @@ class PromiseDocumentFlushedResolver final {
839839
//*** nsGlobalWindowInner: Object Management
840840
//*****************************************************************************
841841

842-
nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow)
843-
: nsPIDOMWindowInner(aOuterWindow),
842+
nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow,
843+
WindowGlobalChild* aActor)
844+
: nsPIDOMWindowInner(aOuterWindow, aActor),
844845
mozilla::webgpu::InstanceProvider(this),
845846
mWasOffline(false),
846847
mHasHadSlowScript(false),
@@ -1606,9 +1607,7 @@ void nsGlobalWindowInner::InnerSetNewDocument(JSContext* aCx,
16061607
// FIXME: Currently, devtools can crete a fallback webextension window global
16071608
// in the content process which does not have a corresponding BrowserChild
16081609
// actor. This means we have no actor to be our parent. (Bug 1498293)
1609-
MOZ_DIAGNOSTIC_ASSERT(!mWindowGlobalChild,
1610-
"Shouldn't have created WindowGlobalChild yet!");
1611-
if (XRE_IsParentProcess() || mBrowserChild) {
1610+
if (!mWindowGlobalChild && (XRE_IsParentProcess() || mBrowserChild)) {
16121611
mWindowGlobalChild = WindowGlobalChild::Create(this);
16131612
}
16141613

@@ -7107,13 +7106,19 @@ mozilla::dom::TabGroup* nsPIDOMWindowInner::TabGroup() {
71077106

71087107
/* static */
71097108
already_AddRefed<nsGlobalWindowInner> nsGlobalWindowInner::Create(
7110-
nsGlobalWindowOuter* aOuterWindow, bool aIsChrome) {
7111-
RefPtr<nsGlobalWindowInner> window = new nsGlobalWindowInner(aOuterWindow);
7109+
nsGlobalWindowOuter* aOuterWindow, bool aIsChrome,
7110+
WindowGlobalChild* aActor) {
7111+
RefPtr<nsGlobalWindowInner> window =
7112+
new nsGlobalWindowInner(aOuterWindow, aActor);
71127113
if (aIsChrome) {
71137114
window->mIsChrome = true;
71147115
window->mCleanMessageManager = true;
71157116
}
71167117

7118+
if (aActor) {
7119+
aActor->InitWindowGlobal(window);
7120+
}
7121+
71177122
window->InitWasOffline();
71187123
return window.forget();
71197124
}
@@ -7166,7 +7171,8 @@ bool nsPIDOMWindowInner::HasStorageAccessGranted(
71667171
return mStorageAccessGranted.Contains(aPermissionKey);
71677172
}
71687173

7169-
nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow)
7174+
nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow,
7175+
WindowGlobalChild* aActor)
71707176
: mMutationBits(0),
71717177
mActivePeerConnections(0),
71727178
mIsDocumentLoaded(false),
@@ -7178,15 +7184,24 @@ nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow)
71787184
mMayHavePointerEnterLeaveEventListener(false),
71797185
mMayHaveTextEventListenerInDefaultGroup(false),
71807186
mOuterWindow(aOuterWindow),
7181-
mWindowID(nsContentUtils::GenerateWindowId()),
7187+
mWindowID(0),
71827188
mHasNotifiedGlobalCreated(false),
71837189
mMarkedCCGeneration(0),
71847190
mHasTriedToCacheTopInnerWindow(false),
71857191
mNumOfIndexedDBDatabases(0),
71867192
mNumOfOpenWebSockets(0),
7187-
mEvent(nullptr) {
7193+
mEvent(nullptr),
7194+
mWindowGlobalChild(aActor) {
71887195
MOZ_ASSERT(aOuterWindow);
71897196
mBrowsingContext = aOuterWindow->GetBrowsingContext();
7197+
7198+
if (mWindowGlobalChild) {
7199+
mWindowID = aActor->InnerWindowId();
7200+
7201+
MOZ_ASSERT(mWindowGlobalChild->BrowsingContext() == mBrowsingContext);
7202+
} else {
7203+
mWindowID = nsContentUtils::GenerateWindowId();
7204+
}
71907205
}
71917206

71927207
void nsPIDOMWindowInner::RegisterReportingObserver(ReportingObserver* aObserver,

dom/base/nsGlobalWindowInner.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
232232
}
233233

234234
static already_AddRefed<nsGlobalWindowInner> Create(
235-
nsGlobalWindowOuter* aOuter, bool aIsChrome);
235+
nsGlobalWindowOuter* aOuter, bool aIsChrome,
236+
mozilla::dom::WindowGlobalChild* aActor);
236237

237238
// nsISupports
238239
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@@ -615,7 +616,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
615616
mozilla::ErrorResult& aError);
616617

617618
protected:
618-
explicit nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow);
619+
explicit nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow,
620+
mozilla::dom::WindowGlobalChild* aActor);
619621
// Initializes the mWasOffline member variable
620622
void InitWasOffline();
621623

dom/base/nsGlobalWindowOuter.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,8 @@ static nsresult CreateNativeGlobalForInner(JSContext* aCx,
18731873

18741874
nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
18751875
nsISupports* aState,
1876-
bool aForceReuseInnerWindow) {
1876+
bool aForceReuseInnerWindow,
1877+
WindowGlobalChild* aActor) {
18771878
MOZ_ASSERT(mDocumentPrincipal == nullptr,
18781879
"mDocumentPrincipal prematurely set!");
18791880
MOZ_ASSERT(mDocumentStoragePrincipal == nullptr,
@@ -2006,7 +2007,7 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument,
20062007
newInnerWindow = wsh->GetInnerWindow();
20072008
newInnerGlobal = newInnerWindow->GetWrapper();
20082009
} else {
2009-
newInnerWindow = nsGlobalWindowInner::Create(this, thisChrome);
2010+
newInnerWindow = nsGlobalWindowInner::Create(this, thisChrome, aActor);
20102011
if (StaticPrefs::dom_timeout_defer_during_load()) {
20112012
// ensure the initial loading state is known
20122013
newInnerWindow->SetActiveLoadingState(

dom/base/nsGlobalWindowOuter.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,9 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget,
313313

314314
void DetachFromDocShell();
315315

316-
virtual nsresult SetNewDocument(Document* aDocument, nsISupports* aState,
317-
bool aForceReuseInnerWindow) override;
316+
virtual nsresult SetNewDocument(
317+
Document* aDocument, nsISupports* aState, bool aForceReuseInnerWindow,
318+
mozilla::dom::WindowGlobalChild* aActor = nullptr) override;
318319

319320
// Outer windows only.
320321
static void PrepareForProcessChange(JSObject* aProxy);

0 commit comments

Comments
 (0)