Bug 989501 - Part 2: When content in an e10s tab requests a new window be opened, forward that call to the TabParent, and have the TabParent pass itself in when creating the new window. r=smaug.

This commit is contained in:
Mike Conley 2014-06-20 14:07:47 -04:00
parent 73177efba4
commit cfb5bc6d79
9 changed files with 302 additions and 99 deletions

View File

@ -94,7 +94,15 @@ parent:
Event(RemoteDOMEvent aEvent);
intr CreateWindow() returns (PBrowser window);
intr CreateWindow(uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
nsString aURI,
nsString aName,
nsString aFeatures,
nsString aBaseURI)
returns (bool windowIsNew, PBrowser window);
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal)

View File

@ -42,9 +42,11 @@
#include "nsFilePickerProxy.h"
#include "mozilla/dom/Element.h"
#include "nsIBaseWindow.h"
#include "nsIBrowserDOMWindow.h"
#include "nsICachedFileDescriptorListener.h"
#include "nsIDocumentInlines.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIDOMChromeWindow.h"
#include "nsIDOMEvent.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowUtils.h"
@ -64,6 +66,7 @@
#include "nsPrintfCString.h"
#include "nsThreadUtils.h"
#include "nsWeakReference.h"
#include "nsWindowWatcher.h"
#include "PermissionMessageUtils.h"
#include "PCOMContentPermissionRequestChild.h"
#include "PuppetWidget.h"
@ -1230,13 +1233,68 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, uint32_t aChromeFlags,
aWindowIsNew, aReturn);
}
// Otherwise, create a new top-level window.
int32_t openLocation =
nsWindowWatcher::GetWindowOpenLocation(aParent, aChromeFlags, aCalledFromJS,
aPositionSpecified, aSizeSpecified);
// If it turns out we're opening in the current browser, just hand over the
// current browser's docshell.
if (openLocation == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
nsCOMPtr<nsIWebBrowser> browser = do_GetInterface(WebNavigation());
*aWindowIsNew = false;
return browser->GetContentDOMWindow(aReturn);
}
// Otherwise, we're opening a new tab or a new window. We have to contact
// TabParent in order to do either.
PBrowserChild* newChild;
if (!CallCreateWindow(&newChild)) {
nsAutoCString uriString;
if (aURI) {
aURI->GetSpec(uriString);
}
nsCOMPtr<nsIDOMDocument> domDoc;
aParent->GetDocument(getter_AddRefs(domDoc));
if (!domDoc) {
NS_ERROR("Could retrieve document from nsIBaseWindow");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc;
doc = do_QueryInterface(domDoc);
if (!doc) {
NS_ERROR("Document from nsIBaseWindow didn't QI to nsIDocument");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
if (!baseURI) {
NS_ERROR("nsIDocument didn't return a base URI");
return NS_ERROR_FAILURE;
}
nsAutoCString baseURIString;
baseURI->GetSpec(baseURIString);
nsAutoString nameString;
nameString.Assign(aName);
nsAutoCString features;
// We can assume that if content is requesting to open a window from a remote
// tab, then we want to enforce that the new window is also a remote tab.
features.Assign(aFeatures);
features.Append(",remote");
if (!CallCreateWindow(aChromeFlags, aCalledFromJS, aPositionSpecified,
aSizeSpecified, NS_ConvertUTF8toUTF16(uriString),
nameString, NS_ConvertUTF8toUTF16(features),
NS_ConvertUTF8toUTF16(baseURIString),
aWindowIsNew, &newChild)) {
return NS_ERROR_NOT_AVAILABLE;
}
*aWindowIsNew = true;
nsCOMPtr<nsIDOMWindow> win =
do_GetInterface(static_cast<TabChild*>(newChild)->WebNavigation());
win.forget(aReturn);

View File

@ -44,15 +44,18 @@
#include "nsIPromptFactory.h"
#include "nsIURI.h"
#include "nsIWebBrowserChrome.h"
#include "nsIWindowCreator2.h"
#include "nsIXULBrowserWindow.h"
#include "nsIXULWindow.h"
#include "nsViewManager.h"
#include "nsIWidget.h"
#include "nsIWindowWatcher.h"
#include "nsPIDOMWindow.h"
#include "nsPIWindowWatcher.h"
#include "nsPrintfCString.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "nsWindowWatcher.h"
#include "private/pprio.h"
#include "PermissionMessageUtils.h"
#include "StructuredCloneUtils.h"
@ -388,35 +391,95 @@ TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
}
bool
TabParent::AnswerCreateWindow(PBrowserParent** retval)
TabParent::AnswerCreateWindow(const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
PBrowserParent** aRetVal)
{
if (!mBrowserDOMWindow) {
return false;
}
if (IsBrowserOrApp()) {
return false;
}
// Only non-app, non-browser processes may call CreateWindow.
if (IsBrowserOrApp()) {
return false;
}
nsresult rv;
nsCOMPtr<nsPIWindowWatcher> pwwatch =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIContent> frame(do_QueryInterface(mFrameElement));
NS_ENSURE_TRUE(frame, false);
nsCOMPtr<nsIDOMWindow> parent = do_QueryInterface(frame->OwnerDoc()->GetWindow());
NS_ENSURE_TRUE(parent, false);
int32_t openLocation =
nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS,
aPositionSpecified, aSizeSpecified);
MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
*aWindowIsNew = true;
// Opening new tabs is the easy case...
if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
NS_ENSURE_TRUE(mBrowserDOMWindow, false);
// Get a new rendering area from the browserDOMWin. We don't want
// to be starting any loads here, so get it with a null URI.
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
mBrowserDOMWindow->OpenURIInFrame(nullptr, nullptr,
nsIBrowserDOMWindow::OPEN_NEWTAB,
nsIBrowserDOMWindow::OPEN_NEW,
getter_AddRefs(frameLoaderOwner));
if (!frameLoaderOwner) {
return false;
}
NS_ENSURE_TRUE(frameLoaderOwner, false);
nsRefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
if (!frameLoader) {
return false;
}
NS_ENSURE_TRUE(frameLoader, false);
*retval = frameLoader->GetRemoteBrowser();
*aRetVal = frameLoader->GetRemoteBrowser();
return true;
}
// WindowWatcher is going to expect a valid URI to open a window
// to. If it can't find one, it's going to attempt to figure one
// out on its own, which is problematic because it can't access
// the document for the remote browser we're opening. Luckily,
// TabChild has sent us a baseURI with which we can ensure that
// the URI we pass to WindowWatcher is valid.
nsCOMPtr<nsIURI> baseURI;
rv = NS_NewURI(getter_AddRefs(baseURI), aBaseURI);
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIURI> finalURI;
rv = NS_NewURI(getter_AddRefs(finalURI), NS_ConvertUTF16toUTF8(aURI).get(), baseURI);
NS_ENSURE_SUCCESS(rv, false);
nsAutoCString finalURIString;
finalURI->GetSpec(finalURIString);
nsCOMPtr<nsIDOMWindow> window;
rv = pwwatch->OpenWindow2(parent, finalURIString.get(),
NS_ConvertUTF16toUTF8(aName).get(),
NS_ConvertUTF16toUTF8(aFeatures).get(), aCalledFromJS,
false, false, this, nullptr, getter_AddRefs(window));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(window);
NS_ENSURE_TRUE(pwindow, false);
nsRefPtr<nsIDocShell> newDocShell = pwindow->GetDocShell();
NS_ENSURE_TRUE(newDocShell, false);
nsCOMPtr<nsITabParent> newRemoteTab = newDocShell->GetOpenedRemote();
NS_ENSURE_TRUE(newRemoteTab, false);
*aRetVal = static_cast<TabParent*>(newRemoteTab.get());
return true;
}
void

View File

@ -127,7 +127,16 @@ public:
const nsString& aName,
const nsString& aFeatures,
bool* aOutWindowOpened) MOZ_OVERRIDE;
virtual bool AnswerCreateWindow(PBrowserParent** retval) MOZ_OVERRIDE;
virtual bool AnswerCreateWindow(const uint32_t& aChromeFlags,
const bool& aCalledFromJS,
const bool& aPositionSpecified,
const bool& aSizeSpecified,
const nsString& aURI,
const nsString& aName,
const nsString& aFeatures,
const nsString& aBaseURI,
bool* aWindowIsNew,
PBrowserParent** aRetVal) MOZ_OVERRIDE;
virtual bool RecvSyncMessage(const nsString& aMessage,
const ClonedMessageData& aData,
const InfallibleTArray<CpowEntry>& aCpows,

View File

@ -9,6 +9,10 @@ UNIFIED_SOURCES += [
'nsWindowWatcher.cpp',
]
EXPORTS += [
'nsWindowWatcher.h',
]
if CONFIG['MOZ_XUL']:
UNIFIED_SOURCES += [
'nsDialogParamBlock.cpp',

View File

@ -15,6 +15,7 @@
#include "plstr.h"
#include "nsIBaseWindow.h"
#include "nsIBrowserDOMWindow.h"
#include "nsIDocShell.h"
#include "nsIDocShellLoadInfo.h"
#include "nsIDocShellTreeItem.h"
@ -438,7 +439,10 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
windowNeedsName = false,
windowIsModal = false,
uriToLoadIsChrome = false,
windowIsModalContentDialog = false;
windowIsModalContentDialog = false,
// Opening tabs are only ever passed to OpenWindowInternal if we're opening
// a window from a remote tab.
openedFromRemoteTab = !!aOpeningTab;
uint32_t chromeFlags;
nsAutoString name; // string version of aName
nsAutoCString features; // string version of aFeatures
@ -447,6 +451,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
nsCOMPtr<nsIDocShellTreeItem> newDocShellItem; // from the new window
nsCxPusher callerContextGuard;
MOZ_ASSERT_IF(openedFromRemoteTab, XRE_GetProcessType() == GeckoProcessType_Default);
NS_ENSURE_ARG_POINTER(_retval);
*_retval = 0;
@ -476,9 +481,17 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
features.StripWhitespace();
}
// try to find an extant window with the given name
nsCOMPtr<nsIDOMWindow> foundWindow = SafeGetWindowByName(name, aParent);
GetWindowTreeItem(foundWindow, getter_AddRefs(newDocShellItem));
// We only want to check for existing named windows if:
// a) We're the child process
// b) We're the parent process, and aOpeningTab wasn't passed
// in.
// This is because when using child processes, the parent process shouldn't
// know or care about names - unless we're opening named windows from chrome.
if (!aOpeningTab) {
// try to find an extant window with the given name
nsCOMPtr<nsIDOMWindow> foundWindow = SafeGetWindowByName(name, aParent);
GetWindowTreeItem(foundWindow, getter_AddRefs(newDocShellItem));
}
// Do sandbox checks here, instead of waiting until nsIDocShell::LoadURI.
// The state of the window can change before this call and if we are blocked
@ -504,7 +517,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
nsCOMPtr<nsIDOMDocument> domdoc;
aParent->GetDocument(getter_AddRefs(domdoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domdoc);
hasChromeParent = doc && nsContentUtils::IsChromeDoc(doc);
hasChromeParent = doc && nsContentUtils::IsChromeDoc(doc) && !openedFromRemoteTab;
}
// Make sure we call CalculateChromeFlags() *before* we push the
@ -513,7 +526,12 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
// security checks.
chromeFlags = CalculateChromeFlags(aParent, features.get(), featuresSpecified,
aDialog, uriToLoadIsChrome,
hasChromeParent);
hasChromeParent, openedFromRemoteTab);
// If we are opening a window from a remote browser, the resulting window
// should also be remote.
MOZ_ASSERT_IF(openedFromRemoteTab,
chromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW);
// If we're not called through our JS version of the API, and we got
// our internal modal option, treat the window we're opening as a
@ -537,7 +555,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
nsCOMPtr<nsIScriptSecurityManager>
sm(do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID));
bool isCallerChrome = nsContentUtils::IsCallerChrome();
bool isCallerChrome = nsContentUtils::IsCallerChrome() && !openedFromRemoteTab;
JSContext *cx = GetJSContextFromWindow(aParent);
@ -939,7 +957,7 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow *aParent,
}
if (isNewToplevelWindow)
SizeOpenedDocShellItem(newDocShellItem, aParent, sizeSpec);
SizeOpenedDocShellItem(newDocShellItem, aParent, isCallerChrome, sizeSpec);
// XXXbz isn't windowIsModal always true when windowIsModalContentDialog?
if (windowIsModal || windowIsModalContentDialog) {
@ -1403,7 +1421,8 @@ uint32_t nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow *aParent,
bool aFeaturesSpecified,
bool aDialog,
bool aChromeURL,
bool aHasChromeParent)
bool aHasChromeParent,
bool aOpenedFromRemoteTab)
{
if(!aFeaturesSpecified || !aFeatures) {
if(aDialog)
@ -1431,7 +1450,7 @@ uint32_t nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow *aParent,
/* Next, allow explicitly named options to override the initial settings */
bool isCallerChrome = nsContentUtils::IsCallerChrome();
bool isCallerChrome = nsContentUtils::IsCallerChrome() && !aOpenedFromRemoteTab;
// Determine whether the window is a private browsing window
if (isCallerChrome) {
@ -1442,7 +1461,7 @@ uint32_t nsWindowWatcher::CalculateChromeFlags(nsIDOMWindow *aParent,
}
// Determine whether the window should have remote tabs.
if (isCallerChrome) {
if (isCallerChrome || aOpenedFromRemoteTab) {
bool remote;
if (Preferences::GetBool("browser.tabs.remote.autostart")) {
remote = !WinHasOption(aFeatures, "non-remote", 0, &presenceFlag);
@ -1877,6 +1896,7 @@ nsWindowWatcher::CalcSizeSpec(const char* aFeatures, SizeSpec& aResult)
void
nsWindowWatcher::SizeOpenedDocShellItem(nsIDocShellTreeItem *aDocShellItem,
nsIDOMWindow *aParent,
bool aIsCallerChrome,
const SizeSpec & aSizeSpec)
{
// position and size of window
@ -1984,7 +2004,7 @@ nsWindowWatcher::SizeOpenedDocShellItem(nsIDocShellTreeItem *aDocShellItem,
// Check security state for use in determing window dimensions
bool enabled = false;
if (nsContentUtils::IsCallerChrome()) {
if (aIsCallerChrome) {
// Only enable special priveleges for chrome when chrome calls
// open() on a chrome window
nsCOMPtr<nsIDOMChromeWindow> chromeWin(do_QueryInterface(aParent));
@ -2102,6 +2122,75 @@ nsWindowWatcher::GetWindowTreeOwner(nsIDOMWindow *inWindow,
treeItem->GetTreeOwner(outTreeOwner);
}
/* static */
int32_t nsWindowWatcher::GetWindowOpenLocation(nsIDOMWindow *aParent,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified)
{
bool isFullScreen = false;
if (aParent) {
aParent->GetFullScreen(&isFullScreen);
}
// Where should we open this?
int32_t containerPref;
if (NS_FAILED(Preferences::GetInt("browser.link.open_newwindow",
&containerPref))) {
// We couldn't read the user preference, so fall back on the default.
return nsIBrowserDOMWindow::OPEN_NEWTAB;
}
bool isDisabledOpenNewWindow =
isFullScreen &&
Preferences::GetBool("browser.link.open_newwindow.disabled_in_fullscreen");
if (isDisabledOpenNewWindow && (containerPref == nsIBrowserDOMWindow::OPEN_NEWWINDOW)) {
containerPref = nsIBrowserDOMWindow::OPEN_NEWTAB;
}
if (containerPref != nsIBrowserDOMWindow::OPEN_NEWTAB &&
containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
// Just open a window normally
return nsIBrowserDOMWindow::OPEN_NEWWINDOW;
}
if (aCalledFromJS) {
/* Now check our restriction pref. The restriction pref is a power-user's
fine-tuning pref. values:
0: no restrictions - divert everything
1: don't divert window.open at all
2: don't divert window.open with features
*/
int32_t restrictionPref =
Preferences::GetInt("browser.link.open_newwindow.restriction", 2);
if (restrictionPref < 0 || restrictionPref > 2) {
restrictionPref = 2; // Sane default behavior
}
if (isDisabledOpenNewWindow) {
// In browser fullscreen, the window should be opened
// in the current window with no features (see bug 803675)
restrictionPref = 0;
}
if (restrictionPref == 1) {
return nsIBrowserDOMWindow::OPEN_NEWWINDOW;
}
if (restrictionPref == 2 &&
// Only continue if there are no size/position features and no special
// chrome flags.
(aChromeFlags != nsIWebBrowserChrome::CHROME_ALL ||
aPositionSpecified || aSizeSpecified)) {
return nsIBrowserDOMWindow::OPEN_NEWWINDOW;
}
}
return containerPref;
}
JSContext *
nsWindowWatcher::GetJSContextFromWindow(nsIDOMWindow *aWindow)
{

View File

@ -51,6 +51,12 @@ public:
NS_DECL_NSPIWINDOWWATCHER
NS_DECL_NSIPROMPTFACTORY
static int32_t GetWindowOpenLocation(nsIDOMWindow *aParent,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified);
protected:
friend class nsPromptService;
bool AddEnumerator(nsWatcherWindowEnumerator* inEnumerator);
@ -92,7 +98,8 @@ protected:
bool aFeaturesSpecified,
bool aDialog,
bool aChromeURL,
bool aHasChromeParent);
bool aHasChromeParent,
bool aOpenedFromRemoteTab);
static int32_t WinHasOption(const char *aOptions, const char *aName,
int32_t aDefault, bool *aPresenceFlag);
/* Compute the right SizeSpec based on aFeatures */
@ -103,6 +110,7 @@ protected:
nsIDOMWindow **aOpenedWindow);
static void SizeOpenedDocShellItem(nsIDocShellTreeItem *aDocShellItem,
nsIDOMWindow *aParent,
bool aIsCallerChrome,
const SizeSpec & aSizeSpec);
static void GetWindowTreeItem(nsIDOMWindow *inWindow,
nsIDocShellTreeItem **outTreeItem);

View File

@ -606,27 +606,39 @@ nsAppShellService::JustCreateTopWindow(nsIXULWindow *aParent,
// Enforce the Private Browsing autoStart pref first.
bool isPrivateBrowsingWindow =
Preferences::GetBool("browser.privatebrowsing.autostart");
bool isUsingRemoteTabs =
Preferences::GetBool("browser.tabs.remote.autostart");
if (aChromeMask & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW) {
// Caller requested a private window
isPrivateBrowsingWindow = true;
}
if (!isPrivateBrowsingWindow) {
if (aChromeMask & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW) {
isUsingRemoteTabs = true;
}
nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(aParent);
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(domWin);
nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(webNav);
if (!isPrivateBrowsingWindow && parentContext) {
// Ensure that we propagate any existing private browsing status
// from the parent, even if it will not actually be used
// as a parent value.
nsCOMPtr<nsIDOMWindow> domWin = do_GetInterface(aParent);
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(domWin);
nsCOMPtr<nsILoadContext> parentContext = do_QueryInterface(webNav);
if (parentContext) {
isPrivateBrowsingWindow = parentContext->UsePrivateBrowsing();
}
isPrivateBrowsingWindow = parentContext->UsePrivateBrowsing();
}
if (!isUsingRemoteTabs && parentContext) {
isUsingRemoteTabs = parentContext->UseRemoteTabs();
}
nsCOMPtr<nsIDOMWindow> newDomWin =
do_GetInterface(NS_ISUPPORTS_CAST(nsIBaseWindow*, window));
nsCOMPtr<nsIWebNavigation> newWebNav = do_GetInterface(newDomWin);
nsCOMPtr<nsILoadContext> thisContext = do_GetInterface(newWebNav);
if (thisContext) {
thisContext->SetPrivateBrowsing(isPrivateBrowsingWindow);
thisContext->SetRemoteTabs(isUsingRemoteTabs);
}
window.swap(*aResult); // transfer reference

View File

@ -34,6 +34,7 @@
#include "nsIExternalURLHandlerService.h"
#include "nsIMIMEInfo.h"
#include "nsIWidget.h"
#include "nsWindowWatcher.h"
#include "mozilla/BrowserElementParent.h"
#include "nsIDOMDocument.h"
@ -869,65 +870,16 @@ nsContentTreeOwner::ProvideWindow(nsIDOMWindow* aParent,
}
}
// the parent window is fullscreen mode or not.
bool isFullScreen = false;
if (aParent) {
aParent->GetFullScreen(&isFullScreen);
}
int32_t openLocation =
nsWindowWatcher::GetWindowOpenLocation(aParent, aChromeFlags, aCalledFromJS,
aPositionSpecified, aSizeSpecified);
// Where should we open this?
int32_t containerPref;
if (NS_FAILED(Preferences::GetInt("browser.link.open_newwindow",
&containerPref))) {
return NS_OK;
}
bool isDisabledOpenNewWindow =
isFullScreen &&
Preferences::GetBool("browser.link.open_newwindow.disabled_in_fullscreen");
if (isDisabledOpenNewWindow && (containerPref == nsIBrowserDOMWindow::OPEN_NEWWINDOW)) {
containerPref = nsIBrowserDOMWindow::OPEN_NEWTAB;
}
if (containerPref != nsIBrowserDOMWindow::OPEN_NEWTAB &&
containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
if (openLocation != nsIBrowserDOMWindow::OPEN_NEWTAB &&
openLocation != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
// Just open a window normally
return NS_OK;
}
if (aCalledFromJS) {
/* Now check our restriction pref. The restriction pref is a power-user's
fine-tuning pref. values:
0: no restrictions - divert everything
1: don't divert window.open at all
2: don't divert window.open with features
*/
int32_t restrictionPref =
Preferences::GetInt("browser.link.open_newwindow.restriction", 2);
if (restrictionPref < 0 || restrictionPref > 2) {
restrictionPref = 2; // Sane default behavior
}
if (isDisabledOpenNewWindow) {
// In browser fullscreen, the window should be opened
// in the current window with no features (see bug 803675)
restrictionPref = 0;
}
if (restrictionPref == 1) {
return NS_OK;
}
if (restrictionPref == 2 &&
// Only continue if there are no size/position features and no special
// chrome flags.
(aChromeFlags != nsIWebBrowserChrome::CHROME_ALL ||
aPositionSpecified || aSizeSpecified)) {
return NS_OK;
}
}
nsCOMPtr<nsIDOMWindow> domWin;
mXULWindow->GetWindowDOMWindow(getter_AddRefs(domWin));
nsCOMPtr<nsIDOMChromeWindow> chromeWin = do_QueryInterface(domWin);
@ -936,21 +888,21 @@ nsContentTreeOwner::ProvideWindow(nsIDOMWindow* aParent,
NS_WARNING("nsXULWindow's DOMWindow is not a chrome window");
return NS_OK;
}
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
chromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
if (!browserDOMWin) {
return NS_OK;
}
*aWindowIsNew = (containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW);
*aWindowIsNew = (openLocation != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW);
{
dom::AutoNoJSAPI nojsapi;
// Get a new rendering area from the browserDOMWin. We don't want
// to be starting any loads here, so get it with a null URI.
return browserDOMWin->OpenURI(nullptr, aParent, containerPref,
return browserDOMWin->OpenURI(nullptr, aParent, openLocation,
nsIBrowserDOMWindow::OPEN_NEW, aReturn);
}
}