зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1172870 - Part 1 - Move PBrowser::CreateWindow to PContent. r=smaug
This commit is contained in:
Родитель
55039de64c
Коммит
bad419762d
|
@ -47,6 +47,7 @@
|
|||
#include "mozilla/layers/ImageBridgeChild.h"
|
||||
#include "mozilla/layers/PCompositorChild.h"
|
||||
#include "mozilla/layers/SharedBufferManagerChild.h"
|
||||
#include "mozilla/layout/RenderFrameChild.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/plugins/PluginInstanceParent.h"
|
||||
#include "mozilla/plugins/PluginModuleParent.h"
|
||||
|
@ -216,6 +217,7 @@ using namespace mozilla::gmp;
|
|||
using namespace mozilla::hal_sandbox;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::layout;
|
||||
using namespace mozilla::net;
|
||||
using namespace mozilla::jsipc;
|
||||
using namespace mozilla::psm;
|
||||
|
@ -608,7 +610,8 @@ ContentChild::~ContentChild()
|
|||
|
||||
NS_INTERFACE_MAP_BEGIN(ContentChild)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIContentChild)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentChild)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
bool
|
||||
|
@ -741,6 +744,149 @@ ContentChild::SetProcessName(const nsAString& aName, bool aDontOverride)
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ContentChild::ProvideWindow(nsIDOMWindow* aParent,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
bool aSizeSpecified,
|
||||
nsIURI* aURI,
|
||||
const nsAString& aName,
|
||||
const nsACString& aFeatures,
|
||||
bool* aWindowIsNew,
|
||||
nsIDOMWindow** aReturn)
|
||||
{
|
||||
return ProvideWindowCommon(nullptr, aParent, false, aChromeFlags,
|
||||
aCalledFromJS, aPositionSpecified,
|
||||
aSizeSpecified, aURI, aName, aFeatures,
|
||||
aWindowIsNew, aReturn);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ContentChild::ProvideWindowCommon(TabChild* aTabOpener,
|
||||
nsIDOMWindow* aParent,
|
||||
bool aIframeMoz,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
bool aSizeSpecified,
|
||||
nsIURI* aURI,
|
||||
const nsAString& aName,
|
||||
const nsACString& aFeatures,
|
||||
bool* aWindowIsNew,
|
||||
nsIDOMWindow** aReturn)
|
||||
{
|
||||
MOZ_ASSERT(aTabOpener);
|
||||
*aReturn = nullptr;
|
||||
|
||||
const TabId openerTabId = aTabOpener->GetTabId();
|
||||
|
||||
PopupIPCTabContext context;
|
||||
context.opener() = openerTabId;
|
||||
context.isBrowserElement() = aTabOpener->IsBrowserElement();
|
||||
|
||||
IPCTabContext ipcContext(context);
|
||||
|
||||
TabId tabId;
|
||||
SendAllocateTabId(openerTabId,
|
||||
ipcContext,
|
||||
GetID(),
|
||||
&tabId);
|
||||
|
||||
RefPtr<TabChild> newChild = new TabChild(this, tabId,
|
||||
*aTabOpener, aChromeFlags);
|
||||
if (NS_FAILED(newChild->Init())) {
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
context.opener() = aTabOpener;
|
||||
unused << SendPBrowserConstructor(
|
||||
// We release this ref in DeallocPBrowserChild
|
||||
RefPtr<TabChild>(newChild).forget().take(),
|
||||
tabId, IPCTabContext(context), aChromeFlags,
|
||||
GetID(), IsForApp(), IsForBrowser());
|
||||
|
||||
nsAutoCString spec;
|
||||
if (aURI) {
|
||||
aURI->GetSpec(spec);
|
||||
}
|
||||
|
||||
NS_ConvertUTF8toUTF16 url(spec);
|
||||
nsString name(aName);
|
||||
nsAutoCString features(aFeatures);
|
||||
nsTArray<FrameScriptInfo> frameScripts;
|
||||
nsCString urlToLoad;
|
||||
|
||||
if (aIframeMoz) {
|
||||
MOZ_ASSERT(aTabOpener);
|
||||
newChild->SendBrowserFrameOpenWindow(aTabOpener, url, name,
|
||||
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);
|
||||
|
||||
nsresult rv;
|
||||
if (!SendCreateWindow(aTabOpener, newChild,
|
||||
aChromeFlags, aCalledFromJS, aPositionSpecified,
|
||||
aSizeSpecified, url,
|
||||
name, features,
|
||||
NS_ConvertUTF8toUTF16(baseURIString),
|
||||
&rv,
|
||||
aWindowIsNew,
|
||||
&frameScripts,
|
||||
&urlToLoad)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if (!*aWindowIsNew) {
|
||||
PBrowserChild::Send__delete__(newChild);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
TextureFactoryIdentifier textureFactoryIdentifier;
|
||||
uint64_t layersId = 0;
|
||||
PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
|
||||
newChild->SendGetRenderFrameInfo(renderFrame,
|
||||
&textureFactoryIdentifier,
|
||||
&layersId);
|
||||
if (layersId == 0) { // if renderFrame is invalid.
|
||||
PRenderFrameChild::Send__delete__(renderFrame);
|
||||
renderFrame = nullptr;
|
||||
}
|
||||
|
||||
// Unfortunately we don't get a window unless we've shown the frame. That's
|
||||
// pretty bogus; see bug 763602.
|
||||
newChild->DoFakeShow(textureFactoryIdentifier, layersId, renderFrame);
|
||||
|
||||
for (size_t i = 0; i < frameScripts.Length(); i++) {
|
||||
FrameScriptInfo& info = frameScripts[i];
|
||||
if (!newChild->RecvLoadRemoteScript(info.url(), info.runInGlobalScope())) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
if (!urlToLoad.IsEmpty()) {
|
||||
newChild->RecvLoadURL(urlToLoad, BrowserConfiguration());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(newChild->WebNavigation());
|
||||
win.forget(aReturn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
ContentChild::GetProcessName(nsAString& aName)
|
||||
{
|
||||
|
@ -2748,7 +2894,8 @@ ContentChild::RecvShutdown()
|
|||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
os->NotifyObservers(this, "content-child-shutdown", nullptr);
|
||||
os->NotifyObservers(static_cast<nsIContentChild*>(this),
|
||||
"content-child-shutdown", nullptr);
|
||||
}
|
||||
|
||||
GetIPCChannel()->SetAbortOnError(false);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "nsTHashtable.h"
|
||||
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsIWindowProvider.h"
|
||||
|
||||
|
||||
struct ChromePackage;
|
||||
|
@ -47,6 +48,7 @@ class ClonedMessageData;
|
|||
class TabChild;
|
||||
|
||||
class ContentChild final : public PContentChild
|
||||
, public nsIWindowProvider
|
||||
, public nsIContentChild
|
||||
{
|
||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||
|
@ -55,6 +57,8 @@ class ContentChild final : public PContentChild
|
|||
typedef mozilla::ipc::URIParams URIParams;
|
||||
|
||||
public:
|
||||
NS_DECL_NSIWINDOWPROVIDER
|
||||
|
||||
ContentChild();
|
||||
virtual ~ContentChild();
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
|
||||
|
@ -71,6 +75,20 @@ public:
|
|||
nsCString vendor;
|
||||
};
|
||||
|
||||
nsresult
|
||||
ProvideWindowCommon(TabChild* aTabOpener,
|
||||
nsIDOMWindow* aOpener,
|
||||
bool aIframeMoz,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
bool aSizeSpecified,
|
||||
nsIURI* aURI,
|
||||
const nsAString& aName,
|
||||
const nsACString& aFeatures,
|
||||
bool* aWindowIsNew,
|
||||
nsIDOMWindow** aReturn);
|
||||
|
||||
bool Init(MessageLoop* aIOLoop,
|
||||
base::ProcessId aParentPid,
|
||||
IPC::Channel* aChannel);
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "base/basictypes.h"
|
||||
|
||||
#include "ContentParent.h"
|
||||
#include "TabParent.h"
|
||||
|
||||
#if defined(ANDROID) || defined(LINUX)
|
||||
# include <sys/time.h>
|
||||
|
@ -144,7 +145,13 @@
|
|||
#include "nsISystemMessagesInternal.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIURIFixup.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsPIWindowWatcher.h"
|
||||
#include "nsWindowWatcher.h"
|
||||
#include "nsIXULRuntime.h"
|
||||
#include "gfxDrawable.h"
|
||||
#include "ImageOps.h"
|
||||
|
@ -166,6 +173,7 @@
|
|||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsDocShell.h"
|
||||
#include "nsOpenURIInFrameParams.h"
|
||||
#include "mozilla/net/NeckoMessageUtils.h"
|
||||
#include "gfxPrefs.h"
|
||||
#include "prio.h"
|
||||
|
@ -5343,6 +5351,226 @@ ContentParent::DeallocPWebBrowserPersistDocumentParent(PWebBrowserPersistDocumen
|
|||
return true;
|
||||
}
|
||||
|
||||
static already_AddRefed<nsPIDOMWindow>
|
||||
FindMostRecentOpenWindow()
|
||||
{
|
||||
nsCOMPtr<nsIWindowMediator> windowMediator =
|
||||
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID);
|
||||
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
|
||||
windowMediator->GetEnumerator(MOZ_UTF16("navigator:browser"),
|
||||
getter_AddRefs(windowEnumerator));
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> latest;
|
||||
|
||||
bool hasMore = false;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
|
||||
while (hasMore) {
|
||||
nsCOMPtr<nsISupports> item;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->GetNext(getter_AddRefs(item))));
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(item);
|
||||
|
||||
if (window && !window->Closed()) {
|
||||
latest = window;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
|
||||
}
|
||||
|
||||
return latest.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvCreateWindow(PBrowserParent* aThisTab,
|
||||
PBrowserParent* aNewTab,
|
||||
const uint32_t& aChromeFlags,
|
||||
const bool& aCalledFromJS,
|
||||
const bool& aPositionSpecified,
|
||||
const bool& aSizeSpecified,
|
||||
const nsString& aURI,
|
||||
const nsString& aName,
|
||||
const nsCString& aFeatures,
|
||||
const nsString& aBaseURI,
|
||||
nsresult* aResult,
|
||||
bool* aWindowIsNew,
|
||||
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
||||
nsCString* aURLToLoad)
|
||||
{
|
||||
// We always expect to open a new window here. If we don't, it's an error.
|
||||
*aWindowIsNew = true;
|
||||
|
||||
// The content process should never be in charge of computing whether or
|
||||
// not a window should be private or remote - the parent will do that.
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW));
|
||||
|
||||
TabParent* thisTabParent = TabParent::GetFrom(aThisTab);
|
||||
MOZ_ASSERT(thisTabParent);
|
||||
|
||||
if (NS_WARN_IF(thisTabParent->IsBrowserOrApp())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIWindowWatcher> pwwatch =
|
||||
do_GetService(NS_WINDOWWATCHER_CONTRACTID, aResult);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
TabParent* newTab = TabParent::GetFrom(aNewTab);
|
||||
MOZ_ASSERT(newTab);
|
||||
|
||||
// Content has requested that we open this new content window, so
|
||||
// we must have an opener.
|
||||
newTab->SetHasContentOpener(true);
|
||||
|
||||
nsCOMPtr<nsIContent> frame(do_QueryInterface(thisTabParent->GetOwnerElement()));
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> parent;
|
||||
if (frame) {
|
||||
parent = frame->OwnerDoc()->GetWindow();
|
||||
|
||||
// If our chrome window is in the process of closing, don't try to open a
|
||||
// new tab in it.
|
||||
if (parent && parent->Closed()) {
|
||||
parent = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin = thisTabParent->GetBrowserDOMWindow();
|
||||
|
||||
// If we haven't found a chrome window to open in, just use the most recently
|
||||
// opened one.
|
||||
if (!parent) {
|
||||
parent = FindMostRecentOpenWindow();
|
||||
if (NS_WARN_IF(!parent)) {
|
||||
*aResult = NS_ERROR_FAILURE;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(parent);
|
||||
if (rootChromeWin) {
|
||||
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
|
||||
}
|
||||
}
|
||||
|
||||
int32_t openLocation =
|
||||
nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS,
|
||||
aPositionSpecified, aSizeSpecified);
|
||||
|
||||
MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
|
||||
openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
|
||||
|
||||
// Opening new tabs is the easy case...
|
||||
if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
|
||||
if (NS_WARN_IF(!browserDOMWin)) {
|
||||
*aResult = NS_ERROR_FAILURE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isPrivate = false;
|
||||
nsCOMPtr<nsILoadContext> loadContext = thisTabParent->GetLoadContext();
|
||||
loadContext->GetUsePrivateBrowsing(&isPrivate);
|
||||
|
||||
nsCOMPtr<nsIOpenURIInFrameParams> params = new nsOpenURIInFrameParams();
|
||||
params->SetReferrer(aBaseURI);
|
||||
params->SetIsPrivate(isPrivate);
|
||||
|
||||
TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
||||
|
||||
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
|
||||
browserDOMWin->OpenURIInFrame(nullptr, params,
|
||||
openLocation,
|
||||
nsIBrowserDOMWindow::OPEN_NEW,
|
||||
getter_AddRefs(frameLoaderOwner));
|
||||
if (!frameLoaderOwner) {
|
||||
*aWindowIsNew = false;
|
||||
}
|
||||
|
||||
newTab->SwapFrameScriptsFrom(*aFrameScripts);
|
||||
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;
|
||||
*aResult = NS_NewURI(getter_AddRefs(baseURI), aBaseURI);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsAutoCString finalURIString;
|
||||
if (!aURI.IsEmpty()) {
|
||||
nsCOMPtr<nsIURI> finalURI;
|
||||
*aResult = NS_NewURI(getter_AddRefs(finalURI), NS_ConvertUTF16toUTF8(aURI).get(), baseURI);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
finalURI->GetSpec(finalURIString);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window;
|
||||
|
||||
TabParent::AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
||||
|
||||
const char* features = aFeatures.Length() ? aFeatures.get() : nullptr;
|
||||
*aResult = pwwatch->OpenWindow2(parent, finalURIString.get(),
|
||||
NS_ConvertUTF16toUTF8(aName).get(),
|
||||
features, aCalledFromJS,
|
||||
false, false, thisTabParent, nullptr, getter_AddRefs(window));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*aResult = NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(window);
|
||||
if (NS_WARN_IF(!pwindow)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> windowDocShell = pwindow->GetDocShell();
|
||||
if (NS_WARN_IF(!windowDocShell)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
windowDocShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
|
||||
nsCOMPtr<nsIXULWindow> xulWin = do_GetInterface(treeOwner);
|
||||
if (NS_WARN_IF(!xulWin)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWin;
|
||||
xulWin->GetXULBrowserWindow(getter_AddRefs(xulBrowserWin));
|
||||
if (NS_WARN_IF(!xulBrowserWin)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITabParent> newRemoteTab;
|
||||
*aResult = xulBrowserWin->ForceInitialBrowserRemote(getter_AddRefs(newRemoteTab));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
|
||||
|
||||
newTab->SwapFrameScriptsFrom(*aFrameScripts);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
ContentParent::PermissionManagerAddref(const ContentParentId& aCpId,
|
||||
const TabId& aTabId)
|
||||
|
|
|
@ -434,6 +434,21 @@ public:
|
|||
void SetNuwaParent(NuwaParent* aNuwaParent) { mNuwaParent = aNuwaParent; }
|
||||
void ForkNewProcess(bool aBlocking);
|
||||
|
||||
virtual bool RecvCreateWindow(PBrowserParent* aThisTabParent,
|
||||
PBrowserParent* aOpener,
|
||||
const uint32_t& aChromeFlags,
|
||||
const bool& aCalledFromJS,
|
||||
const bool& aPositionSpecified,
|
||||
const bool& aSizeSpecified,
|
||||
const nsString& aURI,
|
||||
const nsString& aName,
|
||||
const nsCString& aFeatures,
|
||||
const nsString& aBaseURI,
|
||||
nsresult* aResult,
|
||||
bool* aWindowIsNew,
|
||||
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
||||
nsCString* aURLToLoad) override;
|
||||
|
||||
protected:
|
||||
void OnChannelConnected(int32_t pid) override;
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
|
|
@ -94,12 +94,6 @@ struct ShowInfo
|
|||
double defaultScale;
|
||||
};
|
||||
|
||||
struct FrameScriptInfo
|
||||
{
|
||||
nsString url;
|
||||
bool runInGlobalScope;
|
||||
};
|
||||
|
||||
prio(normal upto urgent) sync protocol PBrowser
|
||||
{
|
||||
manager PContent or PContentBridge;
|
||||
|
@ -165,20 +159,6 @@ parent:
|
|||
|
||||
Event(RemoteDOMEvent aEvent);
|
||||
|
||||
sync CreateWindow(PBrowser aNewTab,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
bool aSizeSpecified,
|
||||
nsString aURI,
|
||||
nsString aName,
|
||||
nsCString aFeatures,
|
||||
nsString aBaseURI)
|
||||
returns (nsresult rv,
|
||||
bool windowOpened,
|
||||
FrameScriptInfo[] frameScripts,
|
||||
nsCString urlToLoad);
|
||||
|
||||
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
|
||||
CpowEntry[] aCpows, Principal aPrincipal)
|
||||
returns (StructuredCloneData[] retval);
|
||||
|
|
|
@ -410,6 +410,12 @@ union GamepadChangeEvent {
|
|||
GamepadButtonInformation;
|
||||
};
|
||||
|
||||
struct FrameScriptInfo
|
||||
{
|
||||
nsString url;
|
||||
bool runInGlobalScope;
|
||||
};
|
||||
|
||||
prio(normal upto urgent) sync protocol PContent
|
||||
{
|
||||
parent spawns PPluginModule;
|
||||
|
@ -1112,6 +1118,21 @@ parent:
|
|||
sync GetGraphicsDeviceInitData()
|
||||
returns (DeviceInitData aData);
|
||||
|
||||
sync CreateWindow(PBrowser aThisTab,
|
||||
PBrowser aNewTab,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
bool aSizeSpecified,
|
||||
nsString aURI,
|
||||
nsString aName,
|
||||
nsCString aFeatures,
|
||||
nsString aBaseURI)
|
||||
returns (nsresult rv,
|
||||
bool windowOpened,
|
||||
FrameScriptInfo[] frameScripts,
|
||||
nsCString urlToLoad);
|
||||
|
||||
sync GetDeviceStorageLocation(nsString type)
|
||||
returns (nsString path);
|
||||
|
||||
|
|
|
@ -1115,145 +1115,19 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, uint32_t aChromeFlags,
|
|||
// Note that ProvideWindowCommon may return NS_ERROR_ABORT if the
|
||||
// open window call was canceled. It's important that we pass this error
|
||||
// code back to our caller.
|
||||
return ProvideWindowCommon(aParent,
|
||||
iframeMoz,
|
||||
aChromeFlags,
|
||||
aCalledFromJS,
|
||||
aPositionSpecified,
|
||||
aSizeSpecified,
|
||||
aURI,
|
||||
aName,
|
||||
aFeatures,
|
||||
aWindowIsNew,
|
||||
aReturn);
|
||||
}
|
||||
|
||||
nsresult
|
||||
TabChild::ProvideWindowCommon(nsIDOMWindow* aOpener,
|
||||
bool aIframeMoz,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
bool aSizeSpecified,
|
||||
nsIURI* aURI,
|
||||
const nsAString& aName,
|
||||
const nsACString& aFeatures,
|
||||
bool* aWindowIsNew,
|
||||
nsIDOMWindow** aReturn)
|
||||
{
|
||||
*aReturn = nullptr;
|
||||
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
const TabId openerTabId = GetTabId();
|
||||
|
||||
// We must use PopupIPCTabContext here; ContentParent will not accept the
|
||||
// result of this->AsIPCTabContext() (which will be a
|
||||
// BrowserFrameIPCTabContext or an AppFrameIPCTabContext), for security
|
||||
// reasons.
|
||||
PopupIPCTabContext context;
|
||||
context.opener() = openerTabId;
|
||||
context.isBrowserElement() = IsBrowserElement();
|
||||
|
||||
IPCTabContext ipcContext(context);
|
||||
|
||||
TabId tabId;
|
||||
cc->SendAllocateTabId(openerTabId,
|
||||
ipcContext,
|
||||
cc->GetID(),
|
||||
&tabId);
|
||||
|
||||
RefPtr<TabChild> newChild = new TabChild(ContentChild::GetSingleton(), tabId,
|
||||
/* TabContext */ *this, aChromeFlags);
|
||||
if (NS_FAILED(newChild->Init())) {
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
context.opener() = this;
|
||||
unused << Manager()->SendPBrowserConstructor(
|
||||
// We release this ref in DeallocPBrowserChild
|
||||
RefPtr<TabChild>(newChild).forget().take(),
|
||||
tabId, IPCTabContext(context), aChromeFlags,
|
||||
cc->GetID(), cc->IsForApp(), cc->IsForBrowser());
|
||||
|
||||
nsAutoCString spec;
|
||||
if (aURI) {
|
||||
aURI->GetSpec(spec);
|
||||
}
|
||||
|
||||
NS_ConvertUTF8toUTF16 url(spec);
|
||||
nsString name(aName);
|
||||
nsAutoCString features(aFeatures);
|
||||
nsTArray<FrameScriptInfo> frameScripts;
|
||||
nsCString urlToLoad;
|
||||
|
||||
if (aIframeMoz) {
|
||||
newChild->SendBrowserFrameOpenWindow(this, url, name,
|
||||
NS_ConvertUTF8toUTF16(features),
|
||||
aWindowIsNew);
|
||||
} else {
|
||||
nsCOMPtr<nsPIDOMWindow> opener = do_QueryInterface(aOpener);
|
||||
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);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (!SendCreateWindow(newChild,
|
||||
aChromeFlags, aCalledFromJS, aPositionSpecified,
|
||||
aSizeSpecified, url,
|
||||
name, features,
|
||||
NS_ConvertUTF8toUTF16(baseURIString),
|
||||
&rv,
|
||||
aWindowIsNew,
|
||||
&frameScripts,
|
||||
&urlToLoad)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if (!*aWindowIsNew) {
|
||||
PBrowserChild::Send__delete__(newChild);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
TextureFactoryIdentifier textureFactoryIdentifier;
|
||||
uint64_t layersId = 0;
|
||||
PRenderFrameChild* renderFrame = newChild->SendPRenderFrameConstructor();
|
||||
newChild->SendGetRenderFrameInfo(renderFrame,
|
||||
&textureFactoryIdentifier,
|
||||
&layersId);
|
||||
if (layersId == 0) { // if renderFrame is invalid.
|
||||
PRenderFrameChild::Send__delete__(renderFrame);
|
||||
renderFrame = nullptr;
|
||||
}
|
||||
|
||||
// Unfortunately we don't get a window unless we've shown the frame. That's
|
||||
// pretty bogus; see bug 763602.
|
||||
newChild->DoFakeShow(textureFactoryIdentifier, layersId, renderFrame);
|
||||
|
||||
for (size_t i = 0; i < frameScripts.Length(); i++) {
|
||||
FrameScriptInfo& info = frameScripts[i];
|
||||
if (!newChild->RecvLoadRemoteScript(info.url(), info.runInGlobalScope())) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
if (!urlToLoad.IsEmpty()) {
|
||||
newChild->RecvLoadURL(urlToLoad, BrowserConfiguration());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(newChild->WebNavigation());
|
||||
win.forget(aReturn);
|
||||
return NS_OK;
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
return cc->ProvideWindowCommon(this,
|
||||
aParent,
|
||||
iframeMoz,
|
||||
aChromeFlags,
|
||||
aCalledFromJS,
|
||||
aPositionSpecified,
|
||||
aSizeSpecified,
|
||||
aURI,
|
||||
aName,
|
||||
aFeatures,
|
||||
aWindowIsNew,
|
||||
aReturn);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -240,6 +240,16 @@ public:
|
|||
static already_AddRefed<TabChild> FindTabChild(const TabId& aTabId);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a new TabChild object.
|
||||
*/
|
||||
TabChild(nsIContentChild* aManager,
|
||||
const TabId& aTabId,
|
||||
const TabContext& aContext,
|
||||
uint32_t aChromeFlags);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
/**
|
||||
* This is expected to be called off the critical path to content
|
||||
* startup. This is an opportunity to load things that are slow
|
||||
|
@ -510,6 +520,11 @@ public:
|
|||
|
||||
virtual ScreenIntSize GetInnerSize() override;
|
||||
|
||||
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
|
||||
void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const uint64_t& aLayersId,
|
||||
PRenderFrameChild* aRenderFrame);
|
||||
|
||||
protected:
|
||||
virtual ~TabChild();
|
||||
|
||||
|
@ -535,16 +550,6 @@ protected:
|
|||
#endif
|
||||
|
||||
private:
|
||||
/**
|
||||
* Create a new TabChild object.
|
||||
*/
|
||||
TabChild(nsIContentChild* aManager,
|
||||
const TabId& aTabId,
|
||||
const TabContext& aContext,
|
||||
uint32_t aChromeFlags);
|
||||
|
||||
nsresult Init();
|
||||
|
||||
class DelayedFireContextMenuEvent;
|
||||
|
||||
// Notify others that our TabContext has been updated. (At the moment, this
|
||||
|
@ -564,11 +569,6 @@ private:
|
|||
void DestroyWindow();
|
||||
void SetProcessNameToAppName();
|
||||
|
||||
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
|
||||
void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
|
||||
const uint64_t& aLayersId,
|
||||
PRenderFrameChild* aRenderFrame);
|
||||
|
||||
void ApplyShowInfo(const ShowInfo& aInfo);
|
||||
|
||||
// These methods are used for tracking synthetic mouse events
|
||||
|
@ -581,19 +581,6 @@ private:
|
|||
void CancelTapTracking();
|
||||
void UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus);
|
||||
|
||||
nsresult
|
||||
ProvideWindowCommon(nsIDOMWindow* aOpener,
|
||||
bool aIframeMoz,
|
||||
uint32_t aChromeFlags,
|
||||
bool aCalledFromJS,
|
||||
bool aPositionSpecified,
|
||||
bool aSizeSpecified,
|
||||
nsIURI* aURI,
|
||||
const nsAString& aName,
|
||||
const nsACString& aFeatures,
|
||||
bool* aWindowIsNew,
|
||||
nsIDOMWindow** aReturn);
|
||||
|
||||
bool HasValidInnerSize();
|
||||
|
||||
void SetTabId(const TabId& aTabId);
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include "nsIContent.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
|
@ -61,26 +60,20 @@
|
|||
#include "nsIPromptFactory.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIWebBrowserChrome.h"
|
||||
#include "nsIWindowCreator2.h"
|
||||
#include "nsIXULBrowserWindow.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsIRemoteBrowser.h"
|
||||
#include "nsViewManager.h"
|
||||
#include "nsVariant.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#ifndef XP_WIN
|
||||
#include "nsJARProtocolHandler.h"
|
||||
#endif
|
||||
#include "nsOpenURIInFrameParams.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIWindowWatcher.h"
|
||||
#include "nsPresShell.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsWindowWatcher.h"
|
||||
#include "private/pprio.h"
|
||||
#include "PermissionMessageUtils.h"
|
||||
#include "StructuredCloneData.h"
|
||||
|
@ -723,249 +716,6 @@ TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
|
|||
return true;
|
||||
}
|
||||
|
||||
struct MOZ_STACK_CLASS TabParent::AutoUseNewTab final
|
||||
{
|
||||
public:
|
||||
AutoUseNewTab(TabParent* aNewTab, bool* aWindowIsNew, nsCString* aURLToLoad)
|
||||
: mNewTab(aNewTab), mWindowIsNew(aWindowIsNew), mURLToLoad(aURLToLoad)
|
||||
{
|
||||
MOZ_ASSERT(!TabParent::sNextTabParent);
|
||||
MOZ_ASSERT(!aNewTab->mCreatingWindow);
|
||||
|
||||
TabParent::sNextTabParent = aNewTab;
|
||||
aNewTab->mCreatingWindow = true;
|
||||
aNewTab->mDelayedURL.Truncate();
|
||||
}
|
||||
|
||||
~AutoUseNewTab()
|
||||
{
|
||||
mNewTab->mCreatingWindow = false;
|
||||
*mURLToLoad = mNewTab->mDelayedURL;
|
||||
|
||||
if (TabParent::sNextTabParent) {
|
||||
MOZ_ASSERT(TabParent::sNextTabParent == mNewTab);
|
||||
TabParent::sNextTabParent = nullptr;
|
||||
*mWindowIsNew = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
TabParent* mNewTab;
|
||||
bool* mWindowIsNew;
|
||||
nsCString* mURLToLoad;
|
||||
};
|
||||
|
||||
static already_AddRefed<nsPIDOMWindow>
|
||||
FindMostRecentOpenWindow()
|
||||
{
|
||||
nsCOMPtr<nsIWindowMediator> windowMediator =
|
||||
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID);
|
||||
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
|
||||
windowMediator->GetEnumerator(MOZ_UTF16("navigator:browser"),
|
||||
getter_AddRefs(windowEnumerator));
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> latest;
|
||||
|
||||
bool hasMore = false;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
|
||||
while (hasMore) {
|
||||
nsCOMPtr<nsISupports> item;
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->GetNext(getter_AddRefs(item))));
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(item);
|
||||
|
||||
if (window && !window->Closed()) {
|
||||
latest = window;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(windowEnumerator->HasMoreElements(&hasMore)));
|
||||
}
|
||||
|
||||
return latest.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvCreateWindow(PBrowserParent* aNewTab,
|
||||
const uint32_t& aChromeFlags,
|
||||
const bool& aCalledFromJS,
|
||||
const bool& aPositionSpecified,
|
||||
const bool& aSizeSpecified,
|
||||
const nsString& aURI,
|
||||
const nsString& aName,
|
||||
const nsCString& aFeatures,
|
||||
const nsString& aBaseURI,
|
||||
nsresult* aResult,
|
||||
bool* aWindowIsNew,
|
||||
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
||||
nsCString* aURLToLoad)
|
||||
{
|
||||
// We always expect to open a new window here. If we don't, it's an error.
|
||||
*aWindowIsNew = true;
|
||||
|
||||
// The content process should never be in charge of computing whether or
|
||||
// not a window should be private or remote - the parent will do that.
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_NON_PRIVATE_WINDOW));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME));
|
||||
MOZ_ASSERT(!(aChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW));
|
||||
|
||||
if (NS_WARN_IF(IsBrowserOrApp()))
|
||||
return false;
|
||||
|
||||
nsCOMPtr<nsPIWindowWatcher> pwwatch =
|
||||
do_GetService(NS_WINDOWWATCHER_CONTRACTID, aResult);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
||||
return true;
|
||||
|
||||
TabParent* newTab = TabParent::GetFrom(aNewTab);
|
||||
MOZ_ASSERT(newTab);
|
||||
|
||||
// Content has requested that we open this new content window, so
|
||||
// we must have an opener.
|
||||
newTab->SetHasContentOpener(true);
|
||||
|
||||
nsCOMPtr<nsIContent> frame(do_QueryInterface(mFrameElement));
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> parent;
|
||||
if (frame) {
|
||||
parent = frame->OwnerDoc()->GetWindow();
|
||||
|
||||
// If our chrome window is in the process of closing, don't try to open a
|
||||
// new tab in it.
|
||||
if (parent && parent->Closed()) {
|
||||
parent = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin = mBrowserDOMWindow;
|
||||
|
||||
// If we haven't found a chrome window to open in, just use the most recently
|
||||
// opened one.
|
||||
if (!parent) {
|
||||
parent = FindMostRecentOpenWindow();
|
||||
if (NS_WARN_IF(!parent)) {
|
||||
*aResult = NS_ERROR_FAILURE;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMChromeWindow> rootChromeWin = do_QueryInterface(parent);
|
||||
if (rootChromeWin) {
|
||||
rootChromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
|
||||
}
|
||||
}
|
||||
|
||||
int32_t openLocation =
|
||||
nsWindowWatcher::GetWindowOpenLocation(parent, aChromeFlags, aCalledFromJS,
|
||||
aPositionSpecified, aSizeSpecified);
|
||||
|
||||
MOZ_ASSERT(openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB ||
|
||||
openLocation == nsIBrowserDOMWindow::OPEN_NEWWINDOW);
|
||||
|
||||
// Opening new tabs is the easy case...
|
||||
if (openLocation == nsIBrowserDOMWindow::OPEN_NEWTAB) {
|
||||
if (NS_WARN_IF(!browserDOMWin)) {
|
||||
*aResult = NS_ERROR_FAILURE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isPrivate;
|
||||
nsCOMPtr<nsILoadContext> loadContext = GetLoadContext();
|
||||
loadContext->GetUsePrivateBrowsing(&isPrivate);
|
||||
|
||||
nsCOMPtr<nsIOpenURIInFrameParams> params = new nsOpenURIInFrameParams();
|
||||
params->SetReferrer(aBaseURI);
|
||||
params->SetIsPrivate(isPrivate);
|
||||
|
||||
AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
||||
|
||||
nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
|
||||
browserDOMWin->OpenURIInFrame(nullptr, params,
|
||||
openLocation,
|
||||
nsIBrowserDOMWindow::OPEN_NEW,
|
||||
getter_AddRefs(frameLoaderOwner));
|
||||
if (!frameLoaderOwner) {
|
||||
*aWindowIsNew = false;
|
||||
}
|
||||
|
||||
aFrameScripts->SwapElements(newTab->mDelayedFrameScripts);
|
||||
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;
|
||||
*aResult = NS_NewURI(getter_AddRefs(baseURI), aBaseURI);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
||||
return true;
|
||||
|
||||
nsAutoCString finalURIString;
|
||||
if (!aURI.IsEmpty()) {
|
||||
nsCOMPtr<nsIURI> finalURI;
|
||||
*aResult = NS_NewURI(getter_AddRefs(finalURI), NS_ConvertUTF16toUTF8(aURI).get(), baseURI);
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
||||
return true;
|
||||
|
||||
finalURI->GetSpec(finalURIString);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window;
|
||||
|
||||
AutoUseNewTab aunt(newTab, aWindowIsNew, aURLToLoad);
|
||||
|
||||
const char* features = aFeatures.Length() ? aFeatures.get() : nullptr;
|
||||
|
||||
*aResult = pwwatch->OpenWindow2(parent, finalURIString.get(),
|
||||
NS_ConvertUTF16toUTF8(aName).get(),
|
||||
features, aCalledFromJS,
|
||||
false, false, this, nullptr, getter_AddRefs(window));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
||||
return true;
|
||||
|
||||
*aResult = NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> pwindow = do_QueryInterface(window);
|
||||
if (NS_WARN_IF(!pwindow)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> windowDocShell = pwindow->GetDocShell();
|
||||
if (NS_WARN_IF(!windowDocShell)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
windowDocShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
|
||||
nsCOMPtr<nsIXULWindow> xulWin = do_GetInterface(treeOwner);
|
||||
if (NS_WARN_IF(!xulWin)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWin;
|
||||
xulWin->GetXULBrowserWindow(getter_AddRefs(xulBrowserWin));
|
||||
if (NS_WARN_IF(!xulBrowserWin)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsITabParent> newRemoteTab;
|
||||
*aResult = xulBrowserWin->ForceInitialBrowserRemote(getter_AddRefs(newRemoteTab));
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(*aResult)))
|
||||
return true;
|
||||
|
||||
MOZ_ASSERT(TabParent::GetFrom(newRemoteTab) == newTab);
|
||||
|
||||
aFrameScripts->SwapElements(newTab->mDelayedFrameScripts);
|
||||
return true;
|
||||
}
|
||||
|
||||
TabParent* TabParent::sNextTabParent;
|
||||
|
||||
/* static */ TabParent*
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/ContentCache.h"
|
||||
#include "mozilla/dom/ipc/IdType.h"
|
||||
#include "mozilla/dom/PBrowserParent.h"
|
||||
#include "mozilla/dom/PContent.h"
|
||||
#include "mozilla/dom/PFilePickerParent.h"
|
||||
#include "mozilla/dom/TabContext.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
|
@ -93,6 +94,9 @@ class TabParent final : public PBrowserParent
|
|||
virtual ~TabParent();
|
||||
|
||||
public:
|
||||
// Helper class for ContentParent::RecvCreateWindow.
|
||||
struct AutoUseNewTab;
|
||||
|
||||
// nsITabParent
|
||||
NS_DECL_NSITABPARENT
|
||||
// nsIDOMEventListener interfaces
|
||||
|
@ -125,6 +129,12 @@ public:
|
|||
mBrowserDOMWindow = aBrowserDOMWindow;
|
||||
}
|
||||
|
||||
void SetHasContentOpener(bool aHasContentOpener);
|
||||
|
||||
void SwapFrameScriptsFrom(nsTArray<FrameScriptInfo>& aFrameScripts) {
|
||||
aFrameScripts.SwapElements(mDelayedFrameScripts);
|
||||
}
|
||||
|
||||
already_AddRefed<nsILoadContext> GetLoadContext();
|
||||
already_AddRefed<nsIWidget> GetTopLevelWidget();
|
||||
nsIXULBrowserWindow* GetXULBrowserWindow();
|
||||
|
@ -147,19 +157,6 @@ public:
|
|||
const nsString& aName,
|
||||
const nsString& aFeatures,
|
||||
bool* aOutWindowOpened) override;
|
||||
virtual bool RecvCreateWindow(PBrowserParent* aOpener,
|
||||
const uint32_t& aChromeFlags,
|
||||
const bool& aCalledFromJS,
|
||||
const bool& aPositionSpecified,
|
||||
const bool& aSizeSpecified,
|
||||
const nsString& aURI,
|
||||
const nsString& aName,
|
||||
const nsCString& aFeatures,
|
||||
const nsString& aBaseURI,
|
||||
nsresult* aResult,
|
||||
bool* aWindowIsNew,
|
||||
InfallibleTArray<FrameScriptInfo>* aFrameScripts,
|
||||
nsCString* aURLToLoad) override;
|
||||
virtual bool RecvSyncMessage(const nsString& aMessage,
|
||||
const ClonedMessageData& aData,
|
||||
InfallibleTArray<CpowEntry>&& aCpows,
|
||||
|
@ -497,8 +494,6 @@ protected:
|
|||
bool InitBrowserConfiguration(const nsCString& aURI,
|
||||
BrowserConfiguration& aConfiguration);
|
||||
|
||||
void SetHasContentOpener(bool aHasContentOpener);
|
||||
|
||||
// Decide whether we have to use a new process to reload the URI associated
|
||||
// with the given channel.
|
||||
bool ShouldSwitchProcess(nsIChannel* aChannel);
|
||||
|
@ -584,9 +579,6 @@ private:
|
|||
|
||||
TabId mTabId;
|
||||
|
||||
// Helper class for RecvCreateWindow.
|
||||
struct AutoUseNewTab;
|
||||
|
||||
// When loading a new tab or window via window.open, the child process sends
|
||||
// a new PBrowser to use. We store that tab in sNextTabParent and then
|
||||
// proceed through the browser's normal paths to create a new
|
||||
|
@ -655,6 +647,38 @@ public:
|
|||
static TabParent* GetTabParentFromLayersId(uint64_t aLayersId);
|
||||
};
|
||||
|
||||
struct MOZ_STACK_CLASS TabParent::AutoUseNewTab final
|
||||
{
|
||||
public:
|
||||
AutoUseNewTab(TabParent* aNewTab, bool* aWindowIsNew, nsCString* aURLToLoad)
|
||||
: mNewTab(aNewTab), mWindowIsNew(aWindowIsNew), mURLToLoad(aURLToLoad)
|
||||
{
|
||||
MOZ_ASSERT(!TabParent::sNextTabParent);
|
||||
MOZ_ASSERT(!aNewTab->mCreatingWindow);
|
||||
|
||||
TabParent::sNextTabParent = aNewTab;
|
||||
aNewTab->mCreatingWindow = true;
|
||||
aNewTab->mDelayedURL.Truncate();
|
||||
}
|
||||
|
||||
~AutoUseNewTab()
|
||||
{
|
||||
mNewTab->mCreatingWindow = false;
|
||||
*mURLToLoad = mNewTab->mDelayedURL;
|
||||
|
||||
if (TabParent::sNextTabParent) {
|
||||
MOZ_ASSERT(TabParent::sNextTabParent == mNewTab);
|
||||
TabParent::sNextTabParent = nullptr;
|
||||
*mWindowIsNew = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
TabParent* mNewTab;
|
||||
bool* mWindowIsNew;
|
||||
nsCString* mURLToLoad;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче