Bug 1330741 - Show filesystem location of add-ons in about:debugging r?jdescottes draft
authorMark Striemer <mstriemer@mozilla.com>
Tue, 21 Mar 2017 18:20:28 -0500
changeset 566592 8d1b311823e400184067bb9a1f4a6ddecf58a081
parent 563733 dda22469d7f2011cd6d9ed0c1378dd1a0680e73f
child 625368 3b6ceed8619c7ee5e7c93bf82bb2d9a9d89ec2ba
push id55274
push userbmo:mstriemer@mozilla.com
push dateFri, 21 Apr 2017 21:07:04 +0000
reviewersjdescottes
bugs1330741
milestone55.0a1
Bug 1330741 - Show filesystem location of add-ons in about:debugging r?jdescottes MozReview-Commit-ID: 3pmdAi80boT
devtools/client/aboutdebugging/aboutdebugging.css
devtools/client/aboutdebugging/components/addons/panel.js
devtools/client/aboutdebugging/components/addons/target.js
devtools/client/aboutdebugging/test/browser.ini
devtools/client/aboutdebugging/test/browser_addons_debug_info.js
devtools/client/locales/en-US/aboutdebugging.properties
--- a/devtools/client/aboutdebugging/aboutdebugging.css
+++ b/devtools/client/aboutdebugging/aboutdebugging.css
@@ -244,16 +244,35 @@ button {
 }
 
 .addon-target-container .name {
   align-self: center;
   font-size: 16px;
   font-weight: 600;
 }
 
+.addon-target-info {
+  display: grid;
+  font-size: 14px;
+  grid-template-columns: 128px 1fr;
+}
+
+.addon-target-info-label {
+  padding-inline-end: 8px;
+  padding-bottom: 8px;
+}
+
+.addon-target-info-label:last-of-type {
+  padding-bottom: 16px;
+}
+
+.addon-target-info-content {
+  margin: 0;
+}
+
 .addon-target-button {
   background: none;
   border: none;
   color: #0087ff;
   font-size: 14px;
   margin: 12px;
   min-width: auto;
   padding: 4px;
@@ -284,8 +303,23 @@ button {
   text-decoration: none;
 }
 
 .addon-target-button:first-of-type {
   /* Subtract the start padding so the button is still a bigger click target but
    * lines up with the icon. */
   margin-inline-start: -4px;
 }
+
+/* We want the ellipsis on the left-hand-side, so make the parent RTL
+ * with an ellipsis and the child can be LTR. */
+.file-path {
+  direction: rtl;
+  max-width: 100%;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.file-path-inner {
+  direction: ltr;
+  unicode-bidi: plaintext;
+}
--- a/devtools/client/aboutdebugging/components/addons/panel.js
+++ b/devtools/client/aboutdebugging/components/addons/panel.js
@@ -71,17 +71,18 @@ module.exports = createClass({
     this.props.client.listAddons()
       .then(({addons}) => {
         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
+            temporarilyInstalled: addon.temporarilyInstalled,
+            url: addon.url,
           };
         });
 
         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
@@ -15,28 +15,48 @@ loader.lazyImporter(this, "BrowserToolbo
   "resource://devtools/client/framework/ToolboxProcess.jsm");
 
 loader.lazyRequireGetter(this, "DebuggerClient",
   "devtools/shared/client/main", true);
 
 const Strings = Services.strings.createBundle(
   "chrome://devtools/locale/aboutdebugging.properties");
 
+function filePathForTarget(target) {
+  // Only show file system paths, and only for temporarily installed add-ons.
+  if (!target.temporarilyInstalled || !target.url || !target.url.startsWith("file://")) {
+    return [];
+  }
+  let path = target.url.slice("file://".length);
+  return [
+    dom.dt(
+      { className: "addon-target-info-label" },
+      Strings.GetStringFromName("location")),
+    // Wrap the file path in a span so we can do some RTL/LTR swapping to get
+    // the ellipsis on the left.
+    dom.dd(
+      { className: "addon-target-info-content file-path" },
+      dom.span({ className: "file-path-inner", title: path }, path),
+    ),
+  ];
+}
+
 module.exports = createClass({
   displayName: "AddonTarget",
 
   propTypes: {
     client: PropTypes.instanceOf(DebuggerClient).isRequired,
     debugDisabled: PropTypes.bool,
     target: PropTypes.shape({
       addonActor: PropTypes.string.isRequired,
       addonID: PropTypes.string.isRequired,
       icon: PropTypes.string,
       name: PropTypes.string.isRequired,
-      temporarilyInstalled: PropTypes.bool
+      temporarilyInstalled: PropTypes.bool,
+      url: PropTypes.string,
     }).isRequired
   },
 
   debug() {
     let { target } = this.props;
     debugAddon(target.addonID);
   },
 
@@ -63,16 +83,20 @@ module.exports = createClass({
       dom.div({ className: "target" },
         dom.img({
           className: "target-icon",
           role: "presentation",
           src: target.icon
         }),
         dom.span({ className: "target-name", title: target.name }, target.name)
       ),
+      dom.dl(
+        { className: "addon-target-info" },
+        ...filePathForTarget(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({
           className: "reload-button addon-target-button",
--- a/devtools/client/aboutdebugging/test/browser.ini
+++ b/devtools/client/aboutdebugging/test/browser.ini
@@ -15,16 +15,17 @@ support-files =
   service-workers/empty-sw.js
   service-workers/fetch-sw.html
   service-workers/fetch-sw.js
   service-workers/push-sw.html
   service-workers/push-sw.js
   !/devtools/client/framework/test/shared-head.js
 
 [browser_addons_debug_bootstrapped.js]
+[browser_addons_debug_info.js]
 [browser_addons_debug_webextension.js]
 tags = webextensions
 [browser_addons_debug_webextension_inspector.js]
 tags = webextensions
 [browser_addons_debug_webextension_nobg.js]
 tags = webextensions
 [browser_addons_debug_webextension_popup.js]
 tags = webextensions
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging/test/browser_addons_debug_info.js
@@ -0,0 +1,28 @@
+"use strict";
+
+const ADDON_ID = "test-devtools@mozilla.org";
+const ADDON_NAME = "test-devtools";
+
+add_task(function* () {
+  let { tab, document } = yield openAboutDebugging("addons");
+  yield waitForInitialAddonList(document);
+
+  yield installAddon({
+    document,
+    path: "addons/unpacked/install.rdf",
+    name: ADDON_NAME,
+  });
+
+  let container = document.querySelector(`[data-addon-id="${ADDON_ID}"]`);
+  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 closeAboutDebugging(tab);
+});
--- a/devtools/client/locales/en-US/aboutdebugging.properties
+++ b/devtools/client/locales/en-US/aboutdebugging.properties
@@ -74,16 +74,20 @@ selectAddonFromFile2 = Select Manifest F
 # This string is displayed as a label of the button that reloads a given addon.
 reload = Reload
 
 # LOCALIZATION NOTE (reloadDisabledTooltip):
 # This string is displayed in a tooltip that appears when hovering over a
 # disabled 'reload' button.
 reloadDisabledTooltip = Only temporarily installed add-ons can be reloaded
 
+# LOCALIZATION NOTE (location):
+# This string is displayed as a label for the filesystem location of an extension.
+location = Location
+
 # LOCALIZATION NOTE (workers):
 # This string is displayed as a header of the about:debugging#workers page.
 workers = Workers
 
 serviceWorkers = Service Workers
 sharedWorkers = Shared Workers
 otherWorkers = Other Workers