зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1575557 - rename webExtension to webExtensionDescriptor; r=ochameau
Differential Revision: https://phabricator.services.mozilla.com/D42867 --HG-- rename : devtools/server/actors/addon/webextension.js => devtools/server/actors/descriptors/webextension.js rename : devtools/shared/fronts/addon/webextension.js => devtools/shared/fronts/descriptors/webextension.js rename : devtools/shared/specs/addon/webextension.js => devtools/shared/specs/descriptors/webextension.js extra : moz-landing-system : lando
This commit is contained in:
Родитель
207370a55c
Коммит
91d20d2982
|
@ -91,13 +91,13 @@ async function _targetFromURL(client, id, type, chrome) {
|
|||
throw ex;
|
||||
}
|
||||
} else if (type === "extension") {
|
||||
const addonFront = await client.mainRoot.getAddon({ id });
|
||||
const addonDescriptor = await client.mainRoot.getAddon({ id });
|
||||
|
||||
if (!addonFront) {
|
||||
if (!addonDescriptor) {
|
||||
throw new Error(`targetFromURL, extension with id '${id}' doesn't exist`);
|
||||
}
|
||||
|
||||
front = await addonFront.connect();
|
||||
front = await addonDescriptor.getTarget();
|
||||
} else if (type === "worker") {
|
||||
front = await client.mainRoot.getWorker(id);
|
||||
|
||||
|
|
|
@ -6,5 +6,4 @@
|
|||
|
||||
DevToolsModules(
|
||||
'webextension-inspected-window.js',
|
||||
'webextension.js',
|
||||
)
|
||||
|
|
|
@ -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";
|
||||
|
||||
/*
|
||||
* Represents a WebExtension add-on in the parent process. This gives some metadata about
|
||||
* the add-on and watches for uninstall events. This uses a proxy to access the
|
||||
* WebExtension in the WebExtension process via the message manager.
|
||||
*
|
||||
* See devtools/docs/backend/actor-hierarchy.md for more details.
|
||||
*/
|
||||
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
const {
|
||||
webExtensionSpec,
|
||||
} = require("devtools/shared/specs/addon/webextension");
|
||||
const { DebuggerServer } = require("devtools/server/debugger-server");
|
||||
|
||||
loader.lazyImporter(
|
||||
this,
|
||||
"AddonManager",
|
||||
"resource://gre/modules/AddonManager.jsm"
|
||||
);
|
||||
loader.lazyImporter(
|
||||
this,
|
||||
"ExtensionParent",
|
||||
"resource://gre/modules/ExtensionParent.jsm"
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates the actor that represents the addon in the parent process, which connects
|
||||
* itself to a WebExtensionTargetActor counterpart which is created in the extension
|
||||
* process (or in the main process if the WebExtensions OOP mode is disabled).
|
||||
*
|
||||
* The WebExtensionActor subscribes itself as an AddonListener on the AddonManager
|
||||
* and forwards this events to child actor (e.g. on addon reload or when the addon is
|
||||
* uninstalled completely) and connects to the child extension process using a `browser`
|
||||
* element provided by the extension internals (it is not related to any single extension,
|
||||
* but it will be created automatically to the currently selected "WebExtensions OOP mode"
|
||||
* and it persist across the extension reloads (it is destroyed once the actor exits).
|
||||
* WebExtensionActor is a child of RootActor, it can be retrieved via
|
||||
* RootActor.listAddons request.
|
||||
*
|
||||
* @param {DebuggerServerConnection} conn
|
||||
* The connection to the client.
|
||||
* @param {AddonWrapper} addon
|
||||
* The target addon.
|
||||
*/
|
||||
const WebExtensionActor = protocol.ActorClassWithSpec(webExtensionSpec, {
|
||||
initialize(conn, addon) {
|
||||
protocol.Actor.prototype.initialize.call(this, conn);
|
||||
this.addon = addon;
|
||||
this.addonId = addon.id;
|
||||
this._childFormPromise = null;
|
||||
|
||||
// Called when the debug browser element has been destroyed
|
||||
this._extensionFrameDisconnect = this._extensionFrameDisconnect.bind(this);
|
||||
this._onChildExit = this._onChildExit.bind(this);
|
||||
AddonManager.addAddonListener(this);
|
||||
},
|
||||
|
||||
form() {
|
||||
const policy = ExtensionParent.WebExtensionPolicy.getByID(this.addonId);
|
||||
return {
|
||||
actor: this.actorID,
|
||||
debuggable: this.addon.isDebuggable,
|
||||
hidden: this.addon.hidden,
|
||||
// iconDataURL is available after calling loadIconDataURL
|
||||
iconDataURL: this._iconDataURL,
|
||||
iconURL: this.addon.iconURL,
|
||||
id: this.addonId,
|
||||
isAPIExtension: this.addon.isAPIExtension,
|
||||
isSystem: this.addon.isSystem,
|
||||
isWebExtension: this.addon.isWebExtension,
|
||||
manifestURL: policy && policy.getURL("manifest.json"),
|
||||
name: this.addon.name,
|
||||
temporarilyInstalled: this.addon.temporarilyInstalled,
|
||||
type: this.addon.type,
|
||||
url: this.addon.sourceURI ? this.addon.sourceURI.spec : undefined,
|
||||
warnings: ExtensionParent.DebugUtils.getExtensionManifestWarnings(
|
||||
this.addonId
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
connect() {
|
||||
if (this._childTargetPromise) {
|
||||
return this._childTargetPromise;
|
||||
}
|
||||
|
||||
this._childTargetPromise = (async () => {
|
||||
const form = await this._extensionFrameConnect();
|
||||
// Merge into the child actor form, some addon metadata
|
||||
// (e.g. the addon name shown in the addon debugger window title).
|
||||
return Object.assign(form, {
|
||||
iconURL: this.addon.iconURL,
|
||||
id: this.addon.id,
|
||||
// Set the isOOP attribute on the connected child actor form.
|
||||
isOOP: this.isOOP,
|
||||
name: this.addon.name,
|
||||
});
|
||||
})();
|
||||
|
||||
return this._childTargetPromise;
|
||||
},
|
||||
|
||||
async _extensionFrameConnect() {
|
||||
if (this._browser) {
|
||||
throw new Error(
|
||||
"This actor is already connected to the extension process"
|
||||
);
|
||||
}
|
||||
|
||||
this._browser = await ExtensionParent.DebugUtils.getExtensionProcessBrowser(
|
||||
this
|
||||
);
|
||||
|
||||
this._form = await DebuggerServer.connectToFrame(
|
||||
this.conn,
|
||||
this._browser,
|
||||
this._extensionFrameDisconnect,
|
||||
{ addonId: this.addonId }
|
||||
);
|
||||
|
||||
this._childActorID = this._form.actor;
|
||||
|
||||
// Exit the proxy child actor if the child actor has been destroyed.
|
||||
this._mm.addMessageListener("debug:webext_child_exit", this._onChildExit);
|
||||
|
||||
return this._form;
|
||||
},
|
||||
|
||||
/** WebExtension Actor Methods **/
|
||||
reload() {
|
||||
return this.addon.reload().then(() => {
|
||||
return {};
|
||||
});
|
||||
},
|
||||
|
||||
// This function will be called from RootActor in case that the debugger client
|
||||
// retrieves list of addons with `iconDataURL` option.
|
||||
async loadIconDataURL() {
|
||||
this._iconDataURL = await this.getIconDataURL();
|
||||
},
|
||||
|
||||
async getIconDataURL() {
|
||||
if (!this.addon.iconURL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.responseType = "blob";
|
||||
xhr.open("GET", this.addon.iconURL, true);
|
||||
|
||||
if (this.addon.iconURL.toLowerCase().endsWith(".svg")) {
|
||||
// Maybe SVG, thus force to change mime type.
|
||||
xhr.overrideMimeType("image/svg+xml");
|
||||
}
|
||||
|
||||
try {
|
||||
const blob = await new Promise((resolve, reject) => {
|
||||
xhr.onload = () => resolve(xhr.response);
|
||||
xhr.onerror = reject;
|
||||
xhr.send();
|
||||
});
|
||||
|
||||
const reader = new FileReader();
|
||||
return await new Promise((resolve, reject) => {
|
||||
reader.onloadend = () => resolve(reader.result);
|
||||
reader.onerror = reject;
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
} catch (_) {
|
||||
console.warn(`Failed to create data url from [${this.addon.iconURL}]`);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: check if we need this, as it is only used in a test
|
||||
get isOOP() {
|
||||
return this._browser ? this._browser.isRemoteBrowser : undefined;
|
||||
},
|
||||
|
||||
// Private Methods
|
||||
get _mm() {
|
||||
return (
|
||||
this._browser &&
|
||||
(this._browser.messageManager || this._browser.frameLoader.messageManager)
|
||||
);
|
||||
},
|
||||
|
||||
_extensionFrameDisconnect() {
|
||||
this._childTargetPromise = null;
|
||||
|
||||
if (this._mm) {
|
||||
this._mm.removeMessageListener(
|
||||
"debug:webext_child_exit",
|
||||
this._onChildExit
|
||||
);
|
||||
|
||||
this._mm.sendAsyncMessage("debug:webext_parent_exit", {
|
||||
actor: this._childActorID,
|
||||
});
|
||||
|
||||
ExtensionParent.DebugUtils.releaseExtensionProcessBrowser(this);
|
||||
}
|
||||
|
||||
this._browser = null;
|
||||
this._childActorID = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle the child actor exit.
|
||||
*/
|
||||
_onChildExit(msg) {
|
||||
if (msg.json.actor !== this._childActorID) {
|
||||
return;
|
||||
}
|
||||
this._extensionFrameDisconnect();
|
||||
},
|
||||
|
||||
// AddonManagerListener callbacks.
|
||||
onInstalled(addon) {
|
||||
if (addon.id != this.addonId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the AddonManager's addon object on reload/update.
|
||||
this.addon = addon;
|
||||
},
|
||||
|
||||
onUninstalled(addon) {
|
||||
if (addon != this.addon) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._extensionFrameDisconnect();
|
||||
},
|
||||
|
||||
destroy() {
|
||||
AddonManager.removeAddonListener(this);
|
||||
this._extensionFrameDisconnect();
|
||||
this.addon = null;
|
||||
protocol.Actor.prototype.destroy.call(this);
|
||||
},
|
||||
});
|
||||
|
||||
exports.WebExtensionActor = WebExtensionActor;
|
|
@ -7,5 +7,6 @@
|
|||
DevToolsModules(
|
||||
'frame.js',
|
||||
'process.js',
|
||||
'webextension.js',
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
/* 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";
|
||||
|
||||
/*
|
||||
* Represents a WebExtension add-on in the parent process. This gives some metadata about
|
||||
* the add-on and watches for uninstall events. This uses a proxy to access the
|
||||
* WebExtension in the WebExtension process via the message manager.
|
||||
*
|
||||
* See devtools/docs/backend/actor-hierarchy.md for more details.
|
||||
*/
|
||||
|
||||
const protocol = require("devtools/shared/protocol");
|
||||
const {
|
||||
webExtensionDescriptorSpec,
|
||||
} = require("devtools/shared/specs/descriptors/webextension");
|
||||
const { DebuggerServer } = require("devtools/server/debugger-server");
|
||||
|
||||
loader.lazyImporter(
|
||||
this,
|
||||
"AddonManager",
|
||||
"resource://gre/modules/AddonManager.jsm"
|
||||
);
|
||||
loader.lazyImporter(
|
||||
this,
|
||||
"ExtensionParent",
|
||||
"resource://gre/modules/ExtensionParent.jsm"
|
||||
);
|
||||
|
||||
/**
|
||||
* Creates the actor that represents the addon in the parent process, which connects
|
||||
* itself to a WebExtensionTargetActor counterpart which is created in the extension
|
||||
* process (or in the main process if the WebExtensions OOP mode is disabled).
|
||||
*
|
||||
* The WebExtensionDescriptorActor subscribes itself as an AddonListener on the AddonManager
|
||||
* and forwards this events to child actor (e.g. on addon reload or when the addon is
|
||||
* uninstalled completely) and connects to the child extension process using a `browser`
|
||||
* element provided by the extension internals (it is not related to any single extension,
|
||||
* but it will be created automatically to the currently selected "WebExtensions OOP mode"
|
||||
* and it persist across the extension reloads (it is destroyed once the actor exits).
|
||||
* WebExtensionDescriptorActor is a child of RootActor, it can be retrieved via
|
||||
* RootActor.listAddons request.
|
||||
*
|
||||
* @param {DebuggerServerConnection} conn
|
||||
* The connection to the client.
|
||||
* @param {AddonWrapper} addon
|
||||
* The target addon.
|
||||
*/
|
||||
const WebExtensionDescriptorActor = protocol.ActorClassWithSpec(
|
||||
webExtensionDescriptorSpec,
|
||||
{
|
||||
initialize(conn, addon) {
|
||||
protocol.Actor.prototype.initialize.call(this, conn);
|
||||
this.addon = addon;
|
||||
this.addonId = addon.id;
|
||||
this._childFormPromise = null;
|
||||
|
||||
// Called when the debug browser element has been destroyed
|
||||
this._extensionFrameDisconnect = this._extensionFrameDisconnect.bind(
|
||||
this
|
||||
);
|
||||
this._onChildExit = this._onChildExit.bind(this);
|
||||
AddonManager.addAddonListener(this);
|
||||
},
|
||||
|
||||
form() {
|
||||
const policy = ExtensionParent.WebExtensionPolicy.getByID(this.addonId);
|
||||
return {
|
||||
actor: this.actorID,
|
||||
debuggable: this.addon.isDebuggable,
|
||||
hidden: this.addon.hidden,
|
||||
// iconDataURL is available after calling loadIconDataURL
|
||||
iconDataURL: this._iconDataURL,
|
||||
iconURL: this.addon.iconURL,
|
||||
id: this.addonId,
|
||||
isAPIExtension: this.addon.isAPIExtension,
|
||||
isSystem: this.addon.isSystem,
|
||||
isWebExtension: this.addon.isWebExtension,
|
||||
manifestURL: policy && policy.getURL("manifest.json"),
|
||||
name: this.addon.name,
|
||||
temporarilyInstalled: this.addon.temporarilyInstalled,
|
||||
type: this.addon.type,
|
||||
url: this.addon.sourceURI ? this.addon.sourceURI.spec : undefined,
|
||||
warnings: ExtensionParent.DebugUtils.getExtensionManifestWarnings(
|
||||
this.addonId
|
||||
),
|
||||
};
|
||||
},
|
||||
|
||||
connect() {
|
||||
return this.getTarget();
|
||||
},
|
||||
|
||||
getTarget() {
|
||||
if (this._childTargetPromise) {
|
||||
return this._childTargetPromise;
|
||||
}
|
||||
|
||||
this._childTargetPromise = (async () => {
|
||||
const form = await this._extensionFrameConnect();
|
||||
// Merge into the child actor form, some addon metadata
|
||||
// (e.g. the addon name shown in the addon debugger window title).
|
||||
return Object.assign(form, {
|
||||
iconURL: this.addon.iconURL,
|
||||
id: this.addon.id,
|
||||
// Set the isOOP attribute on the connected child actor form.
|
||||
isOOP: this.isOOP,
|
||||
name: this.addon.name,
|
||||
});
|
||||
})();
|
||||
|
||||
return this._childTargetPromise;
|
||||
},
|
||||
|
||||
async _extensionFrameConnect() {
|
||||
if (this._browser) {
|
||||
throw new Error(
|
||||
"This actor is already connected to the extension process"
|
||||
);
|
||||
}
|
||||
|
||||
this._browser = await ExtensionParent.DebugUtils.getExtensionProcessBrowser(
|
||||
this
|
||||
);
|
||||
|
||||
this._form = await DebuggerServer.connectToFrame(
|
||||
this.conn,
|
||||
this._browser,
|
||||
this._extensionFrameDisconnect,
|
||||
{ addonId: this.addonId }
|
||||
);
|
||||
|
||||
this._childActorID = this._form.actor;
|
||||
|
||||
// Exit the proxy child actor if the child actor has been destroyed.
|
||||
this._mm.addMessageListener("debug:webext_child_exit", this._onChildExit);
|
||||
|
||||
return this._form;
|
||||
},
|
||||
|
||||
/** WebExtension Actor Methods **/
|
||||
async reload() {
|
||||
await this.addon.reload();
|
||||
return {};
|
||||
},
|
||||
|
||||
// This function will be called from RootActor in case that the debugger client
|
||||
// retrieves list of addons with `iconDataURL` option.
|
||||
async loadIconDataURL() {
|
||||
this._iconDataURL = await this.getIconDataURL();
|
||||
},
|
||||
|
||||
async getIconDataURL() {
|
||||
if (!this.addon.iconURL) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.responseType = "blob";
|
||||
xhr.open("GET", this.addon.iconURL, true);
|
||||
|
||||
if (this.addon.iconURL.toLowerCase().endsWith(".svg")) {
|
||||
// Maybe SVG, thus force to change mime type.
|
||||
xhr.overrideMimeType("image/svg+xml");
|
||||
}
|
||||
|
||||
try {
|
||||
const blob = await new Promise((resolve, reject) => {
|
||||
xhr.onload = () => resolve(xhr.response);
|
||||
xhr.onerror = reject;
|
||||
xhr.send();
|
||||
});
|
||||
|
||||
const reader = new FileReader();
|
||||
return await new Promise((resolve, reject) => {
|
||||
reader.onloadend = () => resolve(reader.result);
|
||||
reader.onerror = reject;
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
} catch (_) {
|
||||
console.warn(`Failed to create data url from [${this.addon.iconURL}]`);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
// TODO: check if we need this, as it is only used in a test
|
||||
get isOOP() {
|
||||
return this._browser ? this._browser.isRemoteBrowser : undefined;
|
||||
},
|
||||
|
||||
// Private Methods
|
||||
get _mm() {
|
||||
return (
|
||||
this._browser &&
|
||||
(this._browser.messageManager ||
|
||||
this._browser.frameLoader.messageManager)
|
||||
);
|
||||
},
|
||||
|
||||
_extensionFrameDisconnect() {
|
||||
this._childTargetPromise = null;
|
||||
AddonManager.removeAddonListener(this);
|
||||
|
||||
this.addon = null;
|
||||
this._childTargetPromise = null;
|
||||
|
||||
if (this._mm) {
|
||||
this._mm.removeMessageListener(
|
||||
"debug:webext_child_exit",
|
||||
this._onChildExit
|
||||
);
|
||||
|
||||
this._mm.sendAsyncMessage("debug:webext_parent_exit", {
|
||||
actor: this._childActorID,
|
||||
});
|
||||
|
||||
ExtensionParent.DebugUtils.releaseExtensionProcessBrowser(this);
|
||||
}
|
||||
|
||||
this._browser = null;
|
||||
this._childActorID = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle the child actor exit.
|
||||
*/
|
||||
_onChildExit(msg) {
|
||||
if (msg.json.actor !== this._childActorID) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._extensionFrameDisconnect();
|
||||
},
|
||||
|
||||
// AddonManagerListener callbacks.
|
||||
onInstalled(addon) {
|
||||
if (addon.id != this.addonId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the AddonManager's addon object on reload/update.
|
||||
this.addon = addon;
|
||||
},
|
||||
|
||||
onUninstalled(addon) {
|
||||
if (addon != this.addon) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._extensionFrameDisconnect();
|
||||
},
|
||||
|
||||
destroy() {
|
||||
this._extensionFrameDisconnect();
|
||||
protocol.Actor.prototype.destroy.call(this);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
exports.WebExtensionDescriptorActor = WebExtensionDescriptorActor;
|
|
@ -24,8 +24,8 @@ loader.lazyRequireGetter(
|
|||
);
|
||||
loader.lazyRequireGetter(
|
||||
this,
|
||||
"WebExtensionActor",
|
||||
"devtools/server/actors/addon/webextension",
|
||||
"WebExtensionDescriptorActor",
|
||||
"devtools/server/actors/descriptors/webextension",
|
||||
true
|
||||
);
|
||||
loader.lazyRequireGetter(
|
||||
|
@ -824,7 +824,7 @@ BrowserAddonList.prototype.getList = async function() {
|
|||
for (const addon of addons) {
|
||||
let actor = this._actorByAddonId.get(addon.id);
|
||||
if (!actor) {
|
||||
actor = new WebExtensionActor(this._connection, addon);
|
||||
actor = new WebExtensionDescriptorActor(this._connection, addon);
|
||||
this._actorByAddonId.set(addon.id, actor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,14 +36,14 @@ async function test_connect_addon(oopMode) {
|
|||
await client.connect();
|
||||
|
||||
// List addons and assertions on the expected addon actor.
|
||||
const addonFront = await client.mainRoot.getAddon({ id: extension.id });
|
||||
ok(addonFront, "The expected webextension addon actor has been found");
|
||||
const addonDescriptor = await client.mainRoot.getAddon({ id: extension.id });
|
||||
ok(addonDescriptor, "The expected webextension addon actor has been found");
|
||||
|
||||
const addonTarget = await addonFront.connect();
|
||||
const addonTarget = await addonDescriptor.getTarget();
|
||||
ok(addonTarget, "The expected webextension target addon actor has been found");
|
||||
|
||||
// Connect to the target addon actor and wait for the updated list of frames.
|
||||
is(addonTarget.targetForm.isOOP, oopMode,
|
||||
is(addonDescriptor.targetForm.isOOP, oopMode,
|
||||
"Got the expected oop mode in the webextension actor form");
|
||||
const frames = await waitForFramesUpdated(addonTarget);
|
||||
const backgroundPageFrame = frames.filter((frame) => {
|
||||
|
|
|
@ -109,8 +109,8 @@ async function attachAddon(addonId) {
|
|||
|
||||
await client.connect();
|
||||
|
||||
const addonFront = await client.mainRoot.getAddon({ id: addonId });
|
||||
const addonTarget = await addonFront.connect();
|
||||
const addonDescriptor = await client.mainRoot.getAddon({ id: addonId });
|
||||
const addonTarget = await addonDescriptor.getTarget();
|
||||
|
||||
if (!addonTarget) {
|
||||
client.close();
|
||||
|
|
|
@ -7,5 +7,4 @@
|
|||
DevToolsModules(
|
||||
'addons.js',
|
||||
'webextension-inspected-window.js',
|
||||
'webextension.js',
|
||||
)
|
||||
|
|
|
@ -7,5 +7,6 @@
|
|||
DevToolsModules(
|
||||
'frame.js',
|
||||
'process.js',
|
||||
'webextension.js',
|
||||
)
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
"use strict";
|
||||
|
||||
const {
|
||||
webExtensionSpec,
|
||||
} = require("devtools/shared/specs/addon/webextension");
|
||||
webExtensionDescriptorSpec,
|
||||
} = require("devtools/shared/specs/descriptors/webextension");
|
||||
const {
|
||||
FrontClassWithSpec,
|
||||
registerFront,
|
||||
|
@ -17,10 +17,13 @@ loader.lazyRequireGetter(
|
|||
true
|
||||
);
|
||||
|
||||
class WebExtensionFront extends FrontClassWithSpec(webExtensionSpec) {
|
||||
class WebExtensionDescriptorFront extends FrontClassWithSpec(
|
||||
webExtensionDescriptorSpec
|
||||
) {
|
||||
constructor(client, targetFront, parentFront) {
|
||||
super(client, targetFront, parentFront);
|
||||
this.client = client;
|
||||
this.traits = {};
|
||||
}
|
||||
|
||||
form(json) {
|
||||
|
@ -29,6 +32,7 @@ class WebExtensionFront extends FrontClassWithSpec(webExtensionSpec) {
|
|||
// Save the full form for Target class usage.
|
||||
// Do not use `form` name to avoid colliding with protocol.js's `form` method
|
||||
this.targetForm = json;
|
||||
this.traits = json.traits || {};
|
||||
|
||||
// We used to manipulate the form rather than the front itself.
|
||||
// Expose all form attributes to ease accessing them.
|
||||
|
@ -40,6 +44,10 @@ class WebExtensionFront extends FrontClassWithSpec(webExtensionSpec) {
|
|||
}
|
||||
}
|
||||
|
||||
connect() {
|
||||
return this.getTarget();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual target front for web extensions.
|
||||
*
|
||||
|
@ -47,7 +55,7 @@ class WebExtensionFront extends FrontClassWithSpec(webExtensionSpec) {
|
|||
* inherits from BrowsingContextTargetActor. This connect method is used to retrieve
|
||||
* the final target actor to use.
|
||||
*/
|
||||
async connect() {
|
||||
async getTarget() {
|
||||
if (
|
||||
this.isWebExtension &&
|
||||
this.client.mainRoot.traits.webExtensionAddonConnect
|
||||
|
@ -59,8 +67,14 @@ class WebExtensionFront extends FrontClassWithSpec(webExtensionSpec) {
|
|||
// the addon (e.g. when the addon is disabled or uninstalled).
|
||||
// To retrieve the target actor instance, we call its "connect" method, (which
|
||||
// fetches the target actor targetForm from a WebExtensionTargetActor instance).
|
||||
const form = await super.connect();
|
||||
const front = new BrowsingContextTargetFront(this.client, {
|
||||
let form = null;
|
||||
// FF70+ The method is now called getTarget`
|
||||
if (!this.traits.isDescriptor) {
|
||||
form = await super.connect();
|
||||
} else {
|
||||
form = await super.getTarget();
|
||||
}
|
||||
const front = new BrowsingContextTargetFront(this.conn, {
|
||||
actor: form.actor,
|
||||
});
|
||||
front.form(form);
|
||||
|
@ -71,5 +85,5 @@ class WebExtensionFront extends FrontClassWithSpec(webExtensionSpec) {
|
|||
}
|
||||
}
|
||||
|
||||
exports.WebExtensionFront = WebExtensionFront;
|
||||
registerFront(WebExtensionFront);
|
||||
exports.WebExtensionDescriptorFront = WebExtensionDescriptorFront;
|
||||
registerFront(WebExtensionDescriptorFront);
|
|
@ -333,8 +333,8 @@ class RootFront extends FrontClassWithSpec(rootSpec) {
|
|||
*/
|
||||
async getAddon({ id }) {
|
||||
const addons = await this.listAddons();
|
||||
const webextensionFront = addons.find(addon => addon.id === id);
|
||||
return webextensionFront;
|
||||
const webextensionDescriptorFront = addons.find(addon => addon.id === id);
|
||||
return webextensionDescriptorFront;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,5 +7,4 @@
|
|||
DevToolsModules(
|
||||
'addons.js',
|
||||
'webextension-inspected-window.js',
|
||||
'webextension.js',
|
||||
)
|
||||
|
|
|
@ -7,5 +7,6 @@
|
|||
DevToolsModules(
|
||||
'frame.js',
|
||||
'process.js',
|
||||
'webextension.js',
|
||||
)
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
const { RetVal, generateActorSpec } = require("devtools/shared/protocol");
|
||||
|
||||
const webExtensionSpec = generateActorSpec({
|
||||
typeName: "webExtension",
|
||||
const webExtensionDescriptorSpec = generateActorSpec({
|
||||
typeName: "webExtensionDescriptor",
|
||||
|
||||
methods: {
|
||||
reload: {
|
||||
|
@ -14,11 +14,16 @@ const webExtensionSpec = generateActorSpec({
|
|||
response: { addon: RetVal("json") },
|
||||
},
|
||||
|
||||
// FF70+ The method is now called getTarget`
|
||||
connect: {
|
||||
request: {},
|
||||
response: { form: RetVal("json") },
|
||||
},
|
||||
getTarget: {
|
||||
request: {},
|
||||
response: { form: RetVal("json") },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
exports.webExtensionSpec = webExtensionSpec;
|
||||
exports.webExtensionDescriptorSpec = webExtensionDescriptorSpec;
|
|
@ -27,11 +27,6 @@ const Types = (exports.__TypesForTests = [
|
|||
spec: "devtools/shared/specs/addon/addons",
|
||||
front: "devtools/shared/fronts/addon/addons",
|
||||
},
|
||||
{
|
||||
types: ["webExtension"],
|
||||
spec: "devtools/shared/specs/addon/webextension",
|
||||
front: "devtools/shared/fronts/addon/webextension",
|
||||
},
|
||||
{
|
||||
types: ["webExtensionInspectedWindow"],
|
||||
spec: "devtools/shared/specs/addon/webextension-inspected-window",
|
||||
|
@ -67,6 +62,11 @@ const Types = (exports.__TypesForTests = [
|
|||
spec: "devtools/shared/specs/descriptors/process",
|
||||
front: "devtools/shared/fronts/descriptors/process",
|
||||
},
|
||||
{
|
||||
types: ["webExtensionDescriptor"],
|
||||
spec: "devtools/shared/specs/descriptors/webextension",
|
||||
front: "devtools/shared/fronts/descriptors/webextension",
|
||||
},
|
||||
{
|
||||
types: ["device"],
|
||||
spec: "devtools/shared/specs/device",
|
||||
|
|
|
@ -65,7 +65,7 @@ const rootSpecPrototype = {
|
|||
iconDataURL: Option(0, "boolean"),
|
||||
},
|
||||
response: {
|
||||
addons: RetVal("array:webExtension"),
|
||||
addons: RetVal("array:webExtensionDescriptor"),
|
||||
},
|
||||
},
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче