simplify: move ! modes to explicit global options
This commit is contained in:
parent
33e517c4a9
commit
933191d25c
|
@ -1086,11 +1086,8 @@
|
|||
"optionsAdvancedNewStyleAsUsercss": {
|
||||
"message": "Write new style as usercss"
|
||||
},
|
||||
"optionsAdvancedAutoSwitchScheme": {
|
||||
"message": "Toggle Light/Dark Mode styles automatically"
|
||||
},
|
||||
"optionsAdvancedAutoSwitchSchemeNever": {
|
||||
"message": "Never"
|
||||
"message": "Disabled. The dark/light setting in styles is ignored."
|
||||
},
|
||||
"optionsAdvancedAutoSwitchSchemeBySystem": {
|
||||
"message": "By system preference"
|
||||
|
@ -1312,26 +1309,20 @@
|
|||
"description": "Label for the checkbox controlling section order in the popup."
|
||||
},
|
||||
"preferScheme": {
|
||||
"message": "Dark/Light mode preference:"
|
||||
"message": "Dark/Light mode preference"
|
||||
},
|
||||
"preferSchemeAlways": {
|
||||
"message": "Currently ignored (the style always applies) because the global Dark/Light mode is disabled"
|
||||
},
|
||||
"preferSchemeDark": {
|
||||
"message": "Dark"
|
||||
},
|
||||
"preferSchemeDarkOnly": {
|
||||
"message": "Dark (strict)"
|
||||
},
|
||||
"preferSchemeLight": {
|
||||
"message": "Light"
|
||||
},
|
||||
"preferSchemeLightOnly": {
|
||||
"message": "Light (strict)"
|
||||
},
|
||||
"preferSchemeNone": {
|
||||
"message": "None (always applied)"
|
||||
},
|
||||
"preferSchemeTip": {
|
||||
"message": "The style will be applied in a matching Dark/Light global mode. For strict options, the mode being active is mandatory, so the style doesn't apply when the mode is 'Never'. For non-strict options, the style also applies when the user doesn't care i.e. the global mode is 'Never'."
|
||||
},
|
||||
"prefShowBadge": {
|
||||
"message": "Number of styles active for the current site",
|
||||
"description": "Label for the checkbox controlling toolbar badge text."
|
||||
|
|
|
@ -8,11 +8,17 @@ const colorScheme = (() => {
|
|||
const kSTATE = 'schemeSwitcher.enabled';
|
||||
const kSTART = 'schemeSwitcher.nightStart';
|
||||
const kEND = 'schemeSwitcher.nightEnd';
|
||||
const SCHEMES = ['dark', 'light', 'dark!', 'light!']; // ! = only if schemeSwitcher is enabled
|
||||
const isDark = {never: null, system: false, time: false};
|
||||
const SCHEMES = ['dark', 'light'];
|
||||
const isDark = {
|
||||
never: null,
|
||||
dark: true,
|
||||
light: false,
|
||||
system: false,
|
||||
time: false,
|
||||
};
|
||||
let isDarkNow = false;
|
||||
|
||||
prefs.subscribe(kSTATE, () => emitChange());
|
||||
prefs.subscribe(kSTATE, () => update());
|
||||
prefs.subscribe([kSTART, kEND], (key, value) => {
|
||||
updateTimePreferDark();
|
||||
createAlarm(key, value);
|
||||
|
@ -28,17 +34,25 @@ const colorScheme = (() => {
|
|||
onChange(listener) {
|
||||
changeListeners.add(listener);
|
||||
},
|
||||
shouldIncludeStyle({preferScheme: val}) {
|
||||
return !SCHEMES.includes(val) ||
|
||||
!val.endsWith('!') && prefs.get(kSTATE) === 'never' ||
|
||||
val.startsWith('dark') === isDarkNow;
|
||||
/** @param {StyleObj | 'darkUI'} val - the string is used by the built-in dark themer */
|
||||
shouldIncludeStyle(val) {
|
||||
return val === 'darkUI'
|
||||
? isDarkNow
|
||||
: prefs.get(kSTATE) === 'never' ||
|
||||
!SCHEMES.includes(val = val.preferScheme) ||
|
||||
isDarkNow === (val === 'dark');
|
||||
},
|
||||
updateSystemPreferDark(val) {
|
||||
emitChange('system', val);
|
||||
update('system', val);
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
function calcTime(key) {
|
||||
const [h, m] = prefs.get(key).split(':');
|
||||
return (h * 3600 + m * 60) * 1000;
|
||||
}
|
||||
|
||||
function createAlarm(key, value) {
|
||||
const date = new Date();
|
||||
const [h, m] = value.split(':');
|
||||
|
@ -59,22 +73,20 @@ const colorScheme = (() => {
|
|||
const val = start > end ?
|
||||
now >= start || now < end :
|
||||
now >= start && now < end;
|
||||
emitChange('time', val);
|
||||
update('time', val);
|
||||
}
|
||||
|
||||
function calcTime(key) {
|
||||
const [h, m] = prefs.get(key).split(':');
|
||||
return (h * 3600 + m * 60) * 1000;
|
||||
}
|
||||
|
||||
function emitChange(type, val) {
|
||||
function update(type, val) {
|
||||
if (type) {
|
||||
if (isDark[type] === val) return;
|
||||
isDark[type] = val;
|
||||
}
|
||||
isDarkNow = isDark[prefs.get(kSTATE)];
|
||||
for (const listener of changeListeners) {
|
||||
listener(isDarkNow);
|
||||
val = isDark[prefs.get(kSTATE)];
|
||||
if (isDarkNow !== val) {
|
||||
isDarkNow = val;
|
||||
for (const listener of changeListeners) {
|
||||
listener(isDarkNow);
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -85,7 +85,7 @@
|
|||
background: linear-gradient(0deg, hsla(180, 100%, 30%, .75) 2px, hsla(180, 100%, 30%, .2) 2px);
|
||||
}
|
||||
|
||||
@media not screen, dark {
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.CodeMirror-dialog {
|
||||
background-color: #333;
|
||||
}
|
||||
|
@ -127,7 +127,7 @@
|
|||
.cm-s-default .cm-operator { color: #d2c057 }
|
||||
.cm-s-default .cm-string { color: #f28b54 }
|
||||
.cm-s-default .cm-variable { color: #d9d9d9 }
|
||||
.cm-s-default .cm-variable-2 { color: #05a }
|
||||
.cm-s-default .cm-variable-2 { color: #72b9ff }
|
||||
.cm-s-default .cm-variable-3 { color: #9bbbdc }
|
||||
|
||||
@keyframes highlight {
|
||||
|
|
|
@ -8,9 +8,7 @@
|
|||
</div>
|
||||
<div id="ss-scheme">
|
||||
<div i18n-text="preferScheme">
|
||||
<a tabindex="0" data-cmd="note" i18n-title="preferSchemeTip">
|
||||
<svg class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg>
|
||||
</a>
|
||||
<div><small id="ss-scheme-off" i18n-text="preferSchemeAlways" hidden></small></div>
|
||||
</div>
|
||||
<label i18n-text-append="preferSchemeNone" class="ss-radio">
|
||||
<input name="ss-scheme" type="radio" value="none">
|
||||
|
@ -18,15 +16,9 @@
|
|||
<label i18n-text-append="preferSchemeDark" class="ss-radio">
|
||||
<input name="ss-scheme" type="radio" value="dark">
|
||||
</label>
|
||||
<label i18n-text-append="preferSchemeDarkOnly" class="ss-radio">
|
||||
<input name="ss-scheme" type="radio" value="dark!">
|
||||
</label>
|
||||
<label i18n-text-append="preferSchemeLight" class="ss-radio">
|
||||
<input name="ss-scheme" type="radio" value="light">
|
||||
</label>
|
||||
<label i18n-text-append="preferSchemeLightOnly" class="ss-radio">
|
||||
<input name="ss-scheme" type="radio" value="light!">
|
||||
</label>
|
||||
</div>
|
||||
<label i18n-text="styleIncludeLabel">
|
||||
<textarea id="ss-inclusions" spellcheck="false" class="w100"
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
/* global API */// msg.js
|
||||
/* global editor */
|
||||
/* global helpPopup */// util.js
|
||||
/* global prefs */
|
||||
/* global t */// localization.js
|
||||
/* global debounce tryURL */// toolbox.js
|
||||
/* exported StyleSettings */
|
||||
'use strict';
|
||||
|
||||
/* exported StyleSettings */
|
||||
async function StyleSettings() {
|
||||
const AUTOSAVE_DELAY = 500; // same as config-dialog.js
|
||||
const SS_ID = 'styleSettings';
|
||||
|
@ -31,6 +32,9 @@ async function StyleSettings() {
|
|||
initArea('exclusions'),
|
||||
];
|
||||
update();
|
||||
prefs.subscribe('schemeSwitcher.enabled', (_, val) => {
|
||||
$('#ss-scheme-off', ui).hidden = val !== 'never';
|
||||
}, {runNow: true});
|
||||
window.on(SS_ID, update);
|
||||
window.on('closeHelp', () => window.off(SS_ID, update), {once: true});
|
||||
helpPopup.show(t(SS_ID), ui, {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@media not screen, dark {
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
/* Comfortable dark themes don't use absolutes so the range is compressed */
|
||||
--c00: hsl(0, 0%, 80%);
|
||||
|
|
|
@ -45,7 +45,12 @@ setTimeout(() => !cm && showSpinner($('#header')), 200);
|
|||
}
|
||||
({tabId, initialUrl} = preinit);
|
||||
liveReload = initLiveReload();
|
||||
preinit.tpl.then(el => $('#ss-scheme').append(...$('#ss-scheme', el).children));
|
||||
preinit.tpl.then(el => {
|
||||
$('#ss-scheme').append(...$('#ss-scheme', el).children);
|
||||
prefs.subscribe('schemeSwitcher.enabled', (_, val) => {
|
||||
$('#ss-scheme-off').hidden = val !== 'never';
|
||||
}, {runNow: true});
|
||||
});
|
||||
|
||||
const [
|
||||
{dup, style, error, sourceCode},
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
/**
|
||||
* This file must be loaded in a <script> tag placed after all the <link> tags
|
||||
* that contain dark themes so that the stylesheets are loaded synchronously
|
||||
* by the time this script runs. The CSS must use `@media not screen, dark {}`
|
||||
* to ensure the rules are loaded before the first paint in inactive state,
|
||||
* then we activate it here.
|
||||
* by the time this script runs. The CSS must use `@media (prefers-color-scheme: dark) {}`
|
||||
* to ensure the rules are loaded before the first paint, then we toggle the rule here,
|
||||
* which also happens before the first paint unless the browser "yields", but that's abnormal
|
||||
* and not even a problem in the most popular case of using system dark/light mode.
|
||||
*/
|
||||
|
||||
API.colorScheme.shouldIncludeStyle({preferScheme: 'dark!'}).then(val => {
|
||||
API.colorScheme.shouldIncludeStyle('darkUI').then(val => {
|
||||
let isDark = val;
|
||||
toggleDarkStyles();
|
||||
msg.onExtension(e => {
|
||||
|
@ -21,8 +22,8 @@ API.colorScheme.shouldIncludeStyle({preferScheme: 'dark!'}).then(val => {
|
|||
function toggleDarkStyles() {
|
||||
for (const sheet of document.styleSheets) {
|
||||
for (const {media: m} of sheet.cssRules) {
|
||||
if (m && m[1] === 'dark' && (m[0] === 'screen') !== isDark) {
|
||||
m.mediaText = `${isDark ? '' : 'not '}screen, dark`;
|
||||
if (m && /dark/.test(m) && (m[0] === 'screen') !== isDark) {
|
||||
m.mediaText = isDark ? 'screen,dark' : 'dark';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
15
options.html
15
options.html
|
@ -52,14 +52,14 @@
|
|||
<h1 i18n-text="stylePreferSchemeLabel"></h1>
|
||||
<div class="items">
|
||||
<div class="radio-group">
|
||||
<span i18n-text="optionsAdvancedAutoSwitchScheme" class="radio-group-label"></span>
|
||||
<label class="radio-group-item">
|
||||
<input type="radio" value="never" name="schemeSwitcher.enabled" class="radio">
|
||||
<span i18n-text="optionsAdvancedAutoSwitchSchemeNever"></span>
|
||||
<label class="radio-group-item" i18n-text-append="preferSchemeDark">
|
||||
<input type="radio" value="light" name="schemeSwitcher.enabled" class="radio">
|
||||
</label>
|
||||
<label class="radio-group-item">
|
||||
<label class="radio-group-item" i18n-text-append="preferSchemeLight">
|
||||
<input type="radio" value="dark" name="schemeSwitcher.enabled" class="radio">
|
||||
</label>
|
||||
<label class="radio-group-item" i18n-text-append="optionsAdvancedAutoSwitchSchemeBySystem">
|
||||
<input type="radio" value="system" name="schemeSwitcher.enabled" class="radio">
|
||||
<span i18n-text="optionsAdvancedAutoSwitchSchemeBySystem"></span>
|
||||
</label>
|
||||
<label class="radio-group-item">
|
||||
<input type="radio" value="time" name="schemeSwitcher.enabled" class="radio">
|
||||
|
@ -68,6 +68,9 @@
|
|||
~
|
||||
<input type="time" required id="schemeSwitcher.nightEnd">
|
||||
</label>
|
||||
<label class="radio-group-item" i18n-text-append="optionsAdvancedAutoSwitchSchemeNever">
|
||||
<input type="radio" value="never" name="schemeSwitcher.enabled" class="radio">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue
Block a user