diff --git a/accessible/generic/ImageAccessible.cpp b/accessible/generic/ImageAccessible.cpp index 05f90a485c56..cd3c0003f79a 100644 --- a/accessible/generic/ImageAccessible.cpp +++ b/accessible/generic/ImageAccessible.cpp @@ -13,6 +13,7 @@ #include "imgIContainer.h" #include "imgIRequest.h" #include "nsGenericHTMLElement.h" +#include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/Document.h" #include "nsIImageLoadingContent.h" #include "nsIServiceManager.h" @@ -109,7 +110,7 @@ bool ImageAccessible::DoAction(uint8_t aIndex) const { nsCOMPtr piWindow = document->GetWindow(); if (!piWindow) return false; - nsCOMPtr tmp; + RefPtr tmp; return NS_SUCCEEDED(piWindow->Open(spec, EmptyString(), EmptyString(), /* aLoadInfo = */ nullptr, /* aForceNoOpener = */ false, diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index d395f5aa401d..082922e72362 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -6485,7 +6485,7 @@ nsBrowserAccess.prototype = { throw Cr.NS_ERROR_FAILURE; } - var newWindow = null; + var browsingContext = null; var isExternal = !!(aFlags & Ci.nsIBrowserDOMWindow.OPEN_EXTERNAL); if (aOpener && isExternal) { @@ -6549,7 +6549,7 @@ nsBrowserAccess.prototype = { // Pass all params to openDialog to ensure that "url" isn't passed through // loadOneOrMoreURIs, which splits based on "|" try { - newWindow = openDialog( + openDialog( AppConstants.BROWSER_CHROME_URL, "_blank", features, @@ -6566,6 +6566,17 @@ nsBrowserAccess.prototype = { null, aCsp ); + // At this point, the new browser window is just starting to load, and + // hasn't created the content that we should return. So we + // can't actually return a valid BrowsingContext for this load without + // spinning the event loop. + // + // Fortunately, no current callers of this API who pass OPEN_NEWWINDOW + // actually use the return value, so we're safe returning null for + // now. + // + // Ideally this should be fixed. + browsingContext = null; } catch (ex) { Cu.reportError(ex); } @@ -6599,12 +6610,13 @@ nsBrowserAccess.prototype = { aCsp ); if (browser) { - newWindow = browser.contentWindow; + browsingContext = browser.browsingContext; } break; default: // OPEN_CURRENTWINDOW or an illegal value - newWindow = window.content; + browsingContext = + window.content && BrowsingContext.getFromWindow(window.content); if (aURI) { let loadflags = isExternal ? Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL @@ -6622,7 +6634,7 @@ nsBrowserAccess.prototype = { window.focus(); } } - return newWindow; + return browsingContext; }, createContentWindowInFrame: function browser_createContentWindowInFrame( diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index dcbff46d509e..af5c2a3b0d89 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -8777,7 +8777,7 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState, nsCOMPtr win = GetWindow(); NS_ENSURE_TRUE(win, NS_ERROR_NOT_AVAILABLE); - nsCOMPtr newWin; + RefPtr newBC; nsAutoCString spec; aLoadState->URI()->GetSpec(spec); @@ -8837,20 +8837,21 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState, EmptyString(), // Features loadState, true, // aForceNoOpener - getter_AddRefs(newWin)); - MOZ_ASSERT(!newWin); + getter_AddRefs(newBC)); + MOZ_ASSERT(!newBC); return rv; } rv = win->OpenNoNavigate(NS_ConvertUTF8toUTF16(spec), aLoadState->Target(), // window name EmptyString(), // Features - getter_AddRefs(newWin)); + getter_AddRefs(newBC)); // In some cases the Open call doesn't actually result in a new // window being opened. We can detect these cases by examining the - // document in |newWin|, if any. - nsCOMPtr piNewWin = newWin; + // document in |newBC|, if any. + nsCOMPtr piNewWin = + newBC ? newBC->GetDOMWindow() : nullptr; if (piNewWin) { RefPtr newDoc = piNewWin->GetExtantDoc(); if (!newDoc || newDoc->IsInitialDocument()) { @@ -8858,8 +8859,9 @@ nsresult nsDocShell::PerformRetargeting(nsDocShellLoadState* aLoadState, } } - nsCOMPtr webNav = do_GetInterface(newWin); - targetDocShell = do_QueryInterface(webNav); + if (newBC) { + targetDocShell = newBC->GetDocShell(); + } } NS_ENSURE_SUCCESS(rv, rv); diff --git a/dom/base/Document.cpp b/dom/base/Document.cpp index 8b79a83fbc74..b7ab6ea296ee 100644 --- a/dom/base/Document.cpp +++ b/dom/base/Document.cpp @@ -8709,12 +8709,12 @@ mozilla::dom::Nullable Document::Open( return nullptr; } RefPtr win = nsGlobalWindowOuter::Cast(outer); - nsCOMPtr newWindow; - rv = win->OpenJS(aURL, aName, aFeatures, getter_AddRefs(newWindow)); - if (!newWindow) { + RefPtr newBC; + rv = win->OpenJS(aURL, aName, aFeatures, getter_AddRefs(newBC)); + if (!newBC) { return nullptr; } - return WindowProxyHolder(newWindow->GetBrowsingContext()); + return WindowProxyHolder(newBC.forget()); } Document* Document::Open(const Optional& /* unused */, diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index 07a827dc8c69..ab10192b931f 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -5734,10 +5734,9 @@ void nsGlobalWindowOuter::FireAbuseEvents( Nullable nsGlobalWindowOuter::OpenOuter( const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, ErrorResult& aError) { - nsCOMPtr window; - aError = OpenJS(aUrl, aName, aOptions, getter_AddRefs(window)); RefPtr bc; - if (!window || !(bc = window->GetBrowsingContext())) { + aError = OpenJS(aUrl, aName, aOptions, getter_AddRefs(bc)); + if (!bc) { return nullptr; } return WindowProxyHolder(bc.forget()); @@ -5748,7 +5747,7 @@ nsresult nsGlobalWindowOuter::Open(const nsAString& aUrl, const nsAString& aOptions, nsDocShellLoadState* aLoadState, bool aForceNoOpener, - nsPIDOMWindowOuter** _retval) { + BrowsingContext** _retval) { return OpenInternal(aUrl, aName, aOptions, false, // aDialog false, // aContentModal @@ -5762,7 +5761,7 @@ nsresult nsGlobalWindowOuter::Open(const nsAString& aUrl, nsresult nsGlobalWindowOuter::OpenJS(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, - nsPIDOMWindowOuter** _retval) { + BrowsingContext** _retval) { return OpenInternal(aUrl, aName, aOptions, false, // aDialog false, // aContentModal @@ -5781,7 +5780,7 @@ nsresult nsGlobalWindowOuter::OpenDialog(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, nsISupports* aExtraArgument, - nsPIDOMWindowOuter** _retval) { + BrowsingContext** _retval) { return OpenInternal(aUrl, aName, aOptions, true, // aDialog false, // aContentModal @@ -5799,7 +5798,7 @@ nsresult nsGlobalWindowOuter::OpenDialog(const nsAString& aUrl, nsresult nsGlobalWindowOuter::OpenNoNavigate(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, - nsPIDOMWindowOuter** _retval) { + BrowsingContext** _retval) { return OpenInternal(aUrl, aName, aOptions, false, // aDialog false, // aContentModal @@ -5824,7 +5823,7 @@ Nullable nsGlobalWindowOuter::OpenDialogOuter( return nullptr; } - nsCOMPtr dialog; + RefPtr dialog; aError = OpenInternal(aUrl, aName, aOptions, true, // aDialog false, // aContentModal @@ -5835,11 +5834,10 @@ Nullable nsGlobalWindowOuter::OpenDialogOuter( nullptr, // aLoadState false, // aForceNoOpener getter_AddRefs(dialog)); - RefPtr bc; - if (!dialog || !(bc = dialog->GetBrowsingContext())) { + if (!dialog) { return nullptr; } - return WindowProxyHolder(bc.forget()); + return WindowProxyHolder(dialog.forget()); } BrowsingContext* nsGlobalWindowOuter::GetFramesOuter() { @@ -7131,7 +7129,7 @@ nsresult nsGlobalWindowOuter::OpenInternal( bool aDialog, bool aContentModal, bool aCalledNoScript, bool aDoJSFixups, bool aNavigate, nsIArray* argv, nsISupports* aExtraArgument, nsDocShellLoadState* aLoadState, bool aForceNoOpener, - nsPIDOMWindowOuter** aReturn) { + BrowsingContext** aReturn) { #ifdef DEBUG uint32_t argc = 0; if (argv) argv->GetLength(&argc); @@ -7248,7 +7246,7 @@ nsresult nsGlobalWindowOuter::OpenInternal( } } - nsCOMPtr domReturn; + RefPtr domReturn; nsCOMPtr wwatch = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv); @@ -7277,6 +7275,7 @@ nsresult nsGlobalWindowOuter::OpenInternal( // dialog is open. AutoPopupStatePusher popupStatePusher(PopupBlocker::openAbused, true); + nsCOMPtr win; if (!aCalledNoScript) { // We asserted at the top of this function that aNavigate is true for // !aCalledNoScript. @@ -7284,7 +7283,7 @@ nsresult nsGlobalWindowOuter::OpenInternal( this, url.IsVoid() ? nullptr : url.get(), name_ptr, options_ptr, /* aCalledFromScript = */ true, aDialog, aNavigate, argv, isPopupSpamWindow, forceNoOpener, forceNoReferrer, aLoadState, - getter_AddRefs(domReturn)); + getter_AddRefs(win)); } else { // Force a system caller here so that the window watcher won't screw us // up. We do NOT want this case looking at the JS context on the stack @@ -7304,7 +7303,10 @@ nsresult nsGlobalWindowOuter::OpenInternal( this, url.IsVoid() ? nullptr : url.get(), name_ptr, options_ptr, /* aCalledFromScript = */ false, aDialog, aNavigate, aExtraArgument, isPopupSpamWindow, forceNoOpener, forceNoReferrer, aLoadState, - getter_AddRefs(domReturn)); + getter_AddRefs(win)); + } + if (win) { + domReturn = nsPIDOMWindowOuter::From(win)->GetBrowsingContext(); } } @@ -7317,7 +7319,8 @@ nsresult nsGlobalWindowOuter::OpenInternal( } if (domReturn && aDoJSFixups) { - nsCOMPtr chrome_win(do_QueryInterface(domReturn)); + nsCOMPtr chrome_win( + do_QueryInterface(domReturn->GetDOMWindow())); if (!chrome_win) { // A new non-chrome window was created from a call to // window.open() from JavaScript, make sure there's a document in @@ -7327,12 +7330,14 @@ nsresult nsGlobalWindowOuter::OpenInternal( // XXXbz should this just use EnsureInnerWindow()? // Force document creation. - nsCOMPtr doc = nsPIDOMWindowOuter::From(domReturn)->GetDoc(); - Unused << doc; + if (nsPIDOMWindowOuter* win = domReturn->GetDOMWindow()) { + nsCOMPtr doc = win->GetDoc(); + Unused << doc; + } } } - *aReturn = do_AddRef(nsPIDOMWindowOuter::From(domReturn)).take(); + domReturn.forget(aReturn); return NS_OK; } diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h index 18b82b8c521b..e806dc1ab5b7 100644 --- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -260,7 +260,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, const nsAString& aGroup); nsresult OpenJS(const nsAString& aUrl, const nsAString& aName, - const nsAString& aOptions, nsPIDOMWindowOuter** _retval); + const nsAString& aOptions, + mozilla::dom::BrowsingContext** _retval); virtual mozilla::EventListenerManager* GetExistingListenerManager() const override; @@ -565,7 +566,8 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, mozilla::ErrorResult& aError); nsresult Open(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, nsDocShellLoadState* aLoadState, - bool aForceNoOpener, nsPIDOMWindowOuter** _retval) override; + bool aForceNoOpener, + mozilla::dom::BrowsingContext** _retval) override; mozilla::dom::Navigator* GetNavigator() override; #if defined(MOZ_WIDGET_ANDROID) @@ -634,7 +636,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, mozilla::ErrorResult& aError); nsresult OpenDialog(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, nsISupports* aExtraArgument, - nsPIDOMWindowOuter** _retval) override; + mozilla::dom::BrowsingContext** _retval) override; void UpdateCommands(const nsAString& anAction, mozilla::dom::Selection* aSel, int16_t aReason) override; @@ -760,9 +762,9 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, // Window Control Functions // Outer windows only. - virtual nsresult OpenNoNavigate(const nsAString& aUrl, const nsAString& aName, - const nsAString& aOptions, - nsPIDOMWindowOuter** _retval) override; + virtual nsresult OpenNoNavigate( + const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, + mozilla::dom::BrowsingContext** _retval) override; private: explicit nsGlobalWindowOuter(uint64_t aWindowID); @@ -822,7 +824,7 @@ class nsGlobalWindowOuter final : public mozilla::dom::EventTarget, bool aDoJSFixups, bool aNavigate, nsIArray* argv, nsISupports* aExtraArgument, nsDocShellLoadState* aLoadState, bool aForceNoOpener, - nsPIDOMWindowOuter** aReturn); + mozilla::dom::BrowsingContext** aReturn); // Checks that the channel was loaded by the URI currently loaded in aDoc static bool SameLoadingURI(Document* aDoc, nsIChannel* aChannel); diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h index fde24ef06a01..37973f27f2af 100644 --- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -1010,7 +1010,7 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy { */ virtual nsresult OpenNoNavigate(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, - nsPIDOMWindowOuter** _retval) = 0; + mozilla::dom::BrowsingContext** _retval) = 0; /** * Fire a popup blocked event on the document. @@ -1049,11 +1049,11 @@ class nsPIDOMWindowOuter : public mozIDOMWindowProxy { virtual nsresult Open(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, nsDocShellLoadState* aLoadState, bool aForceNoOpener, - nsPIDOMWindowOuter** _retval) = 0; + mozilla::dom::BrowsingContext** _retval) = 0; virtual nsresult OpenDialog(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, nsISupports* aExtraArgument, - nsPIDOMWindowOuter** _retval) = 0; + mozilla::dom::BrowsingContext** _retval) = 0; virtual nsresult GetInnerWidth(int32_t* aWidth) = 0; virtual nsresult GetInnerHeight(int32_t* aHeight) = 0; diff --git a/dom/browser-element/BrowserElementParent.cpp b/dom/browser-element/BrowserElementParent.cpp index 7b0764dad6e8..7d52d8ce220a 100644 --- a/dom/browser-element/BrowserElementParent.cpp +++ b/dom/browser-element/BrowserElementParent.cpp @@ -219,8 +219,8 @@ BrowserElementParent::OpenWindowInProcess(BrowsingContext* aOpenerWindow, nsIURI* aURI, const nsAString& aName, const nsACString& aFeatures, bool aForceNoOpener, - mozIDOMWindowProxy** aReturnWindow) { - *aReturnWindow = nullptr; + BrowsingContext** aReturnBC) { + *aReturnBC = nullptr; // If we call window.open from an