зеркало из https://github.com/mozilla/gecko-dev.git
Bug 742944 - Part 4: Handle window.open in <iframe mozbrowser>. r=bz, cjones
--HG-- extra : rebase_source : 4c16c86c5be230af22eea89dfb5f893b7c6091dd
This commit is contained in:
Родитель
9ff0e10da2
Коммит
8d7f4a897e
|
@ -177,6 +177,7 @@
|
||||||
#ifdef MOZ_B2G_RIL
|
#ifdef MOZ_B2G_RIL
|
||||||
@BINPATH@/components/dom_mms.xpt
|
@BINPATH@/components/dom_mms.xpt
|
||||||
#endif
|
#endif
|
||||||
|
@BINPATH@/components/dom_browserelement.xpt
|
||||||
@BINPATH@/components/dom_power.xpt
|
@BINPATH@/components/dom_power.xpt
|
||||||
@BINPATH@/components/dom_range.xpt
|
@BINPATH@/components/dom_range.xpt
|
||||||
@BINPATH@/components/dom_settings.xpt
|
@BINPATH@/components/dom_settings.xpt
|
||||||
|
|
|
@ -188,6 +188,7 @@
|
||||||
#ifdef MOZ_B2G_RIL
|
#ifdef MOZ_B2G_RIL
|
||||||
@BINPATH@/components/dom_mms.xpt
|
@BINPATH@/components/dom_mms.xpt
|
||||||
#endif
|
#endif
|
||||||
|
@BINPATH@/components/dom_browserelement.xpt
|
||||||
@BINPATH@/components/dom_power.xpt
|
@BINPATH@/components/dom_power.xpt
|
||||||
@BINPATH@/components/dom_range.xpt
|
@BINPATH@/components/dom_range.xpt
|
||||||
@BINPATH@/components/dom_settings.xpt
|
@BINPATH@/components/dom_settings.xpt
|
||||||
|
|
|
@ -2211,3 +2211,11 @@ nsFrameLoader::GetOwnerElement(nsIDOMElement **aElement)
|
||||||
ownerElement.forget(aElement);
|
ownerElement.forget(aElement);
|
||||||
return NS_OK;
|
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 nsIView;
|
||||||
class nsIInProcessContentFrameMessageManager;
|
class nsIInProcessContentFrameMessageManager;
|
||||||
class AutoResetInShow;
|
class AutoResetInShow;
|
||||||
|
class nsITabParent;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -256,6 +257,16 @@ public:
|
||||||
|
|
||||||
bool ShouldClampScrollPosition() { return mClampScrollPosition; }
|
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:
|
private:
|
||||||
|
|
||||||
void SetOwnerContent(mozilla::dom::Element* aContent);
|
void SetOwnerContent(mozilla::dom::Element* aContent);
|
||||||
|
|
|
@ -98,7 +98,7 @@ nsGenericHTMLFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
|
||||||
nsresult
|
nsresult
|
||||||
nsGenericHTMLFrameElement::EnsureFrameLoader()
|
nsGenericHTMLFrameElement::EnsureFrameLoader()
|
||||||
{
|
{
|
||||||
if (!GetParent() || !IsInDoc() || mFrameLoader) {
|
if (!GetParent() || !IsInDoc() || mFrameLoader || mFrameLoaderCreationDisallowed) {
|
||||||
// If frame loader is there, we just keep it around, cached
|
// If frame loader is there, we just keep it around, cached
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,16 @@ nsGenericHTMLFrameElement::EnsureFrameLoader()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsGenericHTMLFrameElement::CreateRemoteFrameLoader(nsITabParent* aTabParent)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(!mFrameLoader);
|
||||||
|
EnsureFrameLoader();
|
||||||
|
NS_ENSURE_STATE(mFrameLoader);
|
||||||
|
mFrameLoader->SetRemoteBrowser(aTabParent);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsGenericHTMLFrameElement::GetFrameLoader(nsIFrameLoader **aFrameLoader)
|
nsGenericHTMLFrameElement::GetFrameLoader(nsIFrameLoader **aFrameLoader)
|
||||||
{
|
{
|
||||||
|
@ -296,3 +306,21 @@ nsGenericHTMLFrameElement::GetReallyIsBrowser(bool *aOut)
|
||||||
*aOut = true;
|
*aOut = true;
|
||||||
return NS_OK;
|
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)
|
: nsGenericHTMLElement(aNodeInfo)
|
||||||
, mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK)
|
, mNetworkCreated(aFromParser == mozilla::dom::FROM_PARSER_NETWORK)
|
||||||
, mBrowserFrameListenersRegistered(false)
|
, mBrowserFrameListenersRegistered(false)
|
||||||
|
, mFrameLoaderCreationDisallowed(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,4 +100,5 @@ protected:
|
||||||
bool mNetworkCreated;
|
bool mNetworkCreated;
|
||||||
|
|
||||||
bool mBrowserFrameListenersRegistered;
|
bool mBrowserFrameListenersRegistered;
|
||||||
|
bool mFrameLoaderCreationDisallowed;
|
||||||
};
|
};
|
||||||
|
|
|
@ -521,6 +521,8 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
|
||||||
|
|
||||||
#include "DOMError.h"
|
#include "DOMError.h"
|
||||||
#include "DOMRequest.h"
|
#include "DOMRequest.h"
|
||||||
|
#include "nsIOpenWindowEventDetail.h"
|
||||||
|
#include "nsIDOMGlobalObjectConstructor.h"
|
||||||
|
|
||||||
#include "DOMFileHandle.h"
|
#include "DOMFileHandle.h"
|
||||||
#include "FileRequest.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
|
#undef None // something included above defines this preprocessor symbol, maybe Xlib headers
|
||||||
#include "WebGLContext.h"
|
#include "WebGLContext.h"
|
||||||
|
|
||||||
#include "nsIDOMGlobalObjectConstructor.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
|
@ -1663,6 +1663,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||||
|
|
||||||
NS_DEFINE_CLASSINFO_DATA(DOMRequest, nsEventTargetSH,
|
NS_DEFINE_CLASSINFO_DATA(DOMRequest, nsEventTargetSH,
|
||||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||||
|
NS_DEFINE_CLASSINFO_DATA(OpenWindowEventDetail, nsDOMGenericSH,
|
||||||
|
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||||
|
|
||||||
NS_DEFINE_CLASSINFO_DATA_WITH_NAME(DOMFileHandle, FileHandle, nsEventTargetSH,
|
NS_DEFINE_CLASSINFO_DATA_WITH_NAME(DOMFileHandle, FileHandle, nsEventTargetSH,
|
||||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||||
|
@ -4526,6 +4528,10 @@ nsDOMClassInfo::Init()
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
|
||||||
DOM_CLASSINFO_MAP_END
|
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_BEGIN(DOMFileHandle, nsIDOMFileHandle)
|
||||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileHandle)
|
DOM_CLASSINFO_MAP_ENTRY(nsIDOMFileHandle)
|
||||||
DOM_CLASSINFO_MAP_END
|
DOM_CLASSINFO_MAP_END
|
||||||
|
|
|
@ -532,6 +532,7 @@ DOMCI_CLASS(BluetoothAdapter)
|
||||||
|
|
||||||
DOMCI_CLASS(DOMError)
|
DOMCI_CLASS(DOMError)
|
||||||
DOMCI_CLASS(DOMRequest)
|
DOMCI_CLASS(DOMRequest)
|
||||||
|
DOMCI_CLASS(OpenWindowEventDetail)
|
||||||
|
|
||||||
DOMCI_CLASS(DOMFileHandle)
|
DOMCI_CLASS(DOMFileHandle)
|
||||||
DOMCI_CLASS(FileRequest)
|
DOMCI_CLASS(FileRequest)
|
||||||
|
|
|
@ -8296,11 +8296,9 @@ nsGlobalWindow::GetInterface(const nsIID & aIID, void **aSink)
|
||||||
else if (aIID.Equals(NS_GET_IID(nsIDocShell))) {
|
else if (aIID.Equals(NS_GET_IID(nsIDocShell))) {
|
||||||
FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
|
FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
|
||||||
|
|
||||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(mDocShell);
|
nsCOMPtr<nsIDocShell> docShell = mDocShell;
|
||||||
if (docShell) {
|
|
||||||
docShell.forget(aSink);
|
docShell.forget(aSink);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#ifdef NS_PRINTING
|
#ifdef NS_PRINTING
|
||||||
else if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
|
else if (aIID.Equals(NS_GET_IID(nsIWebBrowserPrint))) {
|
||||||
FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
|
FORWARD_TO_OUTER(GetInterface, (aIID, aSink), NS_ERROR_NOT_INITIALIZED);
|
||||||
|
|
|
@ -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
|
|
@ -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@
|
srcdir = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
relativesrcdir = dom/browser-element
|
|
||||||
|
|
||||||
include $(DEPTH)/config/autoconf.mk
|
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
|
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 = \
|
EXTRA_COMPONENTS = \
|
||||||
BrowserElementParent.js \
|
BrowserElementParent.js \
|
||||||
BrowserElementParent.manifest \
|
BrowserElementParent.manifest \
|
||||||
|
@ -22,4 +46,12 @@ EXTRA_JS_MODULES = \
|
||||||
BrowserElementPromptService.jsm \
|
BrowserElementPromptService.jsm \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/config.mk
|
||||||
|
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
|
INCLUDES += \
|
||||||
|
-I$(topsrcdir)/dom/base \
|
||||||
|
-I$(topsrcdir)/dom/ipc \
|
||||||
|
-I$(topsrcdir)/content/base/src \
|
||||||
|
$(NULL)
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
|
@ -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;
|
||||||
|
}
|
|
@ -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"
|
#include "nsIDOMMozBrowserFrame.idl"
|
||||||
|
|
||||||
[scriptable, uuid(076AD76C-2DF6-4760-B914-21D554F0A2B6)]
|
interface nsITabParent;
|
||||||
|
|
||||||
|
[scriptable, uuid(0acd92dd-2902-48ee-adcf-082d3bb3ec45)]
|
||||||
interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
|
interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -18,4 +20,28 @@ interface nsIMozBrowserFrame : nsIDOMMozBrowserFrame
|
||||||
* may have to pass various security checks.
|
* may have to pass various security checks.
|
||||||
*/
|
*/
|
||||||
readonly attribute boolean reallyIsBrowser;
|
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)
|
sync PIndexedDB(nsCString asciiOrigin)
|
||||||
returns (bool allowed);
|
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__();
|
__delete__();
|
||||||
|
|
||||||
child:
|
child:
|
||||||
|
|
|
@ -77,9 +77,16 @@ rpc protocol PContent
|
||||||
manages PStorage;
|
manages PStorage;
|
||||||
manages PTestShell;
|
manages PTestShell;
|
||||||
|
|
||||||
child:
|
both:
|
||||||
PBrowser(PRUint32 chromeFlags);
|
// 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();
|
PMemoryReportRequest();
|
||||||
|
|
||||||
PTestShell();
|
PTestShell();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
|
/* -*- 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
|
/* 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
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
@ -93,6 +93,7 @@ TabChild::TabChild(PRUint32 aChromeFlags)
|
||||||
, mChromeFlags(aChromeFlags)
|
, mChromeFlags(aChromeFlags)
|
||||||
, mOuterRect(0, 0, 0, 0)
|
, mOuterRect(0, 0, 0, 0)
|
||||||
, mLastBackgroundColor(NS_RGB(255, 255, 255))
|
, mLastBackgroundColor(NS_RGB(255, 255, 255))
|
||||||
|
, mDidFakeShow(false)
|
||||||
{
|
{
|
||||||
printf("creating %d!\n", NS_IsMainThread());
|
printf("creating %d!\n", NS_IsMainThread());
|
||||||
}
|
}
|
||||||
|
@ -331,6 +332,28 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, PRUint32 aChromeFlags,
|
||||||
{
|
{
|
||||||
*aReturn = nsnull;
|
*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;
|
PBrowserChild* newChild;
|
||||||
if (!CallCreateWindow(&newChild)) {
|
if (!CallCreateWindow(&newChild)) {
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
@ -343,6 +366,41 @@ TabChild::ProvideWindow(nsIDOMWindow* aParent, PRUint32 aChromeFlags,
|
||||||
return NS_OK;
|
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;
|
static nsInterfaceHashtable<nsPtrHashKey<PContentDialogChild>, nsIDialogParamBlock> gActiveDialogs;
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -483,9 +541,20 @@ TabChild::RecvLoadURL(const nsCString& uri)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TabChild::DoFakeShow()
|
||||||
|
{
|
||||||
|
RecvShow(nsIntSize(0, 0));
|
||||||
|
mDidFakeShow = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TabChild::RecvShow(const nsIntSize& size)
|
TabChild::RecvShow(const nsIntSize& size)
|
||||||
{
|
{
|
||||||
|
if (mDidFakeShow) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
printf("[TabChild] SHOW (w,h)= (%d, %d)\n", size.width, size.height);
|
printf("[TabChild] SHOW (w,h)= (%d, %d)\n", size.width, size.height);
|
||||||
|
|
||||||
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
|
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(mWebNav);
|
||||||
|
|
|
@ -246,6 +246,17 @@ private:
|
||||||
bool InitWidget(const nsIntSize& size);
|
bool InitWidget(const nsIntSize& size);
|
||||||
void DestroyWindow();
|
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<nsIWebNavigation> mWebNav;
|
||||||
nsCOMPtr<nsIWidget> mWidget;
|
nsCOMPtr<nsIWidget> mWidget;
|
||||||
RenderFrameChild* mRemoteFrame;
|
RenderFrameChild* mRemoteFrame;
|
||||||
|
@ -253,6 +264,7 @@ private:
|
||||||
PRUint32 mChromeFlags;
|
PRUint32 mChromeFlags;
|
||||||
nsIntRect mOuterRect;
|
nsIntRect mOuterRect;
|
||||||
nscolor mLastBackgroundColor;
|
nscolor mLastBackgroundColor;
|
||||||
|
bool mDidFakeShow;
|
||||||
|
|
||||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
|
#include "mozilla/BrowserElementParent.h"
|
||||||
#include "IndexedDBParent.h"
|
#include "IndexedDBParent.h"
|
||||||
#include "IDBFactory.h"
|
#include "IDBFactory.h"
|
||||||
|
|
||||||
|
@ -922,5 +923,18 @@ TabParent::GetWidget() const
|
||||||
return widget.forget();
|
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 tabs
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -52,7 +52,11 @@ public:
|
||||||
|
|
||||||
virtual bool RecvMoveFocus(const bool& aForward);
|
virtual bool RecvMoveFocus(const bool& aForward);
|
||||||
virtual bool RecvEvent(const RemoteDOMEvent& aEvent);
|
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 AnswerCreateWindow(PBrowserParent** retval);
|
||||||
virtual bool RecvSyncMessage(const nsString& aMessage,
|
virtual bool RecvSyncMessage(const nsString& aMessage,
|
||||||
const nsString& aJSON,
|
const nsString& aJSON,
|
||||||
|
|
|
@ -77,6 +77,9 @@ interface nsIWindowProvider : nsISupports
|
||||||
* the nsIWindowProvider implementation or may be a window that
|
* the nsIWindowProvider implementation or may be a window that
|
||||||
* already existed.
|
* 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 nsIWindowWatcher for more information on aFeatures.
|
||||||
* @see nsIWebBrowserChrome for more information on aChromeFlags.
|
* @see nsIWebBrowserChrome for more information on aChromeFlags.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -593,6 +593,7 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
||||||
sizeSpec.SizeSpecified(),
|
sizeSpec.SizeSpecified(),
|
||||||
uriToLoad, name, features, &windowIsNew,
|
uriToLoad, name, features, &windowIsNew,
|
||||||
getter_AddRefs(newWindow));
|
getter_AddRefs(newWindow));
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
GetWindowTreeItem(newWindow, getter_AddRefs(newDocShellItem));
|
GetWindowTreeItem(newWindow, getter_AddRefs(newDocShellItem));
|
||||||
if (windowIsNew && newDocShellItem) {
|
if (windowIsNew && newDocShellItem) {
|
||||||
|
@ -605,6 +606,14 @@ nsWindowWatcher::OpenWindowJSInternal(nsIDOMWindow *aParent,
|
||||||
webNav->Stop(nsIWebNavigation::STOP_NETWORK);
|
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/workers/$(LIB_PREFIX)domworkers_s.$(LIB_SUFFIX) \
|
||||||
$(DEPTH)/dom/indexedDB/$(LIB_PREFIX)dom_indexeddb_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/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/text/$(LIB_PREFIX)texteditor_s.$(LIB_SUFFIX) \
|
||||||
$(DEPTH)/editor/libeditor/base/$(LIB_PREFIX)editorbase_s.$(LIB_SUFFIX) \
|
$(DEPTH)/editor/libeditor/base/$(LIB_PREFIX)editorbase_s.$(LIB_SUFFIX) \
|
||||||
$(DEPTH)/parser/html/$(LIB_PREFIX)html5p_s.$(LIB_SUFFIX) \
|
$(DEPTH)/parser/html/$(LIB_PREFIX)html5p_s.$(LIB_SUFFIX) \
|
||||||
|
|
|
@ -170,6 +170,7 @@
|
||||||
@BINPATH@/components/dom_indexeddb.xpt
|
@BINPATH@/components/dom_indexeddb.xpt
|
||||||
@BINPATH@/components/dom_offline.xpt
|
@BINPATH@/components/dom_offline.xpt
|
||||||
@BINPATH@/components/dom_json.xpt
|
@BINPATH@/components/dom_json.xpt
|
||||||
|
@BINPATH@/components/dom_browserelement.xpt
|
||||||
@BINPATH@/components/dom_power.xpt
|
@BINPATH@/components/dom_power.xpt
|
||||||
@BINPATH@/components/dom_range.xpt
|
@BINPATH@/components/dom_range.xpt
|
||||||
@BINPATH@/components/dom_sidebar.xpt
|
@BINPATH@/components/dom_sidebar.xpt
|
||||||
|
|
|
@ -176,6 +176,7 @@
|
||||||
@BINPATH@/components/dom_html.xpt
|
@BINPATH@/components/dom_html.xpt
|
||||||
@BINPATH@/components/dom_indexeddb.xpt
|
@BINPATH@/components/dom_indexeddb.xpt
|
||||||
@BINPATH@/components/dom_offline.xpt
|
@BINPATH@/components/dom_offline.xpt
|
||||||
|
@BINPATH@/components/dom_browserelement.xpt
|
||||||
@BINPATH@/components/dom_json.xpt
|
@BINPATH@/components/dom_json.xpt
|
||||||
@BINPATH@/components/dom_range.xpt
|
@BINPATH@/components/dom_range.xpt
|
||||||
@BINPATH@/components/dom_sidebar.xpt
|
@BINPATH@/components/dom_sidebar.xpt
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "nsCDefaultURIFixup.h"
|
#include "nsCDefaultURIFixup.h"
|
||||||
#include "nsIWebNavigation.h"
|
#include "nsIWebNavigation.h"
|
||||||
#include "nsIJSContextStack.h"
|
#include "nsIJSContextStack.h"
|
||||||
|
#include "mozilla/BrowserElementParent.h"
|
||||||
|
|
||||||
#include "nsIDOMDocument.h"
|
#include "nsIDOMDocument.h"
|
||||||
#include "nsIScriptObjectPrincipal.h"
|
#include "nsIScriptObjectPrincipal.h"
|
||||||
|
@ -837,6 +838,29 @@ nsContentTreeOwner::ProvideWindow(nsIDOMWindow* aParent,
|
||||||
"Parent from wrong docshell tree?");
|
"Parent from wrong docshell tree?");
|
||||||
#endif
|
#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?
|
// Where should we open this?
|
||||||
PRInt32 containerPref;
|
PRInt32 containerPref;
|
||||||
if (NS_FAILED(Preferences::GetInt("browser.link.open_newwindow",
|
if (NS_FAILED(Preferences::GetInt("browser.link.open_newwindow",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче