From 143941e2d49a073ac21c1adebefe0b7e056671ac Mon Sep 17 00:00:00 2001 From: Nika Layzell Date: Thu, 8 Aug 2019 16:07:12 +0000 Subject: [PATCH] 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 --- docshell/base/nsDocShell.cpp | 59 +++++++++++++++++---- docshell/base/nsDocShell.h | 29 ++++++---- docshell/base/nsIContentViewer.idl | 9 +++- dom/base/Document.cpp | 2 +- dom/base/nsGlobalWindowInner.cpp | 35 ++++++++---- dom/base/nsGlobalWindowInner.h | 6 ++- dom/base/nsGlobalWindowOuter.cpp | 5 +- dom/base/nsGlobalWindowOuter.h | 5 +- dom/base/nsPIDOMWindow.h | 8 +-- dom/ipc/BrowserChild.cpp | 2 +- dom/ipc/WindowGlobalChild.cpp | 4 ++ dom/ipc/WindowGlobalChild.h | 4 ++ gfx/thebes/gfxSVGGlyphs.cpp | 2 +- image/SVGDocumentWrapper.cpp | 2 +- layout/base/nsDocumentViewer.cpp | 29 +++++----- toolkit/components/browser/moz.build | 2 + toolkit/components/browser/nsWebBrowser.cpp | 15 +++++- toolkit/components/browser/nsWebBrowser.h | 7 +++ xpfe/appshell/nsAppShellService.cpp | 6 +-- 19 files changed, 169 insertions(+), 62 deletions(-) diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 14354ac39f76..20b9a114055d 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -306,9 +306,10 @@ static void DecreasePrivateDocShellCount() { } } -nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext) +nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext, + uint64_t aContentWindowID) : nsDocLoader(), - mContentWindowID(nsContentUtils::GenerateWindowId()), + mContentWindowID(aContentWindowID), mBrowsingContext(aBrowsingContext), mForcedCharset(nullptr), mParentCharset(nullptr), @@ -394,6 +395,11 @@ nsDocShell::nsDocShell(BrowsingContext* aBrowsingContext) nsContentUtils::GenerateUUIDInPlace(mHistoryID); + // If no outer window ID was provided, generate a new one. + if (aContentWindowID == 0) { + mContentWindowID = nsContentUtils::GenerateWindowId(); + } + if (gDocShellCount++ == 0) { NS_ASSERTION(sURIFixup == nullptr, "Huh, sURIFixup not null in first nsDocShell ctor!"); @@ -460,11 +466,11 @@ nsDocShell::~nsDocShell() { /* static */ already_AddRefed nsDocShell::Create( - BrowsingContext* aBrowsingContext) { + BrowsingContext* aBrowsingContext, uint64_t aContentWindowID) { MOZ_ASSERT(aBrowsingContext, "DocShell without a BrowsingContext!"); nsresult rv; - RefPtr ds = new nsDocShell(aBrowsingContext); + RefPtr ds = new nsDocShell(aBrowsingContext, aContentWindowID); // Initialize the underlying nsDocLoader. rv = ds->nsDocLoader::Init(); @@ -518,6 +524,7 @@ already_AddRefed nsDocShell::Create( // Make |ds| the primary DocShell for the given context. aBrowsingContext->SetDocShell(ds); + return ds.forget(); } @@ -6243,12 +6250,13 @@ nsresult nsDocShell::RefreshURIFromQueue() { return NS_OK; } -nsresult nsDocShell::Embed(nsIContentViewer* aContentViewer) { +nsresult nsDocShell::Embed(nsIContentViewer* aContentViewer, + WindowGlobalChild* aWindowActor) { // Save the LayoutHistoryState of the previous document, before // setting up new document PersistLayoutHistoryState(); - nsresult rv = SetupNewViewer(aContentViewer); + nsresult rv = SetupNewViewer(aContentViewer, aWindowActor); NS_ENSURE_SUCCESS(rv, rv); // XXX What if SetupNewViewer fails? @@ -6884,6 +6892,7 @@ nsresult nsDocShell::EnsureContentViewer() { nsCOMPtr baseURI; nsIPrincipal* principal = GetInheritedPrincipal(false); nsIPrincipal* storagePrincipal = GetInheritedPrincipal(false, true); + nsCOMPtr parentItem; GetInProcessSameTypeParent(getter_AddRefs(parentItem)); if (parentItem) { @@ -6925,11 +6934,14 @@ nsresult nsDocShell::EnsureContentViewer() { nsresult nsDocShell::CreateAboutBlankContentViewer( nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal, nsIContentSecurityPolicy* aCSP, nsIURI* aBaseURI, - bool aTryToSaveOldPresentation, bool aCheckPermitUnload) { + bool aTryToSaveOldPresentation, bool aCheckPermitUnload, + WindowGlobalChild* aActor) { RefPtr blankDoc; nsCOMPtr viewer; nsresult rv = NS_ERROR_FAILURE; + MOZ_ASSERT_IF(aActor, aActor->DocumentPrincipal() == aPrincipal); + /* mCreatingDocument should never be true at this point. However, it's a theoretical possibility. We want to know about it and make it stop, and this sounds like a job for an assertion. */ @@ -7058,7 +7070,7 @@ nsresult nsDocShell::CreateAboutBlankContentViewer( // hook 'em up if (viewer) { viewer->SetContainer(this); - rv = Embed(viewer); + rv = Embed(viewer, aActor); NS_ENSURE_SUCCESS(rv, rv); SetCurrentURI(blankDoc->GetDocumentURI(), nullptr, true, 0); @@ -7088,6 +7100,32 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal, nullptr); } +nsresult nsDocShell::CreateContentViewerForActor( + WindowGlobalChild* aWindowActor) { + MOZ_ASSERT(aWindowActor); + + // FIXME: WindowGlobalChild should provide the StoragePrincipal. + nsresult rv = CreateAboutBlankContentViewer( + aWindowActor->DocumentPrincipal(), aWindowActor->DocumentPrincipal(), + /* aCsp */ nullptr, + /* aBaseURI */ nullptr, + /* aTryToSaveOldPresentation */ true, + /* aCheckPermitUnload */ true, aWindowActor); + if (NS_SUCCEEDED(rv)) { + RefPtr doc(GetDocument()); + MOZ_ASSERT( + doc, + "Should have a document if CreateAboutBlankContentViewer succeeded"); + MOZ_ASSERT(doc->GetOwnerGlobal() == aWindowActor->WindowGlobal(), + "New document should be in the same global as our actor"); + + // FIXME: We may want to support non-initial documents here. + doc->SetIsInitialDocument(true); + } + + return rv; +} + bool nsDocShell::CanSavePresentation(uint32_t aLoadType, nsIRequest* aNewRequest, Document* aNewDocument) { @@ -8293,7 +8331,8 @@ nsresult nsDocShell::NewContentViewerObj(const nsACString& aContentType, return NS_OK; } -nsresult nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer) { +nsresult nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer, + WindowGlobalChild* aWindowActor) { MOZ_ASSERT(!mIsBeingDestroyed); // @@ -8417,7 +8456,7 @@ nsresult nsDocShell::SetupNewViewer(nsIContentViewer* aNewViewer) { mContentViewer->SetNavigationTiming(mTiming); - if (NS_FAILED(mContentViewer->Init(widget, bounds))) { + if (NS_FAILED(mContentViewer->Init(widget, bounds, aWindowActor))) { mContentViewer = nullptr; NS_WARNING("ContentViewer Initialization failed"); return NS_ERROR_FAILURE; diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 531a322ca234..b88280936a7d 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -201,7 +201,8 @@ class nsDocShell final : public nsDocLoader, // Create a new nsDocShell object, initializing it. static already_AddRefed Create( - mozilla::dom::BrowsingContext* aBrowsingContext); + mozilla::dom::BrowsingContext* aBrowsingContext, + uint64_t aContentWindowID = 0); NS_IMETHOD Stop() override { // Need this here because otherwise nsIWebNavigation::Stop @@ -470,6 +471,11 @@ class nsDocShell final : public nsDocLoader, mSkipBrowsingContextDetachOnDestroy = true; } + // Create a content viewer within this nsDocShell for the given + // `WindowGlobalChild` actor. + nsresult CreateContentViewerForActor( + mozilla::dom::WindowGlobalChild* aWindowActor); + private: // member functions friend class nsDSURIContentListener; friend class FramingChecker; @@ -494,7 +500,8 @@ class nsDocShell final : public nsDocLoader, friend void mozilla::TimelineConsumers::PopMarkers( nsDocShell*, JSContext*, nsTArray&); - explicit nsDocShell(mozilla::dom::BrowsingContext* aBrowsingContext); + nsDocShell(mozilla::dom::BrowsingContext* aBrowsingContext, + uint64_t aContentWindowID); // Security checks to prevent frameset spoofing. See comments at // implementation sites. @@ -548,12 +555,11 @@ class nsDocShell final : public nsDocLoader, // aPrincipal can be passed in if the caller wants. If null is // passed in, the about:blank principal will end up being used. // aCSP, if any, will be used for the new about:blank load. - nsresult CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal, - nsIPrincipal* aStoragePrincipal, - nsIContentSecurityPolicy* aCSP, - nsIURI* aBaseURI, - bool aTryToSaveOldPresentation = true, - bool aCheckPermitUnload = true); + nsresult CreateAboutBlankContentViewer( + nsIPrincipal* aPrincipal, nsIPrincipal* aStoragePrincipal, + nsIContentSecurityPolicy* aCSP, nsIURI* aBaseURI, + bool aTryToSaveOldPresentation = true, bool aCheckPermitUnload = true, + mozilla::dom::WindowGlobalChild* aActor = nullptr); nsresult CreateContentViewer(const nsACString& aContentType, nsIRequest* aRequest, @@ -564,7 +570,9 @@ class nsDocShell final : public nsDocLoader, nsIStreamListener** aContentHandler, nsIContentViewer** aViewer); - nsresult SetupNewViewer(nsIContentViewer* aNewViewer); + nsresult SetupNewViewer( + nsIContentViewer* aNewViewer, + mozilla::dom::WindowGlobalChild* aWindowActor = nullptr); // // Session History @@ -977,7 +985,8 @@ class nsDocShell final : public nsDocLoader, nsresult EnsureFind(); nsresult EnsureCommandHandler(); nsresult RefreshURIFromQueue(); - nsresult Embed(nsIContentViewer* aContentViewer); + nsresult Embed(nsIContentViewer* aContentViewer, + mozilla::dom::WindowGlobalChild* aWindowActor = nullptr); nsPresContext* GetEldestPresContext(); nsresult CheckLoadingPermissions(); nsresult PersistLayoutHistoryState(); diff --git a/docshell/base/nsIContentViewer.idl b/docshell/base/nsIContentViewer.idl index d1320465daa1..98e73e72d232 100644 --- a/docshell/base/nsIContentViewer.idl +++ b/docshell/base/nsIContentViewer.idl @@ -21,7 +21,10 @@ class nsDOMNavigationTiming; namespace mozilla { class Encoding; class PresShell; -} +namespace dom { +class WindowGlobalChild; +} // namespace dom +} // namespace mozilla %} [ptr] native nsIWidgetPtr(nsIWidget); @@ -32,12 +35,14 @@ class PresShell; [ref] native nsIContentViewerTArray(nsTArray >); [ptr] native Encoding(const mozilla::Encoding); [ptr] native PresShellPtr(mozilla::PresShell); +[ptr] native WindowGlobalChildPtr(mozilla::dom::WindowGlobalChild); [scriptable, builtinclass, uuid(2da17016-7851-4a45-a7a8-00b360e01595)] interface nsIContentViewer : nsISupports { [noscript] void init(in nsIWidgetPtr aParentWidget, - [const] in nsIntRectRef aBounds); + [const] in nsIntRectRef aBounds, + in WindowGlobalChildPtr aWindowActor); attribute nsIDocShell container; diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index a313ed42da78..9ba14203af24 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -843,7 +843,7 @@ nsresult ExternalResourceMap::AddExternalResource(nsIURI* aURI, // Make sure that hiding our viewer will tear down its presentation. aViewer->SetSticky(false); - rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0)); + rv = aViewer->Init(nullptr, nsIntRect(0, 0, 0, 0), nullptr); if (NS_SUCCEEDED(rv)) { rv = aViewer->Open(nullptr, nullptr); } diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index e0a461fdb627..ef0982863968 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -839,8 +839,9 @@ class PromiseDocumentFlushedResolver final { //*** nsGlobalWindowInner: Object Management //***************************************************************************** -nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow) - : nsPIDOMWindowInner(aOuterWindow), +nsGlobalWindowInner::nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow, + WindowGlobalChild* aActor) + : nsPIDOMWindowInner(aOuterWindow, aActor), mozilla::webgpu::InstanceProvider(this), mWasOffline(false), mHasHadSlowScript(false), @@ -1606,9 +1607,7 @@ void nsGlobalWindowInner::InnerSetNewDocument(JSContext* aCx, // FIXME: Currently, devtools can crete a fallback webextension window global // in the content process which does not have a corresponding BrowserChild // actor. This means we have no actor to be our parent. (Bug 1498293) - MOZ_DIAGNOSTIC_ASSERT(!mWindowGlobalChild, - "Shouldn't have created WindowGlobalChild yet!"); - if (XRE_IsParentProcess() || mBrowserChild) { + if (!mWindowGlobalChild && (XRE_IsParentProcess() || mBrowserChild)) { mWindowGlobalChild = WindowGlobalChild::Create(this); } @@ -7107,13 +7106,19 @@ mozilla::dom::TabGroup* nsPIDOMWindowInner::TabGroup() { /* static */ already_AddRefed nsGlobalWindowInner::Create( - nsGlobalWindowOuter* aOuterWindow, bool aIsChrome) { - RefPtr window = new nsGlobalWindowInner(aOuterWindow); + nsGlobalWindowOuter* aOuterWindow, bool aIsChrome, + WindowGlobalChild* aActor) { + RefPtr window = + new nsGlobalWindowInner(aOuterWindow, aActor); if (aIsChrome) { window->mIsChrome = true; window->mCleanMessageManager = true; } + if (aActor) { + aActor->InitWindowGlobal(window); + } + window->InitWasOffline(); return window.forget(); } @@ -7166,7 +7171,8 @@ bool nsPIDOMWindowInner::HasStorageAccessGranted( return mStorageAccessGranted.Contains(aPermissionKey); } -nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow) +nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow, + WindowGlobalChild* aActor) : mMutationBits(0), mActivePeerConnections(0), mIsDocumentLoaded(false), @@ -7178,15 +7184,24 @@ nsPIDOMWindowInner::nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow) mMayHavePointerEnterLeaveEventListener(false), mMayHaveTextEventListenerInDefaultGroup(false), mOuterWindow(aOuterWindow), - mWindowID(nsContentUtils::GenerateWindowId()), + mWindowID(0), mHasNotifiedGlobalCreated(false), mMarkedCCGeneration(0), mHasTriedToCacheTopInnerWindow(false), mNumOfIndexedDBDatabases(0), mNumOfOpenWebSockets(0), - mEvent(nullptr) { + mEvent(nullptr), + mWindowGlobalChild(aActor) { MOZ_ASSERT(aOuterWindow); mBrowsingContext = aOuterWindow->GetBrowsingContext(); + + if (mWindowGlobalChild) { + mWindowID = aActor->InnerWindowId(); + + MOZ_ASSERT(mWindowGlobalChild->BrowsingContext() == mBrowsingContext); + } else { + mWindowID = nsContentUtils::GenerateWindowId(); + } } void nsPIDOMWindowInner::RegisterReportingObserver(ReportingObserver* aObserver, diff --git a/dom/base/nsGlobalWindowInner.h b/dom/base/nsGlobalWindowInner.h index 7acfe018ddf8..a664c7c76cc8 100644 --- a/dom/base/nsGlobalWindowInner.h +++ b/dom/base/nsGlobalWindowInner.h @@ -232,7 +232,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget, } static already_AddRefed Create( - nsGlobalWindowOuter* aOuter, bool aIsChrome); + nsGlobalWindowOuter* aOuter, bool aIsChrome, + mozilla::dom::WindowGlobalChild* aActor); // nsISupports NS_DECL_CYCLE_COLLECTING_ISUPPORTS @@ -615,7 +616,8 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget, mozilla::ErrorResult& aError); protected: - explicit nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow); + explicit nsGlobalWindowInner(nsGlobalWindowOuter* aOuterWindow, + mozilla::dom::WindowGlobalChild* aActor); // Initializes the mWasOffline member variable void InitWasOffline(); diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index 748c24e49878..217c0126e65a 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -1873,7 +1873,8 @@ static nsresult CreateNativeGlobalForInner(JSContext* aCx, nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument, nsISupports* aState, - bool aForceReuseInnerWindow) { + bool aForceReuseInnerWindow, + WindowGlobalChild* aActor) { MOZ_ASSERT(mDocumentPrincipal == nullptr, "mDocumentPrincipal prematurely set!"); MOZ_ASSERT(mDocumentStoragePrincipal == nullptr, @@ -2006,7 +2007,7 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument, newInnerWindow = wsh->GetInnerWindow(); newInnerGlobal = newInnerWindow->GetWrapper(); } else { - newInnerWindow = nsGlobalWindowInner::Create(this, thisChrome); + newInnerWindow = nsGlobalWindowInner::Create(this, thisChrome, aActor); if (StaticPrefs::dom_timeout_defer_during_load()) { // ensure the initial loading state is known newInnerWindow->SetActiveLoadingState( diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h index e806dc1ab5b7..7f90211149d3 100644 --- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -313,8 +313,9 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, void DetachFromDocShell(); - virtual nsresult SetNewDocument(Document* aDocument, nsISupports* aState, - bool aForceReuseInnerWindow) override; + virtual nsresult SetNewDocument( + Document* aDocument, nsISupports* aState, bool aForceReuseInnerWindow, + mozilla::dom::WindowGlobalChild* aActor = nullptr) override; // Outer windows only. static void PrepareForProcessChange(JSObject* aProxy); diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h index 37973f27f2af..a86b400407b4 100644 --- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -140,7 +140,8 @@ class nsPIDOMWindowInner : public mozIDOMWindow { friend nsGlobalWindowInner; friend nsGlobalWindowOuter; - explicit nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow); + nsPIDOMWindowInner(nsPIDOMWindowOuter* aOuterWindow, + mozilla::dom::WindowGlobalChild* aActor); ~nsPIDOMWindowInner(); @@ -876,8 +877,9 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy { * * aDocument must not be null. */ - virtual nsresult SetNewDocument(Document* aDocument, nsISupports* aState, - bool aForceReuseInnerWindow) = 0; + virtual nsresult SetNewDocument( + Document* aDocument, nsISupports* aState, bool aForceReuseInnerWindow, + mozilla::dom::WindowGlobalChild* aActor = nullptr) = 0; /** * Set the opener window. aOriginalOpener is true if and only if this is the diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp index 890ff862053e..16af0efc8a7f 100644 --- a/dom/ipc/BrowserChild.cpp +++ b/dom/ipc/BrowserChild.cpp @@ -510,7 +510,7 @@ nsresult BrowserChild::Init(mozIDOMWindowProxy* aParent, nullptr); // HandleWidgetEvent mWebBrowser = nsWebBrowser::Create(this, mPuppetWidget, OriginAttributesRef(), - mBrowsingContext); + mBrowsingContext, aInitialWindowChild); nsIWebBrowser* webBrowser = mWebBrowser; mWebNav = do_QueryInterface(webBrowser); diff --git a/dom/ipc/WindowGlobalChild.cpp b/dom/ipc/WindowGlobalChild.cpp index 46b11824abab..03fdaacb1f70 100644 --- a/dom/ipc/WindowGlobalChild.cpp +++ b/dom/ipc/WindowGlobalChild.cpp @@ -140,6 +140,10 @@ void WindowGlobalChild::Init() { entry.OrInsert([&] { return this; }); } +void WindowGlobalChild::InitWindowGlobal(nsGlobalWindowInner* aWindow) { + mWindowGlobal = aWindow; +} + /* static */ already_AddRefed WindowGlobalChild::GetByInnerWindowId( uint64_t aInnerWindowId) { diff --git a/dom/ipc/WindowGlobalChild.h b/dom/ipc/WindowGlobalChild.h index 1ab5a659774e..c4293c4c982c 100644 --- a/dom/ipc/WindowGlobalChild.h +++ b/dom/ipc/WindowGlobalChild.h @@ -60,6 +60,8 @@ class WindowGlobalChild final : public WindowGlobalActor, nsIURI* GetDocumentURI() override { return mDocumentURI; } void SetDocumentURI(nsIURI* aDocumentURI); + nsIPrincipal* DocumentPrincipal() { return mDocumentPrincipal; } + // The Window ID for this WindowGlobal uint64_t InnerWindowId() { return mInnerWindowId; } uint64_t OuterWindowId() { return mOuterWindowId; } @@ -98,6 +100,8 @@ class WindowGlobalChild final : public WindowGlobalActor, void Init(); + void InitWindowGlobal(nsGlobalWindowInner* aWindow); + nsISupports* GetParentObject(); JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; diff --git a/gfx/thebes/gfxSVGGlyphs.cpp b/gfx/thebes/gfxSVGGlyphs.cpp index 7bfa4beda1b0..9f4e510c685c 100644 --- a/gfx/thebes/gfxSVGGlyphs.cpp +++ b/gfx/thebes/gfxSVGGlyphs.cpp @@ -143,7 +143,7 @@ nsresult gfxSVGGlyphsDocument::SetupPresentation() { getter_AddRefs(viewer)); NS_ENSURE_SUCCESS(rv, rv); - rv = viewer->Init(nullptr, gfx::IntRect(0, 0, 1000, 1000)); + rv = viewer->Init(nullptr, gfx::IntRect(0, 0, 1000, 1000), nullptr); if (NS_SUCCEEDED(rv)) { rv = viewer->Open(nullptr, nullptr); NS_ENSURE_SUCCESS(rv, rv); diff --git a/image/SVGDocumentWrapper.cpp b/image/SVGDocumentWrapper.cpp index 66f307554920..9f018c376c75 100644 --- a/image/SVGDocumentWrapper.cpp +++ b/image/SVGDocumentWrapper.cpp @@ -200,7 +200,7 @@ SVGDocumentWrapper::OnStartRequest(nsIRequest* aRequest) { mViewer->GetDocument()->SetIsBeingUsedAsImage(); StopAnimation(); // otherwise animations start automatically in helper doc - rv = mViewer->Init(nullptr, nsIntRect(0, 0, 0, 0)); + rv = mViewer->Init(nullptr, nsIntRect(0, 0, 0, 0), nullptr); if (NS_SUCCEEDED(rv)) { rv = mViewer->Open(nullptr, nullptr); } diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index 1757e389ea1f..b3cd5d9614b6 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -120,6 +120,7 @@ #include "mozilla/dom/Event.h" #include "mozilla/Telemetry.h" #include "mozilla/dom/ScriptLoader.h" +#include "mozilla/dom/WindowGlobalChild.h" using namespace mozilla; using namespace mozilla::dom; @@ -364,6 +365,7 @@ class nsDocumentViewer final : public nsIContentViewer, * called if the window's current document is already mDocument. */ nsresult InitInternal(nsIWidget* aParentWidget, nsISupports* aState, + mozilla::dom::WindowGlobalChild* aActor, const nsIntRect& aBounds, bool aDoCreation, bool aNeedMakeCX = true, bool aForceSetNewDocument = true); @@ -735,8 +737,9 @@ nsDocumentViewer::GetContainer(nsIDocShell** aResult) { } NS_IMETHODIMP -nsDocumentViewer::Init(nsIWidget* aParentWidget, const nsIntRect& aBounds) { - return InitInternal(aParentWidget, nullptr, aBounds, true); +nsDocumentViewer::Init(nsIWidget* aParentWidget, const nsIntRect& aBounds, + WindowGlobalChild* aActor) { + return InitInternal(aParentWidget, nullptr, aActor, aBounds, true); } nsresult nsDocumentViewer::InitPresentationStuff(bool aDoInitialReflow) { @@ -867,12 +870,10 @@ static nsPresContext* CreatePresContext(Document* aDocument, // This method can be used to initial the "presentation" // The aDoCreation indicates whether it should create // all the new objects or just initialize the existing ones -nsresult nsDocumentViewer::InitInternal(nsIWidget* aParentWidget, - nsISupports* aState, - const nsIntRect& aBounds, - bool aDoCreation, - bool aNeedMakeCX /*= true*/, - bool aForceSetNewDocument /* = true*/) { +nsresult nsDocumentViewer::InitInternal( + nsIWidget* aParentWidget, nsISupports* aState, WindowGlobalChild* aActor, + const nsIntRect& aBounds, bool aDoCreation, bool aNeedMakeCX /*= true*/, + bool aForceSetNewDocument /* = true*/) { if (mIsPageMode) { // XXXbz should the InitInternal in SetPageModeForTesting just pass false // here itself? @@ -978,7 +979,7 @@ nsresult nsDocumentViewer::InitInternal(nsIWidget* aParentWidget, if (window) { nsCOMPtr curDoc = window->GetExtantDoc(); if (aForceSetNewDocument || curDoc != mDocument) { - rv = window->SetNewDocument(mDocument, aState, false); + rv = window->SetNewDocument(mDocument, aState, false, aActor); if (NS_FAILED(rv)) { Destroy(); return rv; @@ -1577,7 +1578,7 @@ nsDocumentViewer::Open(nsISupports* aState, nsISHEntry* aSHEntry) { mDocument->SetContainer(mContainer); } - nsresult rv = InitInternal(mParentWidget, aState, mBounds, false); + nsresult rv = InitInternal(mParentWidget, aState, nullptr, mBounds, false); NS_ENSURE_SUCCESS(rv, rv); mHidden = false; @@ -2036,7 +2037,8 @@ nsDocumentViewer::SetDocumentInternal(Document* aDocument, DestroyPresContext(); mWindow = nullptr; - rv = InitInternal(mParentWidget, nullptr, mBounds, true, true, false); + rv = InitInternal(mParentWidget, nullptr, nullptr, mBounds, true, true, + false); } return rv; @@ -4112,8 +4114,9 @@ NS_IMETHODIMP nsDocumentViewer::SetPageModeForTesting( nsresult rv = mPresContext->Init(mDeviceContext); NS_ENSURE_SUCCESS(rv, rv); } - NS_ENSURE_SUCCESS(InitInternal(mParentWidget, nullptr, mBounds, true, false), - NS_ERROR_FAILURE); + NS_ENSURE_SUCCESS( + InitInternal(mParentWidget, nullptr, nullptr, mBounds, true, false), + NS_ERROR_FAILURE); Show(); return NS_OK; diff --git a/toolkit/components/browser/moz.build b/toolkit/components/browser/moz.build index 164a015a4644..bde8a9d08f13 100644 --- a/toolkit/components/browser/moz.build +++ b/toolkit/components/browser/moz.build @@ -34,6 +34,8 @@ UNIFIED_SOURCES += [ 'nsWebBrowserContentPolicy.cpp', ] +include('/ipc/chromium/chromium-config.mozbuild') + FINAL_LIBRARY = 'xul' LOCAL_INCLUDES += [ '/docshell/base', diff --git a/toolkit/components/browser/nsWebBrowser.cpp b/toolkit/components/browser/nsWebBrowser.cpp index 77be28c17da4..0b97ec54bdb8 100644 --- a/toolkit/components/browser/nsWebBrowser.cpp +++ b/toolkit/components/browser/nsWebBrowser.cpp @@ -38,6 +38,7 @@ #include "mozilla/dom/Element.h" #include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/LoadURIOptionsBinding.h" +#include "mozilla/dom/WindowGlobalChild.h" // for painting the background window #include "mozilla/LookAndFeel.h" @@ -103,7 +104,11 @@ already_AddRefed nsWebBrowser::Create( nsIWebBrowserChrome* aContainerWindow, nsIWidget* aParentWidget, const OriginAttributes& aOriginAttributes, dom::BrowsingContext* aBrowsingContext, + dom::WindowGlobalChild* aInitialWindowChild, bool aDisableHistory /* = false */) { + MOZ_ASSERT_IF(aInitialWindowChild, + aInitialWindowChild->BrowsingContext() == aBrowsingContext); + RefPtr browser = new nsWebBrowser( aBrowsingContext->IsContent() ? typeContentWrapper : typeChromeWrapper); @@ -116,7 +121,11 @@ already_AddRefed nsWebBrowser::Create( return nullptr; } - RefPtr docShell = nsDocShell::Create(aBrowsingContext); + uint64_t outerWindowId = + aInitialWindowChild ? aInitialWindowChild->OuterWindowId() : 0; + + RefPtr docShell = + nsDocShell::Create(aBrowsingContext, outerWindowId); if (NS_WARN_IF(!docShell)) { return nullptr; } @@ -178,6 +187,10 @@ already_AddRefed nsWebBrowser::Create( docShellTreeOwner->AddToWatcher(); // evil twin of Remove in SetDocShell(0) docShellTreeOwner->AddChromeListeners(); + if (aInitialWindowChild) { + docShell->CreateContentViewerForActor(aInitialWindowChild); + } + return browser.forget(); } diff --git a/toolkit/components/browser/nsWebBrowser.h b/toolkit/components/browser/nsWebBrowser.h index 90a3c43bc9d5..48e43dd53c76 100644 --- a/toolkit/components/browser/nsWebBrowser.h +++ b/toolkit/components/browser/nsWebBrowser.h @@ -58,6 +58,12 @@ class nsWebBrowserInitInfo { class mozIDOMWindowProxy; +namespace mozilla { +namespace dom { +class WindowGlobalChild; +} // namespace dom +} // namespace mozilla + class nsWebBrowser final : public nsIWebBrowser, public nsIWebNavigation, public nsIDocShellTreeItem, @@ -109,6 +115,7 @@ class nsWebBrowser final : public nsIWebBrowser, nsIWebBrowserChrome* aContainerWindow, nsIWidget* aParentWidget, const mozilla::OriginAttributes& aOriginAttributes, mozilla::dom::BrowsingContext* aBrowsingContext, + mozilla::dom::WindowGlobalChild* aInitialWindowChild, bool aDisableHistory = false); protected: diff --git a/xpfe/appshell/nsAppShellService.cpp b/xpfe/appshell/nsAppShellService.cpp index 2f7e5e992ea0..1722d3abd87e 100644 --- a/xpfe/appshell/nsAppShellService.cpp +++ b/xpfe/appshell/nsAppShellService.cpp @@ -494,9 +494,9 @@ nsAppShellService::CreateWindowlessBrowser(bool aIsChrome, /* Next, we create an instance of nsWebBrowser. Instances of this class have * an associated doc shell, which is what we're interested in. */ - nsCOMPtr browser = - nsWebBrowser::Create(stub, widget, OriginAttributes(), browsingContext, - true /* disable history */); + nsCOMPtr browser = nsWebBrowser::Create( + stub, widget, OriginAttributes(), browsingContext, + nullptr /* initialWindowChild */, true /* disable history */); if (NS_WARN_IF(!browser)) { NS_ERROR("Couldn't create instance of nsWebBrowser!");