Bug 1471795 - Part 9: Update tab list ui when the actual tabs were changed. r?jdescottes draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Thu, 19 Jul 2018 17:16:53 +0900
changeset 820258 7d7a5c8aca027013c2cc42b030dcb80e28156f3e
parent 820257 5c5041fec319cc4b0b330b9a7f8ca04ca3cca9b1
child 820259 2848a3b8240f3573c15c4244a4c3c610dd01e752
push id116772
push userbmo:dakatsuka@mozilla.com
push dateThu, 19 Jul 2018 09:51:56 +0000
reviewersjdescottes
bugs1471795
milestone63.0a1
Bug 1471795 - Part 9: Update tab list ui when the actual tabs were changed. r?jdescottes MozReview-Commit-ID: D6f02k55k8U
devtools/client/aboutdebugging-new/src/components/DebugTargetsPane.js
devtools/client/aboutdebugging-new/src/runtimes/runtime.js
devtools/client/aboutdebugging-new/src/runtimes/this-firefox.js
--- a/devtools/client/aboutdebugging-new/src/components/DebugTargetsPane.js
+++ b/devtools/client/aboutdebugging-new/src/components/DebugTargetsPane.js
@@ -18,45 +18,59 @@ class DebugTargetsPane extends PureCompo
   static get propTypes() {
     return {
       runtime: PropTypes.instanceOf(Runtime).isRequired,
     };
   }
 
   constructor(props) {
     super(props);
+
+    this.onTabsUpdated = this.onTabsUpdated.bind(this);
+
     this.state = {
       info: {},
       tabs: [],
     };
     this.update(props.runtime);
   }
 
   componentDidUpdate(prevProps) {
     if (prevProps.runtime !== this.props.runtime) {
+      prevProps.runtime.removeTabsUpdateListener(this.onTabsUpdated);
       this.update(this.props.runtime);
     }
   }
 
+  componentWillUnmount() {
+    this.props.runtime.removeTabsUpdateListener(this.onTabsUpdated);
+  }
+
   update(runtime) {
     this.updateRuntimeInfo(runtime);
     this.updateTabs(runtime);
+
+    runtime.addTabsUpdateListener(this.onTabsUpdated);
   }
 
   async updateRuntimeInfo(runtime) {
     const info = await runtime.getRuntimeInfo(runtime);
     this.setState({ info });
   }
 
   async updateTabs(runtime) {
     // Filter out closed tabs (represented as `null`).
     const tabs = (await runtime.getTabs()).filter(t => !!t);
     this.setState({ tabs });
   }
 
+  onTabsUpdated() {
+    this.updateTabs(this.props.runtime);
+  }
+
   render() {
     const { runtime } = this.props;
     const {
       info,
       tabs,
     } = this.state;
 
     return dom.div(
--- a/devtools/client/aboutdebugging-new/src/runtimes/runtime.js
+++ b/devtools/client/aboutdebugging-new/src/runtimes/runtime.js
@@ -4,16 +4,25 @@
 
 "use strict";
 
 /**
  * This class represents a runtime, such as a remote Firefox.
  */
 class Runtime {
   /**
+   * Add a tab update listener to detect tabs change.
+   * Subclass should override this method.
+   * @param {function}
+   */
+  addTabsUpdateListener(listener) {
+    throw new Error("Subclass of Runtime should override addTabsUpdateListener()");
+  }
+
+  /**
    * Connect to this runtime.
    * Subclass should override this method.
    */
   async connect() {
     throw new Error("Subclass of Runtime should override connect()");
   }
 
   /**
@@ -45,11 +54,20 @@ class Runtime {
   /**
    * Inspect the provided tab target which can get by getTabs().
    * Subclass should override this method.
    * @param {Object} - debug target
    */
   async inspectTab(_) {
     throw new Error("Subclass of Runtime should override inspectTab()");
   }
+
+  /**
+   * Remove a tab update listener.
+   * Subclass should override this method.
+   * @param {function}
+   */
+  removeTabsUpdateListener(listener) {
+    throw new Error("Subclass of Runtime should override removeTabsUpdateListener()");
+  }
 }
 
 module.exports = Runtime;
--- a/devtools/client/aboutdebugging-new/src/runtimes/this-firefox.js
+++ b/devtools/client/aboutdebugging-new/src/runtimes/this-firefox.js
@@ -10,16 +10,20 @@ const Services = require("Services");
 
 const Runtime = require("./runtime");
 
 /**
  * This class represents the Firefox instance which runs in the same environment that
  * opened about:debugging.
  */
 class ThisFirefox extends Runtime {
+  addTabsUpdateListener(listener) {
+    this.client.addListener("tabListChanged", listener);
+  }
+
   async connect() {
     // Setup a server if we don't have one already running
     DebuggerServer.init();
     DebuggerServer.registerAllActors();
     const transport = DebuggerServer.connectPipe();
     this.client = new DebuggerClient(transport);
     return this.client.connect();
   }
@@ -35,11 +39,15 @@ class ThisFirefox extends Runtime {
   async getTabs() {
     const { tabs } = await this.client.listTabs({ favicons: true });
     return tabs;
   }
 
   async inspectTab(debugTarget) {
     window.open(`about:devtools-toolbox?type=tab&id=${ debugTarget.outerWindowID }`);
   }
+
+  removeTabsUpdateListener(listener) {
+    this.client.removeListener("tabListChanged", listener);
+  }
 }
 
 module.exports = ThisFirefox;