From 556570d799362716c6a0b174378639206646242e Mon Sep 17 00:00:00 2001 From: welpo Date: Thu, 27 Apr 2023 23:45:58 +0200 Subject: [PATCH 1/8] =?UTF-8?q?=F0=9F=90=9B=20fix:=20only=20load=20script?= =?UTF-8?q?=20when=20themeswitcher=20is=20enabled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/partials/footer.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/partials/footer.html b/templates/partials/footer.html index 24feec0..6ee74dc 100644 --- a/templates/partials/footer.html +++ b/templates/partials/footer.html @@ -13,5 +13,7 @@ Powered by Zola & tabi - + {%- if config.extra.theme_switcher == true -%} + + {%- endif -%} From c36b66b7d46dc30c2dd77386421a396dd777333c Mon Sep 17 00:00:00 2001 From: welpo Date: Fri, 28 Apr 2023 16:10:03 +0200 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=93=9D=20docs:=20acknowledge=20abridg?= =?UTF-8?q?e's=20inspiration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index fe94864..16b1121 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ The content outside the front matter will be rendered between the header title a This theme was inspired by: - [shadharon](https://github.com/syedzayyan/shadharon). tabi started as a fork of [syedzayyan](https://github.com/syedzayyan)'s theme. +- [abridge](https://github.com/Jieiku/abridge) - [tailwind-nextjs-starter-blog](https://github.com/timlrx/tailwind-nextjs-starter-blog) - [tale-zola](https://github.com/aaranxu/tale-zola) - [internetVin's blog](https://internetvin.ghost.io) From 79f8559a3aa87794af45a62d9644689c00b94c51 Mon Sep 17 00:00:00 2001 From: welpo Date: Fri, 28 Apr 2023 16:10:26 +0200 Subject: [PATCH 3/8] =?UTF-8?q?=F0=9F=93=9D=20docs:=20stylise=20KaTeX?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/blog/markdown.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/content/blog/markdown.md b/content/blog/markdown.md index 88150c6..667077d 100644 --- a/content/blog/markdown.md +++ b/content/blog/markdown.md @@ -1,7 +1,7 @@ +++ title = "Markdown examples" date = 2023-01-31 -updated = 2023-04-15 +updated = 2023-04-28 description = "This post showcases some examples of Markdown formatting, including a table, code blocks and tags, quotes, tables, and footnotes." [taxonomies] @@ -11,11 +11,11 @@ tags = ["markdown", "showcase"] katex = true +++ -## KaTeX +## $\KaTeX$ -[KaTeX](https://katex.org/) is a fast and easy-to-use library that enables the rendering of mathematical notation, using LaTeX syntax. +[$\KaTeX$](https://katex.org/) is a fast and easy-to-use library that enables the rendering of mathematical notation, using LaTeX syntax. -You can use KaTeX **inline** by wrapping the expression between `$` or between `\\(` and `\\)`. +You can use $\KaTeX$ **inline** by wrapping the expression between `$` or between `\\(` and `\\)`. For example, `$ \sin(x) = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n + 1)!} x^{2n + 1} $` would render: $ \sin(x) = \sum_{n=0}^{\infty} \frac{(-1)^n}{(2n + 1)!} x^{2n + 1} $ @@ -23,9 +23,9 @@ To display the expression **on its own line and centered**, wrap it around `$$` For example, `\\[ r = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i - \bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i - \bar{y})^2}} \\]` renders: \\[ r = \frac{\sum_{i=1}^{n}(x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum_{i=1}^{n}(x_i - \bar{x})^2}\sqrt{\sum_{i=1}^{n}(y_i - \bar{y})^2}} \\] -To activate KaTeX for a post, include `katex = true` within the `[extra]` section of the post's front matter. For enhanced performance and security, the JavaScript, CSS, and fonts are hosted locally. +To activate $\KaTeX$ for a post, include `katex = true` within the `[extra]` section of the post's front matter. For enhanced performance and security, the JavaScript, CSS, and fonts are hosted locally. -**Note**: After enabling KaTeX, if you want to use \$ without rendering a mathematical expression, escape it with a single backslash: `\$`. +**Note**: After enabling $\KaTeX$, if you want to use \$ without rendering a mathematical expression, escape it with a single backslash: `\$`. ## Table From eb63718bbffce75f5eab584fab37396ac93123a0 Mon Sep 17 00:00:00 2001 From: welpo Date: Fri, 28 Apr 2023 16:12:14 +0200 Subject: [PATCH 4/8] =?UTF-8?q?=F0=9F=9A=9A=20refactor:=20rename=20minifie?= =?UTF-8?q?d=20KaTeX=20css?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/js/{katex.min.js => katex_min.js} | 0 templates/base.html | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename static/js/{katex.min.js => katex_min.js} (100%) diff --git a/static/js/katex.min.js b/static/js/katex_min.js similarity index 100% rename from static/js/katex.min.js rename to static/js/katex_min.js diff --git a/templates/base.html b/templates/base.html index 273fe8e..06a597d 100644 --- a/templates/base.html +++ b/templates/base.html @@ -23,9 +23,9 @@ {% include "partials/footer.html" %} {% if page.extra.katex and page.extra.katex == true %} - + - + {% endif %} From 1efb0330e3926235cde79bdaec9bf157dc6d1743 Mon Sep 17 00:00:00 2001 From: welpo Date: Fri, 28 Apr 2023 16:20:42 +0200 Subject: [PATCH 5/8] =?UTF-8?q?=F0=9F=90=9B=20fix:=20remove=20flash=20when?= =?UTF-8?q?=20navigating=20in=20dark-mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `initialize-theme.js` script takes care of the following: 1. If there is a stored theme value in the localStorage, set the theme based on that value. 2. If there is no stored theme value, check the user's system preference (dark or light) and set the theme accordingly. The new `main.js` takes care of the actual theme switching and listening to system preference changes (if the user has not manually set a theme). Now the icons are stored in CSS, and are set according to the current theme. This allows for having different icons that dynamically switch. Additionally, wraps social and navigation elements in ul/li. Fixes #76 --- config.toml | 2 +- content/blog/almost-no-js.md | 6 ++--- sass/main.scss | 4 +++ sass/parts/_footer.scss | 5 +++- sass/parts/_header.scss | 14 ++++++++--- sass/parts/_theme-switch.scss | 41 ++----------------------------- static/js/initialize_theme.js | 9 +++++++ static/js/initialize_theme_min.js | 1 + static/js/main.js | 16 +++--------- static/js/main_min.js | 1 + static/menu_icon/moon.svg | 3 --- static/menu_icon/sun.svg | 1 - templates/partials/footer.html | 17 +++++++------ templates/partials/header.html | 5 ++++ templates/partials/nav.html | 24 ++++++++---------- 15 files changed, 64 insertions(+), 85 deletions(-) create mode 100644 static/js/initialize_theme.js create mode 100644 static/js/initialize_theme_min.js create mode 100644 static/js/main_min.js delete mode 100644 static/menu_icon/moon.svg delete mode 100644 static/menu_icon/sun.svg diff --git a/config.toml b/config.toml index c97f0a7..6e3a1c7 100644 --- a/config.toml +++ b/config.toml @@ -62,7 +62,7 @@ socials = [ # Default config, allows for https remote images and embedding YouTube and Vimeo content. # This configuration (along with the right webserver settings) gets an A+ in Mozilla's Observatory: https://observatory.mozilla.org allowed_domains = [ - { directive = "img-src", domains = ["'self'", "https://*"] }, + { directive = "img-src", domains = ["'self'", "https://*", "data:"] }, { directive = "script-src", domains = ["'self'"] }, { directive = "style-src", domains = ["'self'"] }, { directive = "frame-src", domains = ["player.vimeo.com", "https://www.youtube-nocookie.com"] }, diff --git a/content/blog/almost-no-js.md b/content/blog/almost-no-js.md index a2bed1b..8e27596 100644 --- a/content/blog/almost-no-js.md +++ b/content/blog/almost-no-js.md @@ -1,7 +1,7 @@ +++ title = "Almost no JavaScript" date = 2023-01-06 -updated = 2023-04-15 +updated = 2023-04-28 description = "JavaScript is only used when HTML and CSS aren't enough." [taxonomies] @@ -10,8 +10,8 @@ tags = ["showcase"] # JavaScript? -This theme has almost no JavaScript. It includes a ~950 byte `.js` file with the logic for the light/dark mode switch which can be disabled by setting `theme_switcher = false` in the `config.toml` file. +This theme has almost no JavaScript. It includes ~900 bytes of `.js` with the logic for the light/dark mode switch, which can be disabled by setting `theme_switcher = false` in the `config.toml` file. -KaTex support, which requires JavaScript, can be activated for specific posts. +KaTex support, which requires loading a 274 KB JavaScript file, can be activated for specific posts. Other than that, it's a fast site with HTML and CSS. Just the way (most of) the web should be :-) diff --git a/sass/main.scss b/sass/main.scss index 692a55b..a8b4b65 100644 --- a/sass/main.scss +++ b/sass/main.scss @@ -62,6 +62,8 @@ --quote-color: #355f62; --border-color: #727272; --meta-color: #5b5b65; + + --theme-switcher-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M283.211 512c78.962 0 151.079-35.925 198.857-94.792 7.068-8.708-.639-21.43-11.562-19.35-124.203 23.654-238.262-71.576-238.262-196.954 0-72.222 38.662-138.635 101.498-174.394 9.686-5.512 7.25-20.197-3.756-22.23A258.156 258.156 0 0 0 283.211 0c-141.309 0-256 114.511-256 256 0 141.309 114.511 256 256 256z'/%3E%3C/svg%3E%0A"); } [data-theme='dark'] { @@ -78,6 +80,8 @@ --border-color: black; --meta-color: #B0B0B0; + --theme-switcher-svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 96 960 960' %3E%3Cpath d='M480 776q-83 0-141.5-58.5T280 576q0-83 58.5-141.5T480 376q83 0 141.5 58.5T680 576q0 83-58.5 141.5T480 776ZM80 616q-17 0-28.5-11.5T40 576q0-17 11.5-28.5T80 536h80q17 0 28.5 11.5T200 576q0 17-11.5 28.5T160 616H80Zm720 0q-17 0-28.5-11.5T760 576q0-17 11.5-28.5T800 536h80q17 0 28.5 11.5T920 576q0 17-11.5 28.5T880 616h-80ZM480 296q-17 0-28.5-11.5T440 256v-80q0-17 11.5-28.5T480 136q17 0 28.5 11.5T520 176v80q0 17-11.5 28.5T480 296Zm0 720q-17 0-28.5-11.5T440 976v-80q0-17 11.5-28.5T480 856q17 0 28.5 11.5T520 896v80q0 17-11.5 28.5T480 1016ZM226 378l-43-42q-12-11-11.5-28t11.5-29q12-12 29-12t28 12l42 43q11 12 11 28t-11 28q-11 12-27.5 11.5T226 378Zm494 495-42-43q-11-12-11-28.5t11-27.5q11-12 27.5-11.5T734 774l43 42q12 11 11.5 28T777 873q-12 12-29 12t-28-12Zm-42-495q-12-11-11.5-27.5T678 322l42-43q11-12 28-11.5t29 11.5q12 12 12 29t-12 28l-43 42q-12 11-28 11t-28-11ZM183 873q-12-12-12-29t12-28l43-42q12-11 28.5-11t27.5 11q12 11 11.5 27.5T282 830l-42 43q-11 12-28 11.5T183 873Z'/%3E%3C/svg%3E"); + .invertible-image { filter: invert(.88); } diff --git a/sass/parts/_footer.scss b/sass/parts/_footer.scss index 2235ecb..87cc771 100644 --- a/sass/parts/_footer.scss +++ b/sass/parts/_footer.scss @@ -13,7 +13,6 @@ footer section { footer nav { display: flex; - gap: 0rem; margin: 0 0rem; } @@ -23,6 +22,10 @@ footer nav { display: flex; flex-wrap: wrap; align-items: flex-end; + + ul { + gap: 5px; + } } .social { diff --git a/sass/parts/_header.scss b/sass/parts/_header.scss index 353365a..18ec4a7 100644 --- a/sass/parts/_header.scss +++ b/sass/parts/_header.scss @@ -43,10 +43,16 @@ header { .nav-navs { display: flex; - gap: 5px; + flex-wrap: wrap; - img { - border: none; + ul { + display: flex; + align-items: center; + gap: 1px; + flex-wrap: wrap; + list-style: none; + padding: 0; + margin: 0; } } @@ -57,6 +63,7 @@ header { justify-content: right; color: var(--text-color); padding: 0.66rem; + line-height: 2.5; } .home-title { @@ -114,6 +121,7 @@ header { margin-top: 0.8rem; width: 100%; justify-content: center; + flex-wrap: wrap; } .navbar { diff --git a/sass/parts/_theme-switch.scss b/sass/parts/_theme-switch.scss index 3388e62..d1188d9 100644 --- a/sass/parts/_theme-switch.scss +++ b/sass/parts/_theme-switch.scss @@ -5,43 +5,6 @@ height: 1rem; position: relative; cursor: pointer; - - .switch { - width: 1rem; - height: 1rem; - position: absolute; - left: 0px; - display: flex; - justify-content: center; - align-items: center; - - img { - width: 100%; - height: auto; - position: absolute; - border: none; - } - - .sun { - opacity: 0; - } - - .moon { - opacity: 1; - } - } - - input { - display: none; - - &:checked + .switch { - .sun { - opacity: 1; - } - - .moon { - opacity: 0; - } - } - } + -webkit-mask: var(--theme-switcher-svg); + background: var(--text-color); } diff --git a/static/js/initialize_theme.js b/static/js/initialize_theme.js new file mode 100644 index 0000000..688b0ff --- /dev/null +++ b/static/js/initialize_theme.js @@ -0,0 +1,9 @@ +(function () { + let currentTheme = localStorage.getItem('theme'); + if (currentTheme) { + document.documentElement.setAttribute('data-theme', currentTheme); + } else { + const isSystemDark = window.matchMedia('(prefers-color-scheme: dark)').matches; + document.documentElement.setAttribute('data-theme', isSystemDark ? 'dark' : 'light'); + } +})(); diff --git a/static/js/initialize_theme_min.js b/static/js/initialize_theme_min.js new file mode 100644 index 0000000..9463f4b --- /dev/null +++ b/static/js/initialize_theme_min.js @@ -0,0 +1 @@ +!function(){let e=localStorage.getItem("theme");if(e)document.documentElement.setAttribute("data-theme",e);else{let t=window.matchMedia("(prefers-color-scheme: dark)").matches;document.documentElement.setAttribute("data-theme",t?"dark":"light")}}(); diff --git a/static/js/main.js b/static/js/main.js index 3a1af20..474a886 100644 --- a/static/js/main.js +++ b/static/js/main.js @@ -1,28 +1,20 @@ -const themeSwitcher = document.querySelector('.theme-switcher input'); +const themeSwitcher = document.querySelector('.theme-switcher'); let currentTheme = localStorage.getItem('theme'); let userHasManuallyChangedTheme = currentTheme !== null; function setTheme(theme) { document.documentElement.setAttribute('data-theme', theme); - themeSwitcher.checked = theme === 'dark'; localStorage.setItem('theme', theme); currentTheme = theme; } -if (currentTheme) { - setTheme(currentTheme); -} else { - const isSystemDark = window.matchMedia('(prefers-color-scheme: dark)').matches; - setTheme(isSystemDark ? 'dark' : 'light'); -} - -function switchTheme(e) { - const newTheme = e.target.checked ? 'dark' : 'light'; +function switchTheme() { + const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; setTheme(newTheme); userHasManuallyChangedTheme = true; } -themeSwitcher.addEventListener('change', switchTheme, false); +themeSwitcher.addEventListener('click', switchTheme, false); window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { if (!userHasManuallyChangedTheme) { diff --git a/static/js/main_min.js b/static/js/main_min.js new file mode 100644 index 0000000..e8ee444 --- /dev/null +++ b/static/js/main_min.js @@ -0,0 +1 @@ +const themeSwitcher=document.querySelector(".theme-switcher");let currentTheme=localStorage.getItem("theme"),userHasManuallyChangedTheme=null!==currentTheme;function setTheme(e){document.documentElement.setAttribute("data-theme",e),localStorage.setItem("theme",e),currentTheme=e}function switchTheme(){let e="dark"===currentTheme?"light":"dark";setTheme(e),userHasManuallyChangedTheme=!0}themeSwitcher.addEventListener("click",switchTheme,!1),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",e=>{userHasManuallyChangedTheme||setTheme(e.matches?"dark":"light")}); diff --git a/static/menu_icon/moon.svg b/static/menu_icon/moon.svg deleted file mode 100644 index 47aedd3..0000000 --- a/static/menu_icon/moon.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/static/menu_icon/sun.svg b/static/menu_icon/sun.svg deleted file mode 100644 index d7ee03d..0000000 --- a/static/menu_icon/sun.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/templates/partials/footer.html b/templates/partials/footer.html index 6ee74dc..4e4f069 100644 --- a/templates/partials/footer.html +++ b/templates/partials/footer.html @@ -2,18 +2,19 @@
Powered by Zola & tabi
- {%- if config.extra.theme_switcher == true -%} - - {%- endif -%} diff --git a/templates/partials/header.html b/templates/partials/header.html index 68e73d9..5a0d843 100644 --- a/templates/partials/header.html +++ b/templates/partials/header.html @@ -55,4 +55,9 @@ {%- endfor -%} {%- endif -%}"> + {%- if config.extra.theme_switcher == true -%} + + + {%- endif -%} + diff --git a/templates/partials/nav.html b/templates/partials/nav.html index 33418bb..5d28cfb 100644 --- a/templates/partials/nav.html +++ b/templates/partials/nav.html @@ -6,23 +6,19 @@ {%- if config.extra.menu %} {% endif %} - From 9512bbb19400be6b770735ceb6daca4e71429630 Mon Sep 17 00:00:00 2001 From: welpo Date: Fri, 28 Apr 2023 16:38:46 +0200 Subject: [PATCH 6/8] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor:=20use=20`con?= =?UTF-8?q?st`=20in=20theme=20initialization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor the theme initialization script to use 'const' instead of 'let' for the 'currentTheme' variable, as the value is not expected to change after initialization. This makes the code more clear and prevents accidental re-assignment. --- static/js/initialize_theme.js | 2 +- static/js/initialize_theme_min.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/static/js/initialize_theme.js b/static/js/initialize_theme.js index 688b0ff..45ba7f6 100644 --- a/static/js/initialize_theme.js +++ b/static/js/initialize_theme.js @@ -1,5 +1,5 @@ (function () { - let currentTheme = localStorage.getItem('theme'); + const currentTheme = localStorage.getItem('theme'); if (currentTheme) { document.documentElement.setAttribute('data-theme', currentTheme); } else { diff --git a/static/js/initialize_theme_min.js b/static/js/initialize_theme_min.js index 9463f4b..eee5bc4 100644 --- a/static/js/initialize_theme_min.js +++ b/static/js/initialize_theme_min.js @@ -1 +1 @@ -!function(){let e=localStorage.getItem("theme");if(e)document.documentElement.setAttribute("data-theme",e);else{let t=window.matchMedia("(prefers-color-scheme: dark)").matches;document.documentElement.setAttribute("data-theme",t?"dark":"light")}}(); +!function(){const e=localStorage.getItem("theme");if(e)document.documentElement.setAttribute("data-theme",e);else{const t=window.matchMedia("(prefers-color-scheme: dark)").matches;document.documentElement.setAttribute("data-theme",t?"dark":"light")}}(); From 3b22e6be6c1ff666c767cea0af4b9cd48f353c46 Mon Sep 17 00:00:00 2001 From: welpo Date: Fri, 28 Apr 2023 16:42:16 +0200 Subject: [PATCH 7/8] =?UTF-8?q?=F0=9F=93=9D=20docs:=20add=20`data:`=20to?= =?UTF-8?q?=20CSP=20to=20load=20local=20svg?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- theme.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/theme.toml b/theme.toml index 0f669de..b392b92 100644 --- a/theme.toml +++ b/theme.toml @@ -44,7 +44,7 @@ menu = [ # Default config, allows for https remote images and embedding YouTube and Vimeo content. # This configuration (along with the right webserver settings) gets an A+ in Mozilla's Observatory: https://observatory.mozilla.org allowed_domains = [ - { directive = "img-src", domains = ["'self'", "https://*"] }, + { directive = "img-src", domains = ["'self'", "https://*", "data:"] }, { directive = "script-src", domains = ["'self'"] }, { directive = "style-src", domains = ["'self'"] }, { directive = "frame-src", domains = ["player.vimeo.com", "https://www.youtube-nocookie.com"] }, From 0c8e0d228ca73dec066dca8b94741807981ee976 Mon Sep 17 00:00:00 2001 From: welpo Date: Fri, 28 Apr 2023 16:45:05 +0200 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=9A=9A=20refactor:=20rename=20katex?= =?UTF-8?q?=20minified=20css?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- static/{katex.min.css => katex_min.css} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename static/{katex.min.css => katex_min.css} (100%) diff --git a/static/katex.min.css b/static/katex_min.css similarity index 100% rename from static/katex.min.css rename to static/katex_min.css