fx-compat: HiddenBrowser: Add more options
- Make docShell properties configurable - Allow requiring a successful HTTP status code
This commit is contained in:
parent
8e6f33f045
commit
4b99b2715d
2 changed files with 60 additions and 1 deletions
|
@ -51,7 +51,12 @@ const browserFrameMap = new WeakMap();
|
||||||
**/
|
**/
|
||||||
const HiddenBrowser = {
|
const HiddenBrowser = {
|
||||||
/**
|
/**
|
||||||
* @param {String) source - HTTP URL, file: URL, or file path
|
* @param {String} source - HTTP URL, file: URL, or file path
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {Boolean} [options.allowJavaScript]
|
||||||
|
* @param {Object} [options.docShell] Fields to set on Browser.docShell
|
||||||
|
* @param {Boolean} [options.requireSuccessfulStatus]
|
||||||
|
* @param {Zotero.CookieSandbox} [options.cookieSandbox]
|
||||||
*/
|
*/
|
||||||
async create(source, options = {}) {
|
async create(source, options = {}) {
|
||||||
let url;
|
let url;
|
||||||
|
@ -69,6 +74,9 @@ const HiddenBrowser = {
|
||||||
var windowlessBrowser = await frame.get();
|
var windowlessBrowser = await frame.get();
|
||||||
windowlessBrowser.browsingContext.allowJavascript = options.allowJavaScript !== false;
|
windowlessBrowser.browsingContext.allowJavascript = options.allowJavaScript !== false;
|
||||||
windowlessBrowser.docShell.allowImages = false;
|
windowlessBrowser.docShell.allowImages = false;
|
||||||
|
if (options.docShell) {
|
||||||
|
Object.assign(windowlessBrowser.docShell, options.docShell);
|
||||||
|
}
|
||||||
var doc = windowlessBrowser.document;
|
var doc = windowlessBrowser.document;
|
||||||
var browser = doc.createXULElement("browser");
|
var browser = doc.createXULElement("browser");
|
||||||
browser.setAttribute("type", "content");
|
browser.setAttribute("type", "content");
|
||||||
|
@ -77,8 +85,23 @@ const HiddenBrowser = {
|
||||||
browser.setAttribute("disableglobalhistory", "true");
|
browser.setAttribute("disableglobalhistory", "true");
|
||||||
doc.documentElement.appendChild(browser);
|
doc.documentElement.appendChild(browser);
|
||||||
|
|
||||||
|
if (options.cookieSandbox) {
|
||||||
|
options.cookieSandbox.attachToBrowser(browser);
|
||||||
|
}
|
||||||
|
|
||||||
browserFrameMap.set(browser, frame);
|
browserFrameMap.set(browser, frame);
|
||||||
|
|
||||||
|
if (Zotero.Debug.enabled) {
|
||||||
|
let weakBrowser = new WeakRef(browser);
|
||||||
|
setTimeout(() => {
|
||||||
|
let browser = weakBrowser.deref();
|
||||||
|
if (browser && browserFrameMap.has(browser)) {
|
||||||
|
Zotero.debug('Browser object still alive after 60 seconds - memory leak?');
|
||||||
|
Zotero.debug('Viewing URI ' + browser.currentURI?.spec)
|
||||||
|
}
|
||||||
|
}, 1000 * 60);
|
||||||
|
}
|
||||||
|
|
||||||
// Next bit adapted from Mozilla's HeadlessShell.jsm
|
// Next bit adapted from Mozilla's HeadlessShell.jsm
|
||||||
const principal = Services.scriptSecurityManager.getSystemPrincipal();
|
const principal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||||
try {
|
try {
|
||||||
|
@ -139,6 +162,21 @@ const HiddenBrowser = {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.requireSuccessfulStatus) {
|
||||||
|
let { channelInfo } = await this.getPageData(browser, ['channelInfo']);
|
||||||
|
if (channelInfo && (channelInfo.responseStatus < 200 || channelInfo.responseStatus >= 400)) {
|
||||||
|
let response = `${channelInfo.responseStatus} ${channelInfo.responseStatusText}`;
|
||||||
|
Zotero.debug(`HiddenBrowser.create: ${url} failed with ${response}`, 2);
|
||||||
|
throw new Zotero.HTTP.UnexpectedStatusException(
|
||||||
|
{
|
||||||
|
status: channelInfo.responseStatus
|
||||||
|
},
|
||||||
|
url,
|
||||||
|
`Invalid response ${response} for ${url}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return browser;
|
return browser;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,27 @@ describe("HiddenBrowser", function() {
|
||||||
"chrome://zotero/content/HiddenBrowser.jsm"
|
"chrome://zotero/content/HiddenBrowser.jsm"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
describe("#create()", function () {
|
||||||
|
var httpd;
|
||||||
|
var port = 16213;
|
||||||
|
var baseURL = `http://127.0.0.1:${port}/`;
|
||||||
|
|
||||||
|
before(function () {
|
||||||
|
Cu.import("resource://zotero-unit/httpd.js");
|
||||||
|
httpd = new HttpServer();
|
||||||
|
httpd.start(port);
|
||||||
|
});
|
||||||
|
|
||||||
|
after(async function () {
|
||||||
|
await new Promise(resolve => httpd.stop(resolve));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should fail on non-2xx response with requireSuccessfulStatus", async function () {
|
||||||
|
let e = await getPromiseError(HiddenBrowser.create(baseURL + 'nonexistent', { requireSuccessfulStatus: true }));
|
||||||
|
assert.instanceOf(e, Zotero.HTTP.UnexpectedStatusException);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("#getPageData()", function () {
|
describe("#getPageData()", function () {
|
||||||
it("should handle local UTF-8 HTML file", async function () {
|
it("should handle local UTF-8 HTML file", async function () {
|
||||||
var path = OS.Path.join(getTestDataDirectory().path, 'test-hidden.html');
|
var path = OS.Path.join(getTestDataDirectory().path, 'test-hidden.html');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue