From 2d26280dab047a0291c1d859eb4c4d5275e5a8be Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Thu, 27 Aug 2020 15:57:24 +1000 Subject: [PATCH] migrate the majority of the sass vars to css variables Allows add-ons to easily override the theme, and allows us to apply styling to elements outside of the normal document flow (like applying the normal background colour to a position: fixed element). --- qt/Makefile | 2 +- qt/aqt/theme.py | 2 +- qt/aqt/webview.py | 118 +++++++++++++++++--------------- qt/ts/scss/_buttons.scss | 22 +++--- qt/ts/scss/_card_counts.scss | 18 +++-- qt/ts/scss/deckbrowser.scss | 25 ++++--- qt/ts/scss/editor.scss | 20 +++--- qt/ts/scss/overview.scss | 5 +- qt/ts/scss/reviewer-bottom.scss | 5 +- qt/ts/scss/reviewer.scss | 6 +- qt/ts/scss/toolbar.scss | 20 +++--- qt/ts/scss/webview.scss | 19 +++-- ts/src/scss/_vars.scss | 53 ++++++++++++-- 13 files changed, 177 insertions(+), 138 deletions(-) diff --git a/qt/Makefile b/qt/Makefile index 4fc6b482f..d690ab52e 100644 --- a/qt/Makefile +++ b/qt/Makefile @@ -52,7 +52,7 @@ all: check ./scripts/copy-qt-files) @touch $@ -TSDEPS := $(wildcard ts/src/*.ts) $(wildcard ts/scss/*.scss) +TSDEPS := $(wildcard ts/src/*.ts) $(wildcard ts/scss/*.scss) $(wildcard ../ts/src/scss/*) .build/js: $(TSDEPS) (cd ts && make build) diff --git a/qt/aqt/theme.py b/qt/aqt/theme.py index 29c926421..a29fa26e6 100644 --- a/qt/aqt/theme.py +++ b/qt/aqt/theme.py @@ -182,7 +182,7 @@ QTabWidget { background-color: %s; } palette.setColor(QPalette.Window, window_bg) palette.setColor(QPalette.AlternateBase, window_bg) - palette.setColor(QPalette.Button, QColor(colors.get("fusion-button-base-bg"))) + palette.setColor(QPalette.Button, QColor("#454545")) frame_bg = self.qcolor("frame-bg") palette.setColor(QPalette.Base, frame_bg) diff --git a/qt/aqt/webview.py b/qt/aqt/webview.py index 150468906..789991c7c 100644 --- a/qt/aqt/webview.py +++ b/qt/aqt/webview.py @@ -359,45 +359,28 @@ class AnkiWebView(QWebEngineView): return QColor("#ececec") return self.style().standardPalette().color(QPalette.Window) - def stdHtml( - self, - body: str, - css: Optional[List[str]] = None, - js: Optional[List[str]] = None, - head: str = "", - context: Optional[Any] = None, - ): - - web_content = WebContent( - body=body, - head=head, - js=["webview.js"] + (["jquery.js"] if js is None else js), - css=["webview.css"] + ([] if css is None else css), - ) - - gui_hooks.webview_will_set_content(web_content, context) - + def standard_css(self) -> str: palette = self.style().standardPalette() color_hl = palette.color(QPalette.Highlight).name() if isWin: # T: include a font for your language on Windows, eg: "Segoe UI", "MS Mincho" family = _('"Segoe UI"') - widgetspec = "button { font-family:%s; }" % family - widgetspec += "\n:focus { outline: 1px solid %s; }" % color_hl - fontspec = "font-size:12px;font-family:%s;" % family + button_style = "button { font-family:%s; }" % family + button_style += "\n:focus { outline: 1px solid %s; }" % color_hl + font = "font-size:12px;font-family:%s;" % family elif isMac: family = "Helvetica" - fontspec = 'font-size:15px;font-family:"%s";' % family - widgetspec = """ + font = 'font-size:15px;font-family:"%s";' % family + button_style = """ button { -webkit-appearance: none; background: #fff; border: 1px solid #ccc; border-radius:5px; font-family: Helvetica }""" else: family = self.font().family() color_hl_txt = palette.color(QPalette.HighlightedText).name() color_btn = palette.color(QPalette.Button).name() - fontspec = 'font-size:14px;font-family:"%s";' % family - widgetspec = """ + font = 'font-size:14px;font-family:"%s";' % family + button_style = """ /* Buttons */ button{ background-color: %(color_btn)s; @@ -416,45 +399,70 @@ div[contenteditable="true"]:focus { "color_hl_txt": color_hl_txt, } - csstxt = "\n".join(self.bundledCSS(fname) for fname in web_content.css) - jstxt = "\n".join(self.bundledScript(fname) for fname in web_content.js) - - from aqt import mw - - head = mw.baseHTML() + csstxt + jstxt + web_content.head - - body_class = theme_manager.body_class() + zoom = self.zoomFactor() + background = self._getWindowColor().name() if is_rtl(anki.lang.currentLang): lang_dir = "rtl" else: lang_dir = "ltr" - html = """ - - -{} + return f""" +body {{ zoom: {zoom}; background: {background}; direction: {lang_dir}; {font} }} +{button_style} +:root {{ --window-bg: {background} }} +""" - - -{} + def stdHtml( + self, + body: str, + css: Optional[List[str]] = None, + js: Optional[List[str]] = None, + head: str = "", + context: Optional[Any] = None, + ): + + web_content = WebContent( + body=body, + head=head, + js=["webview.js"] + (["jquery.js"] if js is None else js), + css=["webview.css"] + ([] if css is None else css), + ) + + gui_hooks.webview_will_set_content(web_content, context) + + csstxt = "" + if "webview.css" in web_content.css: + # we want our dynamic styling to override the defaults in + # webview.css, but come before user-provided stylesheets so that + # they can override us if necessary + web_content.css.remove("webview.css") + csstxt = self.bundledCSS("webview.css") + csstxt += f"" + + csstxt += "\n".join(self.bundledCSS(fname) for fname in web_content.css) + jstxt = "\n".join(self.bundledScript(fname) for fname in web_content.js) + + from aqt import mw + + head = mw.baseHTML() + csstxt + jstxt + web_content.head + body_class = theme_manager.body_class() + + if theme_manager.night_mode: + doc_class = "night-mode" + else: + doc_class = "" + + html = f""" + + + + {self.title} +{head} -{} -""".format( - self.title, - self.zoomFactor(), - self._getWindowColor().name(), - lang_dir, - fontspec, - widgetspec, - head, - body_class, - web_content.body, - ) +{web_content.body} +""" # print(html) self.setHtml(html) diff --git a/qt/ts/scss/_buttons.scss b/qt/ts/scss/_buttons.scss index 4324c5968..70b1288d4 100644 --- a/qt/ts/scss/_buttons.scss +++ b/qt/ts/scss/_buttons.scss @@ -1,4 +1,10 @@ -@use 'vars'; +/* night-mode-specific colours */ +$fusion-button-gradient-start: #555555; +$fusion-button-gradient-end: #656565; +$fusion-button-outline: #222222; +$fusion-button-hover-bg: #656565; +$fusion-button-border: #646464; +$fusion-button-base-bg: #454545; .isWin { button { @@ -19,21 +25,21 @@ -webkit-appearance: none; border-radius: 3px; padding: 5px; - border: 1px solid vars.$day-border; + border: 1px solid var(--border); } } .nightMode { button { -webkit-appearance: none; - color: vars.$night-text-fg; + color: var(--text-fg); /* match the fusion button gradient */ background: linear-gradient(0deg, - vars.$fusion-button-gradient-start 0%, - vars.$fusion-button-gradient-end 100%); - box-shadow: 0 0 3px vars.$fusion-button-outline; - border: 1px solid vars.$fusion-button-border; + $fusion-button-gradient-start 0%, + $fusion-button-gradient-end 100%); + box-shadow: 0 0 3px $fusion-button-outline; + border: 1px solid $fusion-button-border; border-radius: 2px; padding: 10px; @@ -42,7 +48,7 @@ } button:hover { - background: vars.$fusion-button-hover-bg; + background: $fusion-button-hover-bg; } } diff --git a/qt/ts/scss/_card_counts.scss b/qt/ts/scss/_card_counts.scss index 9ee384ae0..2c26a1b4f 100644 --- a/qt/ts/scss/_card_counts.scss +++ b/qt/ts/scss/_card_counts.scss @@ -1,36 +1,34 @@ -@use 'vars'; - .review-count { - color: vars.$day-review-count; + color: var(--review-count); } .new-count { - color: vars.$day-new-count; + color: var(--new-count); } .learn-count { - color: vars.$day-learn-count; + color: var(--learn-count); } .zero-count { - color: vars.$day-zero-count; + color: var(--zero-count); } .nightMode { .review-count { - color: vars.$night-review-count; + color: var(--review-count); } .new-count { - color: vars.$night-new-count; + color: var(--new-count); } .learn-count { - color: vars.$night-learn-count; + color: var(--learn-count); } .zero-count { - color: vars.$night-zero-count; + color: var(--zero-count); } } diff --git a/qt/ts/scss/deckbrowser.scss b/qt/ts/scss/deckbrowser.scss index a0a28e1c4..92cf2a9e6 100644 --- a/qt/ts/scss/deckbrowser.scss +++ b/qt/ts/scss/deckbrowser.scss @@ -1,11 +1,10 @@ /* Copyright: Ankitects Pty Ltd and contributors * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ -@use 'vars'; @use 'card_counts'; a.deck { - color: vars.$day-text-fg; + color: var(--text-fg); text-decoration: none; min-width: 5em; display: inline-block; @@ -16,7 +15,7 @@ a.deck:hover { } tr.deck td { - border-bottom: 1px solid vars.$day-faint-border; + border-bottom: 1px solid var(--faint-border); } tr.top-level-drag-row td { @@ -28,7 +27,7 @@ td { } tr.drag-hover td { - border-bottom: 1px solid vars.$day-border; + border-bottom: 1px solid var(--border); } body { @@ -37,7 +36,7 @@ body { } .current { - background-color: vars.$day-faint-border; + background-color: var(--faint-border); } .decktd { @@ -54,14 +53,14 @@ body { } .collapse { - color: vars.$day-text-fg; + color: var(--text-fg); text-decoration: none; display: inline-block; width: 1em; } .filtered { - color: vars.$day-link !important; + color: var(--link) !important; } .gears { @@ -73,23 +72,23 @@ body { .nightMode { a.deck { - color: vars.$night-text-fg; + color: var(--text-fg); } tr.deck td { - border-bottom-color: vars.$night-faint-border; + border-bottom-color: var(--faint-border); } tr.drag-hover td { - border-bottom-color: vars.$night-border; + border-bottom-color: var(--border); } .current { - background-color: vars.$night-faint-border; + background-color: var(--faint-border); } .collapse { - color: vars.$night-text-fg; + color: var(--text-fg); } .gears { @@ -97,7 +96,7 @@ body { } .filtered { - color: vars.$night-link !important; + color: var(--link) !important; } } \ No newline at end of file diff --git a/qt/ts/scss/editor.scss b/qt/ts/scss/editor.scss index 2e38b9757..7ef3f3169 100644 --- a/qt/ts/scss/editor.scss +++ b/qt/ts/scss/editor.scss @@ -1,12 +1,10 @@ /* Copyright: Ankitects Pty Ltd and contributors * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ -@use 'vars'; - .field { - border: 1px solid vars.$day-border; - background: vars.$day-frame-bg; - color: vars.$day-text-fg; + border: 1px solid var(--border); + background: var(--frame-bg); + color: var(--text-fg); padding: 5px; overflow-wrap: break-word; overflow: auto; @@ -75,14 +73,14 @@ button.highlighted { } .dupe { - background: vars.$day-flag1-bg; + background: var(--flag1-bg); } .nightMode { .field { - border-color: vars.$night-border; - background: vars.$night-frame-bg; - color: vars.$night-text-fg; + border-color: var(--border); + background: var(--frame-bg); + color: var(--text-fg); } button.linkb > img { @@ -90,11 +88,11 @@ button.highlighted { } .dupe { - background: vars.$night-flag1-bg; + background: var(--flag1-bg); } #dupes a { - color: vars.$night-link; + color: var(--link); } } diff --git a/qt/ts/scss/overview.scss b/qt/ts/scss/overview.scss index 82c3f1557..e72a00d5c 100644 --- a/qt/ts/scss/overview.scss +++ b/qt/ts/scss/overview.scss @@ -1,7 +1,6 @@ /* Copyright: Ankitects Pty Ltd and contributors * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ -@use 'vars'; @use 'card_counts'; .smallLink { @@ -14,7 +13,7 @@ h3 { .descfont { padding: 1em; - color: vars.$day-slightly-grey-text; + color: var(--slightly-grey-text); } .description { @@ -37,6 +36,6 @@ h3 { .nightMode { .descfont { - color: vars.$night-slightly-grey-text; + color: var(--slightly-grey-text); } } diff --git a/qt/ts/scss/reviewer-bottom.scss b/qt/ts/scss/reviewer-bottom.scss index 13e2ae4d0..92c9d4d57 100644 --- a/qt/ts/scss/reviewer-bottom.scss +++ b/qt/ts/scss/reviewer-bottom.scss @@ -1,7 +1,6 @@ /* Copyright: Ankitects Pty Ltd and contributors * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ -@use 'vars'; @use 'card_counts'; body { @@ -51,7 +50,7 @@ button { } #outer { - border-top: 1px solid vars.$day-border; + border-top: 1px solid var(--border); } #innertable { @@ -60,6 +59,6 @@ button { .nightMode { #outer { - border-top-color: vars.$night-faint-border; + border-top-color: var(--faint-border); } } diff --git a/qt/ts/scss/reviewer.scss b/qt/ts/scss/reviewer.scss index 220d286d2..4a926f514 100644 --- a/qt/ts/scss/reviewer.scss +++ b/qt/ts/scss/reviewer.scss @@ -1,8 +1,6 @@ /* Copyright: Ankitects Pty Ltd and contributors * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ -@use 'vars'; - hr { background-color: #ccc; } @@ -13,8 +11,8 @@ body { } body.nightMode { - background-color: vars.$night-window-bg; - color: vars.$night-text-fg; + background-color: var(--window-bg); + color: var(--text-fg); } img { diff --git a/qt/ts/scss/toolbar.scss b/qt/ts/scss/toolbar.scss index 9fca95921..f6dd2f897 100644 --- a/qt/ts/scss/toolbar.scss +++ b/qt/ts/scss/toolbar.scss @@ -1,12 +1,10 @@ /* Copyright: Ankitects Pty Ltd and contributors * License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html */ -@use 'vars'; - #header { padding: 3px; font-weight: bold; - border-bottom: 1px solid vars.$day-border; + border-bottom: 1px solid var(--border); } .tdcenter { @@ -28,7 +26,7 @@ body { padding-right: 12px; padding-left: 12px; text-decoration: none; - color: vars.$day-text-fg; + color: var(--text-fg); } .hitem:hover { @@ -39,24 +37,24 @@ body { .nightMode { .hitem { - color: vars.$night-text-fg; + color: var(--text-fg); } #header { - border-bottom-color: vars.$night-faint-border; + border-bottom-color: var(--faint-border); } .normal-sync { - color: vars.$night-new-count; + color: var(--new-count); } .full-sync { - color: vars.$night-learn-count; + color: var(--learn-count); } } .isMac.nightMode #header { - border-bottom-color: vars.$night-frame-bg; + border-bottom-color: var(--frame-bg); } @keyframes spin { @@ -81,11 +79,11 @@ body { } .normal-sync { - color: vars.$day-new-count; + color: var(--new-count); } .full-sync { - color: vars.$day-learn-count; + color: var(--learn-count); } diff --git a/qt/ts/scss/webview.scss b/qt/ts/scss/webview.scss index bd2d19d70..65d433218 100644 --- a/qt/ts/scss/webview.scss +++ b/qt/ts/scss/webview.scss @@ -6,11 +6,8 @@ body { margin: 2em; - color: vars.$day-text-fg; - - // currently this is injected via webview.py to try to match the - // system background color - // background: vars.$day-window-bg; + color: var(--text-fg); + background: var(--window-bg); } h1 { @@ -18,16 +15,16 @@ h1 { } a { - color: vars.$day-link; + color: var(--link); } body.nightMode { - color: vars.$night-text-fg; - background: vars.$night-window-bg; + color: var(--text-fg); + background: var(--window-bg); } body.nightMode::-webkit-scrollbar { - background: vars.$night-window-bg; + background: var(--window-bg); } body.nightMode::-webkit-scrollbar:horizontal { @@ -39,7 +36,7 @@ body.nightMode::-webkit-scrollbar:vertical { } body.nightMode::-webkit-scrollbar-thumb { - background: vars.$fusion-button-hover-bg; + background: buttons.$fusion-button-hover-bg; border-radius: 8px; } @@ -53,7 +50,7 @@ body.nightMode::-webkit-scrollbar-thumb:vertical { .nightMode { a { - color: vars.$night-link; + color: var(--link); } } diff --git a/ts/src/scss/_vars.scss b/ts/src/scss/_vars.scss index 10ea7cd36..084f47494 100644 --- a/ts/src/scss/_vars.scss +++ b/ts/src/scss/_vars.scss @@ -40,10 +40,49 @@ $night-flag4-bg: #3581a9; $night-suspended-bg: #aaaa33; $night-marked-bg: #77c; -/* night-mode-specific colours */ -$fusion-button-gradient-start: #555555; -$fusion-button-gradient-end: #656565; -$fusion-button-outline: #222222; -$fusion-button-hover-bg: #656565; -$fusion-button-border: #646464; -$fusion-button-base-bg: #454545; + +:root { + --text-fg: #{$day-text-fg}; + --window-bg: #{$day-window-bg}; + --frame-bg: #{$day-frame-bg}; + --border: #{$day-border}; + --faint-border: #{$day-faint-border}; + --link: #{$day-link}; + --review-count: #{$day-review-count}; + --new-count: #{$day-new-count}; + --learn-count: #{$day-learn-count}; + --zero-count: #{$day-zero-count}; + --slightly-grey-text: #{$day-slightly-grey-text}; + --highlight-bg: #{$day-highlight-bg}; + --highlight-fg: #{$day-highlight-fg}; + --disabled: #{$day-disabled}; + --flag1-bg: #{$day-flag1-bg}; + --flag2-bg: #{$day-flag2-bg}; + --flag3-bg: #{$day-flag3-bg}; + --flag4-bg: #{$day-flag4-bg}; + --suspended-bg: #{$day-suspended-bg}; + --marked-bg: #{$day-marked-bg}; +} + +:root[class*="night-mode"] { + --text-fg: #{$night-text-fg}; + --window-bg: #{$night-window-bg}; + --frame-bg: #{$night-frame-bg}; + --border: #{$night-border}; + --faint-border: #{$night-faint-border}; + --link: #{$night-link}; + --review-count: #{$night-review-count}; + --new-count: #{$night-new-count}; + --learn-count: #{$night-learn-count}; + --zero-count: #{$night-zero-count}; + --slightly-grey-text: #{$night-slightly-grey-text}; + --highlight-bg: #{$night-highlight-bg}; + --highlight-fg: #{$night-highlight-fg}; + --disabled: #{$night-disabled}; + --flag1-bg: #{$night-flag1-bg}; + --flag2-bg: #{$night-flag2-bg}; + --flag3-bg: #{$night-flag3-bg}; + --flag4-bg: #{$night-flag4-bg}; + --suspended-bg: #{$night-suspended-bg}; + --marked-bg: #{$night-marked-bg}; +}