Bug 1470865 - Dynamically show hidden audio tabs in all tabs menu r?dao draft
authorMark Striemer <mstriemer@mozilla.com>
Wed, 11 Jul 2018 22:30:36 -0500
changeset 826353 053b9f562cde6fbf022402f2e16c73aed8e92dfb
parent 824825 08753fa05058dc1ac0f5e3100eb6f412967dab75
push id118304
push userbmo:mstriemer@mozilla.com
push dateFri, 03 Aug 2018 17:46:19 +0000
reviewersdao
bugs1470865
milestone63.0a1
Bug 1470865 - Dynamically show hidden audio tabs in all tabs menu r?dao When a hidden audio tab is muted it isn't pulled into the main all tabs panel. Unmuting that tab will now add it to the main all tabs panel, even if the all tabs menu it open. MozReview-Commit-ID: 2HtZvy7aBsG
browser/modules/TabsList.jsm
--- a/browser/modules/TabsList.jsm
+++ b/browser/modules/TabsList.jsm
@@ -62,35 +62,26 @@ class TabsListBase {
   /*
    * Populate the popup with menuitems and setup the listeners.
    */
   _populate(event) {
     let fragment = this.doc.createDocumentFragment();
 
     for (let tab of this.gBrowser.tabs) {
       if (this.filterFn(tab)) {
-        let row = this._createRow(tab);
-        row.tab = tab;
-        row.addEventListener("command", this);
-        this.tabToElement.set(tab, row);
-        if (this.className) {
-          row.classList.add(this.className);
-        }
-
-        fragment.appendChild(row);
+        fragment.appendChild(this._createRow(tab));
       }
     }
 
-    if (this.insertBefore) {
-      this.insertBefore.parentNode.insertBefore(fragment, this.insertBefore);
-    } else {
-      this.containerNode.appendChild(fragment);
-    }
+    this._addElement(fragment);
+    this._setupListeners();
+  }
 
-    this._setupListeners();
+  _addElement(elementOrFragment) {
+    this.containerNode.insertBefore(elementOrFragment, this.insertBefore);
   }
 
   /*
    * Remove the menuitems from the DOM, cleanup internal state and listeners.
    */
   _cleanup() {
     for (let item of this.rows) {
       item.remove();
@@ -110,21 +101,42 @@ class TabsListBase {
     this.gBrowser.tabContainer.removeEventListener("TabClose", this);
     this.listenersRegistered = false;
   }
 
   _tabAttrModified(tab) {
     let item = this.tabToElement.get(tab);
     if (item) {
       if (!this.filterFn(tab)) {
-        // If the tab is no longer in this set of tabs, hide the item.
+        // The tab no longer matches our criteria, remove it.
         this._removeItem(item, tab);
       } else {
         this._setRowAttributes(item, tab);
       }
+    } else if (this.filterFn(tab)) {
+      // The tab now matches our criteria, add a row for it.
+      this._addTab(tab);
+    }
+  }
+
+  _addTab(newTab) {
+    let newRow = this._createRow(newTab);
+    let nextTab = newTab.nextSibling;
+
+    while (nextTab && !this.filterFn(nextTab)) {
+      nextTab = nextTab.nextSibling;
+    }
+
+    if (nextTab) {
+      // If we found a tab after this one in the list, insert the new row before it.
+      let nextRow = this.tabToElement.get(nextTab);
+      nextRow.parentNode.insertBefore(newRow, nextRow);
+    } else {
+      // If there's no next tab then insert it as usual.
+      this._addElement(newRow);
     }
   }
 
   _tabClose(tab) {
     let item = this.tabToElement.get(tab);
     if (item) {
       this._removeItem(item, tab);
     }
@@ -201,16 +213,22 @@ class TabsPanel extends TabsListBase {
     super._cleanupListeners();
     this.panelMultiView.removeEventListener(TABS_PANEL_EVENTS.hide, this);
   }
 
   _createRow(tab) {
     let {doc} = this;
     let row = doc.createElementNS(NSXUL, "toolbaritem");
     row.setAttribute("class", "all-tabs-item");
+    if (this.className) {
+      row.classList.add(this.className);
+    }
+    row.tab = tab;
+    row.addEventListener("command", this);
+    this.tabToElement.set(tab, row);
 
     let button = doc.createElementNS(NSXUL, "toolbarbutton");
     button.setAttribute("class", "all-tabs-button subviewbutton subviewbutton-iconic");
     button.setAttribute("flex", "1");
     button.setAttribute("crop", "right");
     button.tab = tab;
 
     row.appendChild(button);