mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 09:18:42 +09:00
Rename Toolkit's webextensions component directory to better reflect what it is.
This commit is contained in:
parent
6955450f7a
commit
d7d16e7fbb
242 changed files with 4 additions and 2 deletions
|
|
@ -1,250 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["LegacyExtensionsUtils"];
|
||||
|
||||
/* exported LegacyExtensionsUtils, LegacyExtensionContext */
|
||||
|
||||
/**
|
||||
* This file exports helpers for Legacy Extensions that want to embed a webextensions
|
||||
* and exchange messages with the embedded WebExtension.
|
||||
*/
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Extension",
|
||||
"resource://gre/modules/Extension.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
Cu.import("resource://gre/modules/ExtensionChild.jsm");
|
||||
Cu.import("resource://gre/modules/ExtensionCommon.jsm");
|
||||
|
||||
var {
|
||||
BaseContext,
|
||||
} = ExtensionCommon;
|
||||
|
||||
var {
|
||||
Messenger,
|
||||
} = ExtensionChild;
|
||||
|
||||
/**
|
||||
* Instances created from this class provide to a legacy extension
|
||||
* a simple API to exchange messages with a webextension.
|
||||
*/
|
||||
var LegacyExtensionContext = class extends BaseContext {
|
||||
/**
|
||||
* Create a new LegacyExtensionContext given a target Extension instance.
|
||||
*
|
||||
* @param {Extension} targetExtension
|
||||
* The webextension instance associated with this context. This will be the
|
||||
* instance of the newly created embedded webextension when this class is
|
||||
* used through the EmbeddedWebExtensionsUtils.
|
||||
*/
|
||||
constructor(targetExtension) {
|
||||
super("legacy_extension", targetExtension);
|
||||
|
||||
// Legacy Extensions (xul overlays, bootstrap restartless and Addon SDK)
|
||||
// runs with a systemPrincipal.
|
||||
let addonPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
|
||||
Object.defineProperty(
|
||||
this, "principal",
|
||||
{value: addonPrincipal, enumerable: true, configurable: true}
|
||||
);
|
||||
|
||||
let cloneScope = Cu.Sandbox(this.principal, {});
|
||||
Cu.setSandboxMetadata(cloneScope, {addonId: targetExtension.id});
|
||||
Object.defineProperty(
|
||||
this, "cloneScope",
|
||||
{value: cloneScope, enumerable: true, configurable: true, writable: true}
|
||||
);
|
||||
|
||||
let sender = {id: targetExtension.uuid};
|
||||
let filter = {extensionId: targetExtension.id};
|
||||
// Legacy addons live in the main process. Messages from other addons are
|
||||
// Messages from WebExtensions are sent to the main process and forwarded via
|
||||
// the parent process manager to the legacy extension.
|
||||
this.messenger = new Messenger(this, [Services.cpmm], sender, filter);
|
||||
|
||||
this.api = {
|
||||
browser: {
|
||||
runtime: {
|
||||
onConnect: this.messenger.onConnect("runtime.onConnect"),
|
||||
onMessage: this.messenger.onMessage("runtime.onMessage"),
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when the extension shuts down or is unloaded,
|
||||
* and it nukes the cloneScope sandbox, if any.
|
||||
*/
|
||||
unload() {
|
||||
if (this.unloaded) {
|
||||
throw new Error("Error trying to unload LegacyExtensionContext twice.");
|
||||
}
|
||||
super.unload();
|
||||
Cu.nukeSandbox(this.cloneScope);
|
||||
this.cloneScope = null;
|
||||
}
|
||||
};
|
||||
|
||||
var EmbeddedExtensionManager;
|
||||
|
||||
/**
|
||||
* Instances of this class are used internally by the exported EmbeddedWebExtensionsUtils
|
||||
* to manage the embedded webextension instance and the related LegacyExtensionContext
|
||||
* instance used to exchange messages with it.
|
||||
*/
|
||||
class EmbeddedExtension {
|
||||
/**
|
||||
* Create a new EmbeddedExtension given the add-on id and the base resource URI of the
|
||||
* container add-on (the webextension resources will be loaded from the "webextension/"
|
||||
* subdir of the base resource URI for the legacy extension add-on).
|
||||
*
|
||||
* @param {Object} containerAddonParams
|
||||
* An object with the following properties:
|
||||
* @param {string} containerAddonParams.id
|
||||
* The Add-on id of the Legacy Extension which will contain the embedded webextension.
|
||||
* @param {nsIURI} containerAddonParams.resourceURI
|
||||
* The nsIURI of the Legacy Extension container add-on.
|
||||
*/
|
||||
constructor({id, resourceURI}) {
|
||||
this.addonId = id;
|
||||
this.resourceURI = resourceURI;
|
||||
|
||||
// Setup status flag.
|
||||
this.started = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the embedded webextension.
|
||||
*
|
||||
* @returns {Promise<LegacyContextAPI>} A promise which resolve to the API exposed to the
|
||||
* legacy context.
|
||||
*/
|
||||
startup() {
|
||||
if (this.started) {
|
||||
return Promise.reject(new Error("This embedded extension has already been started"));
|
||||
}
|
||||
|
||||
// Setup the startup promise.
|
||||
this.startupPromise = new Promise((resolve, reject) => {
|
||||
let embeddedExtensionURI = Services.io.newURI("webextension/", null, this.resourceURI);
|
||||
|
||||
// This is the instance of the WebExtension embedded in the hybrid add-on.
|
||||
this.extension = new Extension({
|
||||
id: this.addonId,
|
||||
resourceURI: embeddedExtensionURI,
|
||||
});
|
||||
|
||||
// This callback is register to the "startup" event, emitted by the Extension instance
|
||||
// after the extension manifest.json has been loaded without any errors, but before
|
||||
// starting any of the defined contexts (which give the legacy part a chance to subscribe
|
||||
// runtime.onMessage/onConnect listener before the background page has been loaded).
|
||||
const onBeforeStarted = () => {
|
||||
this.extension.off("startup", onBeforeStarted);
|
||||
|
||||
// Resolve the startup promise and reset the startupError.
|
||||
this.started = true;
|
||||
this.startupPromise = null;
|
||||
|
||||
// Create the legacy extension context, the legacy container addon
|
||||
// needs to use it before the embedded webextension startup,
|
||||
// because it is supposed to be used during the legacy container startup
|
||||
// to subscribe its message listeners (which are supposed to be able to
|
||||
// receive any message that the embedded part can try to send to it
|
||||
// during its startup).
|
||||
this.context = new LegacyExtensionContext(this.extension);
|
||||
|
||||
// Destroy the LegacyExtensionContext cloneScope when
|
||||
// the embedded webextensions is unloaded.
|
||||
this.extension.callOnClose({
|
||||
close: () => {
|
||||
this.context.unload();
|
||||
},
|
||||
});
|
||||
|
||||
// resolve startupPromise to execute any pending shutdown that has been
|
||||
// chained to it.
|
||||
resolve(this.context.api);
|
||||
};
|
||||
|
||||
this.extension.on("startup", onBeforeStarted);
|
||||
|
||||
// Run ambedded extension startup and catch any error during embedded extension
|
||||
// startup.
|
||||
this.extension.startup().catch((err) => {
|
||||
this.started = false;
|
||||
this.startupPromise = null;
|
||||
this.extension.off("startup", onBeforeStarted);
|
||||
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
|
||||
return this.startupPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the embedded webextension.
|
||||
*
|
||||
* @returns {Promise<void>} a promise that is resolved when the shutdown has been done
|
||||
*/
|
||||
shutdown() {
|
||||
EmbeddedExtensionManager.untrackEmbeddedExtension(this);
|
||||
|
||||
// If there is a pending startup, wait to be completed and then shutdown.
|
||||
if (this.startupPromise) {
|
||||
return this.startupPromise.then(() => {
|
||||
this.extension.shutdown();
|
||||
});
|
||||
}
|
||||
|
||||
// Run shutdown now if the embedded webextension has been correctly started
|
||||
if (this.extension && this.started && !this.extension.hasShutdown) {
|
||||
this.extension.shutdown();
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
// Keep track on the created EmbeddedExtension instances and destroy
|
||||
// them when their container addon is going to be disabled or uninstalled.
|
||||
EmbeddedExtensionManager = {
|
||||
// Map of the existent EmbeddedExtensions instances by addon id.
|
||||
embeddedExtensionsByAddonId: new Map(),
|
||||
|
||||
untrackEmbeddedExtension(embeddedExtensionInstance) {
|
||||
// Remove this instance from the tracked embedded extensions
|
||||
let id = embeddedExtensionInstance.addonId;
|
||||
if (this.embeddedExtensionsByAddonId.get(id) == embeddedExtensionInstance) {
|
||||
this.embeddedExtensionsByAddonId.delete(id);
|
||||
}
|
||||
},
|
||||
|
||||
getEmbeddedExtensionFor({id, resourceURI}) {
|
||||
let embeddedExtension = this.embeddedExtensionsByAddonId.get(id);
|
||||
|
||||
if (!embeddedExtension) {
|
||||
embeddedExtension = new EmbeddedExtension({id, resourceURI});
|
||||
// Keep track of the embedded extension instance.
|
||||
this.embeddedExtensionsByAddonId.set(id, embeddedExtension);
|
||||
}
|
||||
|
||||
return embeddedExtension;
|
||||
},
|
||||
};
|
||||
|
||||
this.LegacyExtensionsUtils = {
|
||||
getEmbeddedExtensionFor: (addon) => {
|
||||
return EmbeddedExtensionManager.getEmbeddedExtensionFor(addon);
|
||||
},
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue