Bug 1477597 - Part 4: Update tab list ui when the actual tabs were changed. r?jdescottes draft
authorDaisuke Akatsuka <dakatsuka@mozilla.com>
Wed, 25 Jul 2018 18:41:51 +0900
changeset 822436 d1e03135f83e593680c782fa3edf0e1fba406057
parent 822435 bbf5b5448a01bfe843d8cffdf3ab625272614235
push id117371
push userbmo:dakatsuka@mozilla.com
push dateWed, 25 Jul 2018 09:46:37 +0000
reviewersjdescottes
bugs1477597
milestone63.0a1
Bug 1477597 - Part 4: Update tab list ui when the actual tabs were changed. r?jdescottes MozReview-Commit-ID: 5WNQsOJ0sFu
devtools/client/aboutdebugging-new/aboutdebugging.js
devtools/client/aboutdebugging-new/src/runtimes/runtime.js
devtools/client/aboutdebugging-new/src/runtimes/this-firefox.js
--- a/devtools/client/aboutdebugging-new/aboutdebugging.js
+++ b/devtools/client/aboutdebugging-new/aboutdebugging.js
@@ -29,50 +29,73 @@ const App = createFactory(require("./src
 const AboutDebugging = {
   async init() {
     if (!Services.prefs.getBoolPref("devtools.enabled", true)) {
       // If DevTools are disabled, navigate to about:devtools.
       window.location = "about:devtools?reason=AboutDebugging";
       return;
     }
 
+    this.onTabsUpdated = this.onTabsUpdated.bind(this);
+
     this.store = configureStore();
     this.actions = bindActionCreators(actions, this.store.dispatch);
 
     const thisFirefox = new ThisFirefox();
     await this.updateSelectedRuntime(thisFirefox);
 
     render(Provider({ store: this.store }, App({ thisFirefox })), this.mount);
   },
 
   destroy() {
+    this.disconnecSelectedtRuntime();
     unmountComponentAtNode(this.mount);
   },
 
+  async disconnecSelectedtRuntime() {
+    const runtime = this.state.runtimes.selectedRuntime;
+
+    if (runtime) {
+      runtime.removeTabsUpdateListener(this.onTabsUpdated);
+      await runtime.disconnect();
+    }
+  },
+
   get mount() {
     return document.getElementById("mount");
   },
 
+  get state() {
+    return this.store.getState();
+  },
+
   async updateRuntimeInfo(runtime) {
     const info = await runtime.getRuntimeInfo();
     this.actions.updateRuntimeInfo(info);
   },
 
   async updateSelectedRuntime(runtime) {
+    await this.disconnecSelectedtRuntime();
     await runtime.connect();
+    runtime.addTabsUpdateListener(this.onTabsUpdated);
+
     this.actions.updateSelectedRuntime(runtime);
 
     this.updateRuntimeInfo(runtime);
     this.updateTabs(runtime);
   },
 
   async updateTabs(runtime) {
     const tabs = await runtime.getTabs();
     this.actions.updateTabs(tabs);
   },
+
+  onTabsUpdated() {
+    this.updateTabs(this.state.runtimes.selectedRuntime);
+  },
 };
 
 window.addEventListener("DOMContentLoaded", () => {
   AboutDebugging.init();
 }, { once: true });
 
 window.addEventListener("unload", () => {
   AboutDebugging.destroy();
--- 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()");
   }
 
   /**
@@ -63,11 +72,20 @@ class Runtime {
   /**
    * Inspect the provided tab target which can get by getTabs().
    * Subclass should override this method.
    * @param {Tab} - 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
@@ -11,25 +11,34 @@ const Services = require("Services");
 const Runtime = require("./runtime");
 const Tab = require("../debugtargets/tab");
 
 /**
  * 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();
   }
 
+  async disconnect() {
+    await this.client.close();
+    DebuggerServer.destroy();
+  }
+
   getIcon() {
     return "chrome://devtools/skin/images/firefox-logo-glyph.svg";
   }
 
   getName() {
     return "This Firefox";
   }
 
@@ -44,11 +53,15 @@ class ThisFirefox extends Runtime {
   async getTabs() {
     const { tabs } = await this.client.listTabs({ favicons: true });
     return tabs.map(t => new Tab(t));
   }
 
   async inspectTab(tab) {
     window.open(`about:devtools-toolbox?type=tab&id=${ tab.target.outerWindowID }`);
   }
+
+  removeTabsUpdateListener(listener) {
+    this.client.removeListener("tabListChanged", listener);
+  }
 }
 
 module.exports = ThisFirefox;