Bug 1477600 - Part 2: Implement remove/reload button. r=jdescottes
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Tue, 14 Aug 2018 10:35:43 +0900
changeset 432046 86e6704908fd
parent 432045 1889060c3412
child 432047 16daef3a89a2
push id106618
push userdakatsuka@mozilla.com
push dateFri, 17 Aug 2018 00:36:46 +0000
treeherdermozilla-inbound@86e6704908fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdescottes
bugs1477600
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1477600 - Part 2: Implement remove/reload button. r=jdescottes Differential Revision: https://phabricator.services.mozilla.com/D3272
devtools/client/aboutdebugging-new/src/actions/runtime.js
devtools/client/aboutdebugging-new/src/components/DebugTargetItem.js
devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.js
devtools/client/aboutdebugging-new/src/components/debugtarget/TabDetail.js
devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionAction.js
devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
devtools/client/aboutdebugging-new/src/reducers/runtime-state.js
--- a/devtools/client/aboutdebugging-new/src/actions/runtime.js
+++ b/devtools/client/aboutdebugging-new/src/actions/runtime.js
@@ -111,16 +111,42 @@ function installTemporaryExtension() {
     } catch (e) {
       console.error(e);
     }
   });
 
   return () => {};
 }
 
+function reloadTemporaryExtension(actor) {
+  return async (_, getState) => {
+    const client = getState().runtime.client;
+
+    try {
+      await client.request({ to: actor, type: "reload" });
+    } catch (e) {
+      console.error(e);
+    }
+  };
+}
+
+function removeTemporaryExtension(id) {
+  return async () => {
+    try {
+      const addon = await AddonManager.getAddonByID(id);
+
+      if (addon) {
+        await addon.uninstall();
+      }
+    } catch (e) {
+      console.error(e);
+    }
+  };
+}
+
 function requestTabs() {
   return async (dispatch, getState) => {
     dispatch({ type: REQUEST_TABS_START });
 
     const client = getState().runtime.client;
 
     try {
       const { tabs } = await client.listTabs({ favicons: true });
@@ -155,11 +181,13 @@ function requestExtensions() {
   };
 }
 
 module.exports = {
   connectRuntime,
   disconnectRuntime,
   inspectDebugTarget,
   installTemporaryExtension,
+  reloadTemporaryExtension,
+  removeTemporaryExtension,
   requestTabs,
   requestExtensions,
 };
--- a/devtools/client/aboutdebugging-new/src/components/DebugTargetItem.js
+++ b/devtools/client/aboutdebugging-new/src/components/DebugTargetItem.js
@@ -5,16 +5,18 @@
 "use strict";
 
 const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react");
 const dom = require("devtools/client/shared/vendor/react-dom-factories");
 const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
 
 const ExtensionDetail = createFactory(require("./debugtarget/ExtensionDetail"));
 const TabDetail = createFactory(require("./debugtarget/TabDetail"));
+const TemporaryExtensionAction =
+  createFactory(require("./debugtarget/TemporaryExtensionAction"));
 
 const Actions = require("../actions/index");
 const { DEBUG_TARGETS } = require("../constants");
 
 /**
  * This component displays debug target.
  */
 class DebugTargetItem extends PureComponent {
@@ -25,16 +27,33 @@ class DebugTargetItem extends PureCompon
     };
   }
 
   inspect() {
     const { dispatch, target } = this.props;
     dispatch(Actions.inspectDebugTarget(target.type, target.id));
   }
 
+  renderAction() {
+    const { dispatch, target } = this.props;
+
+    return dom.div(
+      {},
+      dom.button(
+        {
+          onClick: e => this.inspect(),
+          className: "aboutdebugging-button",
+        },
+        "Inspect"
+      ),
+      target.details.temporarilyInstalled
+        ? TemporaryExtensionAction({ dispatch, target }) : null,
+    );
+  }
+
   renderDetail() {
     const { target } = this.props;
 
     switch (target.type) {
       case DEBUG_TARGETS.EXTENSION:
         return ExtensionDetail({ target });
       case DEBUG_TARGETS.TAB:
         return TabDetail({ target });
@@ -64,31 +83,21 @@ class DebugTargetItem extends PureCompon
           title: target.name,
         },
         target.name
       ),
       this.renderDetail(),
     );
   }
 
