Bug 1477600 - Part 1: Support installing temporary extension. r=jdescottes
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Tue, 14 Aug 2018 10:30:11 +0900
changeset 432045 1889060c3412b13d3f75685a96002e6c9ac7f559
parent 432044 17adf3f924cc0c3be2efeccf648baf3d5ee5032e
child 432046 86e6704908fde59a926376f6e42161d749e80765
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 1: Support installing temporary extension. r=jdescottes Differential Revision: https://phabricator.services.mozilla.com/D3271
devtools/client/aboutdebugging-new/src/actions/runtime.js
devtools/client/aboutdebugging-new/src/components/RuntimePage.js
devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionInstaller.js
devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
--- a/devtools/client/aboutdebugging-new/src/actions/runtime.js
+++ b/devtools/client/aboutdebugging-new/src/actions/runtime.js
@@ -1,16 +1,18 @@
 /* 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 { 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 {
   CONNECT_RUNTIME_FAILURE,
   CONNECT_RUNTIME_START,
   CONNECT_RUNTIME_SUCCESS,
   DEBUG_TARGETS,
@@ -82,16 +84,43 @@ function inspectDebugTarget(type, id) {
   } else {
     console.error(`Failed to inspect the debug target of type: ${ type } id: ${ id }`);
   }
 
   // We cancel the redux flow here since the inspection does not need to update the state.
   return () => {};
 }
 
+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;
+    }
+
+    try {
+      await AddonManager.installTemporaryAddon(file);
+    } catch (e) {
+      console.error(e);
+    }
+  });
+
+  return () => {};
+}
+
 function requestTabs() {
   return async (dispatch, getState) => {
     dispatch({ type: REQUEST_TABS_START });
 
     const client = getState().runtime.client;
 
     try {
       const { tabs } = await client.listTabs({ favicons: true });
@@ -125,11 +154,12 @@ function requestExtensions() {
     }
   };
 }
 
 module.exports = {
   connectRuntime,
   disconnectRuntime,
   inspectDebugTarget,
+  installTemporaryExtension,
   requestTabs,
   requestExtensions,
 };
--- a/devtools/client/aboutdebugging-new/src/components/RuntimePage.js
+++ b/devtools/client/aboutdebugging-new/src/components/RuntimePage.js
@@ -6,16 +6,18 @@
 
 const { connect } = require("devtools/client/shared/vendor/react-redux");
 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 DebugTargetPane = createFactory(require("./DebugTargetPane"));
 const RuntimeInfo = createFactory(require("./RuntimeInfo"));
+const TemporaryExtensionInstaller =
+  createFactory(require("./debugtarget/TemporaryExtensionInstaller"));
 
 const Services = require("Services");
 
 class RuntimePage extends PureComponent {
   static get propTypes() {
     return {
       dispatch: PropTypes.func.isRequired,
       installedExtensions: PropTypes.arrayOf(PropTypes.object).isRequired,
@@ -31,16 +33,17 @@ class RuntimePage extends PureComponent 
       {
         className: "page",
       },
       RuntimeInfo({
         icon: "chrome://branding/content/icon64.png",
         name: Services.appinfo.name,
         version: Services.appinfo.version,
       }),
+      TemporaryExtensionInstaller({ dispatch }),
       DebugTargetPane({
         dispatch,
         name: "Temporary Extensions",
         targets: temporaryExtensions,
       }),
       DebugTargetPane({
         dispatch,
         name: "Extensions",
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/TemporaryExtensionInstaller.js
@@ -0,0 +1,38 @@
+/* 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 an installer for temporary extension.
+ */
+class TemporaryExtensionInstaller extends PureComponent {
+  static get propTypes() {
+    return {
+      dispatch: PropTypes.func.isRequired,
+    };
+  }
+
+  install() {
+    this.props.dispatch(Actions.installTemporaryExtension());
+  }
+
+  render() {
+    return dom.button(
+      {
+        className: "aboutdebugging-button",
+        onClick: e => this.install()
+      },
+      "Load Temporary Add-on…"
+    );
+  }
+}
+
+module.exports = TemporaryExtensionInstaller;
--- a/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
+++ b/devtools/client/aboutdebugging-new/src/components/debugtarget/moz.build
@@ -1,9 +1,10 @@
 # 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',
+    'TemporaryExtensionInstaller.js',
 )