diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css index c251625b955..f45ef977ff3 100644 --- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -122,7 +122,6 @@ tabbrowser { visibility: hidden; } -.tab-close-button, .tab-background { /* Explicitly set the visibility to override the value (collapsed) * we inherit from #TabsToolbar[collapsed] upon opening a browser window. */ @@ -131,15 +130,26 @@ tabbrowser { transition: visibility 0ms 25ms; } -.tab-close-button:not([fadein]):not([pinned]), .tab-background:not([fadein]):not([pinned]) { visibility: hidden; /* Closing tabs are hidden without a delay. */ transition-delay: 0ms; } +.tab-close-button[fadein], +.tab-label[fadein] { + transition: opacity 70ms; +} + +.tab-close-button[fullyopen]:not([fadeinlabel]), +.tab-label[fullyopen]:not([fadeinlabel]) { + visibility: hidden; + opacity: .6; +} + .tab-throbber:not([fadein]):not([pinned]), -.tab-label:not([fadein]):not([pinned]), +.tab-label:not([fullyopen]):not([pinned]), +.tab-close-button:not([fullyopen]):not([pinned]), .tab-icon-image:not([fadein]):not([pinned]) { display: none; } diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 7e8d24241b5..2bc3174ec9e 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -1862,6 +1862,7 @@ this._blurTab(aTab); aTab.style.maxWidth = ""; // ensure that fade-out transition happens aTab.removeAttribute("fadein"); + aTab._fullyOpen = false; if (this.tabs.length - this._removingTabs.length == 1) { // The second tab just got closed and we will end up with a single @@ -3043,6 +3044,7 @@ this.mCurrentTab.linkedPanel = uniqueId; this.mCurrentTab._tPos = 0; this.mCurrentTab._fullyOpen = true; + this.mCurrentTab.setAttribute("fadeinlabel", "true"); this.mCurrentTab.linkedBrowser = this.mCurrentBrowser; // set up the shared autoscroll popup @@ -4063,6 +4065,8 @@ if (tab.parentNode != this) return; tab._fullyOpen = true; + tab.scrollTop; // force a layout flush as part of the fadeinlabel transition + tab.setAttribute("fadeinlabel", "true"); this.adjustTabstrip(); @@ -4702,11 +4706,11 @@ role="presentation"/> @@ -4760,6 +4764,18 @@ 0 + + + return this.getAttribute("fullyopen") == "true"; + + + if (val) { + this.setAttribute("fullyopen", "true"); + } else { + this.removeAttribute("fullyopen"); + } + + false null false diff --git a/browser/base/content/test/general/browser_tabopen_reflows.js b/browser/base/content/test/general/browser_tabopen_reflows.js index aeaf168019e..2985409b3f6 100644 --- a/browser/base/content/test/general/browser_tabopen_reflows.js +++ b/browser/base/content/test/general/browser_tabopen_reflows.js @@ -8,6 +8,10 @@ XPCOMUtils.defineLazyGetter(this, "docShell", () => { }); const EXPECTED_REFLOWS = [ + // tabbrowser._handleNewTab() flushes layout to start the label+close button fade-in + "_handleNewTab@chrome://browser/content/tabbrowser.xml|" + + "onxbltransitionend@chrome://browser/content/tabbrowser.xml|", + // tabbrowser.adjustTabstrip() call after tabopen animation has finished "adjustTabstrip@chrome://browser/content/tabbrowser.xml|" + "_handleNewTab@chrome://browser/content/tabbrowser.xml|" +