-  renderInspectButton() {
-    return dom.button(
-      {
-        onClick: e => this.inspect(),
-        className: "aboutdebugging-button",
-      },
-      "Inspect"
-    );
-  }
-
   render() {
     return dom.li(
       {
         className: "debug-target-item",
       },
       this.renderIcon(),
       this.renderInfo(),
-      this.renderInspectButton(),
+      this.renderAction(),
     );
   }
 }
 
 module.exports = DebugTargetItem;
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.js
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/ExtensionDetail.js
@@ -28,17 +28,17 @@ class ExtensionDetail extends PureCompon
         },
         value,
       ),
     ];
   }
 
   renderUUID() {
     const { target } = this.props;
-    const { manifestURL, uuid } = target;
+    const { manifestURL, uuid } = target.details;
 
     const value = [
       uuid,
       dom.a(
         {
           className: "extension-detail__manifest",
           href: manifestURL,
           target: "_blank",
@@ -47,17 +47,18 @@ class ExtensionDetail extends PureCompon
       )
     ];
 
     return this.renderField("Internal UUID", value, uuid);
   }
 
   render() {
     const { target } = this.props;
-    const { id, location, uuid } = target;
+    const { id, details } = target;
+    const { location, uuid } = details;
 
     return dom.dl(
       {
         className: "extension-detail",
       },
       location ? this.renderField("Location", location) : null,
       this.renderField("Extension ID", id),
       uuid ? this.renderUUID() : null,
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/TabDetail.js
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/TabDetail.js
@@ -14,13 +14,13 @@ const PropTypes = require("devtools/clie
 class TabDetail extends PureComponent {
   static get propTypes() {
     return {
       target: PropTypes.object.isRequired,
     };
   }
 
   render() {
-    return dom.div({ className: "ellipsis-text" }, this.props.target.url);
+    return dom.div({ className: "ellipsis-text" }, this.props.target.details.url);
   }
 }
 
 module.exports = TabDetail;
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionAction.js
@@ -0,0 +1,54 @@
+/* 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";
+
+const { PureComponent } = require("devtools/client/shared/vendor/react");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+
+const Actions = require("../../actions/index");
+
+/**
+ * This component provides components that reload/remove temporary extension.
+ */
+class TemporaryExtensionAction extends PureComponent {
+  static get propTypes() {
+    return {
+      dispatch: PropTypes.func.isRequired,
+      target: PropTypes.object.isRequired,
+    };
+  }
+
+  reload() {
+    const { dispatch, target } = this.props;
+    dispatch(Actions.reloadTemporaryExtension(target.details.actor));
+  }
+
+  remove() {
+    const { dispatch, target } = this.props;
+    dispatch(Actions.removeTemporaryExtension(target.id));
+  }
+
+  render() {
+    return [
+      dom.button(
+        {
+          className: "aboutdebugging-button",
+          onClick: e => this.reload()
+        },
+        "Reload",
+      ),
+      dom.button(
+        {
+          className: "aboutdebugging-button",
+          onClick: e => this.remove()
+        },
+        "Remove",
+      ),
+    ];
+  }
+}
+
+module.exports = TemporaryExtensionAction;
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
@@ -1,10 +1,11 @@
 # 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/.
 
 DevToolsModules(
     'ExtensionDetail.css',
     'ExtensionDetail.js',
     'TabDetail.js',
+    'TemporaryExtensionAction.js',
     'TemporaryExtensionInstaller.js',
 )
--- a/devtools/client/aboutdebugging-new/src/reducers/runtime-state.js
+++ b/devtools/client/aboutdebugging-new/src/reducers/runtime-state.js
@@ -65,33 +65,53 @@ function getExtensionFilePath(extension)
   }
 
   return extension.url.slice("file://".length);
 }
 
 function toExtensionComponentData(extensions) {
   return extensions.map(extension => {
     const type = DEBUG_TARGETS.EXTENSION;
-    const { iconURL, id, manifestURL, name } = extension;
+    const { actor, iconURL, id, manifestURL, name, temporarilyInstalled } = extension;
     const icon = iconURL || "chrome://mozapps/skin/extensions/extensionGeneric.svg";
     const location = getExtensionFilePath(extension);
     const uuid = manifestURL ? /moz-extension:\/\/([^/]*)/.exec(manifestURL)[1] : null;
-    return { type, id, icon, location, manifestURL, name, uuid };
+    return {
+      name,
+      icon,
+      id,
+      type,
+      details: {
+        actor,
+        location,
+        manifestURL,
+        temporarilyInstalled,
+        uuid,
+      },
+    };
   });
 }
 
 function toTabComponentData(tabs) {
   return tabs.map(tab => {
     const type = DEBUG_TARGETS.TAB;
     const id = tab.outerWindowID;
     const icon = tab.favicon
       ? `data:image/png;base64,${ btoa(String.fromCharCode.apply(String, tab.favicon)) }`
       : "chrome://devtools/skin/images/globe.svg";
     const name = tab.title || tab.url;
     const url = tab.url;
-    return { type, id, icon, name, url };
+    return {
+      name,
+      icon,
+      id,
+      type,
+      details: {
+        url,
+      },
+    };
   });
 }
 
 module.exports = {
   RuntimeState,
   runtimeReducer,
 };