From 7b55cda06b5b23fe13ce5ce33aff26be085e2686 Mon Sep 17 00:00:00 2001 From: Fedor Date: Sat, 4 May 2024 16:28:52 +0300 Subject: [PATCH] Better dark mode #399 --- browser/app/profile/mypal.js | 7 - .../components/confirm-delete-dialog.css | 10 +- .../content/components/login-item.css | 4 - .../shared/incontentprefs/preferences.inc.css | 10 +- browser/themes/shared/newInstallPage.css | 17 ++- browser/themes/shared/tabs.inc.css | 2 - .../content/aboutPerformance.css | 36 ++++- .../content/aboutPerformance.js | 138 +++++++++++++++++- .../content/aboutPerformance.xhtml | 8 +- .../themes/linux/global/in-content/common.css | 7 + toolkit/themes/shared/config.css | 1 - .../themes/shared/in-content/common.inc.css | 8 +- 12 files changed, 194 insertions(+), 54 deletions(-) diff --git a/browser/app/profile/mypal.js b/browser/app/profile/mypal.js index 5827c0bc07..a95ae06b59 100644 --- a/browser/app/profile/mypal.js +++ b/browser/app/profile/mypal.js @@ -955,13 +955,6 @@ pref("browser.flash-protected-mode-flip.enable", false); // Whether we've already flipped protected mode automatically pref("browser.flash-protected-mode-flip.done", false); -// Dark in-content pages -#ifdef NIGHTLY_BUILD - pref("browser.in-content.dark-mode", true); -#else - pref("browser.in-content.dark-mode", false); -#endif - pref("dom.ipc.shims.enabledWarnings", false); #if defined(XP_WIN) && defined(MOZ_SANDBOX) diff --git a/browser/components/aboutlogins/content/components/confirm-delete-dialog.css b/browser/components/aboutlogins/content/components/confirm-delete-dialog.css index fb2975d32c..6d050570e7 100644 --- a/browser/components/aboutlogins/content/components/confirm-delete-dialog.css +++ b/browser/components/aboutlogins/content/components/confirm-delete-dialog.css @@ -1,9 +1,3 @@ -:host { - /* these variable values come from about:preferences */ - --in-content-dialogtitle-background: #f1f1f1; - --in-content-dialogtitle-border: #c1c1c1; -} - .overlay { position: fixed; z-index: 1; @@ -39,9 +33,9 @@ position: relative; flex: 0 1 auto; text-align: center; - background-color: var(--in-content-dialogtitle-background); + background-color: var(--in-content-dialog-header-background); padding: 5px; - border-bottom: 1px solid var(--in-content-dialogtitle-border); + border-bottom: 1px solid var(--in-content-border-color); } .title { diff --git a/browser/components/aboutlogins/content/components/login-item.css b/browser/components/aboutlogins/content/components/login-item.css index 0e9e9dd874..b7c8e7dcaa 100644 --- a/browser/components/aboutlogins/content/components/login-item.css +++ b/browser/components/aboutlogins/content/components/login-item.css @@ -11,13 +11,11 @@ --success-color: #00c100; } -@supports -moz-bool-pref("browser.in-content.dark-mode") { @media (prefers-color-scheme: dark) { :host { --success-color: #86DE74; } } -} :host([data-editing]) .edit-button, :host([data-is-new-login]) .delete-button, @@ -181,7 +179,6 @@ box-shadow: 0 0 0 4px var(--in-content-border-active-shadow); } -@supports -moz-bool-pref("browser.in-content.dark-mode") { @media (prefers-color-scheme: dark) { :host { --reveal-checkbox-opacity: .8; @@ -189,4 +186,3 @@ --reveal-checkbox-opacity-active: .6; } } -} diff --git a/browser/themes/shared/incontentprefs/preferences.inc.css b/browser/themes/shared/incontentprefs/preferences.inc.css index 8e2105415e..21a4dbf851 100644 --- a/browser/themes/shared/incontentprefs/preferences.inc.css +++ b/browser/themes/shared/incontentprefs/preferences.inc.css @@ -6,20 +6,14 @@ @namespace html "http://www.w3.org/1999/xhtml"; :root { - --in-content-dialogtitle-background: #f1f1f1; - --in-content-dialogtitle-border: #c1c1c1; --in-content-warning-container: var(--grey-20); } -@supports -moz-bool-pref("browser.in-content.dark-mode") { @media (prefers-color-scheme: dark) { :root { - --in-content-dialogtitle-background: rgba(249,249,250,0.05); - --in-content-dialogtitle-border: rgba(0,0,0,0.5); --in-content-warning-container: var(--grey-90-a30); } } -} * { -moz-user-select: text; @@ -524,8 +518,8 @@ button > hbox > label { .dialogTitleBar { margin-top: 0; padding: 3.5px 0; - background-color: var(--in-content-dialogtitle-background); - border-bottom: 1px solid var(--in-content-dialogtitle-border); + background-color: var(--in-content-dialog-header-background); + border-bottom: 1px solid var(--in-content-border-color); } .dialogTitle { diff --git a/browser/themes/shared/newInstallPage.css b/browser/themes/shared/newInstallPage.css index 1301cb5152..93ebc9d232 100644 --- a/browser/themes/shared/newInstallPage.css +++ b/browser/themes/shared/newInstallPage.css @@ -29,6 +29,13 @@ p { height: 52px; } +@media (prefers-color-scheme: dark) { + #header > img { + -moz-context-properties: fill; + fill: currentColor; + } +} + #content { display: flex; flex-direction: row; @@ -69,7 +76,7 @@ p { #sync-terms { font-size: 87%; margin-bottom: 20px; - color: var(--grey-50); + color: var(--in-content-deemphasized-text); } #sync-terms a, @@ -87,16 +94,12 @@ p { width: 100%; height: 42px; cursor: pointer; - padding: 8px 0; - margin: 0; - color: #FFF !important; - background-color: var(--blue-50); - border-radius: 4px; } #sync-first, #sync-learn { font-size: 87%; - color: var(--grey-50); + color: var(--in-content-deemphasized-text); margin-bottom: 0; text-align: start; + margin-inline: 4px; /* Align with input and button */ } diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css index 7fc107e8d9..7007a79f3a 100644 --- a/browser/themes/shared/tabs.inc.css +++ b/browser/themes/shared/tabs.inc.css @@ -38,14 +38,12 @@ background-color: #25003e; } -@supports -moz-bool-pref("browser.in-content.dark-mode") { @media (prefers-color-scheme: dark) { #tabbrowser-tabpanels { /* Value for --in-content-page-background for dark mode in in-content/common.inc.css */ background-color: #2A2A2E; } } -} #tabbrowser-tabs, #tabbrowser-tabs > .tabbrowser-arrowscrollbox, diff --git a/toolkit/components/aboutperformance/content/aboutPerformance.css b/toolkit/components/aboutperformance/content/aboutPerformance.css index 68d8d8219a..7e79e855bb 100644 --- a/toolkit/components/aboutperformance/content/aboutPerformance.css +++ b/toolkit/components/aboutperformance/content/aboutPerformance.css @@ -123,12 +123,12 @@ tr:-moz-any([selected], :hover) > td > .action-icon { #dispatch-thead > tr > td { border: none; - background-color: var(--in-content-box-background-hover); + background-color: var(--in-content-button-background); } #dispatch-thead > tr > td:not(:first-child) { border-inline-start-width: 1px; border-inline-start-style: solid; - border-image: linear-gradient(transparent 0%, transparent 20%, #c1c1c1 20%, #c1c1c1 80%, transparent 80%, transparent 100%) 1 1; + border-image: linear-gradient(transparent 0%, transparent 20%, var(--in-content-box-border-color) 20%, var(--in-content-box-border-color) 80%, transparent 80%, transparent 100%) 1 1; border-bottom: 1px solid var(--in-content-border-color); } td { @@ -207,3 +207,35 @@ td { #dispatch-tbody > tr:hover { background-color: var(--in-content-item-hover); } + +.clickable { + background-repeat: no-repeat; + background-position: right 4px center; +} +.clickable:dir(rtl) { + background-position: left 4px center; +} +.asc { + background-image: url(chrome://global/skin/icons/arrow-up-12.svg); + -moz-context-properties: fill; + fill: currentColor; +} +.desc { + background-image: url(chrome://global/skin/icons/arrow-dropdown-12.svg); + -moz-context-properties: fill; + fill: currentColor; +} +#dispatch-thead > tr > td.clickable:hover { + background-color: var(--in-content-button-background-hover); +} +#dispatch-thead > tr > td.clickable:active { + background-color: var(--in-content-button-background-active); +} + +.energy-impact { + --bar-width: 0; + background: linear-gradient(to right, var(--blue-40) calc(var(--bar-width) * 1%), transparent calc(var(--bar-width) * 1%)); +} +.energy-impact:dir(rtl) { + background: linear-gradient(to left, var(--blue-40) calc(var(--bar-width) * 1%), transparent calc(var(--bar-width) * 1%)); +} diff --git a/toolkit/components/aboutperformance/content/aboutPerformance.js b/toolkit/components/aboutperformance/content/aboutPerformance.js index bdc829b846..51f7a4652d 100644 --- a/toolkit/components/aboutperformance/content/aboutPerformance.js +++ b/toolkit/components/aboutperformance/content/aboutPerformance.js @@ -480,6 +480,17 @@ var State = { } return counters; }, + + getMaxEnergyImpact(counters) { + return Math.max( + ...counters.map(c => { + return Control._computeEnergyImpact( + c.dispatchesSincePrevious, + c.durationSincePrevious + ); + }) + ); + }, }; var View = { @@ -501,22 +512,52 @@ var View = { row.parentNode.insertBefore(this._fragment, row.nextSibling); this._fragment = document.createDocumentFragment(); }, - displayEnergyImpact(elt, energyImpact) { + displayEnergyImpact(elt, energyImpact, maxEnergyImpact) { if (!energyImpact) { elt.textContent = "–"; + elt.style.setProperty("--bar-width", 0); } else { - let impact = "high"; + let impact; + let barWidth; + const mediumEnergyImpact = 25; if (energyImpact < 1) { impact = "low"; - } else if (energyImpact < 25) { + // Width 0-10%. + barWidth = 10 * energyImpact; + } else if (energyImpact < mediumEnergyImpact) { impact = "medium"; + // Width 10-50%. + barWidth = (10 + 2 * energyImpact) * (5 / 6); + } else { + impact = "high"; + // Width 50-100%. + let energyImpactFromZero = energyImpact - mediumEnergyImpact; + if (maxEnergyImpact > 100) { + barWidth = + 50 + + (energyImpactFromZero / (maxEnergyImpact - mediumEnergyImpact)) * + 50; + } else { + barWidth = 50 + energyImpactFromZero * (2 / 3); + } } document.l10n.setAttributes(elt, "energy-impact-" + impact, { value: energyImpact, }); + if (maxEnergyImpact != -1) { + elt.style.setProperty("--bar-width", barWidth); + } } }, - appendRow(name, energyImpact, memory, tooltip, type, image = "") { + appendRow( + name, + energyImpact, + memory, + tooltip, + type, + maxEnergyImpact = -1, + image = "" + ) { let row = document.createElement("tr"); let elt = document.createElement("td"); @@ -549,7 +590,8 @@ var View = { row.appendChild(elt); elt = document.createElement("td"); - this.displayEnergyImpact(elt, energyImpact); + elt.classList.add("energy-impact"); + this.displayEnergyImpact(elt, energyImpact, maxEnergyImpact); row.appendChild(elt); elt = document.createElement("td"); @@ -600,6 +642,7 @@ var View = { var Control = { _openItems: new Set(), + _sortOrder: "", _removeSubtree(row) { while ( row.nextSibling && @@ -691,6 +734,40 @@ var Control = { this._updateDisplay(true); } }); + + document + .getElementById("dispatch-thead") + .addEventListener("click", async (event) => { + if (!event.target.classList.contains("clickable")) + return; + + if (this._sortOrder) { + let [column, direction] = this._sortOrder.split("_"); + const td = document.getElementById(`column-${column}`); + td.classList.remove(direction); + } + + const columnId = event.target.id; + if (columnId == "column-type") + this._sortOrder = + this._sortOrder == "type_asc" ? "type_desc" : "type_asc"; + else if (columnId == "column-energy-impact") + this._sortOrder = + this._sortOrder == "energy-impact_desc" + ? "energy-impact_asc" + : "energy-impact_desc"; + else if (columnId == "column-memory") + this._sortOrder = + this._sortOrder == "memory_desc" ? "memory_asc" : "memory_desc"; + else if (columnId == "column-name") + this._sortOrder = + this._sortOrder == "name_asc" ? "name_desc" : "name_asc"; + + let direction = this._sortOrder.split("_")[1]; + event.target.classList.add(direction); + + await this._updateDisplay(true); + }); }, _lastMouseEvent: 0, _updateLastMouseEvent() { @@ -710,6 +787,8 @@ var Control = { // The force parameter can force a full update even when the mouse has been // moved recently. async _updateDisplay(force = false) { + let counters = State.getCounters(); + let maxEnergyImpact = State.getMaxEnergyImpact(counters); // If the mouse has been moved recently, update the data displayed // without moving any item to avoid the risk of users clicking an action // button for the wrong item. @@ -724,7 +803,7 @@ var Control = { id, dispatchesSincePrevious, durationSincePrevious, - } of State.getCounters()) { + } of counters) { let energyImpact = this._computeEnergyImpact( dispatchesSincePrevious, durationSincePrevious @@ -740,7 +819,11 @@ var Control = { // risk of making other rows move up or down. const kEnergyImpactColumn = 2; let elt = row.childNodes[kEnergyImpactColumn]; - View.displayEnergyImpact(elt, energyImpactPerId.get(row.windowId)); + View.displayEnergyImpact( + elt, + energyImpactPerId.get(row.windowId), + maxEnergyImpact + ); } row = row.nextSibling; } @@ -757,7 +840,7 @@ var Control = { let openItems = this._openItems; this._openItems = new Set(); - let counters = this._sortCounters(State.getCounters()); + counters = this._sortCounters(counters); for (let { id, name, @@ -784,6 +867,7 @@ var Control = { durationSincePrevious: Math.ceil(durationSincePrevious / 1000), }, type, + maxEnergyImpact, image ); row.windowId = id; @@ -872,6 +956,14 @@ var Control = { // Keep only 2 digits after the decimal point. return Math.ceil(energyImpact * 100) / 100; }, + _getTypeWeight(type) { + let weights = { + tab: 3, + addon: 2, + "system-addon": 1, + }; + return weights[type] || 0; + }, _sortCounters(counters) { return counters.sort((a, b) => { // Force 'Recently Closed Tabs' to be always at the bottom, because it'll @@ -880,6 +972,36 @@ var Control = { return 1; } + if (this._sortOrder) { + let res; + let [column, order] = this._sortOrder.split("_"); + switch (column) { + case "memory": + res = a.memory - b.memory; + break; + case "type": + if (a.type != b.type) + res = this._getTypeWeight(b.type) - this._getTypeWeight(a.type); + else + res = String.prototype.localeCompare.call(a.name, b.name); + break; + case "name": + res = String.prototype.localeCompare.call(a.name, b.name); + break; + case "energy-impact": + res = this._computeEnergyImpact(a.dispatchesSincePrevious, + a.durationSincePrevious) - + this._computeEnergyImpact(b.dispatchesSincePrevious, + b.durationSincePrevious); + break; + default: + res = String.prototype.localeCompare.call(a.name, b.name); + } + if (order == "desc") + res = -1 * res; + return res; + } + // Note: _computeEnergyImpact uses UPDATE_INTERVAL_MS which doesn't match // the time between the most recent sample and the start of the buffer, // BUFFER_DURATION_MS would be better, but the values is never displayed diff --git a/toolkit/components/aboutperformance/content/aboutPerformance.xhtml b/toolkit/components/aboutperformance/content/aboutPerformance.xhtml index a242b3e0ce..e5643d4257 100644 --- a/toolkit/components/aboutperformance/content/aboutPerformance.xhtml +++ b/toolkit/components/aboutperformance/content/aboutPerformance.xhtml @@ -20,10 +20,10 @@ - diff --git a/toolkit/themes/linux/global/in-content/common.css b/toolkit/themes/linux/global/in-content/common.css index 127411bf87..5b2383d7a2 100644 --- a/toolkit/themes/linux/global/in-content/common.css +++ b/toolkit/themes/linux/global/in-content/common.css @@ -4,6 +4,13 @@ %include ../../../shared/in-content/common.inc.css +@media (prefers-color-scheme: dark) { + /* Don't apply scrollbar-color since it removes the native scrollbar style on Linux */ + :root { + scrollbar-color: initial; + } +} + xul|tab[visuallyselected] { /* Override styles for tab[selected] from toolkit/themes/linux/global/tabbox.css */ diff --git a/toolkit/themes/shared/config.css b/toolkit/themes/shared/config.css index 5d9ed51e0a..7e6b761217 100644 --- a/toolkit/themes/shared/config.css +++ b/toolkit/themes/shared/config.css @@ -18,7 +18,6 @@ #warningTitle { font-weight: lighter; line-height: 1.2; - color: #333; margin: 0; margin-bottom: .5em; } diff --git a/toolkit/themes/shared/in-content/common.inc.css b/toolkit/themes/shared/in-content/common.inc.css index 472bbcec0c..0c2a96140c 100644 --- a/toolkit/themes/shared/in-content/common.inc.css +++ b/toolkit/themes/shared/in-content/common.inc.css @@ -49,6 +49,7 @@ --in-content-table-background: #ebebeb; --in-content-table-border-dark-color: #d1d1d1; --in-content-table-header-background: #0a84ff; + --in-content-dialog-header-background: #f1f1f1; --panel-border-radius: 2px; /* This is overridden on Windows */ @@ -65,7 +66,6 @@ --grey-20: #ededf0; --grey-30: #d7d7db; --grey-40: #b1b1b3; - --grey-50: #737373; --grey-60: #4a4a4f; --grey-90: #0c0c0d; --grey-90-a10: rgba(12, 12, 13, 0.1); @@ -103,7 +103,6 @@ --card-shadow-focus: 0 0 0 2px var(--blue-50), 0 0 0 6px var(--blue-50-a30); } -@supports -moz-bool-pref("browser.in-content.dark-mode") { @media (prefers-color-scheme: dark) { :root { /* Keep this in sync with layout/base/PresShell.cpp! */ @@ -133,6 +132,7 @@ --in-content-table-background: #202023; --in-content-table-border-dark-color: rgba(249,249,250,0.2); --in-content-table-header-background: #002b57; + --in-content-dialog-header-background: rgba(249,249,250,0.05); --in-content-category-text-selected: var(--blue-40); --in-content-category-text-selected-active: var(--blue-50); @@ -147,7 +147,6 @@ scrollbar-color: rgba(249,249,250,.4) rgba(20,20,25,.3); } } -} html|html, xul|page, @@ -329,18 +328,21 @@ xul|menulist[disabled="true"] { } html|button[autofocus], +html|button[type="submit"], *|button.primary { background-color: var(--in-content-primary-button-background); color: var(--in-content-selected-text) !important; } html|button[autofocus]:enabled:hover, +html|button[type="submit"]:enabled:hover, html|button.primary:enabled:hover, xul|button.primary:not([disabled="true"]):hover { background-color: var(--in-content-primary-button-background-hover); } html|button[autofocus]:enabled:hover:active, +html|button[type="submit"]:enabled:hover:active, html|button.primary:enabled:hover:active, xul|button.primary:not([disabled="true"]):hover:active { background-color: var(--in-content-primary-button-background-active);
- - - + + + +