/*static*/ BrowserElementParent::OpenWindowResult 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 = aOpenerTabParent->GetOwnerElement(); NS_ENSURE_TRUE(openerFrameElement, BrowserElementParent::OPEN_WINDOW_IGNORED); nsRefPtr<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); return opened; }
/* 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; }