Files
tubestation/toolkit/components/extensions/parent/ext-backgroundPage.js
2018-05-29 17:40:53 -07:00

96 lines
3.0 KiB
JavaScript

"use strict";
ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch",
"resource://gre/modules/TelemetryStopwatch.jsm");
ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm");
var {
HiddenExtensionPage,
promiseExtensionViewLoaded,
} = ExtensionParent;
XPCOMUtils.defineLazyPreferenceGetter(this, "DELAYED_STARTUP",
"extensions.webextensions.background-delayed-startup");
// Responsible for the background_page section of the manifest.
class BackgroundPage extends HiddenExtensionPage {
constructor(extension, options) {
super(extension, "background");
this.page = options.page || null;
this.isGenerated = !!options.scripts;
if (this.page) {
this.url = this.extension.baseURI.resolve(this.page);
} else if (this.isGenerated) {
this.url = this.extension.baseURI.resolve("_generated_background_page.html");
}
}
async build() {
TelemetryStopwatch.start("WEBEXT_BACKGROUND_PAGE_LOAD_MS", this);
await this.createBrowserElement();
this.extension._backgroundPageFrameLoader = this.browser.frameLoader;
extensions.emit("extension-browser-inserted", this.browser);
this.browser.loadURI(this.url, {triggeringPrincipal: this.extension.principal});
let context = await promiseExtensionViewLoaded(this.browser);
TelemetryStopwatch.finish("WEBEXT_BACKGROUND_PAGE_LOAD_MS", this);
if (context) {
// Wait until all event listeners registered by the script so far
// to be handled.
await Promise.all(context.listenerPromises);
context.listenerPromises = null;
}
this.extension.emit("startup");
}
shutdown() {
this.extension._backgroundPageFrameLoader = null;
super.shutdown();
}
}
this.backgroundPage = class extends ExtensionAPI {
onManifestEntry(entryName) {
let {extension} = this;
let {manifest} = extension;
this.bgPage = new BackgroundPage(extension, manifest.background);
if (extension.startupReason !== "APP_STARTUP" || !DELAYED_STARTUP) {
return this.bgPage.build();
}
EventManager.primeListeners(extension);
extension.once("start-background-page", async () => {
await this.bgPage.build();
EventManager.clearPrimedListeners(extension);
});
// There are two ways to start the background page:
// 1. If a primed event fires, then start the background page as
// soon as we have painted a browser window. Note that we have
// to touch browserPaintedPromise here to initialize the listener
// or else we can miss it if the event occurs after the first
// window is painted but before #2
// 2. After all windows have been restored.
extension.once("background-page-event", async () => {
await ExtensionParent.browserPaintedPromise;
extension.emit("start-background-page");
});
ExtensionParent.browserStartupPromise.then(() => {
extension.emit("start-background-page");
});
}
onShutdown() {
this.bgPage.shutdown();
}
};