Bug 1561015: Part 2 - Return BrowsingContext from openWindow2. r=bzbarsky

There are some unfortunate aspects of openWindow() and openWindow2() that make
this difficult. Namely, they sometimes return top-level chrome windows, and
sometimes a single content window from the top-level chrome window that they
open, depending on how they're called.

There really isn't any reason to return a BrowsingContext rather than a chrome
window in the former case, but there also really isn't a way to make the API
polymorphic in a way that would allow handling the two cases differently. So
at some point, the two cases should ideally be split into separate APIs rather
than separate special cases of a single API.

In the mean time, I've left openWindow() returning local mozIDOMWindowProxy
objects, since it isn't used by the DOM window.open() or openDialog() APIs,
and only updated openWindow2(). As a follow-up, we should remove both
openWindow() and openWindow2(), and replace them with openChromeWindow() and
openContentWindow() (or similar) methods which make it immediately clear what
type of window is being returned.

Differential Revision: https://phabricator.services.mozilla.com/D35689
This commit is contained in:
Kris Maglione
2019-08-02 20:48:40 +00:00
parent 1bb60064a6
commit 7575d4eb1d
6 changed files with 41 additions and 43 deletions

View File

@@ -61,6 +61,7 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/Preferences.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/Storage.h"
#include "mozilla/dom/ScriptSettings.h"
@@ -287,13 +288,17 @@ nsWindowWatcher::OpenWindow(mozIDOMWindowProxy* aParent, const char* aUrl,
}
bool dialog = (argc != 0);
return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
/* calledFromJS = */ false, dialog,
/* navigate = */ true, argv,
/* aIsPopupSpam = */ false,
/* aForceNoOpener = */ false,
/* aForceNoReferrer = */ false,
/* aLoadState = */ nullptr, aResult);
RefPtr<BrowsingContext> bc;
MOZ_TRY(OpenWindowInternal(aParent, aUrl, aName, aFeatures,
/* calledFromJS = */ false, dialog,
/* navigate = */ true, argv,
/* aIsPopupSpam = */ false,
/* aForceNoOpener = */ false,
/* aForceNoReferrer = */ false,
/* aLoadState = */ nullptr, getter_AddRefs(bc)));
nsCOMPtr<mozIDOMWindowProxy> win(bc->GetDOMWindow());
win.forget(aResult);
return NS_OK;
}
struct SizeSpec {
@@ -350,7 +355,7 @@ nsWindowWatcher::OpenWindow2(mozIDOMWindowProxy* aParent, const char* aUrl,
bool aIsPopupSpam, bool aForceNoOpener,
bool aForceNoReferrer,
nsDocShellLoadState* aLoadState,
mozIDOMWindowProxy** aResult) {
BrowsingContext** aResult) {
nsCOMPtr<nsIArray> argv = ConvertArgsToArray(aArguments);
uint32_t argc = 0;
@@ -577,7 +582,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
const char* aFeatures, bool aCalledFromJS, bool aDialog, bool aNavigate,
nsIArray* aArgv, bool aIsPopupSpam, bool aForceNoOpener,
bool aForceNoReferrer, nsDocShellLoadState* aLoadState,
mozIDOMWindowProxy** aResult) {
BrowsingContext** aResult) {
MOZ_ASSERT_IF(aForceNoReferrer, aForceNoOpener);
nsresult rv = NS_OK;
@@ -926,12 +931,17 @@ nsresult nsWindowWatcher::OpenWindowInternal(
newDocShell->SetSandboxFlags(activeDocsSandboxFlags);
}
nsCOMPtr<mozIDOMWindowProxy> win;
rv = ReadyOpenedDocShellItem(newDocShellItem, parentWindow, windowIsNew,
aForceNoOpener, aResult);
aForceNoOpener, getter_AddRefs(win));
if (NS_FAILED(rv)) {
return rv;
}
RefPtr<BrowsingContext> bc(
nsPIDOMWindowOuter::From(win)->GetBrowsingContext());
bc.forget(aResult);
if (isNewToplevelWindow) {
nsCOMPtr<nsIDocShellTreeOwner> newTreeOwner;
newDocShellItem->GetTreeOwner(getter_AddRefs(newTreeOwner));
@@ -940,7 +950,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
if ((aDialog || windowIsModalContentDialog) && aArgv) {
// Set the args on the new window.
nsCOMPtr<nsPIDOMWindowOuter> piwin(do_QueryInterface(*aResult));
nsCOMPtr<nsPIDOMWindowOuter> piwin(do_QueryInterface(win));
NS_ENSURE_TRUE(piwin, NS_ERROR_UNEXPECTED);
rv = piwin->SetArguments(aArgv);
@@ -1009,7 +1019,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
// the JS stack, just use the principal of our parent window. In those
// cases we do _not_ set the parent window principal as the owner of the
// load--since we really don't know who the owner is, just leave it null.
nsCOMPtr<nsPIDOMWindowOuter> newWindow = do_QueryInterface(*aResult);
nsCOMPtr<nsPIDOMWindowOuter> newWindow = do_QueryInterface(win);
NS_ASSERTION(newWindow == newDocShell->GetWindow(), "Different windows??");
// The principal of the initial about:blank document gets set up in
@@ -1114,7 +1124,7 @@ nsresult nsWindowWatcher::OpenWindowInternal(
nsCOMPtr<nsIObserverService> obsSvc =
mozilla::services::GetObserverService();
if (obsSvc) {
obsSvc->NotifyObservers(*aResult, "toplevel-window-ready", nullptr);
obsSvc->NotifyObservers(win, "toplevel-window-ready", nullptr);
}
}