/* static */ BrowserElementParent::OpenWindowResult BrowserElementParent::OpenWindowInProcess(nsIDOMWindow* aOpenerWindow, nsIURI* aURI, const nsAString& aName, const nsACString& aFeatures, nsIDOMWindow** aReturnWindow) { *aReturnWindow = NULL; // If we call window.open from an <iframe> inside an <iframe mozbrowser>, // it's as though the top-level document inside the <iframe mozbrowser> // called window.open. (Indeed, in the OOP case, the inner <iframe> lives // out-of-process, so we couldn't touch it if we tried.) // // GetScriptableTop gets us the <iframe mozbrowser>'s window; we'll use its // frame element, rather than aOpenerWindow's frame element, as our "opener // frame element" below. nsCOMPtr<nsIDOMWindow> topWindow; aOpenerWindow->GetScriptableTop(getter_AddRefs(topWindow)); nsCOMPtr<nsIDOMElement> openerFrameDOMElement; topWindow->GetFrameElement(getter_AddRefs(openerFrameDOMElement)); NS_ENSURE_TRUE(openerFrameDOMElement, BrowserElementParent::OPEN_WINDOW_IGNORED); nsCOMPtr<Element> openerFrameElement = do_QueryInterface(openerFrameDOMElement); nsRefPtr<HTMLIFrameElement> popupFrameElement = CreateIframe(openerFrameElement, aName, /* aRemote = */ false); NS_ENSURE_TRUE(popupFrameElement, BrowserElementParent::OPEN_WINDOW_IGNORED); nsAutoCString spec; if (aURI) { aURI->GetSpec(spec); } OpenWindowResult opened = DispatchOpenWindowEvent(openerFrameElement, popupFrameElement, NS_ConvertUTF8toUTF16(spec), aName, NS_ConvertUTF8toUTF16(aFeatures)); if (opened != BrowserElementParent::OPEN_WINDOW_ADDED) { return opened; } // Return popupFrameElement's window. nsCOMPtr<nsIFrameLoader> frameLoader; popupFrameElement->GetFrameLoader(getter_AddRefs(frameLoader)); NS_ENSURE_TRUE(frameLoader, BrowserElementParent::OPEN_WINDOW_IGNORED); nsCOMPtr<nsIDocShell> docshell; frameLoader->GetDocShell(getter_AddRefs(docshell)); NS_ENSURE_TRUE(docshell, BrowserElementParent::OPEN_WINDOW_IGNORED); nsCOMPtr<nsIDOMWindow> window = do_GetInterface(docshell); window.forget(aReturnWindow); return !!*aReturnWindow ? opened : BrowserElementParent::OPEN_WINDOW_CANCELLED; }
/*static*/ BrowserElementParent::OpenWindowResult BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent, TabParent* aPopupTabParent, PRenderFrameParent* aRenderFrame, const nsAString& aURL, const nsAString& aName, const nsAString& aFeatures, TextureFactoryIdentifier* aTextureFactoryIdentifier, uint64_t* aLayersId) { // Create an iframe owned by the same document which owns openerFrameElement. nsCOMPtr<Element> openerFrameElement = aOpenerTabParent->GetOwnerElement(); NS_ENSURE_TRUE(openerFrameElement, BrowserElementParent::OPEN_WINDOW_IGNORED); RefPtr<HTMLIFrameElement> popupFrameElement = CreateIframe(openerFrameElement, aName, /* aRemote = */ true); // 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(); OpenWindowResult opened = DispatchOpenWindowEvent(openerFrameElement, popupFrameElement, aURL, aName, aFeatures); if (opened != BrowserElementParent::OPEN_WINDOW_ADDED) { return opened; } // 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); RenderFrameParent* rfp = static_cast<RenderFrameParent*>(aRenderFrame); if (!aPopupTabParent->SetRenderFrame(rfp) || !aPopupTabParent->GetRenderFrameInfo(aTextureFactoryIdentifier, aLayersId)) { return BrowserElementParent::OPEN_WINDOW_IGNORED; } return opened; }
/*static*/ bool BrowserElementParent::OpenWindowOOP(TabParent* aOpenerTabParent, 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, aName, /* aRemote = */ true); // 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 */ BrowserElementParent::OpenWindowResult BrowserElementParent::OpenWindowInProcess(nsPIDOMWindowOuter* aOpenerWindow, nsIURI* aURI, const nsAString& aName, const nsACString& aFeatures, bool aForceNoOpener, mozIDOMWindowProxy** aReturnWindow) { *aReturnWindow = nullptr; // If we call window.open from an <iframe> inside an <iframe mozbrowser>, // it's as though the top-level document inside the <iframe mozbrowser> // called window.open. (Indeed, in the OOP case, the inner <iframe> lives // out-of-process, so we couldn't touch it if we tried.) // // GetScriptableTop gets us the <iframe mozbrowser>'s window; we'll use its // frame element, rather than aOpenerWindow's frame element, as our "opener // frame element" below. nsCOMPtr<nsPIDOMWindowOuter> win = aOpenerWindow->GetScriptableTop(); nsCOMPtr<Element> openerFrameElement = win->GetFrameElementInternal(); NS_ENSURE_TRUE(openerFrameElement, BrowserElementParent::OPEN_WINDOW_IGNORED); RefPtr<HTMLIFrameElement> popupFrameElement = CreateIframe(openerFrameElement, aName, /* aRemote = */ false); NS_ENSURE_TRUE(popupFrameElement, BrowserElementParent::OPEN_WINDOW_IGNORED); nsAutoCString spec; if (aURI) { aURI->GetSpec(spec); } if (!aForceNoOpener) { ErrorResult res; popupFrameElement->PresetOpenerWindow(aOpenerWindow, res); MOZ_ASSERT(!res.Failed()); } OpenWindowResult opened = DispatchOpenWindowEvent(openerFrameElement, popupFrameElement, NS_ConvertUTF8toUTF16(spec), aName, NS_ConvertUTF8toUTF16(aFeatures)); if (opened != BrowserElementParent::OPEN_WINDOW_ADDED) { return opened; } // Return popupFrameElement's window. RefPtr<nsFrameLoader> frameLoader = popupFrameElement->GetFrameLoader(); NS_ENSURE_TRUE(frameLoader, BrowserElementParent::OPEN_WINDOW_IGNORED); nsCOMPtr<nsIDocShell> docshell; frameLoader->GetDocShell(getter_AddRefs(docshell)); NS_ENSURE_TRUE(docshell, BrowserElementParent::OPEN_WINDOW_IGNORED); nsCOMPtr<nsPIDOMWindowOuter> window = docshell->GetWindow(); window.forget(aReturnWindow); return !!*aReturnWindow ? opened : BrowserElementParent::OPEN_WINDOW_CANCELLED; }