зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1172870 - Part 2 - Enable ServiceWorkerClients::OpenWindow on e10s desktop. r=smaug
This commit is contained in:
Родитель
bad419762d
Коммит
8255b13467
|
@ -36,6 +36,7 @@
|
|||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/DocumentFragment.h"
|
||||
#include "mozilla/dom/DOMTypes.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
@ -188,6 +189,7 @@
|
|||
#include "nsViewManager.h"
|
||||
#include "nsViewportInfo.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
#include "nsIWindowProvider.h"
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "xpcprivate.h" // nsXPConnect
|
||||
|
@ -5206,6 +5208,14 @@ nsContentUtils::RemoveScriptBlocker()
|
|||
sBlockedScriptRunners->RemoveElementsAt(originalFirstBlocker, blockersCount);
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsIWindowProvider*
|
||||
nsContentUtils::GetWindowProviderForContentProcess()
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
return ContentChild::GetSingleton();
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsContentUtils::WarnScriptWasIgnored(nsIDocument* aDocument)
|
||||
|
|
|
@ -102,6 +102,7 @@ class nsWrapperCache;
|
|||
class nsAttrValue;
|
||||
class nsITransferable;
|
||||
class nsPIWindowRoot;
|
||||
class nsIWindowProvider;
|
||||
|
||||
struct JSPropertyDescriptor;
|
||||
struct JSRuntime;
|
||||
|
@ -1640,6 +1641,11 @@ public:
|
|||
return sScriptBlockerCount == 0;
|
||||
}
|
||||
|
||||
// XXXcatalinb: workaround for weird include error when trying to reference
|
||||
// ipdl types in WindowWatcher.
|
||||
static nsIWindowProvider*
|
||||
GetWindowProviderForContentProcess();
|
||||
|
||||
/**
|
||||
* Call this function if !IsSafeToRunScript() and we fail to run the script
|
||||
* (rather than using AddScriptRunner as we usually do). |aDocument| is
|
||||
|
|
|
@ -776,34 +776,47 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
|||
bool* aWindowIsNew,
|
||||
nsIDOMWindow** aReturn)
|
||||
{
|
||||
MOZ_ASSERT(aTabOpener);
|
||||
*aReturn = nullptr;
|
||||
|
||||
const TabId openerTabId = aTabOpener->GetTabId();
|
||||
nsAutoPtr<IPCTabContext> ipcContext;
|
||||
TabId openerTabId = TabId(0);
|
||||
|
||||
PopupIPCTabContext context;
|
||||
context.opener() = openerTabId;
|
||||
context.isBrowserElement() = aTabOpener->IsBrowserElement();
|
||||
|
||||
IPCTabContext ipcContext(context);
|
||||
if (aTabOpener) {
|
||||
PopupIPCTabContext context;
|
||||
openerTabId = aTabOpener->GetTabId();
|
||||
context.opener() = openerTabId;
|
||||
context.isBrowserElement() = aTabOpener->IsBrowserElement();
|
||||
ipcContext = new IPCTabContext(context);
|
||||
} else {
|
||||
// It's possible to not have a TabChild opener in the case
|
||||
// of ServiceWorker::OpenWindow.
|
||||
UnsafeIPCTabContext unsafeTabContext;
|
||||
ipcContext = new IPCTabContext(unsafeTabContext);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(ipcContext);
|
||||
TabId tabId;
|
||||
SendAllocateTabId(openerTabId,
|
||||
ipcContext,
|
||||
*ipcContext,
|
||||
GetID(),
|
||||
&tabId);
|
||||
|
||||
TabContext newTabContext = aTabOpener ? *aTabOpener : TabContext();
|
||||
RefPtr<TabChild> newChild = new TabChild(this, tabId,
|
||||
*aTabOpener, aChromeFlags);
|
||||
newTabContext, aChromeFlags);
|
||||
if (NS_FAILED(newChild->Init())) {
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
context.opener() = aTabOpener;
|
||||
if (aTabOpener) {
|
||||
MOZ_ASSERT(ipcContext->type() == IPCTabContext::TPopupIPCTabContext);
|
||||
ipcContext->get_PopupIPCTabContext().opener() = aTabOpener;
|
||||
}
|
||||
|
||||
unused << SendPBrowserConstructor(
|
||||
// We release this ref in DeallocPBrowserChild
|
||||
RefPtr<TabChild>(newChild).forget().take(),
|
||||
tabId, IPCTabContext(context), aChromeFlags,
|
||||
tabId, *ipcContext, aChromeFlags,
|
||||
GetID(), IsForApp(), IsForBrowser());
|
||||
|
||||
nsAutoCString spec;
|
||||
|
@ -823,16 +836,18 @@ ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
|||
NS_ConvertUTF8toUTF16(features),
|
||||
aWindowIsNew);
|
||||
} else {
|
||||
nsCOMPtr<nsPIDOMWindow> opener = do_QueryInterface(aParent);
|
||||
nsCOMPtr<nsIDocument> doc = opener->GetDoc();
|
||||
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);
|
||||
if (aTabOpener) {
|
||||
nsCOMPtr<nsPIDOMWindow> opener = do_QueryInterface(aParent);
|
||||
nsCOMPtr<nsIDocument> doc = opener->GetDoc();
|
||||
nsCOMPtr<nsIURI> baseURI = doc->GetDocBaseURI();
|
||||
if (!baseURI) {
|
||||
NS_ERROR("nsIDocument didn't return a base URI");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
baseURI->GetSpec(baseURIString);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
if (!SendCreateWindow(aTabOpener, newChild,
|
||||
|
|
|
@ -5405,10 +5405,12 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
|||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW));
|
||||
|
||||
TabParent* thisTabParent = TabParent::GetFrom(aThisTab);
|
||||
MOZ_ASSERT(thisTabParent);
|
||||
TabParent* thisTabParent = nullptr;
|
||||
if (aThisTab) {
|
||||
thisTabParent = TabParent::GetFrom(aThisTab);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(thisTabParent->IsBrowserOrApp())) {
|
||||
if (NS_WARN_IF(thisTabParent && thisTabParent->IsBrowserOrApp())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -5426,7 +5428,10 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
|||
// we must have an opener.
|
||||
newTab->SetHasContentOpener(true);
|
||||
|
||||
nsCOMPtr<nsIContent> frame(do_QueryInterface(thisTabParent->GetOwnerElement()));
|
||||
nsCOMPtr<nsIContent> frame;
|
||||
if (thisTabParent) {
|
||||
frame = do_QueryInterface(thisTabParent->GetOwnerElement());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> parent;
|
||||
if (frame) {
|
||||
|
@ -5439,7 +5444,10 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin = thisTabParent->GetBrowserDOMWindow();
|
||||
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
|
||||
if (thisTabParent) {
|
||||
browserDOMWin = thisTabParent->GetBrowserDOMWindow();
|
||||
}
|
||||
|
||||
// If we haven't found a chrome window to open in, just use the most recently
|
||||
// opened one.
|
||||
|
@ -5471,8 +5479,10 @@ ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
|||
}
|
||||
|
||||
bool isPrivate = false;
|
||||
nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
|
||||
loadContext->GetUsePrivateBrowsing(&isPrivate);
|
||||
if (thisTabParent) {
|
||||
nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
|
||||
loadContext->GetUsePrivateBrowsing(&isPrivate);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIOpenURIInFrameParams> params = new nsOpenURIInFrameParams();
|
||||
params->SetReferrer(aBaseURI);
|
||||
|
|
|
@ -150,10 +150,9 @@ ContentProcessManager::AllocateTabId(const TabId& aOpenerTabId,
|
|||
|
||||
struct RemoteFrameInfo info;
|
||||
|
||||
const IPCTabContextUnion& contextUnion = aContext.contextUnion();
|
||||
// If it's a PopupIPCTabContext, it's the case that a TabChild want to
|
||||
// open a new tab. aOpenerTabId has to be it's parent frame's opener id.
|
||||
if (contextUnion.type() == IPCTabContextUnion::TPopupIPCTabContext) {
|
||||
if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
|
||||
auto remoteFrameIter = iter->second.mRemoteFrames.find(aOpenerTabId);
|
||||
if (remoteFrameIter == iter->second.mRemoteFrames.end()) {
|
||||
ASSERT_UNLESS_FUZZING("Failed to find parent frame's opener id.");
|
||||
|
@ -162,7 +161,7 @@ ContentProcessManager::AllocateTabId(const TabId& aOpenerTabId,
|
|||
|
||||
info.mOpenerTabId = remoteFrameIter->second.mOpenerTabId;
|
||||
|
||||
const PopupIPCTabContext &ipcContext = contextUnion.get_PopupIPCTabContext();
|
||||
const PopupIPCTabContext &ipcContext = aContext.get_PopupIPCTabContext();
|
||||
MOZ_ASSERT(ipcContext.opener().type() == PBrowserOrId::TTabId);
|
||||
|
||||
remoteFrameIter = iter->second.mRemoteFrames.find(ipcContext.opener().get_TabId());
|
||||
|
|
|
@ -1118,7 +1118,7 @@ parent:
|
|||
sync GetGraphicsDeviceInitData()
|
||||
returns (DeviceInitData aData);
|
||||
|
||||
sync CreateWindow(PBrowser aThisTab,
|
||||
sync CreateWindow(nullable PBrowser aThisTab,
|
||||
PBrowser aNewTab,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
|
|
|
@ -44,22 +44,25 @@ struct FrameIPCTabContext
|
|||
nsCString signedPkgOriginNoSuffix;
|
||||
};
|
||||
|
||||
// XXXcatalinb: This is only used by ServiceWorkerClients::OpenWindow.
|
||||
// Because service workers don't have an associated TabChild
|
||||
// we can't satisfy the security constraints on b2g. As such, the parent
|
||||
// process will accept this tab context only on desktop.
|
||||
struct UnsafeIPCTabContext
|
||||
{ };
|
||||
|
||||
// IPCTabContext is an analog to mozilla::dom::TabContext. Both specify an
|
||||
// iframe/PBrowser's own and containing app-ids and tell you whether the
|
||||
// iframe/PBrowser is a browser frame. But only IPCTabContext is allowed to
|
||||
// travel over IPC.
|
||||
//
|
||||
// We need IPCTabContext (specifically, PopupIPCTabContext) to prevent a
|
||||
// privilege escalation attack by a compromised child process. See the comment
|
||||
// on AllocPBrowser for details.
|
||||
union IPCTabContextUnion
|
||||
// privilege escalation attack by a compromised child process.
|
||||
union IPCTabContext
|
||||
{
|
||||
PopupIPCTabContext;
|
||||
FrameIPCTabContext;
|
||||
};
|
||||
|
||||
struct IPCTabContext {
|
||||
IPCTabContextUnion contextUnion;
|
||||
UnsafeIPCTabContext;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -232,10 +232,9 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
|||
nsAutoCString originSuffix;
|
||||
nsAutoCString signedPkgOriginNoSuffix;
|
||||
|
||||
const IPCTabContextUnion& contextUnion = aParams.contextUnion();
|
||||
switch(contextUnion.type()) {
|
||||
case IPCTabContextUnion::TPopupIPCTabContext: {
|
||||
const PopupIPCTabContext &ipcContext = contextUnion.get_PopupIPCTabContext();
|
||||
switch(aParams.type()) {
|
||||
case IPCTabContext::TPopupIPCTabContext: {
|
||||
const PopupIPCTabContext &ipcContext = aParams.get_PopupIPCTabContext();
|
||||
|
||||
TabContext *context;
|
||||
if (ipcContext.opener().type() == PBrowserOrId::TPBrowserParent) {
|
||||
|
@ -281,9 +280,9 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case IPCTabContextUnion::TFrameIPCTabContext: {
|
||||
case IPCTabContext::TFrameIPCTabContext: {
|
||||
const FrameIPCTabContext &ipcContext =
|
||||
contextUnion.get_FrameIPCTabContext();
|
||||
aParams.get_FrameIPCTabContext();
|
||||
|
||||
containingAppId = ipcContext.frameOwnerAppId();
|
||||
signedPkgOriginNoSuffix = ipcContext.signedPkgOriginNoSuffix();
|
||||
|
@ -291,6 +290,23 @@ MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
|
|||
originAttributes.PopulateFromSuffix(originSuffix);
|
||||
break;
|
||||
}
|
||||
case IPCTabContext::TUnsafeIPCTabContext: {
|
||||
// XXXcatalinb: This used *only* by ServiceWorkerClients::OpenWindow.
|
||||
// It is meant as a temporary solution until service workers can
|
||||
// provide a TabChild equivalent. Don't allow this on b2g since
|
||||
// it might be used to escalate privileges.
|
||||
#ifdef MOZ_B2G
|
||||
mInvalidReason = "ServiceWorkerClients::OpenWindow is not supported.";
|
||||
return;
|
||||
#endif
|
||||
if (!Preferences::GetBool("dom.serviceWorkers.enabled", false)) {
|
||||
mInvalidReason = "ServiceWorkers should be enabled.";
|
||||
return;
|
||||
}
|
||||
|
||||
containingAppId = NO_APP_ID;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
|
|
@ -71,35 +71,36 @@ nsIContentParent::DeallocPJavaScriptParent(PJavaScriptParent* aParent)
|
|||
bool
|
||||
nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext)
|
||||
{
|
||||
const IPCTabContextUnion& contextUnion = aContext.contextUnion();
|
||||
|
||||
// We don't trust the IPCTabContext we receive from the child, so we'll bail
|
||||
// if we receive an IPCTabContext that's not a PopupIPCTabContext.
|
||||
// (PopupIPCTabContext lets the child process prove that it has access to
|
||||
// the app it's trying to open.)
|
||||
if (contextUnion.type() != IPCTabContextUnion::TPopupIPCTabContext) {
|
||||
// On e10s we also allow UnsafeTabContext to allow service workers to open
|
||||
// windows. This is enforced in MaybeInvalidTabContext.
|
||||
if (aContext.type() != IPCTabContext::TPopupIPCTabContext &&
|
||||
aContext.type() != IPCTabContext::TUnsafeIPCTabContext) {
|
||||
ASSERT_UNLESS_FUZZING("Unexpected IPCTabContext type. Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const PopupIPCTabContext& popupContext = contextUnion.get_PopupIPCTabContext();
|
||||
if (popupContext.opener().type() != PBrowserOrId::TPBrowserParent) {
|
||||
ASSERT_UNLESS_FUZZING("Unexpected PopupIPCTabContext type. Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
|
||||
const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
|
||||
if (popupContext.opener().type() != PBrowserOrId::TPBrowserParent) {
|
||||
ASSERT_UNLESS_FUZZING("Unexpected PopupIPCTabContext type. Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
|
||||
if (!opener) {
|
||||
ASSERT_UNLESS_FUZZING("Got null opener from child; aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
|
||||
if (!opener) {
|
||||
ASSERT_UNLESS_FUZZING("Got null opener from child; aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Popup windows of isBrowser frames must be isBrowser if the parent
|
||||
// isBrowser. Allocating a !isBrowser frame with same app ID would allow
|
||||
// the content to access data it's not supposed to.
|
||||
if (!popupContext.isBrowserElement() && opener->IsBrowserElement()) {
|
||||
ASSERT_UNLESS_FUZZING("Child trying to escalate privileges! Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
// Popup windows of isBrowser frames must be isBrowser if the parent
|
||||
// isBrowser. Allocating a !isBrowser frame with same app ID would allow
|
||||
// the content to access data it's not supposed to.
|
||||
if (!popupContext.isBrowserElement() && opener->IsBrowserElement()) {
|
||||
ASSERT_UNLESS_FUZZING("Child trying to escalate privileges! Aborting AllocPBrowserParent.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MaybeInvalidTabContext tc(aContext);
|
||||
|
@ -129,26 +130,25 @@ nsIContentParent::AllocPBrowserParent(const TabId& aTabId,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const IPCTabContextUnion& contextUnion = aContext.contextUnion();
|
||||
const PopupIPCTabContext& popupContext = contextUnion.get_PopupIPCTabContext();
|
||||
|
||||
uint32_t chromeFlags = aChromeFlags;
|
||||
if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
|
||||
// CanOpenBrowser has ensured that the IPCTabContext is of
|
||||
// type PopupIPCTabContext, and that the opener TabParent is
|
||||
// reachable.
|
||||
const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
|
||||
auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
|
||||
// We must ensure that the private browsing and remoteness flags
|
||||
// match those of the opener.
|
||||
nsCOMPtr<nsILoadContext> loadContext = opener->GetLoadContext();
|
||||
if (!loadContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// CanOpenBrowser has ensured that the IPCTabContext is of
|
||||
// type PopupIPCTabContext, and that the opener TabParent is
|
||||
// reachable.
|
||||
auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
|
||||
// We must ensure that the private browsing and remoteness flags
|
||||
// match those of the opener.
|
||||
nsCOMPtr<nsILoadContext> loadContext = opener->GetLoadContext();
|
||||
if (!loadContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool isPrivate;
|
||||
loadContext->GetUsePrivateBrowsing(&isPrivate);
|
||||
if (isPrivate) {
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
|
||||
bool isPrivate;
|
||||
loadContext->GetUsePrivateBrowsing(&isPrivate);
|
||||
if (isPrivate) {
|
||||
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
|
||||
}
|
||||
}
|
||||
|
||||
// And because we're allocating a remote browser, of course the
|
||||
|
|
|
@ -20,9 +20,12 @@
|
|||
#include "nsIDOMChromeWindow.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsPIWindowWatcher.h"
|
||||
#include "nsWindowWatcher.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -498,6 +501,31 @@ private:
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
// ContentProcess
|
||||
nsCOMPtr<nsIWindowWatcher> wwatch =
|
||||
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
|
||||
NS_ENSURE_STATE(pwwatch);
|
||||
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> newWindow;
|
||||
pwwatch->OpenWindow2(nullptr,
|
||||
spec.get(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
false, false, true, nullptr, nullptr,
|
||||
getter_AddRefs(newWindow));
|
||||
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(newWindow);
|
||||
pwindow.forget(aWindow);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the most recent browser window and open a new tab in it.
|
||||
nsCOMPtr<nsIDOMWindow> browserWindow;
|
||||
rv = wm->GetMostRecentWindow(MOZ_UTF16("navigator:browser"),
|
||||
|
@ -580,13 +608,6 @@ already_AddRefed<Promise>
|
|||
ServiceWorkerClients::OpenWindow(const nsAString& aUrl,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// XXXcatalinb: This works only on non-multiprocess for now, bail if we're
|
||||
// running in a content process.
|
||||
if (XRE_IsContentProcess()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
|
|
|
@ -545,8 +545,8 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent,
|
|||
|
||||
// no extant window? make a new one.
|
||||
|
||||
// If no parent, consider it chrome.
|
||||
bool hasChromeParent = true;
|
||||
// If no parent, consider it chrome when running in the parent process.
|
||||
bool hasChromeParent = XRE_IsContentProcess() ? false : true;
|
||||
if (aParent) {
|
||||
// Check if the parent document has chrome privileges.
|
||||
nsIDocument* doc = parentWindow->GetDoc();
|
||||
|
@ -613,7 +613,9 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent,
|
|||
// based on whether the docshell type is chrome or content.
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> parentGlobalObject = do_QueryInterface(aParent);
|
||||
if (NS_WARN_IF(!jsapiChromeGuard.Init(parentGlobalObject))) {
|
||||
if (!aParent) {
|
||||
jsapiChromeGuard.Init();
|
||||
} else if (NS_WARN_IF(!jsapiChromeGuard.Init(parentGlobalObject))) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
@ -645,10 +647,16 @@ nsWindowWatcher::OpenWindowInternal(nsIDOMWindow* aParent,
|
|||
!(chromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
|
||||
nsCOMPtr<nsIWindowProvider> provider = do_GetInterface(parentTreeOwner);
|
||||
if (provider) {
|
||||
NS_ASSERTION(aParent, "We've _got_ to have a parent here!");
|
||||
nsCOMPtr<nsIWindowProvider> provider;
|
||||
if (parentTreeOwner) {
|
||||
provider = do_GetInterface(parentTreeOwner);
|
||||
} else if (XRE_IsContentProcess()) {
|
||||
// we're in a content process but we don't have a tabchild we can
|
||||
// use.
|
||||
provider = nsContentUtils::GetWindowProviderForContentProcess();
|
||||
}
|
||||
|
||||
if (provider) {
|
||||
nsCOMPtr<nsIDOMWindow> newWindow;
|
||||
rv = provider->ProvideWindow(aParent, chromeFlags, aCalledFromJS,
|
||||
sizeSpec.PositionSpecified(),
|
||||
|
|
Загрузка…
Ссылка в новой задаче