Bug 1021466 - Part 2: Make it possible to pass in an nsITabParent when opening windows, and then stash that nsITabParent in the newly created chrome docshell. r=smaug.

This commit is contained in:
Mike Conley 2014-06-05 22:51:14 -04:00
parent 1da1d37e14
commit 8697a1814f
15 changed files with 75 additions and 29 deletions

View File

@ -11644,7 +11644,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
// !aCalledNoScript.
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
/* aCalledFromScript = */ true,
aDialog, aNavigate, argv,
aDialog, aNavigate, nullptr, argv,
getter_AddRefs(domReturn));
} else {
// Force a system caller here so that the window watcher won't screw us
@ -11664,7 +11664,7 @@ nsGlobalWindow::OpenInternal(const nsAString& aUrl, const nsAString& aName,
rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
/* aCalledFromScript = */ false,
aDialog, aNavigate, aExtraArgument,
aDialog, aNavigate, nullptr, aExtraArgument,
getter_AddRefs(domReturn));
}

View File

@ -17,10 +17,11 @@
#include "nsIWindowCreator.idl"
interface nsITabParent;
interface nsIURI;
interface nsIWebBrowserChrome;
[scriptable, uuid(f673ec81-a4b0-11d6-964b-eb5a2bf216fc)]
[scriptable, uuid(e28f810b-9b49-4927-a4be-62a74fadfe21)]
interface nsIWindowCreator2 : nsIWindowCreator {
@ -44,6 +45,8 @@ interface nsIWindowCreator2 : nsIWindowCreator {
may use the URL to help determine what sort of window
to open or whether to cancel window creation. It will not
load the URL.
@param aOpeningTab The TabParent that is trying to open this new chrome
window. Can be nullptr.
@param cancel Return |true| to reject window creation. If true the
implementation has determined the window should not
be created at all. The caller should not default
@ -54,5 +57,6 @@ interface nsIWindowCreator2 : nsIWindowCreator {
in uint32_t chromeFlags,
in uint32_t contextFlags,
in nsIURI uri,
in nsITabParent aOpeningTab,
out boolean cancel);
};

View File

@ -15,8 +15,9 @@ interface nsISimpleEnumerator;
interface nsIWebBrowserChrome;
interface nsIDocShellTreeItem;
interface nsIArray;
interface nsITabParent;
[uuid(00788A84-152F-4BD8-A814-FD8EB545DB29)]
[uuid(0f2d9d75-c46b-4114-802e-83b4655e61d2)]
interface nsPIWindowWatcher : nsISupports
{
@ -51,6 +52,9 @@ interface nsPIWindowWatcher : nsISupports
@param aDialog use dialog defaults (see nsIDOMWindow::openDialog)
@param aNavigate true if we should navigate the new window to the
specified URL.
@param aOpeningTab the nsITabParent that is opening the new window. The
nsITabParent is a remote tab belonging to aParent. Can
be nullptr if this window is not being opened from a tab.
@param aArgs Window argument
@return the new window
@ -65,7 +69,8 @@ interface nsPIWindowWatcher : nsISupports
nsIDOMWindow openWindow2(in nsIDOMWindow aParent, in string aUrl,
in string aName, in string aFeatures,
in boolean aCalledFromScript, in boolean aDialog,
in boolean aNavigate, in nsISupports aArgs);
in boolean aNavigate, in nsITabParent aOpeningTab,
in nsISupports aArgs);
/**
* Find a named docshell tree item amongst all windows registered

View File

@ -342,7 +342,7 @@ nsWindowWatcher::OpenWindow(nsIDOMWindow *aParent,
return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
/* calledFromJS = */ false, dialog,
/* navigate = */ true, argv, _retval);
/* navigate = */ true, nullptr, argv, _retval);
}
struct SizeSpec {
@ -394,6 +394,7 @@ nsWindowWatcher::OpenWindow2(nsIDOMWindow *aParent,
bool aCalledFromScript,
bool aDialog,
bool aNavigate,
nsITabParent *aOpeningTab,
nsISupports *aArguments,
nsIDOMWindow **_retval)
{
@ -414,7 +415,7 @@ nsWindowWatcher::OpenWindow2(nsIDOMWindow *aParent,
return OpenWindowInternal(aParent, aUrl, aName, aFeatures,
aCalledFromScript, dialog,
aNavigate, argv, _retval);
aNavigate, aOpeningTab, argv, _retval);
}
nsresult
@ -425,6 +426,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
bool aCalledFromJS,
bool aDialog,
bool aNavigate,
nsITabParent *aOpeningTab,
nsIArray *argv,
nsIDOMWindow **_retval)
{
@ -698,7 +700,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
bool cancel = false;
rv = windowCreator2->CreateChromeWindow2(parentChrome, chromeFlags,
contextFlags, uriToLoad,
&cancel,
aOpeningTab, &cancel,
getter_AddRefs(newChrome));
if (NS_SUCCEEDED(rv) && cancel) {
newChrome = 0; // just in case

View File

@ -15,6 +15,7 @@
#include "nsIWindowCreator.h" // for stupid compilers
#include "nsIWindowWatcher.h"
#include "nsIPromptFactory.h"
#include "nsITabParent.h"
#include "nsPIWindowWatcher.h"
#include "nsTArray.h"
#include "js/TypeDecls.h"
@ -77,6 +78,7 @@ protected:
bool aCalledFromJS,
bool aDialog,
bool aNavigate,
nsITabParent *aOpeningTab,
nsIArray *argv,
nsIDOMWindow **_retval);

View File

@ -612,7 +612,7 @@ nsAppStartup::CreateChromeWindow(nsIWebBrowserChrome *aParent,
nsIWebBrowserChrome **_retval)
{
bool cancel;
return CreateChromeWindow2(aParent, aChromeFlags, 0, 0, &cancel, _retval);
return CreateChromeWindow2(aParent, aChromeFlags, 0, 0, nullptr, &cancel, _retval);
}
@ -625,6 +625,7 @@ nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
uint32_t aChromeFlags,
uint32_t aContextFlags,
nsIURI *aURI,
nsITabParent *aOpeningTab,
bool *aCancel,
nsIWebBrowserChrome **_retval)
{
@ -644,7 +645,7 @@ nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
NS_ASSERTION(xulParent, "window created using non-XUL parent. that's unexpected, but may work.");
if (xulParent)
xulParent->CreateNewWindow(aChromeFlags, getter_AddRefs(newWindow));
xulParent->CreateNewWindow(aChromeFlags, aOpeningTab, getter_AddRefs(newWindow));
// And if it fails, don't try again without a parent. It could fail
// intentionally (bug 115969).
} else { // try using basic methods:
@ -661,6 +662,7 @@ nsAppStartup::CreateChromeWindow2(nsIWebBrowserChrome *aParent,
appShell->CreateTopLevelWindow(0, 0, aChromeFlags,
nsIAppShellService::SIZE_TO_CONTENT,
nsIAppShellService::SIZE_TO_CONTENT,
aOpeningTab,
getter_AddRefs(newWindow));
}

View File

@ -407,7 +407,7 @@ Test4Internal(nsIAppShell* aAppShell)
uint32_t flags = nsIWebBrowserChrome::CHROME_DEFAULT;
nsCOMPtr<nsIXULWindow> xulWindow;
if (NS_FAILED(appService->CreateTopLevelWindow(nullptr, uri, flags, 100, 100,
if (NS_FAILED(appService->CreateTopLevelWindow(nullptr, uri, flags, 100, 100, nullptr,
getter_AddRefs(xulWindow)))) {
fail("Failed to create new window");
return false;

View File

@ -10,6 +10,7 @@ interface nsIWebNavigation;
interface nsIURI;
interface nsIDOMWindow;
interface nsIAppShell;
interface nsITabParent;
[ptr] native JSContext(JSContext);
@ -17,7 +18,7 @@ interface nsIAppShell;
#include "js/TypeDecls.h"
%}
[scriptable, uuid(2fa2f813-c216-4efb-8a8c-de60108ce5e5)]
[scriptable, uuid(41a2f0c6-3ca1-44f9-8efa-744a43aa399d)]
interface nsIAppShellService : nsISupports
{
/**
@ -35,14 +36,16 @@ interface nsIAppShellService : nsISupports
* tag in the XUL. Set to NS_SIZETOCONTENT to force
* the window to wrap to its contents.
* @param aInitialHeight like aInitialWidth, but subtly different.
* @param aResult the newly created window is returned here.
* @param aOpeningTab The TabParent that requested that this window be opened.
* Can be left null.
*/
const long SIZE_TO_CONTENT = -1;
nsIXULWindow createTopLevelWindow(in nsIXULWindow aParent,
in nsIURI aUrl,
in uint32_t aChromeMask,
in long aInitialWidth,
in long aInitialHeight);
in long aInitialHeight,
in nsITabParent aOpeningTab);
/**
* This is the constructor for creating an invisible DocShell.

View File

@ -16,8 +16,9 @@
interface nsIDocShell;
interface nsIDocShellTreeItem;
interface nsIXULBrowserWindow;
interface nsITabParent;
[scriptable, uuid(CCF9E98A-E442-4061-9F74-94539DD9FE9E)]
[scriptable, uuid(a68a40b9-f7df-47ff-a874-2af3df7eb888)]
interface nsIXULWindow : nsISupports
{
/**
@ -108,9 +109,12 @@ interface nsIXULWindow : nsISupports
/**
* Create a new window.
* @param aChromeFlags see nsIWebBrowserChrome
* @param aOpeningTab the TabParent that requested this new window be opened.
* Can be left null.
* @return the newly minted window
*/
nsIXULWindow createNewWindow(in int32_t aChromeFlags);
nsIXULWindow createNewWindow(in int32_t aChromeFlags,
in nsITabParent aOpeningTab);
attribute nsIXULBrowserWindow XULBrowserWindow;

View File

@ -127,7 +127,7 @@ nsAppShellService::CreateHiddenWindowHelper(bool aIsPrivate)
if (!aIsPrivate) {
rv = JustCreateTopWindow(nullptr, url,
chromeMask, initialWidth, initialHeight,
true, getter_AddRefs(newWindow));
true, nullptr, getter_AddRefs(newWindow));
NS_ENSURE_SUCCESS(rv, rv);
mHiddenWindow.swap(newWindow);
@ -137,7 +137,7 @@ nsAppShellService::CreateHiddenWindowHelper(bool aIsPrivate)
rv = JustCreateTopWindow(nullptr, url,
chromeMask, initialWidth, initialHeight,
true, getter_AddRefs(newWindow));
true, nullptr, getter_AddRefs(newWindow));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDocShell> docShell;
@ -181,6 +181,7 @@ nsAppShellService::CreateTopLevelWindow(nsIXULWindow *aParent,
uint32_t aChromeMask,
int32_t aInitialWidth,
int32_t aInitialHeight,
nsITabParent *aOpeningTab,
nsIXULWindow **aResult)
{
@ -191,7 +192,7 @@ nsAppShellService::CreateTopLevelWindow(nsIXULWindow *aParent,
nsWebShellWindow *newWindow = nullptr;
rv = JustCreateTopWindow(aParent, aUrl,
aChromeMask, aInitialWidth, aInitialHeight,
false, &newWindow); // addrefs
false, aOpeningTab, &newWindow); // addrefs
*aResult = newWindow; // transfer ref
@ -487,6 +488,7 @@ nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
int32_t aInitialWidth,
int32_t aInitialHeight,
bool aIsHiddenWindow,
nsITabParent *aOpeningTab,
nsWebShellWindow **aResult)
{
*aResult = nullptr;
@ -597,7 +599,7 @@ nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
nsresult rv = window->Initialize(parent, center ? aParent : nullptr,
aUrl, aInitialWidth, aInitialHeight,
aIsHiddenWindow, widgetInitData);
aIsHiddenWindow, aOpeningTab, widgetInitData);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -13,6 +13,7 @@
#include "nsWebShellWindow.h"
#include "nsStringFwd.h"
#include "nsAutoPtr.h"
#include "nsITabParent.h"
#include "mozilla/Attributes.h"
// {0099907D-123C-4853-A46A-43098B5FB68C}
@ -40,6 +41,7 @@ protected:
uint32_t aChromeMask,
int32_t aInitialWidth, int32_t aInitialHeight,
bool aIsHiddenWindow,
nsITabParent *aOpeningTab,
nsWebShellWindow **aResult);
uint32_t CalculateWindowZLevel(nsIXULWindow *aParent, uint32_t aChromeMask);

View File

@ -111,6 +111,7 @@ nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent,
int32_t aInitialWidth,
int32_t aInitialHeight,
bool aIsHiddenWindow,
nsITabParent *aOpeningTab,
nsWidgetInitData& widgetInitData)
{
nsresult rv;
@ -183,6 +184,8 @@ nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent,
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
mDocShell->SetOpener(aOpeningTab);
// Make sure to set the item type on the docshell _before_ calling
// Create() so it knows what type it is.
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));

