author | Eddy Bruel <ejpbruel@mozilla.com> |
Thu, 04 Apr 2013 15:24:32 +0200 | |
changeset 127713 | 429e15d02de3ac6933b20456a855b79ccbeabf14 |
parent 127712 | 4170679cb85ae13bfed63596c5b6504c0343a6dc |
child 127714 | d68412295d0fb4c38601dc8f4e3f3ad9ac38432b |
push id | 24512 |
push user | ryanvm@gmail.com |
push date | Fri, 05 Apr 2013 20:13:49 +0000 |
treeherder | mozilla-central@139b6ba547fa [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bz, benjamin |
bugs | 846906 |
milestone | 23.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/docshell/test/chrome/Makefile.in +++ b/docshell/test/chrome/Makefile.in @@ -92,16 +92,18 @@ MOCHITEST_CHROME_FILES = \ bug311007_window.xul \ test_principalInherit.xul \ test_mozFrameType.xul \ mozFrameType_window.xul \ test_bug789773.xul \ test_private_hidden_window.html \ docshell_helpers.js \ generic.html \ + test_bug846906.xul \ + bug846906.html \ $(NULL) ifneq ($(MOZ_WIDGET_TOOLKIT),gtk2) MOCHITEST_CHROME_FILES += \ test_bug454235.xul \ $(NULL) else $(filter disabled-temporarily--bug-684176, test_bug454235.xul)
new file mode 100644 --- /dev/null +++ b/docshell/test/chrome/bug846906.html @@ -0,0 +1,10 @@ +<html> + <head> + <title> + </title> + </head> + <body> + <div id="div1" style="width:1024px; height:768px; border:none;"> + </div> + </body> +</html>
new file mode 100644 --- /dev/null +++ b/docshell/test/chrome/test_bug846906.xul @@ -0,0 +1,73 @@ +<?xml version="1.0"?> +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> +<?xml-stylesheet type="text/css" href="/tests/SimpleTest/test.css"?> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=846906 +--> +<window title="Mozilla Bug 846906" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <title>Test for Bug 846906</title> + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <!-- test code goes here --> + <script type="application/javascript"> + <![CDATA[ + + /** Test for Bug 846906 **/ + SimpleTest.waitForExplicitFinish(); + + var appShellService = Components.classes["@mozilla.org/appshell/appShellService;1"] + .getService(Components.interfaces.nsIAppShellService); + ok(appShellService, "Should be able to get app shell service"); + + var webNavigation = appShellService.createWindowlessBrowser(); + ok(webNavigation, "Should be able to create windowless browser"); + + var interfaceRequestor = webNavigation.QueryInterface(Components.interfaces.nsIInterfaceRequestor); + ok(interfaceRequestor, "Should be able to query interface requestor interface"); + + var docShell = interfaceRequestor.getInterface(Components.interfaces.nsIDocShell); + ok(docShell, "Should be able to get doc shell interface"); + + var document = webNavigation.document; + ok(document, "Should be able to get document"); + + var iframe = document.createElement("iframe"); + ok(iframe, "Should be able to create iframe"); + + iframe.onload = function () { + ok(true, "Should receive initial onload event"); + + iframe.onload = function () { + ok(true, "Should receive onload event"); + + var contentDocument = iframe.contentDocument; + ok(contentDocument, "Should be able to get content document"); + + var div = contentDocument.getElementById("div1"); + ok(div, "Should be able to get element by id"); + + var rect = div.getBoundingClientRect(); + ok(rect, "Should be able to get bounding client rect"); + + // xxx: can we do better than hardcoding these values here? + is(rect.width, 1024); + is(rect.height, 768); + + SimpleTest.finish(); + }; + iframe.setAttribute("src", "http://mochi.test:8888/chrome/docshell/test/chrome/bug846906.html"); + }; + document.documentElement.appendChild(iframe); + + ]]> + </script> + + <!-- test results are displayed in the html:body --> + <body xmlns="http://www.w3.org/1999/xhtml"> + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=846906" + target="_blank">Mozilla Bug 846906</a> + </body> +</window>
--- a/widget/xpwidgets/PuppetWidget.cpp +++ b/widget/xpwidgets/PuppetWidget.cpp @@ -31,17 +31,17 @@ InvalidateRegion(nsIWidget* aWidget, con while(const nsIntRect* r = it.Next()) { aWidget->Invalidate(*r); } } /*static*/ already_AddRefed<nsIWidget> nsIWidget::CreatePuppetWidget(TabChild* aTabChild) { - NS_ABORT_IF_FALSE(nsIWidget::UsePuppetWidgets(), + NS_ABORT_IF_FALSE(!aTabChild || nsIWidget::UsePuppetWidgets(), "PuppetWidgets not allowed in this configuration"); nsCOMPtr<nsIWidget> widget = new PuppetWidget(aTabChild); return widget.forget(); } namespace mozilla { namespace widget {
--- a/xpfe/appshell/public/nsIAppShellService.idl +++ b/xpfe/appshell/public/nsIAppShellService.idl @@ -1,16 +1,17 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* 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 nsIXULWindow; +interface nsIWebNavigation; interface nsIURI; interface nsIDOMWindow; interface nsIAppShell; [ptr] native JSContext(JSContext); %{C++ struct JSContext; @@ -38,16 +39,18 @@ interface nsIAppShellService : nsISuppor */ const long SIZE_TO_CONTENT = -1; nsIXULWindow createTopLevelWindow(in nsIXULWindow aParent, in nsIURI aUrl, in uint32_t aChromeMask, in long aInitialWidth, in long aInitialHeight); + nsIWebNavigation createWindowlessBrowser(); + [noscript] void createHiddenWindow(); void destroyHiddenWindow(); /** * Return the (singleton) application hidden window, automatically created * and maintained by this AppShellService.
--- a/xpfe/appshell/src/nsAppShellService.cpp +++ b/xpfe/appshell/src/nsAppShellService.cpp @@ -41,16 +41,20 @@ #include "nsIUnicodeDecoder.h" #include "nsIChromeRegistry.h" #include "nsILoadContext.h" #include "nsIWebNavigation.h" #include "mozilla/Preferences.h" #include "mozilla/StartupTimeline.h" +#include "nsEmbedCID.h" +#include "nsIWebBrowser.h" +#include "nsIDocShell.h" + using namespace mozilla; // Default URL for the hidden window, can be overridden by a pref on Mac #define DEFAULT_HIDDENWINDOW_URL "resource://gre-resources/hiddenWindow.html" class nsIAppShell; nsAppShellService::nsAppShellService() : @@ -198,16 +202,172 @@ nsAppShellService::CreateTopLevelWindow( if (aChromeMask & nsIWebBrowserChrome::CHROME_DEPENDENT) parent = aParent; (*aResult)->SetZLevel(CalculateWindowZLevel(parent, aChromeMask)); } return rv; } +/* + * This class provides a stub implementation of nsIWebBrowserChrome2, as needed + * by nsAppShellService::CreateWindowlessBrowser + */ +class WebBrowserChrome2Stub : public nsIWebBrowserChrome2, + public nsIInterfaceRequestor { +public: + virtual ~WebBrowserChrome2Stub() {} + NS_DECL_ISUPPORTS + NS_DECL_NSIWEBBROWSERCHROME + NS_DECL_NSIWEBBROWSERCHROME2 + NS_DECL_NSIINTERFACEREQUESTOR +}; + +NS_INTERFACE_MAP_BEGIN(WebBrowserChrome2Stub) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome) + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2) + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) +NS_INTERFACE_MAP_END + +NS_IMPL_ADDREF(WebBrowserChrome2Stub) +NS_IMPL_RELEASE(WebBrowserChrome2Stub) + +NS_IMETHODIMP +WebBrowserChrome2Stub::SetStatus(uint32_t aStatusType, const PRUnichar* aStatus) +{ + return NS_OK; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::GetWebBrowser(nsIWebBrowser** aWebBrowser) +{ + NS_NOTREACHED("WebBrowserChrome2Stub::GetWebBrowser is not supported"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::SetWebBrowser(nsIWebBrowser* aWebBrowser) +{ + NS_NOTREACHED("WebBrowserChrome2Stub::SetWebBrowser is not supported"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::GetChromeFlags(uint32_t* aChromeFlags) +{ + *aChromeFlags = 0; + return NS_OK; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::SetChromeFlags(uint32_t aChromeFlags) +{ + NS_NOTREACHED("WebBrowserChrome2Stub::SetChromeFlags is not supported"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::DestroyBrowserWindow() +{ + NS_NOTREACHED("WebBrowserChrome2Stub::DestroyBrowserWindow is not supported"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::SizeBrowserTo(int32_t aCX, int32_t aCY) +{ + NS_NOTREACHED("WebBrowserChrome2Stub::SizeBrowserTo is not supported"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::ShowAsModal() +{ + NS_NOTREACHED("WebBrowserChrome2Stub::ShowAsModal is not supported"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::IsWindowModal(bool* aResult) +{ + *aResult = false; + return NS_OK; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::ExitModalEventLoop(nsresult aStatus) +{ + NS_NOTREACHED("WebBrowserChrome2Stub::ExitModalEventLoop is not supported"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::SetStatusWithContext(uint32_t aStatusType, + const nsAString& aStatusText, + nsISupports* aStatusContext) +{ + return NS_OK; +} + +NS_IMETHODIMP +WebBrowserChrome2Stub::GetInterface(const nsIID & aIID, void **aSink) +{ + return QueryInterface(aIID, aSink); +} + +NS_IMETHODIMP +nsAppShellService::CreateWindowlessBrowser(nsIWebNavigation **aResult) +{ + /* First, we create an instance of nsWebBrowser. Instances of this class have + * an associated doc shell, which is what we're interested in. + */ + nsCOMPtr<nsIWebBrowser> browser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID); + if (!browser) { + NS_ERROR("Couldn't create instance of nsWebBrowser!"); + return NS_ERROR_FAILURE; + } + + /* Next, we set the container window for our instance of nsWebBrowser. Since + * we don't actually have a window, we instead set the container window to be + * an instance of WebBrowserChrome2Stub, which provides a stub implementation + * of nsIWebBrowserChrome2. + */ + nsRefPtr<WebBrowserChrome2Stub> stub = new WebBrowserChrome2Stub(); + if (!stub) { + NS_ERROR("Couldn't create instance of WebBrowserChrome2Stub!"); + return NS_ERROR_FAILURE; + } + browser->SetContainerWindow(stub); + + nsCOMPtr<nsIWebNavigation> navigation = do_QueryInterface(browser); + + nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(navigation); + item->SetItemType(nsIDocShellTreeItem::typeContentWrapper); + + /* A windowless web browser doesn't have an associated OS level window. To + * accomplish this, we initialize the window associated with our instance of + * nsWebBrowser with an instance of PuppetWidget, which provides a stub + * implementation of nsIWidget. + */ + nsCOMPtr<nsIWidget> widget = nsIWidget::CreatePuppetWidget(nullptr); + if (!widget) { + NS_ERROR("Couldn't create instance of PuppetWidget"); + return NS_ERROR_FAILURE; + } + widget->Create(nullptr, 0, nsIntRect(nsIntPoint(0, 0), nsIntSize(0, 0)), + nullptr, nullptr); + nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(navigation); + window->InitWindow(0, widget, 0, 0, 0, 0); + window->Create(); + + navigation.forget(aResult); + return NS_OK; +} + uint32_t nsAppShellService::CalculateWindowZLevel(nsIXULWindow *aParent, uint32_t aChromeMask) { uint32_t zLevel; zLevel = nsIXULWindow::normalZ; if (aChromeMask & nsIWebBrowserChrome::CHROME_WINDOW_RAISED)