Bug 1399242 - Ensure firing visibilitychange event and set document.visibiltyState attribute when hidding devtools panels. r=gregtatum draft
authorAlexandre Poirot <poirot.alex@gmail.com>
Mon, 09 Oct 2017 20:16:01 +0200
changeset 700621 d4cf1e8376870d90d9b0ed0fc02038bd2e796a03
parent 700620 a77b600a6f1a2b8dc3475db0b8a3833e315dc2fb
child 700622 9206292300557b1ed1b07d26bd57572a67ec25a2
push id89914
push userbmo:poirot.alex@gmail.com
push dateMon, 20 Nov 2017 16:31:08 +0000
reviewersgregtatum
bugs1399242
milestone59.0a1
Bug 1399242 - Ensure firing visibilitychange event and set document.visibiltyState attribute when hidding devtools panels. r=gregtatum MozReview-Commit-ID: Gh6jp4KEZkX
devtools/client/framework/toolbox.js
--- a/devtools/client/framework/toolbox.js
+++ b/devtools/client/framework/toolbox.js
@@ -1750,20 +1750,54 @@ Toolbox.prototype = {
     [...collection].forEach(node => {
       if (node.id === id) {
         node.setAttribute("selected", "true");
         node.setAttribute("aria-selected", "true");
       } else {
         node.removeAttribute("selected");
         node.removeAttribute("aria-selected");
       }
+      // The webconsole panel is in a special location due to split console
+      if (!node.id) {
+        node = this.webconsolePanel;
+      }
+
+      let iframe = node.querySelector(".toolbox-panel-iframe");
+      if (iframe) {
+        let visible = node.id == id;
+        this.setIframeVisible(iframe, visible);
+      }
     });
   },
 
   /**
+   * Make a privileged iframe visible/hidden.
+   *
+   * For now, XUL Iframes loading chrome documents (i.e. <iframe type!="content" />)
+   * can't be hidden at platform level. And so don't support 'visibilitychange' event.
+   *
+   * This helper workarounds that by at least being able to send these kind of events.
+   * It will help panel react differently depending on them being displayed or in
+   * background.
+   */
+  setIframeVisible: function (iframe, visible) {
+    let state = visible ? "visible" : "hidden";
+    let win = iframe.contentWindow;
+    let doc = win.document;
+    if (doc.visibilityState != state) {
+      // 1) Overload document's `visibilityState` attribute
+      // Use defineProperty, as by default `document.visbilityState` is read only.
+      Object.defineProperty(doc, "visibilityState", { value: state, configurable: true });
+
+      // 2) Fake the 'visibilitychange' event
+      win.dispatchEvent(new win.Event("visibilitychange"));
+    }
+  },
+
+  /**
    * Switch to the tool with the given id
    *
    * @param {string} id
    *        The id of the tool to switch to
    */
   selectTool: function (id) {
     this.emit("before-select", id);