bug 1360756 show internal ID for about:debugging r?jdescottes
MozReview-Commit-ID: 2LwFAzKSVKT
--- a/devtools/client/aboutdebugging/aboutdebugging.css
+++ b/devtools/client/aboutdebugging/aboutdebugging.css
@@ -274,16 +274,20 @@ button {
.addon-target-info-label:last-of-type {
padding-bottom: 16px;
}
.addon-target-info-content {
margin: 0;
}
+.addon-target-info-more {
+ padding-left: 1ch;
+}
+
.addon-target-button {
background: none;
border: none;
color: #0087ff;
font-size: 14px;
margin: 12px;
min-width: auto;
padding: 4px;
--- a/devtools/client/aboutdebugging/components/addons/panel.js
+++ b/devtools/client/aboutdebugging/components/addons/panel.js
@@ -75,16 +75,17 @@ module.exports = createClass({
let extensions = addons.filter(addon => addon.debuggable).map(addon => {
return {
name: addon.name,
icon: addon.iconURL || ExtensionIcon,
addonID: addon.id,
addonActor: addon.actor,
temporarilyInstalled: addon.temporarilyInstalled,
url: addon.url,
+ baseURL: addon.baseURL,
};
});
this.setState({ extensions });
}, error => {
throw new Error("Client error while listing addons: " + error);
});
},
--- a/devtools/client/aboutdebugging/components/addons/target.js
+++ b/devtools/client/aboutdebugging/components/addons/target.js
@@ -34,16 +34,44 @@ function filePathForTarget(target) {
// the ellipsis on the left.
dom.dd(
{ className: "addon-target-info-content file-path" },
dom.span({ className: "file-path-inner", title: path }, path),
),
];
}
+function internalIDForTarget(target) {
+ if (!target.baseURL) {
+ return [];
+ }
+ // Strip off the protocol and trailing slash.
+ let uuid = /moz-extension:\/\/([^/]*)/.exec(target.baseURL)[1];
+ return [
+ dom.dt(
+ { className: "addon-target-info-label" },
+ Strings.GetStringFromName("internalUUID"),
+ ),
+ dom.dd(
+ { className: "addon-target-info-content internal-uuid" },
+ dom.span(
+ { title: uuid },
+ uuid
+ ),
+ dom.span(
+ { className: "addon-target-info-more" },
+ dom.a(
+ { href: target.baseURL, target: "_blank", className: "base-url" },
+ Strings.GetStringFromName("baseURL"),
+ ),
+ )
+ ),
+ ];
+}
+
module.exports = createClass({
displayName: "AddonTarget",
propTypes: {
client: PropTypes.instanceOf(DebuggerClient).isRequired,
debugDisabled: PropTypes.bool,
target: PropTypes.shape({
addonActor: PropTypes.string.isRequired,
@@ -86,16 +114,17 @@ module.exports = createClass({
role: "presentation",
src: target.icon
}),
dom.span({ className: "target-name", title: target.name }, target.name)
),
dom.dl(
{ className: "addon-target-info" },
...filePathForTarget(target),
+ ...internalIDForTarget(target),
),
dom.div({className: "addon-target-actions"},
dom.button({
className: "debug-button addon-target-button",
onClick: this.debug,
disabled: debugDisabled,
}, Strings.GetStringFromName("debug")),
dom.button({
--- a/devtools/client/aboutdebugging/test/browser_addons_debug_info.js
+++ b/devtools/client/aboutdebugging/test/browser_addons_debug_info.js
@@ -1,28 +1,61 @@
"use strict";
-const ADDON_ID = "test-devtools@mozilla.org";
-const ADDON_NAME = "test-devtools";
+const UUID_REGEX = /^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/;
-add_task(function* () {
+add_task(function* testLegacyAddon() {
+ let addonId = "test-devtools@mozilla.org";
+ let addonName = "test-devtools";
let { tab, document } = yield openAboutDebugging("addons");
yield waitForInitialAddonList(document);
yield installAddon({
document,
path: "addons/unpacked/install.rdf",
- name: ADDON_NAME,
+ name: addonName,
});
- let container = document.querySelector(`[data-addon-id="${ADDON_ID}"]`);
+ let container = document.querySelector(`[data-addon-id="${addonId}"]`);
let filePath = container.querySelector(".file-path");
let expectedFilePath = "browser/devtools/client/aboutdebugging/test/addons/unpacked/";
// Verify that the path to the install location is shown next to its label.
ok(filePath, "file path is in DOM");
ok(filePath.textContent.endsWith(expectedFilePath), "file path is set correctly");
is(filePath.previousElementSibling.textContent, "Location", "file path has label");
- yield uninstallAddon({document, id: ADDON_ID, name: ADDON_NAME});
+ yield uninstallAddon({document, id: addonId, name: addonName});
yield closeAboutDebugging(tab);
});
+
+add_task(function* testWebExtension() {
+ let addonId = "test-devtools-webextension-nobg@mozilla.org";
+ let addonName = "test-devtools-webextension-nobg";
+ let { tab, document } = yield openAboutDebugging("addons");
+
+ yield waitForInitialAddonList(document);
+ yield installAddon({
+ document,
+ path: "addons/test-devtools-webextension-nobg/manifest.json",
+ name: addonName,
+ isWebExtension: true
+ });
+
+ let container = document.querySelector(`[data-addon-id="${addonId}"]`);
+ let filePath = container.querySelector(".file-path");
+ let expectedFilePath = "/test/addons/test-devtools-webextension-nobg/";
+
+ ok(filePath, "file path is in DOM");
+ ok(filePath.textContent.endsWith(expectedFilePath), "file path is set correctly");
+ is(filePath.previousElementSibling.textContent, "Location", "file path has label");
+
+ let internalUUID = container.querySelector(".internal-uuid span");
+ ok(internalUUID.textContent.match(UUID_REGEX), "internalUUID is correct");
+
+ let baseURL = container.querySelector(".base-url");
+ ok(baseURL.href.startsWith("moz-extension://"), "href for baseURL exists");
+
+ yield uninstallAddon({document, id: addonId, name: addonName});
+
+ yield closeAboutDebugging(tab);
+});
--- a/devtools/client/locales/en-US/aboutdebugging.properties
+++ b/devtools/client/locales/en-US/aboutdebugging.properties
@@ -61,16 +61,25 @@ loadTemporaryAddon = Load Temporary Add-
# LOCALIZATION NOTE (extensions):
# This string is displayed as a header above the list of loaded add-ons.
extensions = Extensions
# LOCALIZATION NOTE (temporaryExtensions):
# This string is displayed as a header above the list of temporarily loaded add-ons.
temporaryExtensions = Temporary Extensions
+# LOCALIZATION NOTE (internalUUID):
+# This string is displayed as a label for the internal UUID of an extension.
+internalUUID = Internal UUID
+
+# LOCALIZATION NOTE (baseURL):
+# This string is displayed as a label for the base URL of an extension.
+baseURL = Base URL
+
+
# LOCALIZATION NOTE (webExtTip):
# This string is displayed as a message below the list of temporarily loaded add-ons.
# Web-ext is a command line tool for web-extensions developers.
# See https://developer.mozilla.org/Add-ons/WebExtensions/Getting_started_with_web-ext
webExtTip = You can use web-ext to load temporary WebExtensions from the command line.
# LOCALIZATION NOTE (webExtTip.learnMore):
# This string is displayed as a link next to webExtTip and leads the user to the MDN
--- a/devtools/server/actors/webextension.js
+++ b/devtools/server/actors/webextension.js
@@ -11,16 +11,17 @@ const makeDebugger = require("./utils/ma
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
var { assert } = DevToolsUtils;
loader.lazyRequireGetter(this, "mapURIToAddonID", "devtools/server/actors/utils/map-uri-to-addon-id");
loader.lazyRequireGetter(this, "unwrapDebuggerObjectGlobal", "devtools/server/actors/script", true);
loader.lazyImporter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
+loader.lazyImporter(this, "ExtensionManagement", "resource://gre/modules/ExtensionManagement.jsm");
loader.lazyImporter(this, "XPIProvider", "resource://gre/modules/addons/XPIProvider.jsm");
const FALLBACK_DOC_MESSAGE = "Your addon does not have any document opened yet.";
/**
* Creates a TabActor for debugging all the contexts associated to a target WebExtensions
* add-on.
* Most of the implementation is inherited from ChromeActor (which inherits most of its
@@ -96,16 +97,17 @@ WebExtensionActor.prototype.form = funct
actor: this.actorID,
id: this.id,
name: this.addon.name,
url: this.addon.sourceURI ? this.addon.sourceURI.spec : undefined,
iconURL: this.addon.iconURL,
debuggable: this.addon.isDebuggable,
temporarilyInstalled: this.addon.temporarilyInstalled,
isWebExtension: this.addon.isWebExtension,
+ baseURL: ExtensionManagement.getURLForExtension(this.id),
});
};
WebExtensionActor.prototype._attach = function () {
// NOTE: we need to be sure that `this.window` can return a
// window before calling the ChromeActor.onAttach, or the TabActor
// will not be subscribed to the child doc shell updates.