1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/**
* 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");
}
}
},
};
|