зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1916766 - Centralise HiddenBrowserManager into HiddenFrame.sys.mjs and make it a singleton. r=mossop
Differential Revision: https://phabricator.services.mozilla.com/D221061
This commit is contained in:
Родитель
1a7df855ed
Коммит
72981bee50
|
@ -10,7 +10,7 @@ const lazy = {};
|
|||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.sys.mjs",
|
||||
HiddenFrame: "resource://gre/modules/HiddenFrame.sys.mjs",
|
||||
HiddenBrowserManager: "resource://gre/modules/HiddenFrame.sys.mjs",
|
||||
});
|
||||
|
||||
ChromeUtils.defineLazyGetter(lazy, "logConsole", function () {
|
||||
|
@ -35,9 +35,6 @@ XPCOMUtils.defineLazyPreferenceGetter(
|
|||
|
||||
const ALLOWED_SCHEMES = ["http", "https", "data", "blob"];
|
||||
|
||||
const BACKGROUND_WIDTH = 1024;
|
||||
const BACKGROUND_HEIGHT = 768;
|
||||
|
||||
/**
|
||||
* Shifts the first element out of the set.
|
||||
*
|
||||
|
@ -58,90 +55,6 @@ function shift(set) {
|
|||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* A manager for hidden browsers. Responsible for creating and destroying a
|
||||
* hidden frame to hold them.
|
||||
*/
|
||||
class HiddenBrowserManager {
|
||||
/**
|
||||
* The hidden frame if one has been created.
|
||||
*
|
||||
* @type {HiddenFrame | null}
|
||||
*/
|
||||
#frame = null;
|
||||
/**
|
||||
* The number of hidden browser elements currently in use.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
#browsers = 0;
|
||||
|
||||
/**
|
||||
* Creates and returns a new hidden browser.
|
||||
*
|
||||
* @returns {Browser}
|
||||
*/
|
||||
async #acquireBrowser() {
|
||||
this.#browsers++;
|
||||
if (!this.#frame) {
|
||||
this.#frame = new lazy.HiddenFrame();
|
||||
}
|
||||
|
||||
let frame = await this.#frame.get();
|
||||
let doc = frame.document;
|
||||
let browser = doc.createXULElement("browser");
|
||||
browser.setAttribute("remote", "true");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute(
|
||||
"style",
|
||||
`
|
||||
width: ${BACKGROUND_WIDTH}px;
|
||||
min-width: ${BACKGROUND_WIDTH}px;
|
||||
height: ${BACKGROUND_HEIGHT}px;
|
||||
min-height: ${BACKGROUND_HEIGHT}px;
|
||||
`
|
||||
);
|
||||
browser.setAttribute("maychangeremoteness", "true");
|
||||
doc.documentElement.appendChild(browser);
|
||||
|
||||
return browser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the given hidden browser.
|
||||
*
|
||||
* @param {Browser} browser
|
||||
* The hidden browser element.
|
||||
*/
|
||||
#releaseBrowser(browser) {
|
||||
browser.remove();
|
||||
|
||||
this.#browsers--;
|
||||
if (this.#browsers == 0) {
|
||||
this.#frame.destroy();
|
||||
this.#frame = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a callback function with a new hidden browser.
|
||||
* This function will return whatever the callback function returns.
|
||||
*
|
||||
* @param {Callback} callback
|
||||
* The callback function will be called with the browser element and may
|
||||
* be asynchronous.
|
||||
* @returns {T}
|
||||
*/
|
||||
async withHiddenBrowser(callback) {
|
||||
let browser = await this.#acquireBrowser();
|
||||
try {
|
||||
return await callback(browser);
|
||||
} finally {
|
||||
this.#releaseBrowser(browser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} CacheEntry
|
||||
* An entry in the page data cache.
|
||||
|
@ -293,13 +206,6 @@ export const PageDataService = new (class PageDataService extends EventEmitter {
|
|||
*/
|
||||
#userIsIdle = false;
|
||||
|
||||
/**
|
||||
* A manager for hidden browsers.
|
||||
*
|
||||
* @type {HiddenBrowserManager}
|
||||
*/
|
||||
#browserManager = new HiddenBrowserManager();
|
||||
|
||||
/**
|
||||
* A map of hidden browsers to a resolve function that should be passed the
|
||||
* actor that was created for the browser.
|
||||
|
@ -535,7 +441,7 @@ export const PageDataService = new (class PageDataService extends EventEmitter {
|
|||
* Resolves to the found pagedata or null in case of error.
|
||||
*/
|
||||
async fetchPageData(url) {
|
||||
return this.#browserManager.withHiddenBrowser(async browser => {
|
||||
return lazy.HiddenBrowserManager.withHiddenBrowser(async browser => {
|
||||
try {
|
||||
let { promise, resolve } = Promise.withResolvers();
|
||||
this.#backgroundBrowsers.set(browser, resolve);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
const lazy = {};
|
||||
|
||||
ChromeUtils.defineESModuleGetters(lazy, {
|
||||
HiddenFrame: "resource://gre/modules/HiddenFrame.sys.mjs",
|
||||
HiddenBrowserManager: "resource://gre/modules/HiddenFrame.sys.mjs",
|
||||
Preferences: "resource://gre/modules/Preferences.sys.mjs",
|
||||
setTimeout: "resource://gre/modules/Timer.sys.mjs",
|
||||
clearTimeout: "resource://gre/modules/Timer.sys.mjs",
|
||||
|
@ -27,94 +27,6 @@ ChromeUtils.defineLazyGetter(lazy, "contentPrefs", () => {
|
|||
);
|
||||
});
|
||||
|
||||
const BACKGROUND_WIDTH = 1024;
|
||||
const BACKGROUND_HEIGHT = 768;
|
||||
|
||||
/**
|
||||
* A manager for hidden browsers. Responsible for creating and destroying a
|
||||
* hidden frame to hold them.
|
||||
* All of this is copied from PageDataService.sys.mjs
|
||||
*/
|
||||
class HiddenBrowserManager {
|
||||
/**
|
||||
* The hidden frame if one has been created.
|
||||
*
|
||||
* @type {HiddenFrame | null}
|
||||
*/
|
||||
#frame = null;
|
||||
/**
|
||||
* The number of hidden browser elements currently in use.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
#browsers = 0;
|
||||
|
||||
/**
|
||||
* Creates and returns a new hidden browser.
|
||||
*
|
||||
* @returns {Browser}
|
||||
*/
|
||||
async #acquireBrowser() {
|
||||
this.#browsers++;
|
||||
if (!this.#frame) {
|
||||
this.#frame = new lazy.HiddenFrame();
|
||||
}
|
||||
|
||||
let frame = await this.#frame.get();
|
||||
let doc = frame.document;
|
||||
let browser = doc.createXULElement("browser");
|
||||
browser.setAttribute("remote", "true");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute(
|
||||
"style",
|
||||
`
|
||||
width: ${BACKGROUND_WIDTH}px;
|
||||
min-width: ${BACKGROUND_WIDTH}px;
|
||||
height: ${BACKGROUND_HEIGHT}px;
|
||||
min-height: ${BACKGROUND_HEIGHT}px;
|
||||
`
|
||||
);
|
||||
browser.setAttribute("maychangeremoteness", "true");
|
||||
doc.documentElement.appendChild(browser);
|
||||
|
||||
return browser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the given hidden browser.
|
||||
*
|
||||
* @param {Browser} browser
|
||||
* The hidden browser element.
|
||||
*/
|
||||
#releaseBrowser(browser) {
|
||||
browser.remove();
|
||||
|
||||
this.#browsers--;
|
||||
if (this.#browsers == 0) {
|
||||
this.#frame.destroy();
|
||||
this.#frame = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a callback function with a new hidden browser.
|
||||
* This function will return whatever the callback function returns.
|
||||
*
|
||||
* @param {Callback} callback
|
||||
* The callback function will be called with the browser element and may
|
||||
* be asynchronous.
|
||||
* @returns {T}
|
||||
*/
|
||||
async withHiddenBrowser(callback) {
|
||||
let browser = await this.#acquireBrowser();
|
||||
try {
|
||||
return await callback(browser);
|
||||
} finally {
|
||||
this.#releaseBrowser(browser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class UserCharacteristicsPageService {
|
||||
classId = Components.ID("{ce3e9659-e311-49fb-b18b-7f27c6659b23}");
|
||||
QueryInterface = ChromeUtils.generateQI([
|
||||
|
@ -124,13 +36,6 @@ export class UserCharacteristicsPageService {
|
|||
_initialized = false;
|
||||
_isParentProcess = false;
|
||||
|
||||
/**
|
||||
* A manager for hidden browsers.
|
||||
*
|
||||
* @type {HiddenBrowserManager}
|
||||
*/
|
||||
_browserManager = new HiddenBrowserManager();
|
||||
|
||||
/**
|
||||
* A map of hidden browsers to a resolve function that should be passed the
|
||||
* actor that was created for the browser.
|
||||
|
@ -178,7 +83,7 @@ export class UserCharacteristicsPageService {
|
|||
remoteTypes: ["privilegedabout"],
|
||||
});
|
||||
|
||||
return this._browserManager.withHiddenBrowser(async browser => {
|
||||
return lazy.HiddenBrowserManager.withHiddenBrowser(async browser => {
|
||||
lazy.console.debug(`In withHiddenBrowser`);
|
||||
try {
|
||||
let { promise, resolve } = Promise.withResolvers();
|
||||
|
|
|
@ -2,10 +2,21 @@
|
|||
* 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/. */
|
||||
|
||||
/**
|
||||
* This module contains `HiddenFrame`, a class which creates a windowless browser,
|
||||
* and `HiddenBrowserManager` which is a singleton that can be used to manage
|
||||
* creating and using multiple hidden frames.
|
||||
*/
|
||||
|
||||
const XUL_PAGE = Services.io.newURI("chrome://global/content/win.xhtml");
|
||||
|
||||
const gAllHiddenFrames = new Set();
|
||||
|
||||
// The screen sizes to use for the background browser created by
|
||||
// `HiddenBrowserManager`.
|
||||
const BACKGROUND_WIDTH = 1024;
|
||||
const BACKGROUND_HEIGHT = 768;
|
||||
|
||||
let cleanupRegistered = false;
|
||||
function ensureCleanupRegistered() {
|
||||
if (!cleanupRegistered) {
|
||||
|
@ -121,3 +132,87 @@ export class HiddenFrame {
|
|||
this.#browser.loadURI(XUL_PAGE, loadURIOptions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A manager for hidden browsers. Responsible for creating and destroying a
|
||||
* hidden frame to hold them.
|
||||
*/
|
||||
export const HiddenBrowserManager = new (class HiddenBrowserManager {
|
||||
/**
|
||||
* The hidden frame if one has been created.
|
||||
*
|
||||
* @type {HiddenFrame | null}
|
||||
*/
|
||||
#frame = null;
|
||||
/**
|
||||
* The number of hidden browser elements currently in use.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
#browsers = 0;
|
||||
|
||||
/**
|
||||
* Creates and returns a new hidden browser.
|
||||
*
|
||||
* @returns {Browser}
|
||||
*/
|
||||
async #acquireBrowser() {
|
||||
this.#browsers++;
|
||||
if (!this.#frame) {
|
||||
this.#frame = new HiddenFrame();
|
||||
}
|
||||
|
||||
let frame = await this.#frame.get();
|
||||
let doc = frame.document;
|
||||
let browser = doc.createXULElement("browser");
|
||||
browser.setAttribute("remote", "true");
|
||||
browser.setAttribute("type", "content");
|
||||
browser.setAttribute(
|
||||
"style",
|
||||
`
|
||||
width: ${BACKGROUND_WIDTH}px;
|
||||
min-width: ${BACKGROUND_WIDTH}px;
|
||||
height: ${BACKGROUND_HEIGHT}px;
|
||||
min-height: ${BACKGROUND_HEIGHT}px;
|
||||
`
|
||||
);
|
||||
browser.setAttribute("maychangeremoteness", "true");
|
||||
doc.documentElement.appendChild(browser);
|
||||
|
||||
return browser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the given hidden browser.
|
||||
*
|
||||
* @param {Browser} browser
|
||||
* The hidden browser element.
|
||||
*/
|
||||
#releaseBrowser(browser) {
|
||||
browser.remove();
|
||||
|
||||
this.#browsers--;
|
||||
if (this.#browsers == 0) {
|
||||
this.#frame.destroy();
|
||||
this.#frame = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a callback function with a new hidden browser.
|
||||
* This function will return whatever the callback function returns.
|
||||
*
|
||||
* @param {Callback} callback
|
||||
* The callback function will be called with the browser element and may
|
||||
* be asynchronous.
|
||||
* @returns {T}
|
||||
*/
|
||||
async withHiddenBrowser(callback) {
|
||||
let browser = await this.#acquireBrowser();
|
||||
try {
|
||||
return await callback(browser);
|
||||
} finally {
|
||||
this.#releaseBrowser(browser);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
Загрузка…
Ссылка в новой задаче