/** * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ var { AppConstants } = ChromeUtils.importESModule( "resource://gre/modules/AppConstants.sys.mjs" ); var ToolbarIconColor = { _windowState: { active: false, fullscreen: false, tabsintitlebar: false, }, init() { this._initialized = true; window.addEventListener("activate", this); window.addEventListener("deactivate", this); window.addEventListener("toolbarvisibilitychange", this); window.addEventListener("windowlwthemeupdate", this); // 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("activate"); } }, uninit() { this._initialized = false; window.removeEventListener("activate", this); window.removeEventListener("deactivate", this); window.removeEventListener("toolbarvisibilitychange", this); window.removeEventListener("windowlwthemeupdate", this); }, handleEvent(event) { switch (event.type) { case "activate": case "deactivate": case "windowlwthemeupdate": this.inferFromText(event.type); break; case "toolbarvisibilitychange": this.inferFromText(event.type, event.visible); break; } }, // A cache of luminance values for each toolbar to avoid unnecessary calls to // getComputedStyle(). _toolbarLuminanceCache: new Map(), // A cache of the current sidebar color to avoid unnecessary conditions and // luminance calculations. _sidebarColorCache: null, 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 "windowlwthemeupdate": // Theme change, we'll need to recalculate all color values. this._toolbarLuminanceCache.clear(); this._sidebarColorCache = null; break; case "toolbarvisibilitychange": // Toolbar changes dont require reset of the cached color values. break; case "tabsintitlebar": this._windowState.tabsintitlebar = reasonValue; break; } let toolbarSelector = "toolbox > toolbar:not([collapsed=true])"; if (AppConstants.platform == "macosx") { toolbarSelector += ":not([type=menubar])"; } toolbarSelector += ", .toolbar"; // The getComputedStyle calls and setting the brighttext are separated in // two loops to avoid flushing layout and making it dirty repeatedly. let cachedLuminances = this._toolbarLuminanceCache; let luminances = new Map(); for (let toolbar of document.querySelectorAll(toolbarSelector)) { // Toolbars *should* all have ids, but guard anyway to avoid blowing up. let cacheKey = toolbar.id && toolbar.id + JSON.stringify(this._windowState); // 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); } const luminanceThreshold = 127; // In between 0 and 255 for (let [toolbar, luminance] of luminances) { if (luminance <= luminanceThreshold) { toolbar.removeAttribute("brighttext"); } else { toolbar.setAttribute("brighttext", "true"); } } // On Linux, we need to detect if the OS theme caused a text color change in // the sidebar icons and properly update the brighttext attribute. if ( reason == "activate" && AppConstants.platform == "linux" && Services.prefs.getCharPref("extensions.activeThemeID", "") == "default-theme@mozilla.org" ) { let folderTree = document.getElementById("folderTree"); if (!folderTree) { return; } let sidebarColor = getComputedStyle(folderTree).color; // Interrupt if the sidebar color didn't change. if (sidebarColor == this._sidebarColorCache) { return; } this._sidebarColorCache = sidebarColor; let mainWindow = document.getElementById("messengerWindow"); if (!mainWindow) { return; } let [r, g, b] = parseRGB(sidebarColor); let luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b; if (luminance <= 110) { mainWindow.removeAttribute("lwt-tree-brighttext"); } else { mainWindow.setAttribute("lwt-tree-brighttext", "true"); } } }, };