Bug 1443849 - Part 3: Get rid of the tabbrowser property, use gBrowser directly. r=Gijs draft
authorDão Gottwald <dao@mozilla.com>
Tue, 13 Mar 2018 16:13:48 +0100
changeset 766892 9b88797f191dbefa4e52749c28e326e341ca833c
parent 766891 50efff0e595e9aefcde76a126d5680609d94996a
child 766893 45dec7271435e7f7123fc03c358e48b6387d7a4c
push id102434
push userdgottwald@mozilla.com
push dateTue, 13 Mar 2018 15:21:11 +0000
reviewersGijs
bugs1443849
milestone61.0a1
Bug 1443849 - Part 3: Get rid of the tabbrowser property, use gBrowser directly. r=Gijs MozReview-Commit-ID: HaWvdDJDlmJ
browser/base/content/tabbrowser.xml
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -41,18 +41,18 @@
         }
 
         tabs.removeAttribute("overflow");
 
         if (tabs._lastTabClosedByMouse) {
           tabs._expandSpacerBy(this._scrollButtonDown.clientWidth);
         }
 
-        for (let tab of Array.from(tabs.tabbrowser._removingTabs)) {
-          tabs.tabbrowser.removeTab(tab);
+        for (let tab of Array.from(gBrowser._removingTabs)) {
+          gBrowser.removeTab(tab);
         }
 
         tabs._positionPinnedTabs();
       ]]></handler>
       <handler event="overflow"><![CDATA[
         // Ignore overflow events:
         // - from nested scrollable elements
         // - for vertical orientation
@@ -147,17 +147,17 @@
         <![CDATA[
           Services.prefs.removeObserver("privacy.userContext", this);
 
           CustomizableUI.removeListener(this);
         ]]>
       </destructor>
 
       <field name="tabbox" readonly="true">
-        this.tabbrowser.tabbox;
+        document.getElementById("tabbrowser-tabbox");
       </field>
 
       <field name="contextMenu" readonly="true">
         document.getElementById("tabContextMenu");
       </field>
 
       <field name="arrowScrollbox">
         document.getAnonymousElementByAttribute(this, "anonid", "arrowscrollbox");
@@ -172,22 +172,16 @@
       <field name="restoreTabsButton">
         document.getAnonymousElementByAttribute(this, "anonid", "restore-tabs-button");
       </field>
       <field name="_restoreTabsButtonWrapperWidth">0</field>
       <field name="windowUtils">
         window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
       </field>
 
-      <property name="tabbrowser" readonly="true">
-        <getter>
-          return window.gBrowser;
-        </getter>
-      </property>
-
       <property name="_tabMinWidth">
         <setter>
           this.style.setProperty("--tab-min-width", val + "px");
           return val;
         </setter>
       </property>
 
       <property name="restoreTabsButtonWrapperWidth" readonly="true">
@@ -400,20 +394,21 @@
             gTabBrowserBundle.GetStringFromName(visible ? "tabs.closeTab" : "tabs.close"));
 
           TabsInTitlebar.allowedBy("tabs-visible", visible);
         ]]></body>
       </method>
 
       <method name="updateVisibility">
         <body><![CDATA[
-          if (this.childNodes.length - this.tabbrowser._removingTabs.length == 1)
+          if (this.childNodes.length - gBrowser._removingTabs.length == 1) {
             this.visible = window.toolbar.visible;
-          else
+          } else {
             this.visible = true;
+          }
         ]]></body>
       </method>
 
       <field name="_closeButtonsUpdatePending">false</field>
       <method name="_updateCloseButtons">
         <body><![CDATA[
           // If we're overflowing, tabs are at their minimum widths.
           if (this.getAttribute("overflow") == "true") {
@@ -483,80 +478,82 @@
           let tabs = this._getVisibleTabs();
           if (!tabs.length) {
             return;
           }
 
           var isEndTab = (aTab._tPos > tabs[tabs.length - 1]._tPos);
           var tabWidth = aTab.getBoundingClientRect().width;
 
-          if (!this._tabDefaultMaxWidth)
+          if (!this._tabDefaultMaxWidth) {
             this._tabDefaultMaxWidth =
               parseFloat(window.getComputedStyle(aTab).maxWidth);
+          }
           this._lastTabClosedByMouse = true;
 
           if (this.getAttribute("overflow") == "true") {
             // Don't need to do anything if we're in overflow mode and aren't scrolled
             // all the way to the right, or if we're closing the last tab.
-            if (isEndTab || !this.arrowScrollbox._scrollButtonDown.disabled)
+            if (isEndTab || !this.arrowScrollbox._scrollButtonDown.disabled) {
               return;
-
+            }
             // If the tab has an owner that will become the active tab, the owner will
             // be to the left of it, so we actually want the left tab to slide over.
             // This can't be done as easily in non-overflow mode, so we don't bother.
-            if (aTab.owner)
+            if (aTab.owner) {
               return;
-
+            }
             this._expandSpacerBy(tabWidth);
           } else { // non-overflow mode
             // Locking is neither in effect nor needed, so let tabs expand normally.
-            if (isEndTab && !this._hasTabTempMaxWidth)
+            if (isEndTab && !this._hasTabTempMaxWidth) {
               return;
-
-            let numPinned = this.tabbrowser._numPinnedTabs;
+            }
+            let numPinned = gBrowser._numPinnedTabs;
             // Force tabs to stay the same width, unless we're closing the last tab,
             // which case we need to let them expand just enough so that the overall
             // tabbar width is the same.
             if (isEndTab) {
               let numNormalTabs = tabs.length - numPinned;
               tabWidth = tabWidth * (numNormalTabs + 1) / numNormalTabs;
-              if (tabWidth > this._tabDefaultMaxWidth)
+              if (tabWidth > this._tabDefaultMaxWidth) {
                 tabWidth = this._tabDefaultMaxWidth;
+              }
             }
             tabWidth += "px";
             for (let i = numPinned; i < tabs.length; i++) {
               let tab = tabs[i];
               tab.style.setProperty("max-width", tabWidth, "important");
               if (!isEndTab) { // keep tabs the same width
                 tab.style.transition = "none";
                 tab.clientTop; // flush styles to skip animation; see bug 649247
                 tab.style.transition = "";
               }
             }
             this._hasTabTempMaxWidth = true;
-            this.tabbrowser.addEventListener("mousemove", this);
+            gBrowser.addEventListener("mousemove", this);
             window.addEventListener("mouseout", this);
           }
         ]]></body>
       </method>
 
       <method name="_expandSpacerBy">
         <parameter name="pixels"/>
         <body><![CDATA[
           let spacer = this._closingTabsSpacer;
           spacer.style.width = parseFloat(spacer.style.width) + pixels + "px";
           this.setAttribute("using-closing-tabs-spacer", "true");
-          this.tabbrowser.addEventListener("mousemove", this);
+          gBrowser.addEventListener("mousemove", this);
           window.addEventListener("mouseout", this);
         ]]></body>
       </method>
 
       <method name="_unlockTabSizing">
         <body><![CDATA[
-          this.tabbrowser.removeEventListener("mousemove", this);
+          gBrowser.removeEventListener("mousemove", this);
           window.removeEventListener("mouseout", this);
 
           if (this._hasTabTempMaxWidth) {
             this._hasTabTempMaxWidth = false;
             let tabs = this._getVisibleTabs();
             for (let i = 0; i < tabs.length; i++) {
               tabs[i].style.maxWidth = "";
             }
@@ -894,20 +891,21 @@
           }
           return "none";
         ]]></body>
       </method>
 
       <method name="_handleNewTab">
         <parameter name="tab"/>
         <body><![CDATA[
-          if (tab.parentNode != this)
+          if (tab.parentNode != this) {
             return;
+          }
           tab._fullyOpen = true;
-          this.tabbrowser.tabAnimationsInProgress--;
+          gBrowser.tabAnimationsInProgress--;
 
           this._updateCloseButtons();
 
           if (tab.getAttribute("selected") == "true") {
             this._handleTabSelect();
           } else if (!tab.hasAttribute("skipbackgroundnotify")) {
             this._notifyBackgroundTab(tab);
           }
@@ -915,17 +913,17 @@
           // XXXmano: this is a temporary workaround for bug 345399
           // We need to manually update the scroll buttons disabled state
           // if a tab was inserted to the overflow area or removed from it
           // without any scrolling and when the tabbar has already
           // overflowed.
           this.arrowScrollbox._updateScrollButtonsDisabledState();
 
           // Preload the next about:newtab if there isn't one already.
-          this.tabbrowser._createPreloadBrowser();
+          gBrowser._createPreloadBrowser();
         ]]></body>
       </method>
 
       <method name="_canAdvanceToTab">
         <parameter name="aTab"/>
         <body>
         <![CDATA[
           return !aTab.closing;
@@ -1006,28 +1004,30 @@
         ]]></body>
       </method>
     </implementation>
 
     <handlers>
       <handler event="TabSelect" action="this._handleTabSelect();"/>
 
       <handler event="transitionend"><![CDATA[
-        if (event.propertyName != "max-width")
+        if (event.propertyName != "max-width") {
           return;
+        }
 
         var tab = event.target;
 
         if (tab.getAttribute("fadein") == "true") {
-          if (tab._fullyOpen)
+          if (tab._fullyOpen) {
             this._updateCloseButtons();
-          else
+          } else {
             this._handleNewTab(tab);
+          }
         } else if (tab.closing) {
-          this.tabbrowser._endRemoveTab(tab);
+          gBrowser._endRemoveTab(tab);
         }
       ]]></handler>
 
       <handler event="dblclick"><![CDATA[
         // When the tabbar has an unified appearance with the titlebar
         // and menubar, a double-click in it should have the same behavior
         // as double-clicking the titlebar
         if (TabsInTitlebar.enabled || this.parentNode._dragBindingAlive)
@@ -1093,31 +1093,34 @@
             return;
           }
           delete this._clickedTabBarOnce;
           this._blockDblClick = false;
         }
       ]]></handler>
 
       <handler event="click"><![CDATA[
-        if (event.button != 1)
+        if (event.button != 1) {
           return;
+        }
 
         if (event.target.localName == "tab") {
-          this.tabbrowser.removeTab(event.target, {animate: true,
-                byMouse: event.mozInputSource == MouseEvent.MOZ_SOURCE_MOUSE});
+          gBrowser.removeTab(event.target, {
+            animate: true,
+            byMouse: event.mozInputSource == MouseEvent.MOZ_SOURCE_MOUSE,
+          });
         } else if (event.originalTarget.localName == "box") {
           // The user middleclicked an open space on the tabstrip. This could
           // be because they intend to open a new tab, but it could also be
           // because they just removed a tab and they now middleclicked on the
           // resulting space while that tab is closing. In that case, we don't
           // want to open a tab. So if we're removing one or more tabs, and
           // the tab click is before the end of the last visible tab, we do
           // nothing.
-          if (this.tabbrowser._removingTabs.length) {
+          if (gBrowser._removingTabs.length) {
             let visibleTabs = this._getVisibleTabs();
             let ltr = (window.getComputedStyle(this).direction == "ltr");
             let lastTab = visibleTabs[visibleTabs.length - 1];
             let endOfTab = lastTab.getBoundingClientRect()[ltr ? "right" : "left"];
             if ((ltr && event.clientX > endOfTab) ||
                 (!ltr && event.clientX < endOfTab)) {
               BrowserOpenTab();
             }
@@ -1145,30 +1148,30 @@
         if (wrongModifiers)
           return;
 
         // Don't check if the event was already consumed because tab navigation
         // should work always for better user experience.
 
         switch (event.keyCode) {
           case KeyEvent.DOM_VK_UP:
-            this.tabbrowser.moveTabBackward();
+            gBrowser.moveTabBackward();
             break;
           case KeyEvent.DOM_VK_DOWN:
-            this.tabbrowser.moveTabForward();
+            gBrowser.moveTabForward();
             break;
           case KeyEvent.DOM_VK_RIGHT:
           case KeyEvent.DOM_VK_LEFT:
-            this.tabbrowser.moveTabOver(event);
+            gBrowser.moveTabOver(event);
             break;
           case KeyEvent.DOM_VK_HOME:
-            this.tabbrowser.moveTabToStart();
+            gBrowser.moveTabToStart();
             break;
           case KeyEvent.DOM_VK_END:
-            this.tabbrowser.moveTabToEnd();
+            gBrowser.moveTabToEnd();
             break;
           default:
             // Consume the keydown event for the above keyboard
             // shortcuts only.
             return;
         }
         event.preventDefault();
       ]]></handler>
@@ -1377,64 +1380,67 @@
             return;
         }
 
         this._tabDropIndicator.collapsed = true;
         event.stopPropagation();
         if (draggedTab && dropEffect == "copy") {
           // copy the dropped tab (wherever it's from)
           let newIndex = this._getDropIndex(event, false);
-          let newTab = this.tabbrowser.duplicateTab(draggedTab);
-          this.tabbrowser.moveTabTo(newTab, newIndex);
-          if (draggedTab.parentNode != this || event.shiftKey)
+          let newTab = gBrowser.duplicateTab(draggedTab);
+          gBrowser.moveTabTo(newTab, newIndex);
+          if (draggedTab.parentNode != this || event.shiftKey) {
             this.selectedItem = newTab;
+          }
         } else if (draggedTab && draggedTab.parentNode == this) {
           let oldTranslateX = Math.round(draggedTab._dragData.translateX);
           let tabWidth = Math.round(draggedTab._dragData.tabWidth);
           let translateOffset = oldTranslateX % tabWidth;
           let newTranslateX = oldTranslateX - translateOffset;
           if (oldTranslateX > 0 && translateOffset > tabWidth / 2) {
             newTranslateX += tabWidth;
           } else if (oldTranslateX < 0 && -translateOffset > tabWidth / 2) {
             newTranslateX -= tabWidth;
           }
 
           let dropIndex = "animDropIndex" in draggedTab._dragData &&
                           draggedTab._dragData.animDropIndex;
           if (dropIndex && dropIndex > draggedTab._tPos)
             dropIndex--;
 
-          let animate = this.tabbrowser.animationsEnabled;
+          let animate = gBrowser.animationsEnabled;
           if (oldTranslateX && oldTranslateX != newTranslateX && animate) {
             draggedTab.setAttribute("tabdrop-samewindow", "true");
             draggedTab.style.transform = "translateX(" + newTranslateX + "px)";
             let onTransitionEnd = transitionendEvent => {
               if (transitionendEvent.propertyName != "transform" ||
                   transitionendEvent.originalTarget != draggedTab) {
                 return;
               }
               draggedTab.removeEventListener("transitionend", onTransitionEnd);
 
               draggedTab.removeAttribute("tabdrop-samewindow");
 
               this._finishAnimateTabMove();
-              if (dropIndex !== false)
-                this.tabbrowser.moveTabTo(draggedTab, dropIndex);
+              if (dropIndex !== false) {
+                gBrowser.moveTabTo(draggedTab, dropIndex);
+              }
 
-              this.tabbrowser.syncThrobberAnimations(draggedTab);
+              gBrowser.syncThrobberAnimations(draggedTab);
             };
             draggedTab.addEventListener("transitionend", onTransitionEnd);
           } else {
             this._finishAnimateTabMove();
-            if (dropIndex !== false)
-              this.tabbrowser.moveTabTo(draggedTab, dropIndex);
+            if (dropIndex !== false) {
+              gBrowser.moveTabTo(draggedTab, dropIndex);
+            }
           }
         } else if (draggedTab) {
           let newIndex = this._getDropIndex(event, false);
-          this.tabbrowser.adoptTab(draggedTab, newIndex, true);
+          gBrowser.adoptTab(draggedTab, newIndex, true);
         } else {
           // Pass true to disallow dropping javascript: or data: urls
           let links;
           try {
             links = browserDragAndDrop.dropLinks(event, true);
           } catch (ex) {}
 
           if (!links || links.length === 0)
@@ -1457,17 +1463,17 @@
               // Sync dialog cannot be used inside drop event handler.
               let answer = await OpenInTabsUtils.promiseConfirmOpenInTabs(urls.length,
                                                                           window);
               if (!answer) {
                 return;
               }
             }
 
-            this.tabbrowser.loadTabs(urls, {
+            gBrowser.loadTabs(urls, {
               inBackground,
               replace,
               allowThirdPartyFixup: true,
               targetTab,
               newIndex,
               userContextId,
               triggeringPrincipal,
             });
@@ -1538,30 +1544,30 @@
         var winHeight = Math.min(window.outerHeight, availHeight.value);
         var left = Math.min(Math.max(eX - draggedTab._dragData.offsetX, availX.value),
                             availX.value + availWidth.value - winWidth);
         var top = Math.min(Math.max(eY - draggedTab._dragData.offsetY, availY.value),
                            availY.value + availHeight.value - winHeight);
 
         delete draggedTab._dragData;
 
-        if (this.tabbrowser.tabs.length == 1) {
+        if (gBrowser.tabs.length == 1) {
           // resize _before_ move to ensure the window fits the new screen.  if
           // the window is too large for its screen, the window manager may do
           // automatic repositioning.
           window.resizeTo(winWidth, winHeight);
           window.moveTo(left, top);
           window.focus();
         } else {
           let props = { screenX: left, screenY: top, suppressanimation: 1 };
           if (AppConstants.platform != "win") {
             props.outerWidth = winWidth;
             props.outerHeight = winHeight;
           }
-          this.tabbrowser.replaceTabWithWindow(draggedTab, props);
+          gBrowser.replaceTabWithWindow(draggedTab, props);
         }
         event.stopPropagation();
       ]]></handler>
 
       <handler event="dragexit"><![CDATA[
         this._dragTime = 0;
 
         // This does not work at all (see bug 458613)
@@ -1808,19 +1814,19 @@
             this.startUnselectedTabHoverTimer();
           }
 
           // Prepare connection to host beforehand.
           SessionStore.speculativeConnectOnTabHover(this);
 
           let tabToWarm = this;
           if (this.mOverCloseButton) {
-            tabToWarm = tabContainer.tabbrowser._findTabToBlurTo(this);
+            tabToWarm = gBrowser._findTabToBlurTo(this);
           }
-          tabContainer.tabbrowser.warmupTab(tabToWarm);
+          gBrowser.warmupTab(tabToWarm);
         ]]></body>
       </method>
 
       <method name="_mouseleave">
         <body><![CDATA[
           let tabContainer = this.parentNode;
           if (tabContainer._beforeHoveredTab) {
             tabContainer._beforeHoveredTab.removeAttribute("beforehovered");
@@ -1900,17 +1906,16 @@
         <parameter name="aMuteReason"/>
         <body>
         <![CDATA[
           // Do not attempt to toggle mute state if browser is lazy.
           if (!this.linkedPanel) {
             return;
           }
 
-          let tabContainer = this.parentNode;
           let browser = this.linkedBrowser;
           let modifiedAttrs = [];
           let hist = Services.telemetry.getHistogramById("TAB_AUDIO_INDICATOR_USED");
 
           if (this.hasAttribute("activemedia-blocked")) {
             this.removeAttribute("activemedia-blocked");
             modifiedAttrs.push("activemedia-blocked");
 
@@ -1927,17 +1932,17 @@
               browser.mute();
               this.setAttribute("muted", "true");
               BrowserUITelemetry.countTabMutingEvent("mute", aMuteReason);
               hist.add(0 /* mute */);
             }
             this.muteReason = aMuteReason || null;
             modifiedAttrs.push("muted");
           }
-          tabContainer.tabbrowser._tabAttrModified(this, modifiedAttrs);
+          gBrowser._tabAttrModified(this, modifiedAttrs);
         ]]>
         </body>
       </method>
 
       <method name="setUserContextId">
         <parameter name="aUserContextId"/>
         <body>
         <![CDATA[
@@ -2002,22 +2007,23 @@
 
       <handler event="click" button="0"><![CDATA[
         if (this._overPlayingIcon) {
           this.toggleMuteAudio();
           return;
         }
 
         if (event.originalTarget.getAttribute("anonid") == "close-button") {
-          let tabContainer = this.parentNode;
-          tabContainer.tabbrowser.removeTab(this, {animate: true,
-                  byMouse: event.mozInputSource == MouseEvent.MOZ_SOURCE_MOUSE});
+          gBrowser.removeTab(this, {
+            animate: true,
+            byMouse: event.mozInputSource == MouseEvent.MOZ_SOURCE_MOUSE,
+          });
           // This enables double-click protection for the tab container
           // (see tabbrowser-tabs 'click' handler).
-          tabContainer._blockDblClick = true;
+          gBrowser.tabContainer._blockDblClick = true;
         }
       ]]></handler>
 
       <handler event="dblclick" button="0" phase="capturing"><![CDATA[
         // for the one-close-button case
         if (event.originalTarget.getAttribute("anonid") == "close-button") {
           event.stopPropagation();
         }