diff --git a/browser/base/content/browser-fullScreen.js b/browser/base/content/browser-fullScreen.js index a7aebffac..7dbe1a87b 100644 --- a/browser/base/content/browser-fullScreen.js +++ b/browser/base/content/browser-fullScreen.js @@ -604,7 +604,7 @@ var FullScreen = { } } - ToolbarIconColor.inferFromText(); + ToolbarIconColor.inferFromText("fullscreen", aEnterFS); // For Lion fullscreen, all fullscreen controls are hidden, don't // bother to touch them. If we don't stop here, the following code diff --git a/browser/base/content/browser-tabsintitlebar.js b/browser/base/content/browser-tabsintitlebar.js index 0d4d2120a..802df0be9 100644 --- a/browser/base/content/browser-tabsintitlebar.js +++ b/browser/base/content/browser-tabsintitlebar.js @@ -243,7 +243,7 @@ var TabsInTitlebar = { menubar.style.paddingBottom = ""; } - ToolbarIconColor.inferFromText(); + ToolbarIconColor.inferFromText("tabsintitlebar", TabsInTitlebar.enabled); if (CustomizationHandler.isCustomizing()) { gCustomizeMode.updateLWTStyling(); } diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 10d431181..cebdbefc7 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -5292,8 +5292,6 @@ function setToolbarVisibility(toolbar, isVisible, persist=true) { PlacesToolbarHelper.init(); BookmarkingUI.onToolbarVisibilityChange(); gBrowser.updateWindowResizers(); - if (isVisible) - ToolbarIconColor.inferFromText(); } var TabletModeUpdater = { @@ -8014,18 +8012,25 @@ function BrowserOpenNewTabOrWindow(event) { } var ToolbarIconColor = { + _windowState: { + "active": false, + "fullscreen": false, + "tabsintitlebar": false + }, init: function () { this._initialized = true; window.addEventListener("activate", this); window.addEventListener("deactivate", this); + window.addEventListener("toolbarvisibilitychange", this); Services.obs.addObserver(this, "lightweight-theme-styling-update", false); // If the window isn't active now, we assume that it has never been active // before and will soon become active such that inferFromText will be // called from the initial activate event. - if (Services.focus.activeWindow == window) - this.inferFromText(); + if (Services.focus.activeWindow == window) { + this.inferFromText("activate"); + } }, uninit: function () { @@ -8033,14 +8038,18 @@ var ToolbarIconColor = { window.removeEventListener("activate", this); window.removeEventListener("deactivate", this); + window.removeEventListener("toolbarvisibilitychange", this); Services.obs.removeObserver(this, "lightweight-theme-styling-update"); }, handleEvent: function (event) { switch (event.type) { - case "activate": + case "activate": // falls through case "deactivate": - this.inferFromText(); + this.inferFromText(event.type); + break; + case "toolbarvisibilitychange": + this.inferFromText(event.type, event.visible); break; } }, @@ -8050,32 +8059,67 @@ var ToolbarIconColor = { case "lightweight-theme-styling-update": // inferFromText needs to run after LightweightThemeConsumer.jsm's // lightweight-theme-styling-update observer. - setTimeout(() => { this.inferFromText(); }, 0); + setTimeout(() => { + this.inferFromText(aTopic); + }, 0); break; } }, - inferFromText: function () { + // a cache of luminance values for each toolbar + // to avoid unnecessary calls to getComputedStyle + _toolbarLuminanceCache: new Map(), + + inferFromText(reason, reasonValue) { if (!this._initialized) return; - function parseRGB(aColorString) { let rgb = aColorString.match(/^rgba?\((\d+), (\d+), (\d+)/); rgb.shift(); return rgb.map(x => parseInt(x)); } + switch (reason) { + case "activate": // falls through + case "deactivate": + this._windowState.active = (reason === "activate"); + break; + case "fullscreen": + this._windowState.fullscreen = reasonValue; + break; + case "lightweight-theme-styling-update": + // theme change, we'll need to recalculate all color values + this._toolbarLuminanceCache.clear(); + break; + case "toolbarvisibilitychange": + // toolbar changes dont require reset of the cached color values + break; + case "tabsintitlebar": + this._windowState.tabsintitlebar = reasonValue; + break; + } + let toolbarSelector = "#navigator-toolbox > toolbar:not([collapsed=true]):not(#addon-bar)"; //if (AppConstants.platform == "macosx") toolbarSelector += ":not([type=menubar])"; // The getComputedStyle calls and setting the brighttext are separated in // two loops to avoid flushing layout and making it dirty repeatedly. - - let luminances = new Map; + let cachedLuminances = this._toolbarLuminanceCache; + let luminances = new Map(); + let windowStateKey = JSON.stringify(this._windowState); // TenFourFox for (let toolbar of document.querySelectorAll(toolbarSelector)) { - let [r, g, b] = parseRGB(getComputedStyle(toolbar).color); - let luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b; + // toolbars *should* all have ids, but guard anyway to avoid blowing up + let cacheKey = toolbar.id && toolbar.id + windowStateKey; + // lookup cached luminance value for this toolbar in this window state + let luminance = cacheKey && cachedLuminances.get(cacheKey); + if (isNaN(luminance)) { + let [r, g, b] = parseRGB(getComputedStyle(toolbar).color); + luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b; + if (cacheKey) { + cachedLuminances.set(cacheKey, luminance); + } + } luminances.set(toolbar, luminance); }