mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 742944 - Part 4: Handle window.open in <iframe mozbrowser>. r=bz, cjones
--HG-- extra : rebase_source : 4c16c86c5be230af22eea89dfb5f893b7c6091dd
This commit is contained in:
parent
dd8aad7da8
commit
d19ebc4677
@ -177,6 +177,7 @@
|
||||
#ifdef MOZ_B2G_RIL
|
||||
@BINPATH@/components/dom_mms.xpt
|
||||
#endif
|
||||
@BINPATH@/components/dom_browserelement.xpt
|
||||
@BINPATH@/components/dom_power.xpt
|
||||
@BINPATH@/components/dom_range.xpt
|
||||
@BINPATH@/components/dom_settings.xpt
|
||||
|
@ -188,6 +188,7 @@
|
||||
#ifdef MOZ_B2G_RIL
|
||||
@BINPATH@/components/dom_mms.xpt
|
||||
#endif
|
||||
@BINPATH@/components/dom_browserelement.xpt
|
||||
@BINPATH@/components/dom_power.xpt
|
||||
@BINPATH@/components/dom_range.xpt
|
||||
@BINPATH@/components/dom_settings.xpt
|
||||
|
@ -2211,3 +2211,11 @@ nsFrameLoader::GetOwnerElement(nsIDOMElement **aElement)
|
||||
ownerElement.forget(aElement);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsFrameLoader::SetRemoteBrowser(nsITabParent* aTabParent)
|
||||
{
|
||||
MOZ_ASSERT(!mRemoteBrowser);
|
||||
MOZ_ASSERT(!mCurrentRemoteFrame);
|
||||
mRemoteBrowser = static_cast<TabParent*>(aTabParent);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ class nsSubDocumentFrame;
|
||||
class nsIView;
|
||||
class nsIInProcessContentFrameMessageManager;
|
||||
class AutoResetInShow;
|
||||
class nsITabParent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -256,6 +257,16 @@ public:
|
||||
|
||||
bool ShouldClampScrollPosition() { return mClampScrollPosition; }
|
||||
|
||||
/**
|
||||
* Tell this FrameLoader to use a particular remote browser.
|
||||
*
|
||||
* This will assert if mRemoteBrowser or mCurrentRemoteFrame is non-null. In
|
||||
* practice, this means you can't have successfully run TryRemoteBrowser() on
|
||||
* this object, which means you can't have called ShowRemoteFrame() or
|
||||
* ReallyStartLoading().
|
||||
*/
|
||||
void SetRemoteBrowser(nsITabParent* aTabParent);
|
||||
|
||||
private:
|
||||
|
||||
void SetOwnerContent(mozilla::dom::Element* aContent);
|
||||
|
@ -98,7 +98,7 @@ nsGenericHTMLFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
|
||||
nsresult
|
||||
nsGenericHTMLFrameElement::EnsureFrameLoader()
|
||||
{
|
||||
if (!GetParent() || !IsInDoc() || mFrameLoader) {
|
||||
if (!GetParent() || !IsInDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) {
|
||||
// If frame loader is there, we just keep it around, cached
|
||||
return NS_OK;
|
||||
}
|
||||
@ -113,6 +113,16 @@ nsGenericHTMLFrameElement::EnsureFrameLoader()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLFrameElement::CreateRemoteFrameLoader(nsITabParent* aTabParent)
|
||||
{
|
||||
MOZ_ASSERT(!mFrameLoader);
|
||||
EnsureFrameLoader();
|
||||
NS_ENSURE_STATE(mFrameLoader);
|
||||
mFrameLoader->SetRemoteBrowser(aTabParent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::GetFrameLoader(nsIFrameLoader **aFrameLoader)
|
||||
{
|
||||
@ -296,3 +306,21 @@ nsGenericHTMLFrameElement::GetReallyIsBrowser(bool *aOut)
|
||||
*aOut = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::DisallowCreateFrameLoader()
|
||||
{
|
||||
MOZ_ASSERT(!mFrameLoader);
|
||||
MOZ_ASSERT(!mFrameLoaderCreationDisallowed);
|
||||
mFrameLoaderCreationDisallowed = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::AllowCreateFrameLoader()
|
||||
{
|
||||
MOZ_ASSERT(!mFrameLoader);
|
||||
MOZ_ASSERT(mFrameLoaderCreationDisallowed);
|
||||
mFrameLoaderCreationDisallowed = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ public:
|
||||
: nsGenericHTMLElement(aNodeInfo)
|
||||
, mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK)
|
||||
, mBrowserFrameListenersRegistered(false)
|
||||
, mFrameLoaderCreationDisallowed(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -99,4 +100,5 @@ protected:
|
||||
bool mNetworkCreated;
|
||||
|
||||
bool mBrowserFrameListenersRegistered;
|
||||
bool mFrameLoaderCreationDisallowed;
|
||||
};
|
||||
|
@ -521,6 +521,8 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
|
||||
|
||||
#include "DOMError.h"
|
||||
#include "DOMRequest.h"
|
||||
#include "nsIOpenWindowEventDetail.h"
|
||||
#include "nsIDOMGlobalObjectConstructor.h"
|
||||
|
||||
#include "DOMFileHandle.h"
|
||||
#include "FileRequest.h"
|
||||
@ -531,8 +533,6 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
|
||||
#undef None // something included above defines this preprocessor symbol, maybe Xlib headers
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#include "nsIDOMGlobalObjectConstructor.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@ -1663,6 +1663,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(DOMRequest, nsEventTargetSH,
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(OpenWindowEventDetail, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA_WITH_NAME(DOMFileHandle, FileHandle, nsEventTargetSH,
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
@ -4526,6 +4528,10 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(OpenWindowEventDetail, nsIOpenWindowEventDetail)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIOpenWindowEventDetail)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(DOMFileHandle, nsIDOMFileHandle)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileHandle)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
@ -532,6 +532,7 @@ DOMCI_CLASS(BluetoothAdapter)
|
||||
|
||||
DOMCI_CLASS(DOMError)
|
||||
DOMCI_CLASS(DOMRequest)
|
||||
DOMCI_CLASS(OpenWindowEventDetail)
|
||||
|
||||
DOMCI_CLASS(DOMFileHandle)
|
||||
DOMCI_CLASS(FileRequest)
|
||||
|
@ -8296,10 +8296,8 @@ nsGlobalWindow::GetInterface(const nsIID & aIID, void **aSink)
|
||||
else if (aIID.Equals(NS_GET_IID(nsIDocShell))) {
|
||||
FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(mDocShell);
|
||||
if (docShell) {
|
||||
docShell.forget(aSink);
|
||||
}
|
||||
nsCOMPtr<nsIDocShell> docShell = mDocShell;
|
||||
docShell.forget(aSink);
|
||||
}
|
||||
#ifdef NS_PRINTING
|
||||
else if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
|
||||
|
209
dom/browser-element/BrowserElementParent.cpp
Normal file
209
dom/browser-element/BrowserElementParent.cpp
Normal file
@ -0,0 +1,209 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "TabParent.h"
|
||||
|
||||
// TabParent.h transitively includes <windows.h>, which does
|
||||
// #define CreateEvent CreateEventW
|
||||
// That messes up our call to nsEventDispatcher::CreateEvent below.
|
||||
|
||||
#ifdef CreateEvent
|
||||
#undef CreateEvent
|
||||
#endif
|
||||
|
||||
#include "BrowserElementParent.h"
|
||||
#include "nsHTMLIFrameElement.h"
|
||||
#include "nsOpenWindowEventDetail.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsIDOMCustomEvent.h"
|
||||
#include "nsVariant.h"
|
||||
|
||||
using mozilla::dom::Element;
|
||||
using mozilla::dom::TabParent;
|
||||
|
||||
namespace {
|
||||
|
||||
/**
|
||||
* Create an <iframe mozbrowser> owned by the same document as
|
||||
* aOpenerFrameElement.
|
||||
*/
|
||||
already_AddRefed<nsHTMLIFrameElement>
|
||||
CreateIframe(Element* aOpenerFrameElement)
|
||||
{
|
||||
nsNodeInfoManager *nodeInfoManager =
|
||||
aOpenerFrameElement->OwnerDoc()->NodeInfoManager();
|
||||
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo =
|
||||
nodeInfoManager->GetNodeInfo(nsGkAtoms::iframe,
|
||||
/* aPrefix = */ nsnull,
|
||||
kNameSpaceID_XHTML,
|
||||
nsIDOMNode::ELEMENT_NODE);
|
||||
|
||||
nsRefPtr<nsHTMLIFrameElement> popupFrameElement =
|
||||
static_cast<nsHTMLIFrameElement*>(
|
||||
NS_NewHTMLIFrameElement(nodeInfo.forget(), mozilla::dom::NOT_FROM_PARSER));
|
||||
|
||||
popupFrameElement->SetMozbrowser(true);
|
||||
|
||||
// Copy the opener frame's mozapp attribute to the popup frame.
|
||||
if (aOpenerFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozapp)) {
|
||||
nsAutoString mozapp;
|
||||
aOpenerFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapp, mozapp);
|
||||
popupFrameElement->SetAttr(kNameSpaceID_None, nsGkAtoms::mozapp,
|
||||
mozapp, /* aNotify = */ false);
|
||||
}
|
||||
|
||||
return popupFrameElement.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch a mozbrowseropenwindow event to the given opener frame element.
|
||||
* The "popup iframe" (event.detail.frameElement) will be |aPopupFrameElement|.
|
||||
*
|
||||
* Returns true iff there were no unexpected failures and the window.open call
|
||||
* was accepted by the embedder.
|
||||
*/
|
||||
bool
|
||||
DispatchOpenWindowEvent(Element* aOpenerFrameElement,
|
||||
Element* aPopupFrameElement,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aName,
|
||||
const nsAString& aFeatures)
|
||||
{
|
||||
// Dispatch a CustomEvent at aOpenerFrameElement with a detail object
|
||||
// (nsIOpenWindowEventDetail) containing aPopupFrameElement, aURL, aName, and
|
||||
// aFeatures.
|
||||
|
||||
// Create the event's detail object.
|
||||
nsRefPtr<nsOpenWindowEventDetail> detail =
|
||||
new nsOpenWindowEventDetail(aURL, aName, aFeatures,
|
||||
aPopupFrameElement->AsDOMNode());
|
||||
nsCOMPtr<nsIWritableVariant> detailVariant = new nsVariant();
|
||||
nsresult rv = detailVariant->SetAsISupports(detail);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// Create the CustomEvent.
|
||||
nsIPresShell *shell = aOpenerFrameElement->OwnerDoc()->GetShell();
|
||||
nsRefPtr<nsPresContext> presContext;
|
||||
if (shell) {
|
||||
presContext = shell->GetPresContext();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
nsEventDispatcher::CreateEvent(presContext, nsnull,
|
||||
NS_LITERAL_STRING("customevent"),
|
||||
getter_AddRefs(domEvent));
|
||||
NS_ENSURE_TRUE(domEvent, false);
|
||||
|
||||
nsCOMPtr<nsIDOMCustomEvent> customEvent = do_QueryInterface(domEvent);
|
||||
NS_ENSURE_TRUE(customEvent, false);
|
||||
customEvent->InitCustomEvent(NS_LITERAL_STRING("mozbrowseropenwindow"),
|
||||
/* bubbles = */ true,
|
||||
/* cancelable = */ false,
|
||||
detailVariant);
|
||||
customEvent->SetTrusted(true);
|
||||
|
||||
// Dispatch the event.
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
rv = nsEventDispatcher::DispatchDOMEvent(aOpenerFrameElement, nsnull,
|
||||
domEvent, presContext, &status);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
// If the iframe is not in some document's DOM at this point, the embedder
|
||||
// has "blocked" the popup.
|
||||
return aPopupFrameElement->IsInDoc();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/*static*/ bool
|
||||
BrowserElementParent::OpenWindowOOP(mozilla::dom::TabParent* aOpenerTabParent,
|
||||
mozilla::dom::TabParent* aPopupTabParent,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aName,
|
||||
const nsAString& aFeatures)
|
||||
{
|
||||
// Create an iframe owned by the same document which owns openerFrameElement.
|
||||
nsCOMPtr<Element> openerFrameElement =
|
||||
do_QueryInterface(aOpenerTabParent->GetOwnerElement());
|
||||
NS_ENSURE_TRUE(openerFrameElement, false);
|
||||
nsRefPtr<nsHTMLIFrameElement> popupFrameElement =
|
||||
CreateIframe(openerFrameElement);
|
||||
|
||||
// Normally an <iframe> element will try to create a frameLoader when the
|
||||
// page touches iframe.contentWindow or sets iframe.src.
|
||||
//
|
||||
// But in our case, we want to delay the creation of the frameLoader until
|
||||
// we've verified that the popup has gone through successfully. If the popup
|
||||
// is "blocked" by the embedder, we don't want to load the popup's url.
|
||||
//
|
||||
// Therefore we call DisallowCreateFrameLoader() on the element and call
|
||||
// AllowCreateFrameLoader() only after we've verified that the popup was
|
||||
// allowed.
|
||||
popupFrameElement->DisallowCreateFrameLoader();
|
||||
|
||||
bool dispatchSucceeded =
|
||||
DispatchOpenWindowEvent(openerFrameElement, popupFrameElement,
|
||||
aURL, aName, aFeatures);
|
||||
if (!dispatchSucceeded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The popup was not blocked, so hook up the frame element and the popup tab
|
||||
// parent, and return success.
|
||||
aPopupTabParent->SetOwnerElement(popupFrameElement);
|
||||
popupFrameElement->AllowCreateFrameLoader();
|
||||
popupFrameElement->CreateRemoteFrameLoader(aPopupTabParent);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
BrowserElementParent::OpenWindowInProcess(nsIDOMWindow* aOpenerWindow,
|
||||
nsIURI* aURI,
|
||||
const nsAString& aName,
|
||||
const nsACString& aFeatures,
|
||||
nsIDOMWindow** aReturnWindow)
|
||||
{
|
||||
*aReturnWindow = NULL;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> openerFrameDOMElement;
|
||||
aOpenerWindow->GetFrameElement(getter_AddRefs(openerFrameDOMElement));
|
||||
NS_ENSURE_TRUE(openerFrameDOMElement, false);
|
||||
|
||||
nsCOMPtr<nsINode> openerFrameNode = do_QueryInterface(openerFrameDOMElement);
|
||||
nsRefPtr<Element> openerFrameElement = openerFrameNode->AsElement();
|
||||
|
||||
nsRefPtr<nsHTMLIFrameElement> popupFrameElement =
|
||||
CreateIframe(openerFrameElement);
|
||||
NS_ENSURE_TRUE(popupFrameElement, false);
|
||||
|
||||
nsCAutoString spec;
|
||||
aURI->GetSpec(spec);
|
||||
bool dispatchSucceeded =
|
||||
DispatchOpenWindowEvent(openerFrameElement, popupFrameElement,
|
||||
NS_ConvertUTF8toUTF16(spec),
|
||||
aName,
|
||||
NS_ConvertUTF8toUTF16(aFeatures));
|
||||
if (!dispatchSucceeded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return popupFrameElement's window.
|
||||
nsCOMPtr<nsIFrameLoader> frameLoader;
|
||||
popupFrameElement->GetFrameLoader(getter_AddRefs(frameLoader));
|
||||
NS_ENSURE_TRUE(frameLoader, false);
|
||||
|
||||
nsCOMPtr<nsIDocShell> docshell;
|
||||
frameLoader->GetDocShell(getter_AddRefs(docshell));
|
||||
NS_ENSURE_TRUE(docshell, false);
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(docshell);
|
||||
window.forget(aReturnWindow);
|
||||
return !!*aReturnWindow;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
89
dom/browser-element/BrowserElementParent.h
Normal file
89
dom/browser-element/BrowserElementParent.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_BrowserElementHelpers_h
|
||||
#define mozilla_BrowserElementHelpers_h
|
||||
|
||||
#include "nsAString.h"
|
||||
|
||||
class nsIDOMWindow;
|
||||
class nsIURI;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class TabParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* BrowserElementParent implements a portion of the parent-process side of
|
||||
* <iframe mozbrowser>.
|
||||
*
|
||||
* Most of the parent-process side of <iframe mozbrowser> is implemented in
|
||||
* BrowserElementParent.js. This file implements the few parts of this
|
||||
* functionality which must be written in C++.
|
||||
*
|
||||
* We don't communicate with the JS code that lives in BrowserElementParent.js;
|
||||
* the JS and C++ parts are completely separate.
|
||||
*/
|
||||
class BrowserElementParent
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Handle a window.open call from an out-of-process <iframe mozbrowser>.
|
||||
*
|
||||
* window.open inside <iframe mozbrowser> doesn't actually open a new
|
||||
* top-level window. Instead, the "embedder" (the document which contains
|
||||
* the <iframe mozbrowser> whose content called window.open) gets the
|
||||
* opportunity to place a new <iframe mozbrowser> in the DOM somewhere. This
|
||||
* new "popup" iframe acts as the opened window.
|
||||
*
|
||||
* This method proceeds in three steps.
|
||||
*
|
||||
* 1) We fire a mozbrowseropenwindow CustomEvent on the opener
|
||||
* iframe element. This event's detail is an instance of
|
||||
* nsIOpenWindowEventDetail.
|
||||
*
|
||||
* 2) The embedder (the document which contains the opener iframe) can accept
|
||||
* the window.open request by inserting event.detail.frameElement (an iframe
|
||||
* element) into the DOM somewhere.
|
||||
*
|
||||
* 3) If the embedder accepted the window.open request, we return true and
|
||||
* set aPopupTabParent's frame element to event.detail.frameElement.
|
||||
* Otherwise, we return false.
|
||||
*
|
||||
* @param aOpenerTabParent the TabParent whose TabChild called window.open.
|
||||
* @param aPopupTabParent the TabParent inside which the opened window will
|
||||
* live.
|
||||
* @return true on success, false otherwise. Failure is not (necessarily)
|
||||
* an error; it may indicate that the embedder simply rejected the
|
||||
* window.open request.
|
||||
*/
|
||||
static bool
|
||||
OpenWindowOOP(mozilla::dom::TabParent* aOpenerTabParent,
|
||||
mozilla::dom::TabParent* aPopupTabParent,
|
||||
const nsAString& aURL,
|
||||
const nsAString& aName,
|
||||
const nsAString& aFeatures);
|
||||
|
||||
/**
|
||||
* Handle a window.open call from an in-process <iframe mozbrowser>.
|
||||
*
|
||||
* As with OpenWindowOOP, we return true if the window.open request
|
||||
* succeeded, and return false if the embedder denied the request.
|
||||
*
|
||||
* (These parameter types are silly, but they match what our caller has in
|
||||
* hand. Feel free to add an override, if they are inconvenient to you.)
|
||||
*/
|
||||
static bool
|
||||
OpenWindowInProcess(nsIDOMWindow* aOpenerWindow,
|
||||
nsIURI* aURI,
|
||||
const nsAString& aName,
|
||||
const nsACString& aFeatures,
|
||||
nsIDOMWindow** aReturnWindow);
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -7,12 +7,36 @@ topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
relativesrcdir = dom/browser-element
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = dom
|
||||
LIBRARY_NAME = dom_browserelement_s
|
||||
XPIDL_MODULE = dom_browserelement
|
||||
LIBXUL_LIBRARY = 1
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/dom/dom-config.mk
|
||||
|
||||
TEST_DIRS += mochitest
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIOpenWindowEventDetail.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsOpenWindowEventDetail.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_NAMESPACES = mozilla
|
||||
EXPORTS_mozilla = \
|
||||
BrowserElementParent.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsOpenWindowEventDetail.cpp \
|
||||
BrowserElementParent.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_COMPONENTS = \
|
||||
BrowserElementParent.js \
|
||||
BrowserElementParent.manifest \
|
||||
@ -22,4 +46,12 @@ EXTRA_JS_MODULES = \
|
||||
BrowserElementPromptService.jsm \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += \
|
||||
-I$(topsrcdir)/dom/base \
|
||||
-I$(topsrcdir)/dom/ipc \
|
||||
-I$(topsrcdir)/content/base/src \
|
||||
$(NULL)
|
||||
|
20
dom/browser-element/nsIOpenWindowEventDetail.idl
Normal file
20
dom/browser-element/nsIOpenWindowEventDetail.idl
Normal file
@ -0,0 +1,20 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMNode;
|
||||
|
||||
/**
|
||||
* When we send a mozbrowseropenwindow event (an instance of CustomEvent), we
|
||||
* use an instance of this interface as the event's detail.
|
||||
*/
|
||||
[scriptable, uuid(94377af6-956a-4adf-908b-363f7023ae1a)]
|
||||
interface nsIOpenWindowEventDetail : nsISupports
|
||||
{
|
||||
readonly attribute AString url;
|
||||
readonly attribute AString name;
|
||||
readonly attribute AString features;
|
||||
readonly attribute nsIDOMNode frameElement;
|
||||
};
|
49
dom/browser-element/nsOpenWindowEventDetail.cpp
Normal file
49
dom/browser-element/nsOpenWindowEventDetail.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsOpenWindowEventDetail.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_1(nsOpenWindowEventDetail, mFrameElement)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsOpenWindowEventDetail)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsOpenWindowEventDetail)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsOpenWindowEventDetail)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIOpenWindowEventDetail)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(OpenWindowEventDetail)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
DOMCI_DATA(OpenWindowEventDetail, nsOpenWindowEventDetail)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOpenWindowEventDetail::GetUrl(nsAString& aOut)
|
||||
{
|
||||
aOut.Assign(mURL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOpenWindowEventDetail::GetName(nsAString& aOut)
|
||||
{
|
||||
aOut.Assign(mName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOpenWindowEventDetail::GetFeatures(nsAString& aOut)
|
||||
{
|
||||
aOut.Assign(mFeatures);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOpenWindowEventDetail::GetFrameElement(nsIDOMNode** aOut)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> out = mFrameElement;
|
||||
out.forget(aOut);
|
||||
return NS_OK;
|
||||
}
|
39
dom/browser-element/nsOpenWindowEventDetail.h
Normal file
39
dom/browser-element/nsOpenWindowEventDetail.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsIOpenWindowEventDetail.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
/**
|
||||
* When we send a mozbrowseropenwindow event (an instance of CustomEvent), we
|
||||
* use an instance of this class as the event's detail.
|
||||
*/
|
||||
class nsOpenWindowEventDetail : public nsIOpenWindowEventDetail
|
||||
{
|
||||
public:
|
||||
nsOpenWindowEventDetail(const nsAString& aURL,
|
||||
const nsAString& aName,
|
||||
const nsAString& aFeatures,
|
||||
nsIDOMNode* aFrameElement)
|
||||
: mURL(aURL)
|
||||
, mName(aName)
|
||||
, mFeatures(aFeatures)
|
||||
, mFrameElement(aFrameElement)
|
||||
{}
|
||||
|
||||
virtual ~nsOpenWindowEventDetail() {}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsOpenWindowEventDetail)
|
||||
NS_DECL_NSIOPENWINDOWEVENTDETAIL
|
||||
|
||||
private:
|
||||
const nsString mURL;
|
||||
const nsString mName;
|
||||
const nsString mFeatures;
|
||||
nsCOMPtr<nsIDOMNode> mFrameElement;
|
||||
};
|
@ -7,7 +7,9 @@
|
||||
|
||||
#include "nsIDOMMozBrowserFrame.idl"
|
||||
|
||||
[scriptable, uuid(076AD76C-2DF6-4760-B914-21D554F0A2B6)]
|
||||
interface nsITabParent;
|
||||
|
||||
[scriptable, uuid(0acd92dd-2902-48ee-adcf-082d3bb3ec45)]
|
||||
interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
|
||||
{
|
||||
/**
|
||||
@ -18,4 +20,28 @@ interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
|
||||
* may have to pass various security checks.
|
||||
*/
|
||||
readonly attribute boolean reallyIsBrowser;
|
||||
|
||||
/**
|
||||
* Normally, a frame tries to create its frame loader when its src is
|
||||
* modified, or its contentWindow is accessed.
|
||||
*
|
||||
* disallowCreateFrameLoader prevents the frame element from creating its
|
||||
* frame loader (in the same way that not being inside a document prevents the
|
||||
* creation of a frame loader). allowCreateFrameLoader lifts this restriction.
|
||||
*
|
||||
* These methods are not re-entrant -- it is an error to call
|
||||
* disallowCreateFrameLoader twice without first calling allowFrameLoader.
|
||||
*
|
||||
* It's also an error to call either method if we already have a frame loader.
|
||||
*/
|
||||
void disallowCreateFrameLoader();
|
||||
void allowCreateFrameLoader();
|
||||
|
||||
/**
|
||||
* Create a remote (i.e., out-of-process) frame loader attached to the given
|
||||
* tab parent.
|
||||
*
|
||||
* It is an error to call this method if we already have a frame loader.
|
||||
*/
|
||||
void createRemoteFrameLoader(in nsITabParent aTabParent);
|
||||
};
|
||||
|
@ -205,6 +205,21 @@ parent:
|
||||
sync PIndexedDB(nsCString asciiOrigin)
|
||||
returns (bool allowed);
|
||||
|
||||
/**
|
||||
* window.open from inside <iframe mozbrowser> is special. When the child
|
||||
* process calls window.open, it creates a new PBrowser (in its own
|
||||
* process), then calls BrowserFrameOpenWindow on it.
|
||||
*
|
||||
* The parent process gets a chance to accept or reject the window.open
|
||||
* call, and windowOpened is set to true if we ended up going through with
|
||||
* the window.open.
|
||||
*
|
||||
* @param opener the PBrowser whose content called window.open.
|
||||
*/
|
||||
sync BrowserFrameOpenWindow(PBrowser opener, nsString aURL,
|
||||
nsString aName, nsString aFeatures)
|
||||
returns (bool windowOpened);
|
||||
|
||||
__delete__();
|
||||
|
||||
child:
|
||||
|
@ -77,9 +77,16 @@ rpc protocol PContent
|
||||
manages PStorage;
|
||||
manages PTestShell;
|
||||
|
||||
child:
|
||||
PBrowser(PRUint32 chromeFlags);
|
||||
both:
|
||||
// Depending on exactly how the new browser is being created, it might be
|
||||
// created from either the child or parent process!
|
||||
//
|
||||
// The child creates the PBrowser as part of
|
||||
// TabChild::BrowserFrameProvideWindow, and the parent creates the PBrowser
|
||||
// as part of ContentParent::CreateTab.
|
||||
async PBrowser(PRUint32 chromeFlags);
|
||||
|
||||
child:
|
||||
PMemoryReportRequest();
|
||||
|
||||
PTestShell();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* vim: set sw=2 sts=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -93,6 +93,7 @@ TabChild::TabChild(PRUint32 aChromeFlags)
|
||||
, mChromeFlags(aChromeFlags)
|
||||
, mOuterRect(0, 0, 0, 0)
|
||||
, mLastBackgroundColor(NS_RGB(255, 255, 255))
|
||||
, mDidFakeShow(false)
|
||||
{
|
||||
printf("creating %d!\n", NS_IsMainThread());
|
||||
}
|
||||
@ -331,6 +332,28 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, PRUint32 aChromeFlags,
|
||||
{
|
||||
*aReturn = nsnull;
|
||||
|
||||
// If aParent is inside an <iframe mozbrowser> and this isn't a request to
|
||||
// open a modal-type window, we're going to create a new <iframe mozbrowser>
|
||||
// and return its window here.
|
||||
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
|
||||
bool inBrowserFrame = false;
|
||||
if (docshell) {
|
||||
docshell->GetContainedInBrowserFrame(&inBrowserFrame);
|
||||
}
|
||||
|
||||
if (inBrowserFrame &&
|
||||
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
|
||||
|
||||
// Note that BrowserFrameProvideWindow 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 BrowserFrameProvideWindow(aParent, aURI, aName, aFeatures,
|
||||
aWindowIsNew, aReturn);
|
||||
}
|
||||
|
||||
// Otherwise, create a new top-level window.
|
||||
PBrowserChild* newChild;
|
||||
if (!CallCreateWindow(&newChild)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -343,6 +366,41 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, PRUint32 aChromeFlags,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
|
||||
nsIURI* aURI,
|
||||
const nsAString& aName,
|
||||
const nsACString& aFeatures,
|
||||
bool* aWindowIsNew,
|
||||
nsIDOMWindow** aReturn)
|
||||
{
|
||||
*aReturn = nsnull;
|
||||
|
||||
nsRefPtr<TabChild> newChild =
|
||||
static_cast<TabChild*>(Manager()->SendPBrowserConstructor(0));
|
||||
|
||||
nsCAutoString spec;
|
||||
aURI->GetSpec(spec);
|
||||
|
||||
NS_ConvertUTF8toUTF16 url(spec);
|
||||
nsString name(aName);
|
||||
NS_ConvertUTF8toUTF16 features(aFeatures);
|
||||
newChild->SendBrowserFrameOpenWindow(this, url, name,
|
||||
features, aWindowIsNew);
|
||||
if (!*aWindowIsNew) {
|
||||
PBrowserChild::Send__delete__(newChild);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
// Unfortunately we don't get a window unless we've shown the frame. That's
|
||||
// pretty bogus; see bug 763602.
|
||||
newChild->DoFakeShow();
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(newChild->mWebNav);
|
||||
win.forget(aReturn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsInterfaceHashtable<nsPtrHashKey<PContentDialogChild>, nsIDialogParamBlock> gActiveDialogs;
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -483,9 +541,20 @@ TabChild::RecvLoadURL(const nsCString& uri)
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TabChild::DoFakeShow()
|
||||
{
|
||||
RecvShow(nsIntSize(0, 0));
|
||||
mDidFakeShow = true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabChild::RecvShow(const nsIntSize& size)
|
||||
{
|
||||
if (mDidFakeShow) {
|
||||
return true;
|
||||
}
|
||||
|
||||
printf("[TabChild] SHOW (w,h)= (%d, %d)\n", size.width, size.height);
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
|
||||
|
@ -246,6 +246,17 @@ private:
|
||||
bool InitWidget(const nsIntSize& size);
|
||||
void DestroyWindow();
|
||||
|
||||
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
|
||||
void DoFakeShow();
|
||||
|
||||
nsresult
|
||||
BrowserFrameProvideWindow(nsIDOMWindow* aOpener,
|
||||
nsIURI* aURI,
|
||||
const nsAString& aName,
|
||||
const nsACString& aFeatures,
|
||||
bool* aWindowIsNew,
|
||||
nsIDOMWindow** aReturn);
|
||||
|
||||
nsCOMPtr<nsIWebNavigation> mWebNav;
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
RenderFrameChild* mRemoteFrame;
|
||||
@ -253,6 +264,7 @@ private:
|
||||
PRUint32 mChromeFlags;
|
||||
nsIntRect mOuterRect;
|
||||
nscolor mLastBackgroundColor;
|
||||
bool mDidFakeShow;
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
};
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "mozilla/BrowserElementParent.h"
|
||||
#include "IndexedDBParent.h"
|
||||
#include "IDBFactory.h"
|
||||
|
||||
@ -922,5 +923,18 @@ TabParent::GetWidget() const
|
||||
return widget.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
|
||||
const nsString& aURL,
|
||||
const nsString& aName,
|
||||
const nsString& aFeatures,
|
||||
bool* aOutWindowOpened)
|
||||
{
|
||||
*aOutWindowOpened =
|
||||
BrowserElementParent::OpenWindowOOP(static_cast<TabParent*>(aOpener),
|
||||
this, aURL, aName, aFeatures);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace tabs
|
||||
} // namespace mozilla
|
||||
|
@ -52,7 +52,11 @@ public:
|
||||
|
||||
virtual bool RecvMoveFocus(const bool& aForward);
|
||||
virtual bool RecvEvent(const RemoteDOMEvent& aEvent);
|
||||
|
||||
virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
|
||||
const nsString& aURL,
|
||||
const nsString& aName,
|
||||
const nsString& aFeatures,
|
||||
bool* aOutWindowOpened);
|
||||
virtual bool AnswerCreateWindow(PBrowserParent** retval);
|
||||
virtual bool RecvSyncMessage(const nsString& aMessage,
|
||||
const nsString& aJSON,
|
||||
|
@ -77,6 +77,9 @@ interface nsIWindowProvider : nsISupports
|
||||
* the nsIWindowProvider implementation or may be a window that
|
||||
* already existed.
|
||||
*
|
||||
* @throw NS_ERROR_ABORT if the caller should cease its attempt to open a new
|
||||
* window.
|
||||
*
|
||||
* @see nsIWindowWatcher for more information on aFeatures.
|
||||
* @see nsIWebBrowserChrome for more information on aChromeFlags.
|
||||
*/
|
||||
|
@ -593,6 +593,7 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
||||
sizeSpec.SizeSpecified(),
|
||||
uriToLoad, name, features, &windowIsNew,
|
||||
getter_AddRefs(newWindow));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
GetWindowTreeItem(newWindow, getter_AddRefs(newDocShellItem));
|
||||
if (windowIsNew && newDocShellItem) {
|
||||
@ -605,6 +606,14 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
||||
webNav->Stop(nsIWebNavigation::STOP_NETWORK);
|
||||
}
|
||||
}
|
||||
else if (rv == NS_ERROR_ABORT) {
|
||||
// NS_ERROR_ABORT means the window provider has flat-out rejected
|
||||
// the open-window call and we should bail. Don't return an error
|
||||
// here, because our caller may propagate that error, which might
|
||||
// cause e.g. window.open to throw! Just return null for our out
|
||||
// param.
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ SHARED_LIBRARY_LIBS = \
|
||||
$(DEPTH)/dom/workers/$(LIB_PREFIX)domworkers_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/dom/indexedDB/$(LIB_PREFIX)dom_indexeddb_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/dom/indexedDB/ipc/$(LIB_PREFIX)dom_indexeddb_ipc_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/dom/browser-element/$(LIB_PREFIX)dom_browserelement_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/editor/libeditor/text/$(LIB_PREFIX)texteditor_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/editor/libeditor/base/$(LIB_PREFIX)editorbase_s.$(LIB_SUFFIX) \
|
||||
$(DEPTH)/parser/html/$(LIB_PREFIX)html5p_s.$(LIB_SUFFIX) \
|
||||
|
@ -170,6 +170,7 @@
|
||||
@BINPATH@/components/dom_indexeddb.xpt
|
||||
@BINPATH@/components/dom_offline.xpt
|
||||
@BINPATH@/components/dom_json.xpt
|
||||
@BINPATH@/components/dom_browserelement.xpt
|
||||
@BINPATH@/components/dom_power.xpt
|
||||
@BINPATH@/components/dom_range.xpt
|
||||
@BINPATH@/components/dom_sidebar.xpt
|
||||
|
@ -176,6 +176,7 @@
|
||||
@BINPATH@/components/dom_html.xpt
|
||||
@BINPATH@/components/dom_indexeddb.xpt
|
||||
@BINPATH@/components/dom_offline.xpt
|
||||
@BINPATH@/components/dom_browserelement.xpt
|
||||
@BINPATH@/components/dom_json.xpt
|
||||
@BINPATH@/components/dom_range.xpt
|
||||
@BINPATH@/components/dom_sidebar.xpt
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "nsCDefaultURIFixup.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "mozilla/BrowserElementParent.h"
|
||||
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
@ -837,6 +838,29 @@ nsContentTreeOwner::ProvideWindow(nsIDOMWindow* aParent,
|
||||
"Parent from wrong docshell tree?");
|
||||
#endif
|
||||
|
||||
// If aParent is inside an <iframe mozbrowser> and this isn't a request to
|
||||
// open a modal-type window, we're going to create a new <iframe mozbrowser>
|
||||
// and return its window here.
|
||||
nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
|
||||
bool inBrowserFrame = false;
|
||||
if (docshell) {
|
||||
docshell->GetContainedInBrowserFrame(&inBrowserFrame);
|
||||
}
|
||||
|
||||
if (inBrowserFrame &&
|
||||
!(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
|
||||
nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) {
|
||||
bool openSucceeded =
|
||||
BrowserElementParent::OpenWindowInProcess(aParent, aURI, aName,
|
||||
aFeatures, aReturn);
|
||||
|
||||
// If OpenWindowInProcess failed (perhaps because the embedder blocked the
|
||||
// popup), tell our caller not to proceed trying to create a new window
|
||||
// through other means.
|
||||
return openSucceeded ? NS_OK : NS_ERROR_ABORT;
|
||||
}
|
||||
|
||||
// Where should we open this?
|
||||
PRInt32 containerPref;
|
||||
if (NS_FAILED(Preferences::GetInt("browser.link.open_newwindow",
|
||||
|
Loading…
Reference in New Issue
Block a user