mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
73177efba4
commit
cfb5bc6d79
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -9,6 +9,10 @@ UNIFIED_SOURCES += [
|
||||
'nsWindowWatcher.cpp',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsWindowWatcher.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_XUL']:
|
||||
UNIFIED_SOURCES += [
|
||||
'nsDialogParamBlock.cpp',
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user