View File

@ -12,6 +12,7 @@
#include "nsCOMPtr.h"
#include "nsXULWindow.h"
#include "nsIWidgetListener.h"
#include "nsITabParent.h"
/* Forward declarations.... */
class nsIURI;
@ -37,6 +38,7 @@ public:
nsIURI* aUrl,
int32_t aInitialWidth, int32_t aInitialHeight,
bool aIsHiddenWindow,
nsITabParent *aOpeningTab,
nsWidgetInitData& widgetInitData);
nsresult Toolbar();

View File

@ -1714,16 +1714,18 @@ NS_IMETHODIMP nsXULWindow::ExitModalLoop(nsresult aStatus)
// top-level function to create a new window
NS_IMETHODIMP nsXULWindow::CreateNewWindow(int32_t aChromeFlags,
nsITabParent *aOpeningTab,
nsIXULWindow **_retval)
{
NS_ENSURE_ARG_POINTER(_retval);
if (aChromeFlags & nsIWebBrowserChrome::CHROME_OPENAS_CHROME)
return CreateNewChromeWindow(aChromeFlags, _retval);
return CreateNewContentWindow(aChromeFlags, _retval);
return CreateNewChromeWindow(aChromeFlags, aOpeningTab, _retval);
return CreateNewContentWindow(aChromeFlags, aOpeningTab, _retval);
}
NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags,
nsITabParent *aOpeningTab,
nsIXULWindow **_retval)
{
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
@ -1735,6 +1737,7 @@ NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags,
appShell->CreateTopLevelWindow(this, nullptr, aChromeFlags,
nsIAppShellService::SIZE_TO_CONTENT,
nsIAppShellService::SIZE_TO_CONTENT,
aOpeningTab,
getter_AddRefs(newWindow));
NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
@ -1746,6 +1749,7 @@ NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(int32_t aChromeFlags,
}
NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
nsITabParent *aOpeningTab,
nsIXULWindow **_retval)
{
nsCOMPtr<nsIAppShellService> appShell(do_GetService(NS_APPSHELLSERVICE_CONTRACTID));
@ -1778,6 +1782,7 @@ NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
AutoNoJSAPI nojsapi;
appShell->CreateTopLevelWindow(this, uri,
aChromeFlags, 615, 480,
aOpeningTab,
getter_AddRefs(newWindow));
NS_ENSURE_TRUE(newWindow, NS_ERROR_FAILURE);
}
@ -1798,7 +1803,16 @@ NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(int32_t aChromeFlags,
}
}
// If aOpeningTab is not null, it means that we're creating a new window
// with a remote browser, which doesn't have a primary docshell. In that
// case, we check for the chrome window docshell and make sure that a new
// remote tab was opened and stashed in that docshell.
if (aOpeningTab) {
NS_ENSURE_STATE(xulWin->mDocShell);
NS_ENSURE_STATE(xulWin->mDocShell->GetOpenedRemote());
} else {
NS_ENSURE_STATE(xulWin->mPrimaryContentShell);
}
*_retval = newWindow;
NS_ADDREF(*_retval);

View File

@ -32,6 +32,7 @@
#include "nsIXULBrowserWindow.h"
#include "nsIWeakReference.h"
#include "nsIWidgetListener.h"
#include "nsITabParent.h"
namespace mozilla {
namespace dom {
@ -108,8 +109,8 @@ protected:
NS_IMETHOD SizeShellTo(nsIDocShellTreeItem* aShellItem, int32_t aCX,
int32_t aCY);
NS_IMETHOD ExitModalLoop(nsresult aStatus);
NS_IMETHOD CreateNewChromeWindow(int32_t aChromeFlags, nsIXULWindow **_retval);
NS_IMETHOD CreateNewContentWindow(int32_t aChromeFlags, nsIXULWindow **_retval);
NS_IMETHOD CreateNewChromeWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, nsIXULWindow **_retval);
NS_IMETHOD CreateNewContentWindow(int32_t aChromeFlags, nsITabParent* aOpeningTab, nsIXULWindow **_retval);
void EnableParent(bool aEnable);
bool ConstrainToZLevel(bool aImmediate, nsWindowZ *aPlacement,