Bug 1487078 - Reuse addon debugging helpers from aboutdebugging in new ui;r=daisuke

Differential Revision: https://phabricator.services.mozilla.com/D4548

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Julian Descottes 2018-08-31 06:52:16 +00:00
parent f856e68ebe
commit 82f188b48e
5 changed files with 77 additions and 75 deletions

View File

@ -5,13 +5,16 @@
"use strict";
const { AddonManager } = require("resource://gre/modules/AddonManager.jsm");
const { BrowserToolboxProcess } =
require("resource://devtools/client/framework/ToolboxProcess.jsm");
const { Cc, Ci } = require("chrome");
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
const { DebuggerServer } = require("devtools/server/main");
const { gDevToolsBrowser } = require("devtools/client/framework/devtools-browser");
const {
debugLocalAddon,
openTemporaryExtension,
uninstallAddon,
} = require("devtools/client/aboutdebugging/modules/addon");
const {
CONNECT_RUNTIME_FAILURE,
CONNECT_RUNTIME_START,
@ -31,8 +34,6 @@ const {
REQUEST_WORKERS_SUCCESS,
} = require("../constants");
let browserToolboxProcess = null;
function connectRuntime() {
return async (dispatch, getState) => {
dispatch({ type: CONNECT_RUNTIME_START });
@ -80,17 +81,7 @@ function inspectDebugTarget(type, id) {
break;
}
case DEBUG_TARGETS.EXTENSION: {
// Close current debugging toolbox and open a new one.
if (browserToolboxProcess) {
browserToolboxProcess.close();
}
browserToolboxProcess = BrowserToolboxProcess.init({
addonID: id,
onClose: () => {
browserToolboxProcess = null;
}
});
debugLocalAddon(id);
break;
}
case DEBUG_TARGETS.WORKER: {
@ -108,30 +99,15 @@ function inspectDebugTarget(type, id) {
}
function installTemporaryExtension() {
const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(window, "Select Manifest File or Package (.xpi)", Ci.nsIFilePicker.modeOpen);
fp.open(async res => {
if (res == Ci.nsIFilePicker.returnCancel || !fp.file) {
return;
}
let file = fp.file;
// AddonManager.installTemporaryAddon accepts either
// addon directory or final xpi file.
if (!file.isDirectory() &&
!file.leafName.endsWith(".xpi") && !file.leafName.endsWith(".zip")) {
file = file.parent;
}
return async (dispatch, getState) => {
const message = "Select Manifest File or Package (.xpi)";
const file = await openTemporaryExtension(window, message);
try {
await AddonManager.installTemporaryAddon(file);
} catch (e) {
console.error(e);
}
});
return () => {};
};
}
function pushServiceWorker(actor) {
@ -161,11 +137,7 @@ function reloadTemporaryExtension(actor) {
function removeTemporaryExtension(id) {
return async () => {
try {
const addon = await AddonManager.getAddonByID(id);
if (addon) {
await addon.uninstall();
}
await uninstallAddon(id);
} catch (e) {
console.error(e);
}

View File

@ -9,6 +9,11 @@ const {
REQUEST_EXTENSIONS_SUCCESS,
} = require("../constants");
const {
getExtensionUuid,
parseFileUri
} = require("devtools/client/aboutdebugging/modules/addon");
/**
* This middleware converts extensions object that get from DebuggerClient.listAddons()
* to data which is used in DebugTargetItem.
@ -33,16 +38,7 @@ function getFilePath(extension) {
return null;
}
// Strip a leading slash from Windows drive letter URIs.
// file:///home/foo ~> /home/foo
// file:///C:/foo ~> C:/foo
const windowsRegex = /^file:\/\/\/([a-zA-Z]:\/.*)/;
if (windowsRegex.test(extension.url)) {
return windowsRegex.exec(extension.url)[1];
}
return extension.url.slice("file://".length);
return parseFileUri(extension.url);
}
function toComponentData(extensions) {
@ -51,7 +47,7 @@ function toComponentData(extensions) {
const { actor, iconURL, id, manifestURL, name } = extension;
const icon = iconURL || "chrome://mozapps/skin/extensions/extensionGeneric.svg";
const location = getFilePath(extension);
const uuid = manifestURL ? /moz-extension:\/\/([^/]*)/.exec(manifestURL)[1] : null;
const uuid = getExtensionUuid(extension);
return {
name,
icon,

View File

@ -10,10 +10,10 @@
loader.lazyImporter(this, "AddonManager",
"resource://gre/modules/AddonManager.jsm");
const { Cc, Ci } = require("chrome");
const { createFactory, Component } = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
const { openTemporaryExtension } = require("devtools/client/aboutdebugging/modules/addon");
const Services = require("Services");
const AddonsInstallError = createFactory(require("./InstallError"));
@ -49,26 +49,10 @@ class AddonsControls extends Component {
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", enabled);
}
loadAddonFromFile() {
this.setState({ installError: null });
const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(window,
Strings.GetStringFromName("selectAddonFromFile2"),
Ci.nsIFilePicker.modeOpen);
fp.open(res => {
if (res == Ci.nsIFilePicker.returnCancel || !fp.file) {
return;
}
let file = fp.file;
// AddonManager.installTemporaryAddon accepts either
// addon directory or final xpi file.
if (!file.isDirectory() &&
!file.leafName.endsWith(".xpi") && !file.leafName.endsWith(".zip")) {
file = file.parent;
}
this.installAddon(file);
});
async loadAddonFromFile() {
const message = Strings.GetStringFromName("selectAddonFromFile2");
const file = await openTemporaryExtension(window, message);
this.installAddon(file);
}
retryInstall() {

View File

@ -12,6 +12,7 @@ const dom = require("devtools/client/shared/vendor/react-dom-factories");
const {
debugLocalAddon,
debugRemoteAddon,
getExtensionUuid,
isLegacyTemporaryExtension,
isTemporaryID,
parseFileUri,
@ -65,11 +66,11 @@ function addonIDforTarget(target) {
}
function internalIDForTarget(target) {
if (!target.manifestURL) {
const uuid = getExtensionUuid(target);
if (!uuid) {
return [];
}
// Strip off the protocol and rest, leaving us with just the UUID.
const uuid = /moz-extension:\/\/([^/]*)/.exec(target.manifestURL)[1];
return [
dom.dt(
{ className: "addon-target-info-label" },

View File

@ -4,6 +4,7 @@
"use strict";
const { Cc, Ci } = require("chrome");
loader.lazyImporter(this, "BrowserToolboxProcess",
"resource://devtools/client/framework/ToolboxProcess.jsm");
loader.lazyImporter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
@ -72,6 +73,10 @@ exports.debugRemoteAddon = async function(addonForm, client) {
});
};
/**
* Uninstall the addon with the provided id.
* Resolves when the addon shutdown has completed.
*/
exports.uninstallAddon = async function(addonID) {
const addon = await AddonManager.getAddonByID(addonID);
return addon && addon.uninstall();
@ -104,3 +109,47 @@ exports.parseFileUri = function(url) {
}
return url.slice("file://".length);
};
exports.getExtensionUuid = function(extension) {
const { manifestURL } = extension;
// Strip off the protocol and rest, leaving us with just the UUID.
return manifestURL ? /moz-extension:\/\/([^/]*)/.exec(manifestURL)[1] : null;
};
/**
* Open a file picker to allow the user to locate a temporary extension. A temporary
* extension can either be:
* - a folder
* - a .xpi file
* - a .zip file
*
* @param {Window} win
* The window object where the filepicker should be opened.
* Note: We cannot use the global window object here because it is undefined if
* this module is loaded from a file outside of devtools/client/aboutdebugging/.
* See browser-loader.js `uri.startsWith(baseURI)` for more details.
* @param {String} message
* The help message that should be displayed to the user in the filepicker.
* @return {Promise} returns a promise that resolves a File object corresponding to the
* file selected by the user.
*/
exports.openTemporaryExtension = function(win, message) {
return new Promise(resolve => {
const fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(win, message, Ci.nsIFilePicker.modeOpen);
fp.open(res => {
if (res == Ci.nsIFilePicker.returnCancel || !fp.file) {
return;
}
let file = fp.file;
// AddonManager.installTemporaryAddon accepts either
// addon directory or final xpi file.
if (!file.isDirectory() &&
!file.leafName.endsWith(".xpi") && !file.leafName.endsWith(".zip")) {
file = file.parent;
}
resolve(file);
});
});
};