Bug 1240804 - Ignore actions dispatched after RDM close. r=me
authorJ. Ryan Stinnett <jryans@gmail.com>
Wed, 30 Mar 2016 11:13:40 -0500
changeset 291338 76e4e7620f839730994c6b9242ed78b648795409
parent 291337 57e1fe3dfc6da778da6ac4b3349d5e0293a214f3
child 291339 587a80aed81e49b6c7df3117b66d15e2793b9406
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1240804
milestone48.0a1
Bug 1240804 - Ignore actions dispatched after RDM close. r=me MozReview-Commit-ID: Kby5Zy4jeZ2
devtools/client/responsive.html/index.js
devtools/client/responsive.html/test/browser/head.js
--- a/devtools/client/responsive.html/index.js
+++ b/devtools/client/responsive.html/index.js
@@ -42,34 +42,54 @@ let bootstrap = {
               "agent");
     this.telemetry.toolOpened("responsive");
     let store = this.store = Store();
     let app = App({
       onExit: () => window.postMessage({ type: "exit" }, "*"),
     });
     let provider = createElement(Provider, { store }, app);
     ReactDOM.render(provider, document.querySelector("#root"));
+    this.initDevices();
     window.postMessage({ type: "init" }, "*");
   },
 
   destroy() {
     this.store = null;
     this.telemetry.toolClosed("responsive");
     this.telemetry = null;
   },
 
   /**
    * While most actions will be dispatched by React components, some external
    * APIs that coordinate with the larger browser UI may also have actions to
    * to dispatch.  They can do so here.
    */
   dispatch(action) {
+    if (!this.store) {
+      // If actions are dispatched after store is destroyed, ignore them.  This
+      // can happen in tests that close the tool quickly while async tasks like
+      // initDevices() below are still pending.
+      return;
+    }
     this.store.dispatch(action);
   },
 
+  initDevices() {
+    GetDevices().then(devices => {
+      for (let type of devices.TYPES) {
+        this.dispatch(addDeviceType(type));
+        for (let device of devices[type]) {
+          if (device.os != "fxos") {
+            this.dispatch(addDevice(device, type));
+          }
+        }
+      }
+    });
+  },
+
 };
 
 window.addEventListener("load", function onLoad() {
   window.removeEventListener("load", onLoad);
   bootstrap.init();
 });
 
 window.addEventListener("unload", function onUnload() {
@@ -87,25 +107,13 @@ Object.defineProperty(window, "store", {
 });
 
 /**
  * Called by manager.js to add the initial viewport based on the original page.
  */
 window.addInitialViewport = contentURI => {
   try {
     bootstrap.dispatch(changeLocation(contentURI));
-
-    GetDevices().then(devices => {
-      for (let type of devices.TYPES) {
-        bootstrap.dispatch(addDeviceType(type));
-        for (let device of devices[type]) {
-          if (device.os != "fxos") {
-            bootstrap.dispatch(addDevice(device, type));
-          }
-        }
-      }
-    });
-
     bootstrap.dispatch(addViewport());
   } catch (e) {
     console.error(e);
   }
 };
--- a/devtools/client/responsive.html/test/browser/head.js
+++ b/devtools/client/responsive.html/test/browser/head.js
@@ -11,16 +11,18 @@ Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
   this);
 Services.scriptloader.loadSubScript(
   "chrome://mochitests/content/browser/devtools/client/framework/test/shared-redux-head.js",
   this);
 
 const TEST_URI_ROOT = "http://example.com/browser/devtools/client/responsive.html/test/browser/";
 
+SimpleTest.requestCompleteLog();
+
 DevToolsUtils.testing = true;
 Services.prefs.setCharPref("devtools.devices.url",
   TEST_URI_ROOT + "devices.json");
 Services.prefs.setBoolPref("devtools.responsive.html.enabled", true);
 
 registerCleanupFunction(() => {
   DevToolsUtils.testing = false;
   Services.prefs.clearUserPref("devtools.devices.url");