forked from mirrors/gecko-dev
Bug 1479570. Get Add a getter to get a docshell from nsIWindowlessBrowser. r=kmag
Differential Revision: https://phabricator.services.mozilla.com/D2669 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
9987b543d1
commit
357b6b1348
20 changed files with 80 additions and 81 deletions
|
|
@ -48,9 +48,9 @@ function loadContentWindow(webNavigation, uri) {
|
|||
|
||||
async function takeScreenshot(fullWidth, fullHeight, contentWidth, contentHeight, path, url) {
|
||||
try {
|
||||
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
||||
var webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);
|
||||
let contentWindow = await loadContentWindow(webNavigation, url);
|
||||
var windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
||||
// nsIWindowlessBrowser inherits from nsIWebNavigation.
|
||||
let contentWindow = await loadContentWindow(windowlessBrowser, url);
|
||||
contentWindow.resizeTo(contentWidth, contentHeight);
|
||||
|
||||
let canvas = contentWindow.document.createElementNS("http://www.w3.org/1999/xhtml", "html:canvas");
|
||||
|
|
@ -82,8 +82,8 @@ async function takeScreenshot(fullWidth, fullHeight, contentWidth, contentHeight
|
|||
} catch (e) {
|
||||
dump("Failure taking screenshot: " + e + "\n");
|
||||
} finally {
|
||||
if (webNavigation) {
|
||||
webNavigation.close();
|
||||
if (windowlessBrowser) {
|
||||
windowlessBrowser.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,7 @@ function createFakeAddonWindow({addonId} = {}) {
|
|||
const principal = Services.scriptSecurityManager
|
||||
.createCodebasePrincipal(baseURI, {});
|
||||
const chromeWebNav = Services.appShell.createWindowlessBrowser(true);
|
||||
const docShell = chromeWebNav.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
const { docShell } = chromeWebNav;
|
||||
docShell.createAboutBlankContentViewer(principal);
|
||||
const addonWindow = docShell.contentViewer.DOMDocument.defaultView;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,14 +51,12 @@ function test() {
|
|||
}
|
||||
}
|
||||
|
||||
var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].
|
||||
createInstance(Ci.nsIPrincipal);
|
||||
var webNav = Cc["@mozilla.org/appshell/appShellService;1"].
|
||||
getService(Ci.nsIAppShellService).
|
||||
createWindowlessBrowser(true);
|
||||
var docShell = webNav.
|
||||
QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDocShell);
|
||||
var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"]
|
||||
.getService(Ci.nsIPrincipal);
|
||||
var webNav = Cc["@mozilla.org/appshell/appShellService;1"]
|
||||
.getService(Ci.nsIAppShellService)
|
||||
.createWindowlessBrowser(true);
|
||||
var docShell = webNav.docShell;
|
||||
docShell.createAboutBlankContentViewer(systemPrincipal);
|
||||
var win = docShell.contentViewer.DOMDocument.defaultView;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=846906
|
|||
var interfaceRequestor = windowlessBrowser.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
ok(interfaceRequestor, "Should be able to query interface requestor interface");
|
||||
|
||||
var docShell = interfaceRequestor.getInterface(Ci.nsIDocShell);
|
||||
var docShell = windowlessBrowser.docShell;
|
||||
ok(docShell, "Should be able to get doc shell interface");
|
||||
|
||||
var document = webNavigation.document;
|
||||
|
|
|
|||
|
|
@ -71,10 +71,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1342989
|
|||
|
||||
var webNav = Cc["@mozilla.org/appshell/appShellService;1"].
|
||||
getService(Ci.nsIAppShellService).createWindowlessBrowser(true);
|
||||
let docShell = webNav.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIDocShell);
|
||||
let docShell = webNav.docShell;
|
||||
docShell.createAboutBlankContentViewer(
|
||||
Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal));
|
||||
Cc["@mozilla.org/systemprincipal;1"].getService(Ci.nsIPrincipal));
|
||||
|
||||
progressListener.add(docShell, function(success) {
|
||||
webNav.close();
|
||||
|
|
|
|||
|
|
@ -6,10 +6,9 @@ ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|||
add_task(async function() {
|
||||
let webNav = Services.appShell.createWindowlessBrowser(false);
|
||||
|
||||
let loadContext = webNav.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsILoadContext);
|
||||
let docShell = webNav.docShell;
|
||||
|
||||
let docShell = webNav.getInterface(Ci.nsIDocShell);
|
||||
let loadContext = docShell.QueryInterface(Ci.nsILoadContext);
|
||||
|
||||
equal(loadContext.usePrivateBrowsing, false, "Should start out in non-private mode");
|
||||
|
||||
|
|
|
|||
|
|
@ -69,8 +69,7 @@ function test()
|
|||
.createCodebasePrincipal(baseURI, {});
|
||||
|
||||
let chromeWebNav = Services.appShell.createWindowlessBrowser(true);
|
||||
let interfaceRequestor = chromeWebNav.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let docShell = interfaceRequestor.getInterface(Ci.nsIDocShell);
|
||||
let docShell = chromeWebNav.docShell;
|
||||
docShell.createAboutBlankContentViewer(principal);
|
||||
|
||||
info("fake webextension docShell created");
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ add_task(async function test_windowlessBrowserTroubleshootCrash() {
|
|||
let webNav = Services.appShell.createWindowlessBrowser(false);
|
||||
|
||||
let onLoaded = new Promise((resolve, reject) => {
|
||||
let docShell = webNav.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
let docShell = webNav.docShell;
|
||||
let listener = {
|
||||
observe(contentWindow, topic, data) {
|
||||
let observedDocShell = contentWindow.docShell
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@ add_task(async function() {
|
|||
|
||||
let webnav = Services.appShell.createWindowlessBrowser(false);
|
||||
|
||||
let docShell = webnav.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
let docShell = webnav.docShell;
|
||||
|
||||
docShell.createAboutBlankContentViewer(principal);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ function getWindowlessBrowser(url) {
|
|||
|
||||
let webnav = Services.appShell.createWindowlessBrowser(false);
|
||||
|
||||
let docShell = webnav.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
let docShell = webnav.docShell;
|
||||
|
||||
docShell.createAboutBlankContentViewer(principal);
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,7 @@ ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|||
add_task(async function() {
|
||||
let webnav = Services.appShell.createWindowlessBrowser(false);
|
||||
|
||||
let docShell = webnav.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
let docShell = webnav.docShell;
|
||||
|
||||
docShell.createAboutBlankContentViewer(null);
|
||||
|
||||
|
|
|
|||
|
|
@ -1077,14 +1077,12 @@ class HiddenXULWindow {
|
|||
// The windowless browser is a thin wrapper around a docShell that keeps
|
||||
// its related resources alive. It implements nsIWebNavigation and
|
||||
// forwards its methods to the underlying docShell, but cannot act as a
|
||||
// docShell itself. Calling `getInterface(nsIDocShell)` gives us the
|
||||
// docShell itself. Getting .docShell gives us the
|
||||
// underlying docShell, and `QueryInterface(nsIWebNavigation)` gives us
|
||||
// access to the webNav methods that are already available on the
|
||||
// windowless browser, but contrary to appearances, they are not the same
|
||||
// object.
|
||||
this.chromeShell = this._windowlessBrowser
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
this.chromeShell = this._windowlessBrowser.docShell
|
||||
.QueryInterface(Ci.nsIWebNavigation);
|
||||
|
||||
if (PrivateBrowsingUtils.permanentPrivateBrowsing) {
|
||||
|
|
|
|||
|
|
@ -118,9 +118,8 @@ class ContentPage {
|
|||
|
||||
let system = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
|
||||
let chromeShell = this.windowlessBrowser.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.QueryInterface(Ci.nsIWebNavigation);
|
||||
let chromeShell = this.windowlessBrowser.docShell
|
||||
.QueryInterface(Ci.nsIWebNavigation);
|
||||
|
||||
chromeShell.createAboutBlankContentViewer(system);
|
||||
chromeShell.useGlobalHistory = false;
|
||||
|
|
|
|||
|
|
@ -708,9 +708,7 @@ this.downloads = class extends ExtensionAPI {
|
|||
|
||||
return new Promise((resolve, reject) => {
|
||||
let chromeWebNav = Services.appShell.createWindowlessBrowser(true);
|
||||
chromeWebNav
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
chromeWebNav.docShell
|
||||
.createAboutBlankContentViewer(Services.scriptSecurityManager.getSystemPrincipal());
|
||||
|
||||
let img = chromeWebNav.document.createElement("img");
|
||||
|
|
|
|||
|
|
@ -808,8 +808,7 @@ function loadImage(img, data) {
|
|||
|
||||
add_task(async function test_getFileIcon() {
|
||||
let webNav = Services.appShell.createWindowlessBrowser(false);
|
||||
let docShell = webNav.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
let docShell = webNav.docShell;
|
||||
|
||||
let system = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
docShell.createAboutBlankContentViewer(system);
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ HiddenFrame.prototype = {
|
|||
}
|
||||
};
|
||||
this._webProgress.addProgressListener(this._listener, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
|
||||
let docShell = this._browser.getInterface(Ci.nsIDocShell);
|
||||
let docShell = this._browser.docShell;
|
||||
docShell.createAboutBlankContentViewer(Services.scriptSecurityManager.getSystemPrincipal());
|
||||
docShell.useGlobalHistory = false;
|
||||
this._browser.loadURI(XUL_PAGE, 0, null, null, null);
|
||||
|
|
|
|||
|
|
@ -18,11 +18,10 @@ registerCleanupFunction(() => { server.stop(() => {})});
|
|||
// before they are called.
|
||||
const progressListeners = new Map();
|
||||
|
||||
function loadContentWindow(webNavigation, uri) {
|
||||
function loadContentWindow(windowlessBrowser, uri) {
|
||||
return new Promise((resolve, reject) => {
|
||||
webNavigation.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
|
||||
let docShell = webNavigation.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
windowlessBrowser.loadURI(uri, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
|
||||
let docShell = windowlessBrowser.docShell;
|
||||
let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
let progressListener = {
|
||||
|
|
@ -35,8 +34,6 @@ function loadContentWindow(webNavigation, uri) {
|
|||
if (flags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
|
||||
return;
|
||||
}
|
||||
let docShell = webNavigation.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDocShell);
|
||||
let contentWindow = docShell.domWindow;
|
||||
webProgress.removeProgressListener(progressListener);
|
||||
progressListeners.delete(progressListener);
|
||||
|
|
@ -55,8 +52,7 @@ function loadContentWindow(webNavigation, uri) {
|
|||
|
||||
add_task(async function test_snapshot() {
|
||||
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
||||
let webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);
|
||||
let contentWindow = await loadContentWindow(webNavigation, HEADLESS_URL);
|
||||
let contentWindow = await loadContentWindow(windowlessBrowser, HEADLESS_URL);
|
||||
const contentWidth = 400;
|
||||
const contentHeight = 300;
|
||||
// Verify dimensions.
|
||||
|
|
@ -93,13 +89,13 @@ add_task(async function test_snapshot() {
|
|||
}
|
||||
ok(found, "Found blue text on page.");
|
||||
|
||||
webNavigation.close();
|
||||
windowlessBrowser.close();
|
||||
});
|
||||
|
||||
add_task(async function test_snapshot_widget_layers() {
|
||||
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
||||
let webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);
|
||||
let contentWindow = await loadContentWindow(webNavigation, HEADLESS_URL);
|
||||
// nsIWindowlessBrowser inherits from nsIWebNavigation.
|
||||
let contentWindow = await loadContentWindow(windowlessBrowser, HEADLESS_URL);
|
||||
const contentWidth = 1;
|
||||
const contentHeight = 2;
|
||||
// Verify dimensions.
|
||||
|
|
@ -125,14 +121,14 @@ add_task(async function test_snapshot_widget_layers() {
|
|||
);
|
||||
ok(true, "Snapshot with widget layers didn't crash.");
|
||||
|
||||
webNavigation.close();
|
||||
windowlessBrowser.close();
|
||||
});
|
||||
|
||||
// Ensure keydown events are triggered on the windowless browser.
|
||||
add_task(async function test_keydown() {
|
||||
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
||||
let webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);
|
||||
let contentWindow = await loadContentWindow(webNavigation, HEADLESS_URL);
|
||||
// nsIWindowlessBrowser inherits from nsIWebNavigation.
|
||||
let contentWindow = await loadContentWindow(windowlessBrowser, HEADLESS_URL);
|
||||
|
||||
let keydown = new Promise((resolve) => {
|
||||
contentWindow.addEventListener("keydown", () => {
|
||||
|
|
@ -149,15 +145,15 @@ add_task(async function test_keydown() {
|
|||
await keydown;
|
||||
ok(true, "Send keydown didn't crash");
|
||||
|
||||
webNavigation.close();
|
||||
windowlessBrowser.close();
|
||||
});
|
||||
|
||||
// Test dragging the mouse on a button to ensure the creation of the drag
|
||||
// service doesn't crash in headless.
|
||||
add_task(async function test_mouse_drag() {
|
||||
let windowlessBrowser = Services.appShell.createWindowlessBrowser(false);
|
||||
let webNavigation = windowlessBrowser.QueryInterface(Ci.nsIWebNavigation);
|
||||
let contentWindow = await loadContentWindow(webNavigation, HEADLESS_BUTTON_URL);
|
||||
// nsIWindowlessBrowser inherits from nsIWebNavigation.
|
||||
let contentWindow = await loadContentWindow(windowlessBrowser, HEADLESS_BUTTON_URL);
|
||||
contentWindow.resizeTo(400, 400);
|
||||
|
||||
let target = contentWindow.document.getElementById('btn');
|
||||
|
|
@ -175,5 +171,5 @@ add_task(async function test_mouse_drag() {
|
|||
|
||||
ok(true, "Send mouse event didn't crash");
|
||||
|
||||
webNavigation.close();
|
||||
windowlessBrowser.close();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -452,25 +452,10 @@ public:
|
|||
mInterfaceRequestor = do_QueryInterface(aBrowser);
|
||||
}
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWINDOWLESSBROWSER
|
||||
NS_FORWARD_SAFE_NSIWEBNAVIGATION(mWebNavigation)
|
||||
NS_FORWARD_SAFE_NSIINTERFACEREQUESTOR(mInterfaceRequestor)
|
||||
|
||||
NS_IMETHOD
|
||||
Close() override
|
||||
{
|
||||
NS_ENSURE_TRUE(!mClosed, NS_ERROR_UNEXPECTED);
|
||||
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
|
||||
"WindowlessBrowser::Close called when not safe to run scripts");
|
||||
|
||||
mClosed = true;
|
||||
|
||||
mWebNavigation = nullptr;
|
||||
mInterfaceRequestor = nullptr;
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(mBrowser);
|
||||
return window->Destroy();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~WindowlessBrowser()
|
||||
{
|
||||
|
|
@ -500,6 +485,33 @@ private:
|
|||
|
||||
NS_IMPL_ISUPPORTS(WindowlessBrowser, nsIWindowlessBrowser, nsIWebNavigation, nsIInterfaceRequestor)
|
||||
|
||||
NS_IMETHODIMP
|
||||
WindowlessBrowser::Close()
|
||||
{
|
||||
NS_ENSURE_TRUE(!mClosed, NS_ERROR_UNEXPECTED);
|
||||
NS_ASSERTION(nsContentUtils::IsSafeToRunScript(),
|
||||
"WindowlessBrowser::Close called when not safe to run scripts");
|
||||
|
||||
mClosed = true;
|
||||
|
||||
mWebNavigation = nullptr;
|
||||
mInterfaceRequestor = nullptr;
|
||||
|
||||
nsCOMPtr<nsIBaseWindow> window = do_QueryInterface(mBrowser);
|
||||
return window->Destroy();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WindowlessBrowser::GetDocShell(nsIDocShell** aDocShell)
|
||||
{
|
||||
nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mInterfaceRequestor);
|
||||
if (!docShell) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
docShell.forget(aDocShell);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAppShellService::CreateWindowlessBrowser(bool aIsChrome, nsIWindowlessBrowser **aResult)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "nsIWebNavigation.idl"
|
||||
|
||||
interface nsIDocShell;
|
||||
|
||||
/**
|
||||
* This interface represents a nsIWebBrowser instance with no associated OS
|
||||
* window. Its main function is to manage the lifetimes of those windows.
|
||||
|
|
@ -23,5 +25,11 @@ interface nsIWindowlessBrowser : nsIWebNavigation
|
|||
* reference is released.
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Get the docshell for this browser. This is the docshell that gets
|
||||
* navigated when the browser's nsIWebNavigation interface is used.
|
||||
*/
|
||||
readonly attribute nsIDocShell docShell;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,7 @@ function testWindowlessBrowser(chromePrivileged) {
|
|||
|
||||
ok(webNav, "createWindowlessBrowser should return a wevNav");
|
||||
|
||||
let interfaceRequestor = webNav.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let docShell = interfaceRequestor.getInterface(Ci.nsIDocShell);
|
||||
let docShell = webNav.docShell;
|
||||
|
||||
ok(docShell, "docShell should be defined");
|
||||
ok(docShell.contentViewer.DOMDocument.defaultView, "docShell defaultView should be defined");
|
||||
|
|
|
|||
Loading…
Reference in a new issue