use color palette and enable a simple dark theme

This commit is contained in:
tophf 2022-02-13 16:12:57 +03:00
parent dd38856eda
commit 7cb05f2381
30 changed files with 592 additions and 364 deletions

View File

@ -623,18 +623,6 @@
"message": "Update style",
"description": "Label for update button"
},
"installPreferSchemeLabel": {
"message": "The style should be applied:"
},
"installPreferSchemeNone": {
"message": "Always"
},
"installPreferSchemeDark": {
"message": "In Dark Mode"
},
"installPreferSchemeLight": {
"message": "In Light Mode"
},
"installUpdate": {
"message": "Install update",
"description": "Label for the button to install an update for a single style"
@ -1323,6 +1311,27 @@
"message": "Styles before commands",
"description": "Label for the checkbox controlling section order in the popup."
},
"preferScheme": {
"message": "Dark/Light mode preference:"
},
"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."

View File

@ -4,33 +4,45 @@
'use strict';
const colorScheme = (() => {
let systemPreferDark = false;
let timePreferDark = false;
const changeListeners = new Set();
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};
let isDarkNow = false;
const checkTime = ['schemeSwitcher.nightStart', 'schemeSwitcher.nightEnd'];
prefs.subscribe(checkTime, (key, value) => {
prefs.subscribe(kSTATE, () => emitChange());
prefs.subscribe([kSTART, kEND], (key, value) => {
updateTimePreferDark();
createAlarm(key, value);
});
checkTime.forEach(key => createAlarm(key, prefs.get(key)));
prefs.subscribe(['schemeSwitcher.enabled'], emitChange);
chrome.alarms.onAlarm.addListener(info => {
if (checkTime.includes(info.name)) {
}, {runNow: true});
chrome.alarms.onAlarm.addListener(({name}) => {
if (name === kSTART || name === kEND) {
updateTimePreferDark();
}
});
updateSystemPreferDark();
updateTimePreferDark();
return {shouldIncludeStyle, onChange, updateSystemPreferDark};
return {
SCHEMES,
onChange(listener) {
changeListeners.add(listener);
},
shouldIncludeStyle({preferScheme: val}) {
return !SCHEMES.includes(val) ||
!val.endsWith('!') && prefs.get(kSTATE) === 'never' ||
val.startsWith('dark') === isDarkNow;
},
updateSystemPreferDark(val) {
emitChange('system', val);
return true;
},
};
function createAlarm(key, value) {
const date = new Date();
applyDate(date, value);
const [h, m] = value.split(':');
date.setHours(h, m, 0, 0);
if (date.getTime() < Date.now()) {
date.setDate(date.getDate() + 1);
}
@ -40,61 +52,29 @@ const colorScheme = (() => {
});
}
function shouldIncludeStyle(style) {
const isDark = style.preferScheme === 'dark';
const isLight = style.preferScheme === 'light';
if (!isDark && !isLight) {
return true;
}
const switcherState = prefs.get('schemeSwitcher.enabled');
if (switcherState === 'never') {
return true;
}
if (switcherState === 'system') {
return systemPreferDark && isDark ||
!systemPreferDark && isLight;
}
return timePreferDark && isDark ||
!timePreferDark && isLight;
}
function updateSystemPreferDark() {
const oldValue = systemPreferDark;
systemPreferDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
if (systemPreferDark !== oldValue) {
emitChange();
}
return true;
}
function updateTimePreferDark() {
const oldValue = timePreferDark;
const date = new Date();
const now = date.getTime();
applyDate(date, prefs.get('schemeSwitcher.nightStart'));
const start = date.getTime();
applyDate(date, prefs.get('schemeSwitcher.nightEnd'));
const end = date.getTime();
timePreferDark = start > end ?
const now = Date.now() - new Date().setHours(0, 0, 0, 0);
const start = calcTime(kSTART);
const end = calcTime(kEND);
const val = start > end ?
now >= start || now < end :
now >= start && now < end;
if (timePreferDark !== oldValue) {
emitChange();
emitChange('time', val);
}
function calcTime(key) {
const [h, m] = prefs.get(key).split(':');
return (h * 3600 + m * 60) * 1000;
}
function emitChange(type, val) {
if (type) {
if (isDark[type] === val) return;
isDark[type] = val;
}
}
function applyDate(date, time) {
const [h, m] = time.split(':').map(Number);
date.setHours(h, m, 0, 0);
}
function onChange(listener) {
changeListeners.add(listener);
}
function emitChange() {
isDarkNow = isDark[prefs.get(kSTATE)];
for (const listener of changeListeners) {
listener();
listener(isDarkNow);
}
}
})();

View File

@ -84,11 +84,11 @@ const styleMan = (() => {
handleDraft(port);
}
});
// function handleColorScheme() {
colorScheme.onChange(() => {
for (const {style: data} of dataMap.values()) {
if (data.preferScheme === 'dark' || data.preferScheme === 'light') {
broadcastStyleUpdated(data, 'colorScheme', undefined, false);
colorScheme.onChange(value => {
msg.broadcastExtension({method: 'colorScheme', value});
for (const {style} of dataMap.values()) {
if (colorScheme.SCHEMES.includes(style.preferScheme)) {
broadcastStyleUpdated(style, 'colorScheme');
}
}
});
@ -320,7 +320,8 @@ const styleMan = (() => {
async config(id, prop, value) {
if (ready.then) await ready;
const style = Object.assign({}, id2style(id));
style[prop] = value;
const {preview = {}} = dataMap.get(id);
style[prop] = preview[prop] = value;
return saveStyle(style, {reason: 'config'});
},
};

View File

@ -52,6 +52,12 @@
xo.observe(el);
};
// FIXME: move this to background page when following bugs are fixed:
// https://bugzil.la/1587723, https://crbug.com/968651
const mqDark = matchMedia('(prefers-color-scheme: dark)');
mqDark.onchange = e => API.colorScheme.updateSystemPreferDark(e.matches);
mqDark.onchange(mqDark);
// Declare all vars before init() or it'll throw due to "temporal dead zone" of const/let
const ready = init();
@ -70,13 +76,6 @@
window.addEventListener(orphanEventId, orphanCheck, true);
}
// detect media change in content script
// FIXME: move this to background page when following bugs are fixed:
// https://bugzilla.mozilla.org/show_bug.cgi?id=1561546
// https://bugs.chromium.org/p/chromium/issues/detail?id=968651
const media = window.matchMedia('(prefers-color-scheme: dark)');
media.addListener(() => API.colorScheme.updateSystemPreferDark().catch(console.error));
function onInjectorUpdate() {
if (!isOrphaned) {
updateCount();

View File

@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="global.css" rel="stylesheet">
<link href="global-dark.css" rel="stylesheet">
<link id="cm-theme" rel="stylesheet">
<script src="js/polyfill.js"></script>
@ -239,6 +240,7 @@
<link href="js/color/color-picker.css" rel="stylesheet">
<link href="edit/codemirror-default.css" rel="stylesheet">
<link href="edit/edit.css" rel="stylesheet">
<script src="js/dark-themer.js"></script> <!-- must be here to avoid FOUC -->
</head>
<body id="stylus-edit">

View File

@ -4,13 +4,23 @@
z-index: 999;
}
.CodeMirror-hint:hover {
color: white;
color: var(--bg);
background: #08f;
}
.CodeMirror {
border: solid #CCC 1px;
border: solid var(--c80) 1px;
transition: box-shadow .1s;
}
.CodeMirror {
color: inherit;
background-color: inherit;
border: solid var(--c80) 1px;
transition: box-shadow .1s;
}
.CodeMirror-gutters {
background-color: var(--c95);
border-color: var(--c85);
}
#stylus#stylus .CodeMirror {
/* Using a specificity hack to override userstyles */
/* Not using the ring-color hack as it became ugly in new Chrome */
@ -26,7 +36,7 @@
width: 5em;
}
.CodeMirror-search-hint {
color: #888;
color: var(--c50);
}
.CodeMirror-activeline .applies-to:before {
background-color: hsla(214, 100%, 90%, 0.15);
@ -74,3 +84,55 @@
.gutter-bookmark {
background: linear-gradient(0deg, hsla(180, 100%, 30%, .75) 2px, hsla(180, 100%, 30%, .2) 2px);
}
@media not screen, dark {
.CodeMirror-dialog {
background-color: #333;
}
.CodeMirror-dialog-top {
border-color: #555;
}
.CodeMirror-activeline-background {
background: hsl(180, 21%, 18%);
}
.CodeMirror-selected,
.CodeMirror-focused .CodeMirror-selected,
.CodeMirror-line::selection,
.CodeMirror-line > span::selection,
.CodeMirror-line > span > span::selection {
background: #444;
}
.CodeMirror-line::-moz-selection,
.CodeMirror-line > span::-moz-selection,
.CodeMirror-line > span > span::-moz-selection {
/* TODO: remove this when strict_min_version >= 62 */
background: #444;
}
/* Using Chromium's dark devtools colors */
.cm-s-default .cm-atom,
.cm-s-default .cm-number { color: #a1f7b5 }
.cm-s-default .cm-attribute { color: #6194c6 }
.cm-s-default .cm-bracket { color: #997 }
.cm-s-default .cm-builtin,
.cm-s-default .cm-link { color: #9fb4d6 }
.cm-s-default .cm-comment { color: #747474 }
.cm-s-default .cm-qualifier { color: #ffa34f }
.cm-s-default .cm-def,
.cm-s-default .cm-header,
.cm-s-default .cm-tag,
.cm-s-default .cm-type { color: #5db0d7 }
.cm-s-default .cm-hr { color: #999 }
.cm-s-default .cm-keyword { color: #9a7fd5 }
.cm-s-default .cm-meta { color: #ddfb55 }
.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-3 { color: #9bbbdc }
@keyframes highlight {
from {
background-color: #888;
}
}
}

View File

@ -5,12 +5,11 @@
}
body {
margin: 0;
height: 100vh;
}
a {
color: #000;
color: var(--fg);
transition: color .5s;
}
a:hover {
@ -55,8 +54,8 @@ html:not(.is-new-style) #heading::after {
top: 0;
z-index: 1001;
border: none;
background: #fff;
box-shadow: 0 0 30px #000;
background: var(--bg);
box-shadow: 0 0 30px var(--fg);
}
#popup-iframe:not([data-loaded]) {
opacity: 0;
@ -97,7 +96,7 @@ label {
position: fixed;
top: 0;
padding-top: var(--pad);
box-shadow: 0 0 3rem -1.2rem black;
box-shadow: 0 0 3rem -1.2rem #000;
box-sizing: border-box;
z-index: 10;
display: flex;
@ -173,7 +172,7 @@ label {
#preview-errors {
background-color: red;
color: white;
color: var(--bg);
padding: 0 6px;
border-radius: 9px;
margin-left: -.5em;
@ -206,12 +205,12 @@ label {
.svg-icon:hover,
.svg-icon.info,
.svg-icon.settings {
fill: #666;
fill: var(--c40);
}
.svg-icon,
.svg-icon.info:hover,
.svg-icon.settings:hover {
fill: #000;
fill: var(--fg);
}
#options span .svg-icon {
margin-top: -3px; /* inline info and config icons */
@ -256,7 +255,7 @@ input:invalid {
text-overflow: ellipsis;
}
#header summary:hover h2 {
border-color: #bbb;
border-color: var(--c70);
}
#header summary svg {
margin-top: -3px;
@ -385,7 +384,7 @@ input:invalid {
padding: 1rem;
}
.sectioned .section:not(:first-child) {
border-top: 2px solid hsl(0, 0%, 80%);
border-top: 2px solid var(--c80);
}
.add-section:after {
content: attr(short-text);
@ -649,14 +648,14 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
.add-applies-to .svg-icon,
.remove-applies-to .svg-icon {
pointer-events: none;
fill: hsl(0, 0%, 60%);
fill: var(--c60);
height: 12px;
width: 12px;
}
.add-applies-to:hover .svg-icon,
.remove-applies-to:hover .svg-icon {
pointer-events: none;
fill: hsl(0, 0%, 0%);
fill: var(--fg);
}
.test-regexp {
display: none;
@ -688,7 +687,7 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
color: darkgreen;
}
.regexp-report details[data-type="partial"] {
color: darkgray;
color: var(--c65);
}
.regexp-report details[data-type="invalid"] {
color: maroon;
@ -721,7 +720,7 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
margin-right: .5em;
}
.regexp-report-note {
color: #999;
color: var(--c60);
position: absolute;
bottom: 0;
hyphens: auto;
@ -736,7 +735,7 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
max-width: 50vw;
position: fixed;
display: none;
background-color: white;
background-color: var(--bg);
box-shadow: 3px 3px 30px rgba(0, 0, 0, 0.5);
padding: var(--pad-y) var(--pad-x) 0;
z-index: 99;
@ -980,12 +979,12 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
}
#footer a {
color: #333;
color: var(--c20);
transition: color .5s;
}
#footer a:hover {
color: #666;
color: var(--c40);
}
/************ line widget *************/
@ -1041,14 +1040,14 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
height: unset;
width: 100%;
overflow: visible;
background: #fff;
background: var(--bg);
border-right: none;
border-bottom: 1px dashed #AAA;
border-bottom: 1px dashed var(--c65);
padding: var(--pad05) var(--pad05) 0;
}
#header.sticky {
flex-direction: row;
box-shadow: 0 0 3rem -.75rem black;
box-shadow: 0 0 3rem -.75rem;
}
#header.sticky #basic-info,
#header.sticky #mozilla-format-buttons,
@ -1106,7 +1105,7 @@ body:not(.find-open) [data-match-highlight-count="1"] .CodeMirror-selection-high
position: absolute;
overflow: hidden auto;
max-height: var(--max-height, 10vh);
background: #fff;
background: var(--bg);
box-shadow: 0 6px 20px rgba(0, 0, 0, .3);
padding: var(--pad);
margin-top: var(--pad05);

View File

@ -140,7 +140,6 @@ async function handleExternalUpdate({style, reason}) {
delete style.name;
delete style.enabled;
Object.assign(editor.style, style);
editor.updateLivePreview();
} else {
await editor.replaceStyle(style);
}

View File

@ -158,6 +158,7 @@ function MozSectionWidget(cm, finder = MozSectionFinder(cm)) {
}
if (msg.style || msg.styles ||
msg.prefs && 'disableAll' in msg.prefs ||
msg.method === 'colorScheme' ||
msg.method === 'styleDeleted') {
requestAnimationFrame(updateWidgetStyle);
}

View File

@ -21,7 +21,7 @@
margin-bottom: 0;
}
.style-settings input[type=radio] {
margin-left: -.5em; /* compensate for label's 16px margin in edit.css */
margin: 0 .3em 0 0;
}
.style-settings input:disabled ~ label {
opacity: .5;
@ -44,3 +44,12 @@
.style-settings textarea:not(:placeholder-shown) {
min-width: 50vw;
}
.ss-radio {
display: inline-flex;
align-items: center;
line-height: 2;
padding: 0 .8em 0 0;
}
a[data-cmd=note] {
vertical-align: text-bottom;
}

View File

@ -7,16 +7,26 @@
<input id="ss-update-url" type="url" class="w100" i18n-placeholder="styleUpdateUrlLabel">
</div>
<div id="ss-scheme">
<div i18n-text="installPreferSchemeLabel"></div>
<label i18n-text-append="installPreferSchemeNone">
<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>
<label i18n-text-append="preferSchemeNone" class="ss-radio">
<input name="ss-scheme" type="radio" value="none">
</label>
<label i18n-text-append="installPreferSchemeDark">
<label i18n-text-append="preferSchemeDark" class="ss-radio">
<input name="ss-scheme" type="radio" value="dark">
</label>
<label i18n-text-append="installPreferSchemeLight">
<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"

102
global-dark.css Normal file
View File

@ -0,0 +1,102 @@
@media not screen, dark {
:root {
/* Comfortable dark themes don't use absolutes so the range is compressed */
--c00: hsl(0, 0%, 80%);
--c10: hsl(0, 0%, 73.5%);
--c20: hsl(0, 0%, 66%);
--c30: hsl(0, 0%, 59.5%);
--c40: hsl(0, 0%, 53%);
--c45: hsl(0, 0%, 49.75%);
--c50: hsl(0, 0%, 46.5%);
--c60: hsl(0, 0%, 40%);
--c65: hsl(0, 0%, 36.75%);
--c70: hsl(0, 0%, 33.5%);
--c75: hsl(0, 0%, 30.25%);
--c80: hsl(0, 0%, 27%);
--c85: hsl(0, 0%, 23.75%);
--c90: hsl(0, 0%, 20.5%);
--c95: hsl(0, 0%, 17.25%);
--c100: hsl(0, 0%, 14%);
/* min/max are exposed in case we want to use an overdrive color for emphasis */
--cmin: hsl(0, 0%, 100%);
--cmax: hsl(0, 0%, 0%);
--accent-1: hsl(180, 100%, 95%);
--accent-3: hsl(180, 30%, 18%);
--input-bg: var(--c95);
}
textarea,
input[type=url],
input[type=time] {
background-color: var(--input-bg);
color: var(--fg);
}
input::-webkit-inner-spin-button {
filter: invert(.8);
}
input[type=radio]:checked:after {
background-color: var(--fg);
}
input[type=time]::-webkit-calendar-picker-indicator {
filter: invert(1);
}
select {
background-color: var(--bg);
}
.onoffswitch {
--knob: var(--c50);
}
::-webkit-scrollbar {
width: 14px;
height: 14px;
background: var(--bg);
}
::-webkit-scrollbar-button:single-button {
background: radial-gradient(circle at center, #333 40%, var(--bg) 40%);
}
::-webkit-scrollbar-button:single-button:hover {
background: radial-gradient(circle at center, #444 40%, var(--bg) 40%);
}
::-webkit-scrollbar-button:single-button:active {
background: radial-gradient(circle at center, #555 40%, var(--bg) 40%);
}
::-webkit-scrollbar-track-piece {
background: #333;
border: 4px solid var(--bg);
border-radius: 8px;
}
::-webkit-scrollbar-track-piece:hover {
background: #444;
}
::-webkit-scrollbar-track-piece:active {
background: #555;
}
::-webkit-scrollbar-thumb {
border: 3px solid var(--bg);
border-radius: 8px;
background: #555;
}
::-webkit-scrollbar-thumb:hover {
background: #666;
}
::-webkit-scrollbar-thumb:active {
background: #777;
}
::-webkit-resizer {
background: var(--input-bg) linear-gradient(-45deg,
transparent 3px, #888 3px,
#888 4px, transparent 4px,
transparent 6px, #888 6px,
#888 7px, transparent 7px) no-repeat;
border: 2px solid transparent;
}
:-webkit-autofill {
box-shadow: 0 0 0 1000px var(--input-bg) inset;
-webkit-text-fill-color: #fff;
}
@supports (-moz-appearance: none) {
/* Workarounds for FF bugs/quirks */
textarea {
border: 1px solid var(--c65);
}
}
}

View File

@ -7,9 +7,35 @@ html#stylus #header *:not(#\1transition-suppressor) {
:root {
--family: Arial, "Helvetica Neue", Helvetica, system-ui, sans-serif;
--input-height: 22px;
--cmin: hsl(0, 0%, 00%);
--c00: hsl(0, 0%, 00%);
--c10: hsl(0, 0%, 10%);
--c20: hsl(0, 0%, 20%);
--c30: hsl(0, 0%, 30%);
--c40: hsl(0, 0%, 40%);
--c45: hsl(0, 0%, 45%);
--c50: hsl(0, 0%, 50%);
--c60: hsl(0, 0%, 60%);
--c65: hsl(0, 0%, 65%);
--c70: hsl(0, 0%, 70%);
--c75: hsl(0, 0%, 75%);
--c80: hsl(0, 0%, 80%);
--c85: hsl(0, 0%, 85%);
--c90: hsl(0, 0%, 90%);
--c95: hsl(0, 0%, 95%);
--c100: hsl(0, 0%, 100%);
--cmax: hsl(0, 0%, 100%);
--bg: var(--c100);
--fg: var(--c00);
--accent-1: hsl(180, 100%, 15%);
--accent-2: hsl(180, 50%, 40%);
--accent-3: hsl(180, 40%, 69%);
}
body {
font: normal 12px var(--family);
background-color: var(--bg);
color: var(--fg);
margin: 0;
}
body:lang(ja) {
font-family: Arial, 'Meiryo UI', 'MS Gothic', system-ui, sans-serif;
@ -31,12 +57,12 @@ button {
overflow: hidden;
text-overflow: ellipsis;
padding: 2px 7px;
border: 1px solid hsl(0, 0%, 62%);
border: 1px solid var(--c60);
font: inherit;
font-size: 13px;
line-height: 1.2;
color: #000;
background-color: hsl(0, 0%, 100%);
color: var(--fg);
background-color: var(--bg);
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAYAAADtlXTHAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QwGBBwIHvKt6QAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAL0lEQVQI12NoaGgQZ2JgYGBkYmBgYGZiYGBggrMY4VxsYsyoskQQCB2MWAxAMhkADVECDhlW9CoAAAAASUVORK5CYII=');
background-repeat: repeat-x;
background-size: 100% 100%;
@ -44,13 +70,13 @@ button {
}
button:not(:disabled):hover {
background-color: hsl(0, 0%, 95%);
border-color: hsl(0, 0%, 52%);
background-color: var(--c95);
border-color: var(--c50);
}
button:active {
background-color: hsl(0, 0%, 95%);
border-color: hsl(0, 0%, 52%);
background-color: var(--c95);
border-color: var(--c50);
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAYAAADtlXTHAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QwJARIWJNZvuQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAMElEQVQI12NoaGgIZmJgYPjLxMDA8I+JgYHhP5z1Dy7xH5X7jxQCzWQ0A9DEILYBABm5HtJk2jPHAAAAAElFTkSuQmCC');
background-repeat: repeat-x;
background-size: 100% 100%;
@ -62,27 +88,28 @@ button .svg-icon {
/* For some odd reason these hovers appear lighter than all other button hovers in every browser */
#message-box-buttons button:not(:disabled):hover {
background-color: hsl(0, 0%, 90%);
border-color: hsl(0, 0%, 50%);
background-color: var(--c90);
border-color: var(--c50);
}
input {
font: inherit;
border: 1px solid hsl(0, 0%, 66%);
border: 1px solid var(--c65);
transition: border-color .1s, box-shadow .1s;
}
input:not([type]),
input[type=text],
input[type=number],
input[type=search] {
background: #fff;
color: #000;
background: var(--bg);
color: var(--fg);
height: var(--input-height);
min-height: var(--input-height)!important;
line-height: var(--input-height);
box-sizing: border-box;
padding: 0 3px;
border: 1px solid hsl(0, 0%, 66%);
border: 1px solid var(--c65);
}
.svg-icon {
@ -91,11 +118,11 @@ input[type=search] {
transition: fill .5s;
width: 20px;
height: 20px;
fill: #666;
fill: var(--c40);
}
.svg-icon:hover {
fill: #000;
fill: var(--fg);
}
.svg-icon.info {
@ -114,7 +141,7 @@ input[type=search] {
height: 8px;
width: 8px;
display: none;
fill: #000;
fill: var(--fg);
margin: 2px 0 0 2px;
}
@ -129,7 +156,7 @@ input[type="checkbox"]:not(.slider) {
position: absolute;
left: 0;
top: 0;
border: 1px solid hsl(0, 0%, 46%);
border: 1px solid var(--c45);
height: 12px;
width: 12px;
display: inline-flex;
@ -140,8 +167,8 @@ input[type="checkbox"]:not(.slider) {
}
input[type="checkbox"]:not(.slider):hover {
border-color: hsl(0, 0%, 32%);
background-color: hsl(0, 0%, 82%);
border-color: var(--c30);
background-color: var(--c80);
}
input[type="checkbox"]:not(.slider):checked + .svg-icon.checked {
@ -153,15 +180,15 @@ input[type="checkbox"]:not(.slider):checked + .svg-icon.checked {
input[type="checkbox"]:not(.slider):disabled {
background-color: transparent;
border-color: hsl(0, 0%, 50%);
border-color: var(--c50);
}
input[type="checkbox"]:not(.slider):disabled + .svg-icon.checked {
fill: hsl(0, 0%, 50%);
fill: var(--c50);
}
input[type="checkbox"]:not(.slider):disabled + .svg-icon.checked + span {
color: hsl(0, 0%, 50%);
color: var(--c50);
}
label {
@ -173,9 +200,9 @@ select {
-webkit-appearance: none;
height: var(--input-height);
font: inherit;
color: #000;
color: var(--fg);
background-color: transparent;
border: 1px solid hsl(0, 0%, 66%);
border: 1px solid var(--c65);
padding: 0 20px 0 6px;
transition: color .5s;
}
@ -193,7 +220,7 @@ select {
display: inline-flex;
height: 14px;
width: 14px;
fill: #000;
fill: var(--fg);
position: absolute;
top: 4px;
right: 4px;
@ -203,9 +230,9 @@ select {
input[type="radio"] {
-webkit-appearance: none;
-moz-appearance: none;
background: hsl(0, 0%, 88%);
background: var(--c90);
border-radius: 50%;
border: 1px solid hsl(0, 0%, 60%);
border: 1px solid var(--c60);
cursor: default;
height: 13px;
width: 13px;
@ -227,7 +254,7 @@ input[type="radio"]:after {
}
input[type="radio"]:checked:after {
background-color: hsl(0, 0%, 30%);
background-color: var(--c30);
transform: scale(1);
}
@ -241,7 +268,7 @@ select[disabled] > option {
select:disabled + .select-arrow,
select[disabled] + .select-arrow {
fill: hsl(0, 0%, 50%);
fill: var(--c50);
}
summary {
@ -289,12 +316,12 @@ input[type="number"][data-focused-via-click]:focus {
cursor: e-resize;
border-width: 0 1px;
border-style: solid;
color: #8888;
color: hsla(0, 0%, 50%, .5);
border-color: currentColor;
pointer-events: auto;
}
#header-resizer:active {
border-color: #888;
border-color: var(--c50);
}
#header-resizer::after {
content: '';
@ -340,13 +367,14 @@ body.resizing-v > * {
box-shadow: inset 0 0 100px rgba(0, 0, 0, .2);
}
.split-btn-menu {
background: #fff;
background: var(--bg);
position: absolute;
box-shadow: 2px 3px 7px rgba(0, 0, 0, .5);
border: 1px solid hsl(180deg, 50%, 50%);
white-space: nowrap;
cursor: pointer;
padding: .25em 0;
z-index: 1000;
}
.split-btn-menu > * {
padding: .5em 1em;
@ -354,7 +382,7 @@ body.resizing-v > * {
}
.split-btn-menu > :hover {
background-color: hsla(180deg, 50%, 50%, .25);
color: #000;
color: var(--fg);
}
@supports (-moz-appearance: none) {
@ -370,9 +398,9 @@ body.resizing-v > * {
/* We can customize everything about number inputs except arrows. They're horrible in Linux FF, so we'll hide them unless hovered or focused. */
.firefox.non-windows input[type="number"] {
-moz-appearance: textfield;
background: #fff;
color: #000;
border: 1px solid hsl(0, 0%, 66%);
background: var(--bg);
color: var(--fg);
border: 1px solid var(--c65);
}
.firefox.non-windows input[type="number"]:not(:disabled):hover,
@ -381,8 +409,8 @@ body.resizing-v > * {
}
.firefox.non-windows input[type="color"] {
background: #fff;
border: 1px solid hsl(0, 0%, 66%);
background: var(--bg);
border: 1px solid var(--c65);
padding: 4px;
}
}

View File

@ -44,7 +44,7 @@
justify-content: space-between;
position: relative; /* for incremental-search */
padding: 1px 1px 1px 1rem; /* keyboard focus outline */
color: #000;
color: var(--fg);
transition: transform .25s ease-in-out;
z-index: 1;
user-select: none;

View File

@ -7,6 +7,7 @@
<title>Loading...</title>
<link href="global.css" rel="stylesheet">
<link href="global-dark.css" rel="stylesheet">
<script src="js/polyfill.js"></script>
<script src="js/msg.js"></script>
@ -20,8 +21,47 @@
<script src="content/style-injector.js"></script>
<script src="content/apply.js"></script>
<template data-id="jumpToLine">
<span i18n-text="editGotoLine">: <input class="CodeMirror-jump-field" type="text"></span>
</template>
<script src="vendor/codemirror/lib/codemirror.js"></script>
<script src="vendor/codemirror/mode/css/css.js"></script>
<script src="vendor/codemirror/mode/stylus/stylus.js"></script>
<script src="vendor/codemirror/addon/dialog/dialog.js"></script>
<script src="vendor/codemirror/addon/edit/closebrackets.js"></script>
<script src="vendor/codemirror/addon/scroll/annotatescrollbar.js"></script>
<script src="vendor/codemirror/addon/search/searchcursor.js"></script>
<script src="vendor/codemirror/addon/search/matchesonscrollbar.js"></script>
<script src="vendor/codemirror/addon/comment/comment.js"></script>
<script src="vendor/codemirror/addon/selection/active-line.js"></script>
<script src="vendor/codemirror/addon/edit/matchbrackets.js"></script>
<script src="vendor/codemirror/addon/fold/foldcode.js"></script>
<script src="vendor/codemirror/addon/fold/foldgutter.js"></script>
<script src="vendor/codemirror/addon/fold/brace-fold.js"></script>
<script src="vendor/codemirror/addon/fold/indent-fold.js"></script>
<script src="vendor/codemirror/addon/fold/comment-fold.js"></script>
<script src="vendor/codemirror/addon/lint/lint.js"></script>
<script src="vendor/codemirror/addon/hint/show-hint.js"></script>
<script src="vendor/codemirror/addon/hint/css-hint.js"></script>
<script src="vendor/codemirror/keymap/sublime.js"></script>
<script src="vendor/codemirror/keymap/emacs.js"></script>
<script src="vendor/codemirror/keymap/vim.js"></script>
<script src="vendor-overwrites/codemirror-addon/match-highlighter.js"></script>
<script src="edit/codemirror-default.js"></script>
<script src="js/color/color-converter.js"></script>
<script src="js/color/color-view.js"></script>
<script src="js/sections-util.js"></script>
<script src="js/cmpver.js"></script>
<link href="vendor/codemirror/lib/codemirror.css" rel="stylesheet">
<link href="vendor/codemirror/addon/dialog/dialog.css" rel="stylesheet">
<link href="vendor/codemirror/addon/fold/foldgutter.css" rel="stylesheet">
<link href="vendor/codemirror/addon/search/matchesonscrollbar.css" rel="stylesheet">
<link href="edit/codemirror-default.css" rel="stylesheet">
<link href="spinner.css" rel="stylesheet">
<link href="install-usercss/install-usercss.css" rel="stylesheet">
<script src="js/dark-themer.js"></script> <!-- must be here to avoid FOUC -->
</head>
<body id="stylus-install-usercss">
<div id="header">
@ -80,6 +120,11 @@
</div>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none !important;">
<symbol id="svg-icon-help" viewBox="0 0 14 16" i18n-alt="helpAlt">
<circle cx="7" cy="5" r="1"/>
<path d="M8,8c0-0.5-0.5-1-1-1H6C5.5,7,5,7.4,5,8h1v3c0,0.5,0.5,1,1,1h1c0.5,0,1-0.4,1-1H8V8z"/>
<path d="M7,1c3.9,0,7,3.1,7,7s-3.1,7-7,7s-7-3.1-7-7S3.1,1,7,1z M7,2.3C3.9,2.3,1.3,4.9,1.3,8s2.6,5.7,5.7,5.7s5.7-2.6,5.7-5.7S10.1,2.3,7,2.3C7,2.3,7,2.3,7,2.3z"/>
</symbol>
<symbol id="svg-icon-checked" viewBox="0 0 1000 1000">
<path fill-rule="evenodd" d="M983.2,184.3L853,69.8c-4-3.5-9.3-5.3-14.5-5c-5.3,0.4-10.3,2.8-13.8,6.8L352.3,609.2L184.4,386.9c-3.2-4.2-8-7-13.2-7.8c-5.3-0.8-10.6,0.6-14.9,3.9L18,487.5c-8.8,6.7-10.6,19.3-3.9,28.1L325,927.2c3.6,4.8,9.3,7.7,15.3,8c0.2,0,0.5,0,0.7,0c5.8,0,11.3-2.5,15.1-6.8L985,212.6C992.3,204.3,991.5,191.6,983.2,184.3z"/>
</symbol>

View File

@ -1,18 +1,16 @@
body {
overflow: hidden;
margin: 0;
background: white;
display: flex;
height: 100vh;
}
a {
color: #000;
color: var(--fg);
transition: color .5s;
}
a:hover {
color: #666;
color: var(--c40);
}
img.icon {
@ -21,7 +19,7 @@ img.icon {
}
input:disabled + span {
color: rgb(128, 128, 128);
color: var(--c50);
}
#header,
@ -54,7 +52,7 @@ input:disabled + span {
flex-basis: auto;
background: #ffe2e2;
border-right: none;
border-bottom: 1px dashed #aaa;
border-bottom: 1px dashed var(--c65);
}
.has-warnings .warnings {
@ -143,7 +141,7 @@ h1 {
.install:hover:not(:disabled) {
background-color: hsl(0, 0%, 38%);
color: #fff;
color: var(--bg);
text-shadow: none;
}
@ -326,7 +324,7 @@ li {
flex-direction: column;
}
#header {
border-bottom: 1px dashed #AAA;
border-bottom: 1px dashed var(--c65);
min-height: 6rem;
max-height: 40vh;
resize: vertical;

View File

@ -1,9 +1,12 @@
/* global $$ $ $create $createLink $$remove showSpinner */// dom.js
/* global API */// msg.js
/* global CodeMirror */
/* global URLS closeCurrentTab deepEqual */// toolbox.js
/* global compareVersion */// cmpver.js
/* global messageBox */
/* global prefs */
/* global preinit */
/* global styleCodeEmpty */// sections-util.js
/* global t */// localization.js
'use strict';
@ -40,31 +43,6 @@ setTimeout(() => !cm && showSpinner($('#header')), 200);
if (theme !== 'default') {
require([`/vendor/codemirror/theme/${theme}.css`]); // not awaiting as it may be absent
}
const scriptsReady = require([
'/vendor/codemirror/lib/codemirror', /* global CodeMirror */
]).then(() => require([
'/vendor/codemirror/keymap/sublime',
'/vendor/codemirror/keymap/emacs',
'/vendor/codemirror/keymap/vim', // TODO: load conditionally
'/vendor/codemirror/mode/css/css',
'/vendor/codemirror/mode/stylus/stylus',
'/vendor/codemirror/addon/search/searchcursor',
'/vendor/codemirror/addon/fold/foldcode',
'/vendor/codemirror/addon/fold/foldgutter',
'/vendor/codemirror/addon/fold/brace-fold',
'/vendor/codemirror/addon/fold/indent-fold',
'/vendor/codemirror/addon/selection/active-line',
'/vendor/codemirror/lib/codemirror.css',
'/vendor/codemirror/addon/fold/foldgutter.css',
'/js/cmpver', /* global compareVersion */
'/js/sections-util', /* global styleCodeEmpty */
'/js/color/color-converter',
'/edit/codemirror-default.css',
])).then(() => require([
'/edit/codemirror-default',
'/js/color/color-view',
]));
({tabId, initialUrl} = preinit);
liveReload = initLiveReload();
preinit.tpl.then(el => $('#ss-scheme').append(...$('#ss-scheme', el).children));
@ -80,7 +58,6 @@ setTimeout(() => !cm && showSpinner($('#header')), 200);
messageBox.alert(isNaN(error) ? `${error}` : 'HTTP Error ' + error, 'pre');
return;
}
await scriptsReady;
cm = CodeMirror($('.main'), {
value: sourceCode || style.sourceCode,
readOnly: true,

30
js/dark-themer.js Normal file
View File

@ -0,0 +1,30 @@
/* global API msg */// msg.js
'use strict';
/**
* 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.
*/
API.colorScheme.shouldIncludeStyle({preferScheme: 'dark!'}).then(val => {
let isDark = val;
toggleDarkStyles();
msg.onExtension(e => {
if (e.method === 'colorScheme') {
isDark = e.value;
toggleDarkStyles();
}
});
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`;
}
}
}
}
});

View File

@ -49,7 +49,7 @@
}
.config-body label:not(:first-child) {
border-top: 1px dotted #ccc;
border-top: 1px dotted var(--c80);
}
.config-body .dirty {
@ -125,7 +125,7 @@
.config-reset-icon .svg-icon {
cursor: pointer;
fill: #aaa;
fill: var(--c65);
width: var(--pad);
height: var(--pad);
padding: 0 1px;
@ -134,7 +134,7 @@
}
.config-reset-icon:hover .svg-icon {
fill: #666;
fill: var(--c40);
}
#config-autosave-wrapper {
@ -188,7 +188,7 @@
position: absolute;
top: 0;
left: 0;
border: 1px solid gray;
border: 1px solid var(--c50);
cursor: pointer;
opacity: 1;
z-index: 2;

View File

@ -26,7 +26,7 @@
position: fixed;
display: flex;
flex-direction: column;
background-color: white;
background-color: var(--bg);
box-shadow: 5px 5px 50px rgba(0, 0, 0, 0.225);
z-index: 9999991;
-moz-user-select: text;
@ -68,7 +68,7 @@
#message-box-title {
font-weight: bold;
background-color: rgb(145, 208, 198);
background-color: var(--accent-3);
padding: .75rem 24px .75rem 52px;
font-size: 1rem;
position: relative;
@ -143,7 +143,7 @@
#message-box-buttons {
padding: .75rem .375rem;
background-color: #f0f0f0;
background-color: var(--c95);
text-align: center;
}

View File

@ -278,7 +278,7 @@ function moveFocus(rootElement, step) {
function onDOMready() {
return document.readyState !== 'loading'
? Promise.resolve()
: new Promise(resolve => document.on('DOMContentLoaded', resolve, {once: true}));
: new Promise(resolve => document.on('DOMContentLoaded', () => resolve(), {once: true}));
}
/**

View File

@ -32,7 +32,7 @@
// checkbox in style config dialog
'config.autosave': true,
'schemeSwitcher.enabled': 'never',
'schemeSwitcher.enabled': 'system',
'schemeSwitcher.nightStart': '18:00',
'schemeSwitcher.nightEnd': '06:00',

View File

@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title i18n-text="manageTitle"></title>
<link rel="stylesheet" href="global.css">
<link href="global-dark.css" rel="stylesheet">
<!-- Notes:
* Chrome doesn't garbage-collect (or even leaks) SVG <symbol> referenced via <use> so we'll embed the code directly
@ -155,6 +156,7 @@
<script src="manage/manage.js"></script>
<link rel="stylesheet" href="manage/manage.css">
<script src="js/dark-themer.js"></script> <!-- must be here to avoid FOUC -->
</head>
<body id="stylus-manage" i18n-dragndrop-hint="dragDropMessage">

View File

@ -3,9 +3,7 @@
--name-padding-right: 40px;
--actions-width: 75px;
}
body {
margin: 0;
/* Fill the entire viewport to enable json import via drag'n'drop */
display: flex;
height: 100vh;
@ -37,12 +35,12 @@ body.all-styles-hidden-by-filters::after {
}
a, .disabled a:hover {
color: #000;
color: var(--fg);
transition: color .5s;
}
a:hover {
color: #666;
color: var(--c40);
}
#header {
@ -98,7 +96,7 @@ a:hover {
}
#add-style-as-usercss-wrapper:not(:hover) input:not(:checked) ~ a svg {
fill: #aaa;
fill: var(--c65);
}
#add-style-as-usercss-wrapper input {
@ -136,7 +134,7 @@ a:hover {
.entry {
margin: 0;
padding: 1.25em 2em;
border-top: 1px solid #ddd;
border-top: 1px solid var(--c85);
}
.entry:first-child {
@ -225,7 +223,7 @@ a:hover {
content: "UC";
background-color: hsla(180, 35%, 50%, .35);
padding: 2px 3px;
color: #000;
color: var(--fg);
}
.oldUI .disabled h2::after {
content: var(--genericDisabledLabel);
@ -244,8 +242,8 @@ a:hover {
.disabled h2 .style-name-link,
.disabled .applies-to,
.newUI .disabled.entry .svg-icon {
color: #888;
fill: #c4c4c4;
color: var(--c50);
fill: var(--c80);
font-weight: normal;
transition: color .5s .1s, fill .5s .1s;
}
@ -311,7 +309,7 @@ a:hover {
margin-bottom: .1em;
}
#header summary:hover h2 {
border-color: #bbb;
border-color: var(--c75);
}
#header summary h2 [data-cmd="note"] {
display: inline-flex;
@ -349,7 +347,7 @@ a:hover {
}
.style-info[data-type=version] {
color: #666;
color: var(--c40);
padding-left: .5em;
font-weight: normal;
}
@ -359,7 +357,7 @@ a:hover {
display: none;
}
.newUI .entry .style-info[data-type=age] {
color: #999;
color: var(--c60);
text-align: right;
padding-right: 1em;
}
@ -459,7 +457,7 @@ a:hover {
.newUI .entry .svg-icon.checked,
.newUI .entry:hover .svg-icon.checked {
fill: #000;
fill: var(--fg);
}
.newUI .entry input[type="checkbox"]:not(.slider) {
@ -486,7 +484,7 @@ a:hover {
}
.newUI .entry.enabled .style-name:hover .style-name-link {
color: hsla(180, 100%, 15%, 1);
color: var(--accent-1);
}
.newUI .style-name:after {
@ -521,15 +519,15 @@ a:hover {
}
.newUI .entry .svg-icon {
fill: #999;
fill: var(--c60);
}
.newUI .entry:hover .svg-icon {
fill: #666;
fill: var(--c40);
}
.newUI .entry:hover .svg-icon:hover {
fill: #000;
fill: var(--fg);
}
.newUI .checking-update .check-update {
@ -823,7 +821,7 @@ a:hover {
}
#reset-filters svg {
fill: hsla(180, 50%, 27%, .5);
fill: var(--accent-2);
width: 24px; /* widen the click area a bit */
height: 20px;
padding: 2px;
@ -831,7 +829,7 @@ a:hover {
}
#reset-filters:hover svg {
fill: hsla(180, 50%, 27%, 1);
filter: brightness(1.2);
}
#filters summary:not(.active) #reset-filters,
@ -866,12 +864,12 @@ a:hover {
#search, #manage\.newUI\.sort {
min-width: 4em; /* reduces the big default width */
flex-grow: 1;
background: #fff;
background: var(--bg);
height: 20px;
box-sizing: border-box;
padding: 3px 3px 3px 4px;
color: #000;
border: 1px solid hsl(0, 0%, 66%);
color: var(--fg);
border: 1px solid var(--c65);
}
#manage\.newUI\.sort {
@ -1086,7 +1084,7 @@ a:hover {
width: 100%;
position: static;
border-right: none;
border-bottom: 1px dashed #AAA;
border-bottom: 1px dashed var(--c65);
}
#manage-settings {

View File

@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title i18n-text-append="optionsHeading">Stylus </title>
<link rel="stylesheet" href="global.css">
<link href="global-dark.css" rel="stylesheet">
<script src="js/polyfill.js"></script>
<script src="js/toolbox.js"></script>
@ -18,6 +19,7 @@
<link rel="stylesheet" href="options/onoffswitch.css">
<link rel="stylesheet" href="options/options.css">
<script src="js/dark-themer.js"></script> <!-- must be here to avoid FOUC -->
</head>
<body id="stylus-options">
@ -46,6 +48,30 @@
</div>
</div>
<div class="block">
<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>
<label class="radio-group-item">
<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">
<span i18n-text="optionsAdvancedAutoSwitchSchemeByTime"></span>
<input type="time" required id="schemeSwitcher.nightStart">
~
<input type="time" required id="schemeSwitcher.nightEnd">
</label>
</div>
</div>
</div>
<div class="block">
<h1 i18n-text="optionsCustomizeIcon"></h1>
<div class="items">
@ -288,26 +314,6 @@
<span></span>
</span>
</label>
<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>
<label class="radio-group-item">
<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">
<span>
<span i18n-text="optionsAdvancedAutoSwitchSchemeByTime"></span>
<input type="text" pattern="\d{2}:\d{2}" required id="schemeSwitcher.nightStart" class="input-sm">
~
<input type="text" pattern="\d{2}:\d{2}" required id="schemeSwitcher.nightEnd" class="input-sm">
</span>
</label>
</div>
</div>
</div>

View File

@ -5,6 +5,7 @@
margin: 1ex 0;
-moz-user-select: none;
user-select: none;
--knob: var(--c95);
}
.onoffswitch input {
@ -32,9 +33,9 @@
height: 12px;
padding: 0;
line-height: 12px;
border: 0 solid #E3E3E3;
border: 0 solid var(--c90);
border-radius: 12px;
background-color: #E0E0E0;
background-color: var(--c85);
box-shadow: inset 2px 2px 4px rgba(0,0,0,0.1);
pointer-events: none; /* this is just a non-clickable decoration, only `input` is clickable */
}
@ -45,7 +46,7 @@
width: 18px;
height: 18px;
margin: -3px;
background: #efefef;
background: var(--knob);
position: absolute;
top: 0;
bottom: 0;
@ -55,7 +56,7 @@
}
.onoffswitch input:checked + span {
background-color: #CAEBE3;
background-color: hsla(165, 45%, 50%, .3);
}
.onoffswitch input:checked + span, .onoffswitch input:checked + span::before {

View File

@ -8,7 +8,6 @@ html {
body {
background: none;
margin: 0;
font-family: "Helvetica Neue", Helvetica, sans-serif;
font-size: 12px;
display: flex;
@ -16,7 +15,7 @@ body {
width: auto;
max-width: 800px;
max-height: calc(100vh - 32px);
border: 1px solid #999;
border: 1px solid var(--c60);
box-shadow: 0px 5px 15px 3px hsla(0, 0%, 0%, .35);
animation: scalein .25s ease-in-out;
}
@ -26,7 +25,7 @@ body.scaleout {
}
#options {
background: #fff;
background: var(--bg);
display: flex;
flex-direction: column;
overflow: hidden;
@ -37,17 +36,17 @@ body.scaleout {
}
a {
color: #000;
color: var(--fg);
transition: color .5s;
}
a:hover {
color: #666;
color: var(--c40);
}
a:hover .svg-icon,
.svg-icon:hover {
fill: #000;
fill: var(--fg);
}
.svg-inline-wrapper .svg-icon {
@ -55,12 +54,12 @@ a:hover .svg-icon,
}
#options-close-icon .svg-icon {
fill: #666;
fill: var(--c40);
transition: fill .5s;
}
#options-close-icon:hover .svg-icon {
fill: #000;
fill: var(--fg);
}
#options-close-icon {
@ -78,14 +77,14 @@ a:hover .svg-icon,
#options-title {
font-weight: bold;
background-color: rgb(145, 208, 198);
background-color: var(--accent-3);
padding: .75rem 26px .75rem calc(30% + 4px);
font-size: 22px;
letter-spacing: .5px;
position: relative;
min-height: 42px;
box-sizing: border-box;
border-bottom: 1px solid #999;
border-bottom: 1px solid var(--c40);
}
#options-title::before {
@ -107,7 +106,7 @@ a:hover .svg-icon,
}
label.chromium-only > :first-child::after {
content: '(Chrome)';
color: #888;
color: var(--c50);
margin-left: .5ex;
}
@ -115,7 +114,7 @@ label.chromium-only > :first-child::after {
display: flex;
align-items: center;
margin: 1em 0;
border-bottom: 1px dotted #ccc;
border-bottom: 1px dotted var(--c80);
padding: 0 16px .75em;
position: relative;
}
@ -215,7 +214,7 @@ input[type="color"] {
white-space: nowrap;
background-color: rgba(0, 0, 0, .05);
margin: 0;
border-top: 1px solid #999;
border-top: 1px solid var(--c60);
border-bottom: none;
min-height: min-content; /* workaround for old Chrome ~70 bug when the window height is small */
}
@ -275,12 +274,12 @@ html:not(.firefox):not(.opera) #updates {
.svg-inline-wrapper .svg-icon {
width: 16px;
height: 16px;
fill: #666;
fill: var(--c40);
vertical-align: sub;
}
.svg-inline-wrapper:hover .svg-icon {
fill: #000;
fill: var(--fg);
}
#message-box.note {
@ -296,55 +295,22 @@ html:not(.firefox):not(.opera) #updates {
position: relative;
}
/* radio group */
.radio-group-item {
display: flex;
align-items: center;
min-height: 1.5em;
line-height: 1.5;
}
.radio-group-item > input {
margin: 0 8px 0 0;
flex-grow: 0;
.radio-group-item > input[type=radio] {
margin: 0 .5em 0 0;
flex: 0 0 auto;
}
.radio-group-label {
display: block;
margin: 0 0 .3em;
}
.input-sm {
width: 3em;
}
/* pixel perfect radio */
input[type="radio"].radio::after {
position: absolute;
top: -1px;
right: -1px;
bottom: -1px;
left: -1px;
height: auto;
width: auto;
transform: scale(0);
}
input[type="radio"].radio:checked::after {
transform: scale(.65);
}
@keyframes fadeinout {
0% { opacity: 0 }
10% { opacity: 1 }
25% { opacity: 1 }
100% { opacity: 0 }
}
@media (hover: none) {
.expanded-note {
font-size: 90%;
white-space: normal;
color: #666;
margin-top: .5em;
hyphens: auto;
}
input[type=time] {
margin: 0 .5em;
max-width: 7em; /* TODO: remove when strict_min_version >= 57 */
}
.sync-status {

View File

@ -5,6 +5,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="global.css">
<link href="global-dark.css" rel="stylesheet">
<template data-id="style">
<div class="entry">
@ -171,6 +172,7 @@
<script src="content/apply.js"></script>
<link rel="stylesheet" href="popup/popup.css">
<script src="js/dark-themer.js"></script> <!-- must be here to avoid FOUC -->
</head>
<body id="stylus-popup">

View File

@ -11,12 +11,7 @@ html, body {
body {
width: 252px;
margin: 0;
}
.firefox body {
color: #000;
background-color: #fff;
overflow: hidden;
}
.firefox button {
@ -33,14 +28,10 @@ body > div:not(#installed):not(#message-box):not(.colorpicker-popup) {
}
/************ checkbox ************/
.style-name:hover .checker:checked {
border-color: hsl(0, 0%, 32%);
background-color: hsl(0, 0%, 82%);
}
.style-name:hover .checker:checked,
.style-name:hover .checker {
border-color: hsl(0, 0%, 32%);
background-color: hsl(0, 0%, 82%);
border-color: var(--c30);
background-color: var(--c80);
}
#disable-all-wrapper input[type="checkbox"]:not(.slider):checked + .svg-icon.checked {
@ -59,7 +50,7 @@ body > div:not(#installed):not(#message-box):not(.colorpicker-popup) {
}
#installed.disabled + .actions #disableAll:checked:hover + .svg-icon.checked {
fill: #fff;
fill: var(--bg);
}
#disableAll:hover {
@ -119,12 +110,12 @@ body > div:not(#installed):not(#message-box):not(.colorpicker-popup) {
}
a {
color: #000;
color: var(--fg);
transition: color .5s;
}
a:hover {
color: #666;
color: var(--c40);
}
.actions > .main-controls {
@ -141,7 +132,7 @@ body.blocked > DIV {
}
#installed {
border-bottom: 1px solid black;
border-bottom: 1px solid var(--c85);
max-height: 445px;
overflow-y: auto;
counter-reset: style-number;
@ -181,10 +172,6 @@ html[style] .entry-content {
padding: 0 var(--hotkey-margin) 0 0;
}
#no-styles.entry {
padding: 0 14px;
}
.entry .actions {
display: inline-flex;
align-items: center;
@ -224,14 +211,14 @@ html[style] .entry-content {
.entry.disabled .style-name,
.entry.disabled .svg-icon {
font-weight: normal;
color: #888;
fill: #aaa;
color: var(--c50);
fill: var(--c65);
}
.entry.disabled:hover .svg-icon {
fill: #666;
fill: var(--c40);
}
.entry.disabled:hover a:hover .svg-icon {
fill: #000;
fill: var(--fg);
}
.entry .main-controls {
@ -254,7 +241,7 @@ html[style] .entry-content {
position: absolute;
top: .9ex;
right: 5px;
color: #aaa;
color: var(--c65);
}
.entry:nth-child(11):before {
@ -367,7 +354,7 @@ a.configure[target="_blank"] .svg-icon.config {
display: flex;
position: relative;
flex-direction: column;
background-color: #fff;
background-color: var(--bg);
border: solid 2px rgba(0, 0, 0, 0.5);
}
.menu-buttons-wrapper {
@ -393,7 +380,7 @@ a.configure[target="_blank"] .svg-icon.config {
}
.entry .menu-item:hover,
.entry .menu-item:active {
background-color: rgba(0, 0, 0, 0.1);
background-color: var(--c95);
transition: background-color .25s;
}
.entry .menu-icon {
@ -445,16 +432,16 @@ a.configure[target="_blank"] .svg-icon.config {
#regexp-explanation {
position: fixed;
background-color: white;
background-color: var(--bg);
top: 50%;
transform: translateY(-50%);
left: 0;
right: 0;
padding: .5rem;
font-size: 90%;
border-top: 2px solid black;
border-bottom: 2px solid black;
box-shadow: 0 0 100px black;
border-top: 2px solid var(--fg);
border-bottom: 2px solid var(--fg);
box-shadow: 0 0 100px var(--fg);
display: flex;
flex-direction: column;
z-index: 999999;
@ -483,7 +470,7 @@ a.configure[target="_blank"] .svg-icon.config {
}
a:hover .svg-icon {
fill: #000;
fill: var(--fg);
}
body > .actions {
@ -620,7 +607,7 @@ body.blocked .actions > .main-controls {
}
.breadcrumbs:hover a {
color: #bbb;
color: var(--c75);
text-decoration: none
}
@ -714,7 +701,7 @@ html:not(.styles-last) .split-btn-pedal::after {
order: 2;
}
.styles-last #installed {
border-top: 1px solid black;
border-top: 1px solid var(--fg);
}
/* confirm */
@ -756,7 +743,7 @@ html:not(.styles-last) .split-btn-pedal::after {
max-height: 80%;
min-height: 6em;
padding: 1em;
background-color: #fff;
background-color: var(--bg);
display: flex;
flex-direction: column;
border: solid 2px rgba(0, 0, 0, 0.5);
@ -780,7 +767,7 @@ html:not(.styles-last) .split-btn-pedal::after {
max-height: 80%;
min-height: 6em;
padding: 1em;
background-color: #fff;
background-color: var(--bg);
display: flex;
flex-direction: column;
border: solid 2px rgba(0, 0, 0, 0.5);
@ -810,7 +797,7 @@ html:not(.styles-last) .split-btn-pedal::after {
}
.unreachable .blocked-info {
border-bottom: 1px solid black;
border-bottom: 1px solid var(--fg);
}
.blocked-info {
@ -843,12 +830,12 @@ html:not(.styles-last) .split-btn-pedal::after {
}
.blocked-info .copy:hover {
color: #000;
color: var(--fg);
}
.blocked-info .copy.copied {
background: hsl(170, 40%, 80%);
color: #000;
color: var(--fg);
}
.copy-message {
@ -863,7 +850,7 @@ html:not(.styles-last) .split-btn-pedal::after {
text-align: center;
padding: 4px 0;
background: hsl(170, 40%, 80%);
color: #000;
color: var(--fg);
z-index: 10;
}
@ -907,7 +894,7 @@ html:not(.styles-last) .split-btn-pedal::after {
cursor: auto;
display: flex;
flex-direction: column;
border-left: 2px solid white;
border-left: 2px solid var(--bg);
box-shadow: 0 0 90px rgba(0, 0, 0, .5);
z-index: 5;
}
@ -921,8 +908,8 @@ html:not(.styles-last) .split-btn-pedal::after {
#hotkey-info div {
padding: 1em;
border-top: 1px solid #ddd;
background-color: white;
border-top: 1px solid var(--c85);
background-color: var(--bg);
}
#hotkey-info div:last-child {
@ -940,10 +927,10 @@ html:not(.styles-last) .split-btn-pedal::after {
#hotkey-info mark {
display: inline-block;
background: linear-gradient(#ccc, #fff);
background: linear-gradient(var(--c80), var(--bg));
padding: 1px 6px 0;
margin: 2px;
border: 1px solid white;
border: 1px solid var(--bg);
border-radius: 4px;
box-shadow: 1px 1px 4px rgba(0, 0, 0, .3);
font-weight: bold;

View File

@ -49,19 +49,19 @@ body.search-results-shown {
.search-result {
box-shadow: 1px 1px 10px rgba(0, 0, 0, .75);
border-radius: 4px;
border: 1px solid #555;
border: 1px solid var(--c50);
margin-bottom: 24px;
background-color: #eee;
background-color: var(--c95);
}
.search-result:hover {
border-color: #000;
background-color: #fff;
border-color: var(--fg);
background-color: var(--c90);
}
#search-results .lds-spinner {
transform: scale(.5);
filter: invert(1) drop-shadow(1px 1px 3px #000);
filter: invert(1) drop-shadow(1px 1px 3px var(--fg));
}
#search-results .search-result-empty .lds-spinner {
@ -79,7 +79,7 @@ body.search-results-shown {
display: flex;
align-items: center;
margin-bottom: .5em;
color: #555;
color: var(--c30);
overflow-wrap: break-word;
}
@ -95,7 +95,7 @@ body.search-results-shown {
}
.search-result:hover .search-result-title {
color: initial;
color: var(--fg);
}
.search-result-info {
@ -110,7 +110,7 @@ body.search-results-shown {
text-align: center;
position: absolute;
background-color: hsla(180, 100%, 27%, .75);
color: #fff;
color: var(--bg);
transition: background-color .5s;
pointer-events: none;
}
@ -123,7 +123,7 @@ body.search-results-shown {
}
.search-result-screenshot:hover ~ .search-result-status {
background-color: hsla(180, 100%, 27%, 1);
color: #fff;
color: var(--bg);
}
.search-result-actions {
@ -142,7 +142,7 @@ body.search-results-shown {
opacity: 1;
}
.search-result-actions button {
box-shadow: 2px 2px 20px #000;
box-shadow: 2px 2px 20px var(--fg);
white-space: nowrap;
margin: 3px;
}
@ -160,7 +160,6 @@ body.search-results-shown {
}
.search-result-meta {
background-color: hsla(0, 0%, 93%, 0.75);
display: flex;
justify-content: space-between;
flex-wrap: wrap;
@ -171,9 +170,25 @@ body.search-results-shown {
margin: 0;
padding-bottom: 3px;
}
.search-result-meta::before {
transition: .25s;
background-color: var(--c95);
opacity: .65;
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 22px;
z-index: 1;
}
.search-result-meta > * {
z-index: 2;
}
.search-result:hover .search-result-meta {
background-color: hsla(0, 0%, 100%, 0.75);
.search-result:hover .search-result-meta::before {
background-color: var(--c90);
opacity: 1;
}
.search-result-meta dt {