diff --git a/docshell/test/chrome/Makefile.in b/docshell/test/chrome/Makefile.in index 56af5314ea7c..d6d7ea57f872 100644 --- a/docshell/test/chrome/Makefile.in +++ b/docshell/test/chrome/Makefile.in @@ -97,6 +97,7 @@ MOCHITEST_CHROME_FILES = \ test_private_hidden_window.html \ docshell_helpers.js \ generic.html \ + test_bug846906.xul \ $(NULL) ifneq ($(MOZ_WIDGET_TOOLKIT),gtk2) diff --git a/docshell/test/chrome/test_bug846906.xul b/docshell/test/chrome/test_bug846906.xul new file mode 100644 index 000000000000..1129d225115a --- /dev/null +++ b/docshell/test/chrome/test_bug846906.xul @@ -0,0 +1,78 @@ + + + + + + + Test for Bug 846906 + + + + + + + + Mozilla Bug 846906 + + diff --git a/mach b/mach deleted file mode 100755 index 9aba2825387e..000000000000 --- a/mach +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python -# 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/. - -from __future__ import print_function, unicode_literals - -import os -import sys - -def ancestors(path): - while path: - yield path - (path, child) = os.path.split(path) - if child == "": - break - -def load_mach(topsrcdir): - sys.path[0:0] = [os.path.join(topsrcdir, "build")] - import mach_bootstrap - return mach_bootstrap.bootstrap(topsrcdir) - -# Check whether the current directory is within a mach src or obj dir. -for dir_path in ancestors(os.getcwd()): - # If we find a "mozinfo.json" file, we are in the objdir. - mozinfo_path = os.path.join(dir_path, "mozinfo.json") - if os.path.isfile(mozinfo_path): - import json - info = json.load(open(mozinfo_path)) - if "mozconfig" in info and "MOZCONFIG" not in os.environ: - # If the MOZCONFIG environment variable is not already set, set it - # to the value from mozinfo.json. This will tell the build system - # to look for a config file at the path in $MOZCONFIG rather than - # its default locations. - # - # Note: subprocess requires native strings in os.environ Python - # 2.7.2 and earlier on Windows. - os.environ[b"MOZCONFIG"] = str(info["mozconfig"]) - - if "topsrcdir" in info: - # Continue searching for mach_bootstrap in the source directory. - dir_path = info["topsrcdir"] - - # If we find the mach bootstrap module, we are in the srcdir. - mach_path = os.path.join(dir_path, "build/mach_bootstrap.py") - if os.path.isfile(mach_path): - mach = load_mach(dir_path) - sys.exit(mach.run(sys.argv[1:])) - -print("Could not run mach: No mach source directory found") -sys.exit(1) diff --git a/widget/xpwidgets/PuppetWidget.cpp b/widget/xpwidgets/PuppetWidget.cpp index ddd6ae6cb767..dffa04b07c66 100644 --- a/widget/xpwidgets/PuppetWidget.cpp +++ b/widget/xpwidgets/PuppetWidget.cpp @@ -36,7 +36,7 @@ InvalidateRegion(nsIWidget* aWidget, const nsIntRegion& aRegion) /*static*/ already_AddRefed nsIWidget::CreatePuppetWidget(TabChild* aTabChild) { - NS_ABORT_IF_FALSE(nsIWidget::UsePuppetWidgets(), + NS_ABORT_IF_FALSE(!aTabChild || nsIWidget::UsePuppetWidgets(), "PuppetWidgets not allowed in this configuration"); nsCOMPtr widget = new PuppetWidget(aTabChild); diff --git a/xpfe/appshell/public/nsIAppShellService.idl b/xpfe/appshell/public/nsIAppShellService.idl index f73bfd42b158..c29483c2cc2a 100644 --- a/xpfe/appshell/public/nsIAppShellService.idl +++ b/xpfe/appshell/public/nsIAppShellService.idl @@ -6,6 +6,7 @@ #include "nsISupports.idl" interface nsIXULWindow; +interface nsIWebNavigation; interface nsIURI; interface nsIDOMWindow; interface nsIAppShell; @@ -43,6 +44,8 @@ interface nsIAppShellService : nsISupports in long aInitialWidth, in long aInitialHeight); + nsIWebNavigation createWindowlessBrowser(); + [noscript] void createHiddenWindow(); diff --git a/xpfe/appshell/src/nsAppShellService.cpp b/xpfe/appshell/src/nsAppShellService.cpp index 4511534ee038..7aebfcdb0bf5 100644 --- a/xpfe/appshell/src/nsAppShellService.cpp +++ b/xpfe/appshell/src/nsAppShellService.cpp @@ -46,6 +46,10 @@ #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 @@ -203,6 +207,162 @@ nsAppShellService::CreateTopLevelWindow(nsIXULWindow *aParent, 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 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 stub = new WebBrowserChrome2Stub(); + if (!stub) { + NS_ERROR("Couldn't create instance of WebBrowserChrome2Stub!"); + return NS_ERROR_FAILURE; + } + browser->SetContainerWindow(stub); + + nsCOMPtr navigation = do_QueryInterface(browser); + + nsCOMPtr 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 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 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)