mirror of
https://github.com/cotes2020/jekyll-theme-chirpy.git
synced 2025-12-18 05:41:31 +00:00
Compare commits
27 Commits
v7.1.0
...
9706811c3a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9706811c3a | ||
|
|
a4812e4a1f | ||
|
|
65f960c31a | ||
|
|
d51345e297 | ||
|
|
2f844978aa | ||
|
|
42dea8ee29 | ||
|
|
81d3d055e4 | ||
|
|
86b13c917f | ||
|
|
4ef3cd8efc | ||
|
|
c7f967529c | ||
|
|
74ed06321c | ||
|
|
d4f7f39ece | ||
|
|
c1bd9eb9ee | ||
|
|
6f461132c0 | ||
|
|
03e302cbf6 | ||
|
|
8a064a5e5a | ||
|
|
740bd84c51 | ||
|
|
93f616b25d | ||
|
|
e6b87d2811 | ||
|
|
73749067c5 | ||
|
|
fd0df8320f | ||
|
|
fbcdf8ce85 | ||
|
|
fac6116af1 | ||
|
|
5a63244721 | ||
|
|
3ab3b844d2 | ||
|
|
367262e74d | ||
|
|
cbc93193e1 |
7
.github/workflows/cd.yml
vendored
7
.github/workflows/cd.yml
vendored
@@ -2,13 +2,12 @@ name: CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- production
|
||||
tags-ignore:
|
||||
- "**"
|
||||
branches: [production]
|
||||
tags-ignore: ["**"]
|
||||
|
||||
jobs:
|
||||
release:
|
||||
if: ${{ ! startsWith(github.event.head_commit.message, 'chore(release)') }}
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
|
||||
20
.github/workflows/ci.yml
vendored
20
.github/workflows/ci.yml
vendored
@@ -1,17 +1,25 @@
|
||||
name: "CI"
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- "master"
|
||||
- "hotfix/**"
|
||||
- master
|
||||
- "hotfix/*"
|
||||
paths-ignore:
|
||||
- ".github/**"
|
||||
- "!.github/workflows/ci.yml"
|
||||
- ".gitignore"
|
||||
- .gitignore
|
||||
- "docs/**"
|
||||
- "README.md"
|
||||
- "LICENSE"
|
||||
- README.md
|
||||
- LICENSE
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- ".github/**"
|
||||
- "!.github/workflows/ci.yml"
|
||||
- .gitignore
|
||||
- "docs/**"
|
||||
- README.md
|
||||
- LICENSE
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
8
.github/workflows/commitlint.yml
vendored
8
.github/workflows/commitlint.yml
vendored
@@ -1,5 +1,11 @@
|
||||
name: Lint Commit Messages
|
||||
on: pull_request
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- "hotfix/*"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
commitlint:
|
||||
|
||||
25
.github/workflows/pr-filter.yml
vendored
Normal file
25
.github/workflows/pr-filter.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: PR Filter
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened]
|
||||
|
||||
jobs:
|
||||
check-template:
|
||||
if: github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check PR Content
|
||||
id: intercept
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const script = require('.github/workflows/scripts/pr-filter.js');
|
||||
await script({ github, context, core });
|
||||
1
.github/workflows/publish.yml
vendored
1
.github/workflows/publish.yml
vendored
@@ -10,6 +10,7 @@ on:
|
||||
required: true
|
||||
BUILDER:
|
||||
required: true
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
launch:
|
||||
|
||||
36
.github/workflows/scripts/pr-filter.js
vendored
Normal file
36
.github/workflows/scripts/pr-filter.js
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
function hasTypes(markdown) {
|
||||
return /## Type of change/.test(markdown) && /-\s\[x\]/i.test(markdown);
|
||||
}
|
||||
|
||||
function hasDescription(markdown) {
|
||||
return (
|
||||
/## Description/.test(markdown) &&
|
||||
!/## Description\s*\n\s*(##|\s*$)/.test(markdown)
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = async ({ github, context, core }) => {
|
||||
const pr = context.payload.pull_request;
|
||||
const body = pr.body === null ? '' : pr.body;
|
||||
const markdown = body.replace(/<!--[\s\S]*?-->/g, '');
|
||||
const action = context.payload.action;
|
||||
|
||||
const isValid =
|
||||
markdown !== '' && hasTypes(markdown) && hasDescription(markdown);
|
||||
|
||||
if (!isValid) {
|
||||
await github.rest.pulls.update({
|
||||
...context.repo,
|
||||
pull_number: pr.number,
|
||||
state: 'closed'
|
||||
});
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
...context.repo,
|
||||
issue_number: pr.number,
|
||||
body: `Oops, it seems you've ${action} an invalid pull request. No worries, we'll close it for you.`
|
||||
});
|
||||
|
||||
core.setFailed('PR content does not meet template requirements.');
|
||||
}
|
||||
};
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -9,7 +9,7 @@ permissions:
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
STALE_LABEL: stale
|
||||
STALE_LABEL: inactive
|
||||
EXEMPT_LABELS: "pending,planning,in progress"
|
||||
MESSAGE: >
|
||||
This conversation has been automatically marked as stale because it has not had recent activity.
|
||||
|
||||
6
.github/workflows/style-lint.yml
vendored
6
.github/workflows/style-lint.yml
vendored
@@ -1,8 +1,10 @@
|
||||
name: "Style Lint"
|
||||
name: Style Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["master", "hotfix/**"]
|
||||
branches:
|
||||
- master
|
||||
- "hotfix/*"
|
||||
paths: ["_sass/**/*.scss"]
|
||||
pull_request:
|
||||
paths: ["_sass/**/*.scss"]
|
||||
|
||||
2
Gemfile
2
Gemfile
@@ -11,4 +11,4 @@ platforms :mingw, :x64_mingw, :mswin, :jruby do
|
||||
gem "tzinfo-data"
|
||||
end
|
||||
|
||||
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||
gem "wdm", "~> 0.2.0", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||
|
||||
@@ -14,7 +14,7 @@ tabs:
|
||||
categories: Catégories
|
||||
tags: Tags
|
||||
archives: Archives
|
||||
about: A propos de
|
||||
about: À propos
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
@@ -32,12 +32,12 @@ copyright:
|
||||
license:
|
||||
template: Cet article est sous licence :LICENSE_NAME par l'auteur.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
link: https://creativecommons.org/licenses/by/4.0/deed.fr
|
||||
|
||||
# Displayed in the footer
|
||||
brief: Certains droits réservés.
|
||||
verbose: >-
|
||||
Sauf mention contraire, les articles de ce site sont publiés sous licence
|
||||
Sauf mention contraire, les articles de ce site sont publiés
|
||||
sous la licence Creative Commons Attribution 4.0 International (CC BY 4.0) par l'auteur.
|
||||
|
||||
meta: Propulsé par :PLATFORM avec le thème :THEME
|
||||
|
||||
@@ -14,24 +14,23 @@ tabs:
|
||||
categories: Kategóriák
|
||||
tags: Címkék
|
||||
archives: Archívum
|
||||
about: Rólam
|
||||
about: Bemutatkozás
|
||||
|
||||
# the text displayed in the search bar & search results
|
||||
search:
|
||||
hint: keresés
|
||||
cancel: Mégse
|
||||
no_results: Oops! Nincs találat a keresésre.
|
||||
no_results: Hoppá! Nincs találat a keresésre.
|
||||
|
||||
panel:
|
||||
lastmod: Legutóbb frissítve
|
||||
trending_tags: Népszerű Címkék
|
||||
toc: Tartalom
|
||||
links: Blog linkek
|
||||
|
||||
copyright:
|
||||
# Shown at the bottom of the post
|
||||
license:
|
||||
template: A bejegyzés :LICENSE_NAME licenccel rendelkezik.
|
||||
template: A bejegyzést a szerző :LICENSE_NAME licenc alatt engedélyezte.
|
||||
name: CC BY 4.0
|
||||
link: https://creativecommons.org/licenses/by/4.0/
|
||||
|
||||
@@ -42,7 +41,7 @@ copyright:
|
||||
Creative Commons Attribution 4.0 International (CC BY 4.0) licenccel rendelkeznek,
|
||||
hacsak másképp nincs jelezve.
|
||||
|
||||
meta: Készítve :PLATFORM motorral :THEME témával
|
||||
meta: Készítve :THEME témával a :PLATFORM platformra.
|
||||
|
||||
not_found:
|
||||
statement: Sajnáljuk, az URL-t rosszul helyeztük el, vagy valami nem létezőre mutat.
|
||||
@@ -73,7 +72,21 @@ post:
|
||||
title: Link másolása
|
||||
succeed: Link sikeresen másolva!
|
||||
|
||||
# Date time format.
|
||||
# See: <http://strftime.net/>, <https://day.js.org/docs/en/display/format>
|
||||
df:
|
||||
post:
|
||||
strftime: "%Y. %B. %e."
|
||||
dayjs: "YYYY. MMMM D."
|
||||
archives:
|
||||
strftime: "%B"
|
||||
dayjs: "MMM"
|
||||
|
||||
# categories page
|
||||
categories:
|
||||
category_measure: kategória
|
||||
post_measure: bejegyzés
|
||||
category_measure:
|
||||
singular: kategória
|
||||
plural: kategória
|
||||
post_measure:
|
||||
singular: bejegyzés
|
||||
plural: bejegyzés
|
||||
|
||||
@@ -4,4 +4,3 @@
|
||||
src="https://static.cloudflareinsights.com/beacon.min.js"
|
||||
data-cf-beacon='{"token": "{{ site.analytics.cloudflare.id }}"}'
|
||||
></script>
|
||||
<!-- End Cloudflare Web Analytics -->
|
||||
|
||||
@@ -2,6 +2,5 @@
|
||||
<script
|
||||
src="https://cdn.usefathom.com/script.js"
|
||||
data-site="{{ site.analytics.fathom.id }}"
|
||||
defer>
|
||||
</script>
|
||||
<!-- End Fathom Code -->
|
||||
defer
|
||||
></script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script defer src="https://www.googletagmanager.com/gtag/js?id={{ site.analytics.google.id }}"></script>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function (event) {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
<!-- Matomo -->
|
||||
<script type="text/javascript">
|
||||
var _paq = window._paq = window._paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
var _paq = (window._paq = window._paq || []);
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
var u="//{{ site.analytics.matomo.domain }}/";
|
||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||
_paq.push(['setSiteId', {{ site.analytics.matomo.id }}]);
|
||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||
g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||
})();
|
||||
});
|
||||
</script>
|
||||
<!-- End Matomo Code -->
|
||||
|
||||
@@ -1,38 +1,25 @@
|
||||
<!-- The Disqus lazy loading. -->
|
||||
|
||||
<div id="disqus_thread">
|
||||
<p class="text-center text-muted small">Comments powered by <a href="https://disqus.com/">Disqus</a>.</p>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
var disqus_config = function () {
|
||||
this.page.url = '{{ page.url | absolute_url }}';
|
||||
this.page.identifier = '{{ page.url }}';
|
||||
};
|
||||
|
||||
{%- comment -%} Lazy loading {%- endcomment -%}
|
||||
var disqus_observer = new IntersectionObserver(
|
||||
function (entries) {
|
||||
if (entries[0].isIntersecting) {
|
||||
(function () {
|
||||
var d = document,
|
||||
s = d.createElement('script');
|
||||
s.src = 'https://{{ site.comments.disqus.shortname }}.disqus.com/embed.js';
|
||||
s.setAttribute('data-timestamp', +new Date());
|
||||
(d.head || d.body).appendChild(s);
|
||||
})();
|
||||
function addDisqus() {
|
||||
let disqusThread = document.createElement('div');
|
||||
let paragraph = document.createElement('p');
|
||||
|
||||
disqus_observer.disconnect();
|
||||
}
|
||||
},
|
||||
{ threshold: [0] }
|
||||
);
|
||||
disqusThread.id = 'disqus_thread';
|
||||
paragraph.className = 'text-center text-muted small';
|
||||
paragraph.innerHTML = 'Comments powered by <a href="https://disqus.com/">Disqus</a>.';
|
||||
disqusThread.appendChild(paragraph);
|
||||
|
||||
disqus_observer.observe(document.getElementById('disqus_thread'));
|
||||
const footer = document.querySelector('footer');
|
||||
footer.insertAdjacentElement("beforebegin", disqusThread);
|
||||
}
|
||||
|
||||
{%- comment -%} Auto switch theme {%- endcomment -%}
|
||||
function reloadDisqus() {
|
||||
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
||||
function reloadDisqus(event) {
|
||||
if (event.source === window && event.data && event.data.id === Theme.ID) {
|
||||
{%- comment -%} Disqus hasn't been loaded {%- endcomment -%}
|
||||
if (typeof DISQUS === 'undefined') {
|
||||
return;
|
||||
@@ -44,7 +31,27 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (document.getElementById('mode-toggle')) {
|
||||
window.addEventListener('message', reloadDisqus);
|
||||
addDisqus();
|
||||
|
||||
if (Theme.switchable) {
|
||||
addEventListener('message', reloadDisqus);
|
||||
}
|
||||
|
||||
{%- comment -%} Lazy loading {%- endcomment -%}
|
||||
var disqusObserver = new IntersectionObserver(
|
||||
function (entries) {
|
||||
if (entries[0].isIntersecting) {
|
||||
var d = document,
|
||||
s = d.createElement('script');
|
||||
s.src = 'https://{{ site.comments.disqus.shortname }}.disqus.com/embed.js';
|
||||
s.setAttribute('data-timestamp', +new Date());
|
||||
(d.head || d.body).appendChild(s);
|
||||
|
||||
disqusObserver.disconnect();
|
||||
}
|
||||
},
|
||||
{ threshold: [0] }
|
||||
);
|
||||
|
||||
disqusObserver.observe(document.getElementById('disqus_thread'));
|
||||
</script>
|
||||
|
||||
@@ -1,21 +1,8 @@
|
||||
<!-- https://giscus.app/ -->
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
(function () {
|
||||
const origin = 'https://giscus.app';
|
||||
const lightTheme = 'light';
|
||||
const darkTheme = 'dark_dimmed';
|
||||
|
||||
let initTheme = lightTheme;
|
||||
const html = document.documentElement;
|
||||
|
||||
if (
|
||||
(html.hasAttribute('data-mode') &&
|
||||
html.getAttribute('data-mode') === 'dark') ||
|
||||
(!html.hasAttribute('data-mode') &&
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
) {
|
||||
initTheme = darkTheme;
|
||||
}
|
||||
const themeMapper = Theme.getThemeMapper('light', 'dark_dimmed');
|
||||
const initTheme = themeMapper[Theme.visualState];
|
||||
|
||||
let lang = '{{ site.comments.giscus.lang | default: lang }}';
|
||||
{%- comment -%} https://github.com/giscus/giscus/tree/main/locales {%- endcomment -%}
|
||||
@@ -41,30 +28,27 @@
|
||||
async: ''
|
||||
};
|
||||
|
||||
let giscusScript = document.createElement('script');
|
||||
let giscusNode = document.createElement('script');
|
||||
Object.entries(giscusAttributes).forEach(([key, value]) =>
|
||||
giscusScript.setAttribute(key, value)
|
||||
giscusNode.setAttribute(key, value)
|
||||
);
|
||||
document.getElementById('tail-wrapper').appendChild(giscusScript);
|
||||
|
||||
const $footer = document.querySelector('footer');
|
||||
$footer.insertAdjacentElement("beforebegin", giscusNode);
|
||||
|
||||
addEventListener('message', (event) => {
|
||||
if (
|
||||
event.source === window &&
|
||||
event.data &&
|
||||
event.data.direction === ModeToggle.ID
|
||||
) {
|
||||
{%- comment -%} global theme mode changed {%- endcomment -%}
|
||||
const mode = event.data.message;
|
||||
const theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
|
||||
if (event.source === window && event.data && event.data.id === Theme.ID) {
|
||||
const newTheme = themeMapper[Theme.visualState];
|
||||
|
||||
const message = {
|
||||
setConfig: {
|
||||
theme: theme
|
||||
theme: newTheme
|
||||
}
|
||||
};
|
||||
|
||||
const giscus = document.getElementsByClassName('giscus-frame')[0].contentWindow;
|
||||
giscus.postMessage({ giscus: message }, origin);
|
||||
const giscus =
|
||||
document.getElementsByClassName('giscus-frame')[0].contentWindow;
|
||||
giscus.postMessage({ giscus: message }, 'https://giscus.app');
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -1,49 +1,38 @@
|
||||
<!-- https://utteranc.es/ -->
|
||||
<script
|
||||
src="https://utteranc.es/client.js"
|
||||
repo="{{ site.comments.utterances.repo }}"
|
||||
issue-term="{{ site.comments.utterances.issue_term }}"
|
||||
crossorigin="anonymous"
|
||||
async
|
||||
></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
<script>
|
||||
(function () {
|
||||
const origin = 'https://utteranc.es';
|
||||
const lightTheme = 'github-light';
|
||||
const darkTheme = 'github-dark';
|
||||
let initTheme = lightTheme;
|
||||
const html = document.documentElement;
|
||||
const themeMapper = Theme.getThemeMapper('github-light', 'github-dark');
|
||||
const initTheme = themeMapper[Theme.visualState];
|
||||
|
||||
if (
|
||||
(html.hasAttribute('data-mode') && html.getAttribute('data-mode') === 'dark') ||
|
||||
(!html.hasAttribute('data-mode') && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
) {
|
||||
initTheme = darkTheme;
|
||||
}
|
||||
let script = document.createElement('script');
|
||||
script.src = 'https://utteranc.es/client.js';
|
||||
script.setAttribute('repo', '{{ site.comments.utterances.repo }}');
|
||||
script.setAttribute('issue-term', '{{ site.comments.utterances.issue_term }}');
|
||||
script.setAttribute('theme', initTheme);
|
||||
script.crossOrigin = 'anonymous';
|
||||
script.async = true;
|
||||
|
||||
const $footer = document.querySelector('footer');
|
||||
$footer.insertAdjacentElement('beforebegin', script);
|
||||
|
||||
addEventListener('message', (event) => {
|
||||
let theme;
|
||||
let newTheme;
|
||||
|
||||
{%- comment -%} credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347> {%- endcomment -%}
|
||||
if (event.origin === origin) {
|
||||
{%- comment -%} page initial {%- endcomment -%}
|
||||
theme = initTheme;
|
||||
} else if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
||||
{%- comment -%} global theme mode changed {%- endcomment -%}
|
||||
const mode = event.data.message;
|
||||
theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
|
||||
} else {
|
||||
return;
|
||||
{%- comment -%}
|
||||
Credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347>
|
||||
{%- endcomment -%}
|
||||
if (event.source === window && event.data && event.data.id === Theme.ID) {
|
||||
newTheme = themeMapper[Theme.visualState];
|
||||
|
||||
const message = {
|
||||
type: 'set-theme',
|
||||
theme: newTheme
|
||||
};
|
||||
|
||||
const utterances = document.querySelector('.utterances-frame').contentWindow;
|
||||
utterances.postMessage(message, origin);
|
||||
}
|
||||
|
||||
const message = {
|
||||
type: 'set-theme',
|
||||
theme: theme
|
||||
};
|
||||
|
||||
const utterances = document.getElementsByClassName('utterances-frame')[0].contentWindow;
|
||||
utterances.postMessage(message, origin);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7">
|
||||
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta
|
||||
name="viewport"
|
||||
@@ -97,11 +97,32 @@
|
||||
<link rel="stylesheet" href="{{ site.data.origin[type].glightbox.css | relative_url }}">
|
||||
{% endif %}
|
||||
|
||||
<!-- JavaScript -->
|
||||
<!-- Scripts -->
|
||||
|
||||
{% unless site.theme_mode %}
|
||||
{% include mode-toggle.html %}
|
||||
<script src="{{ '/assets/js/dist/theme.min.js' | relative_url }}"></script>
|
||||
{% endunless %}
|
||||
|
||||
{% include js-selector.html lang=lang %}
|
||||
|
||||
{% if jekyll.environment == 'production' %}
|
||||
<!-- PWA -->
|
||||
{% if site.pwa.enabled %}
|
||||
<script
|
||||
defer
|
||||
src="{{ '/app.min.js' | relative_url }}?baseurl={{ site.baseurl | default: '' }}®ister={{ site.pwa.cache.enabled }}"
|
||||
></script>
|
||||
{% endif %}
|
||||
|
||||
<!-- Web Analytics -->
|
||||
{% for analytics in site.analytics %}
|
||||
{% capture str %}{{ analytics }}{% endcapture %}
|
||||
{% assign platform = str | split: '{' | first %}
|
||||
{% if site.analytics[platform].id and site.analytics[platform].id != empty %}
|
||||
{% include analytics/{{ platform }}.html %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% include metadata-hook.html %}
|
||||
</head>
|
||||
|
||||
@@ -62,12 +62,12 @@
|
||||
|
||||
{% capture script %}/assets/js/dist/{{ js }}.min.js{% endcapture %}
|
||||
|
||||
<script src="{{ script | relative_url }}"></script>
|
||||
<script defer src="{{ script | relative_url }}"></script>
|
||||
|
||||
{% if page.math %}
|
||||
<!-- MathJax -->
|
||||
<script src="{{ '/assets/js/data/mathjax.js' | relative_url }}"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
|
||||
<script async src="{{ '/assets/js/data/mathjax.js' | relative_url }}"></script>
|
||||
<script async src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
|
||||
<script id="MathJax-script" async src="{{ site.data.origin[type].mathjax.js | relative_url }}"></script>
|
||||
{% endif %}
|
||||
|
||||
@@ -84,23 +84,3 @@
|
||||
{% endcase %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if page.mermaid %}
|
||||
{% include mermaid.html %}
|
||||
{% endif %}
|
||||
|
||||
{% if jekyll.environment == 'production' %}
|
||||
<!-- PWA -->
|
||||
{% if site.pwa.enabled %}
|
||||
<script defer src="{{ 'app.min.js' | relative_url }}"></script>
|
||||
{% endif %}
|
||||
|
||||
<!-- Web Analytics -->
|
||||
{% for analytics in site.analytics %}
|
||||
{% capture str %}{{ analytics }}{% endcapture %}
|
||||
{% assign type = str | split: '{' | first %}
|
||||
{% if site.analytics[type].id and site.analytics[type].id != empty %}
|
||||
{% include analytics/{{ type }}.html %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% assign urls = include.urls | split: ',' %}
|
||||
|
||||
{% assign combined_urls = nil %}
|
||||
{% assign combined_urls = null %}
|
||||
|
||||
{% assign domain = 'https://cdn.jsdelivr.net/' %}
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
{% endif %}
|
||||
|
||||
{% elsif url contains '//' %}
|
||||
<script src="{{ url }}"></script>
|
||||
<script defer src="{{ url }}"></script>
|
||||
{% else %}
|
||||
<script src="{{ url | relative_url }}"></script>
|
||||
<script defer src="{{ url | relative_url }}"></script>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if combined_urls %}
|
||||
<script src="{{ combined_urls }}"></script>
|
||||
<script defer src="{{ combined_urls }}"></script>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
<!-- mermaid-js loader -->
|
||||
<script type="text/javascript">
|
||||
function updateMermaid(event) {
|
||||
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
||||
const mode = event.data.message;
|
||||
|
||||
if (typeof mermaid === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
let expectedTheme = mode === ModeToggle.DARK_MODE ? 'dark' : 'default';
|
||||
let config = { theme: expectedTheme };
|
||||
|
||||
{%- comment -%}
|
||||
Re-render the SVG › <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344>
|
||||
{%- endcomment -%}
|
||||
const mermaidList = document.getElementsByClassName('mermaid');
|
||||
|
||||
[...mermaidList].forEach((elem) => {
|
||||
const svgCode = elem.previousSibling.children.item(0).innerHTML;
|
||||
elem.innerHTML = svgCode;
|
||||
elem.removeAttribute('data-processed');
|
||||
});
|
||||
|
||||
mermaid.initialize(config);
|
||||
mermaid.init(undefined, '.mermaid');
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
let initTheme = 'default';
|
||||
const html = document.documentElement;
|
||||
|
||||
if (
|
||||
(html.hasAttribute('data-mode') && html.getAttribute('data-mode') === 'dark') ||
|
||||
(!html.hasAttribute('data-mode') && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
) {
|
||||
initTheme = 'dark';
|
||||
}
|
||||
|
||||
let mermaidConf = {
|
||||
theme: initTheme {%- comment -%} <default | dark | forest | neutral> {%- endcomment -%}
|
||||
};
|
||||
|
||||
{%- comment -%} Create mermaid tag {%- endcomment -%}
|
||||
const basicList = document.getElementsByClassName('language-mermaid');
|
||||
[...basicList].forEach((elem) => {
|
||||
const svgCode = elem.textContent;
|
||||
const backup = elem.parentElement;
|
||||
backup.classList.add('d-none');
|
||||
{%- comment -%} create mermaid node {%- endcomment -%}
|
||||
let mermaid = document.createElement('pre');
|
||||
mermaid.classList.add('mermaid');
|
||||
const text = document.createTextNode(svgCode);
|
||||
mermaid.appendChild(text);
|
||||
backup.after(mermaid);
|
||||
});
|
||||
|
||||
mermaid.initialize(mermaidConf);
|
||||
window.addEventListener('message', updateMermaid);
|
||||
})();
|
||||
</script>
|
||||
@@ -1,116 +0,0 @@
|
||||
<!-- Switch the mode between dark and light. -->
|
||||
|
||||
<script type="text/javascript">
|
||||
class ModeToggle {
|
||||
static get MODE_KEY() {
|
||||
return 'mode';
|
||||
}
|
||||
static get MODE_ATTR() {
|
||||
return 'data-mode';
|
||||
}
|
||||
static get DARK_MODE() {
|
||||
return 'dark';
|
||||
}
|
||||
static get LIGHT_MODE() {
|
||||
return 'light';
|
||||
}
|
||||
static get ID() {
|
||||
return 'mode-toggle';
|
||||
}
|
||||
|
||||
constructor() {
|
||||
let self = this;
|
||||
|
||||
{%- comment -%} always follow the system prefers {%- endcomment -%}
|
||||
this.sysDarkPrefers.addEventListener('change', () => {
|
||||
if (self.hasMode) {
|
||||
self.clearMode();
|
||||
}
|
||||
self.notify();
|
||||
});
|
||||
|
||||
if (!this.hasMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isDarkMode) {
|
||||
this.setDark();
|
||||
} else {
|
||||
this.setLight();
|
||||
}
|
||||
}
|
||||
|
||||
get sysDarkPrefers() {
|
||||
return window.matchMedia('(prefers-color-scheme: dark)');
|
||||
}
|
||||
|
||||
get isPreferDark() {
|
||||
return this.sysDarkPrefers.matches;
|
||||
}
|
||||
|
||||
get isDarkMode() {
|
||||
return this.mode === ModeToggle.DARK_MODE;
|
||||
}
|
||||
|
||||
get hasMode() {
|
||||
return this.mode != null;
|
||||
}
|
||||
|
||||
get mode() {
|
||||
return sessionStorage.getItem(ModeToggle.MODE_KEY);
|
||||
}
|
||||
|
||||
{%- comment -%} get the current mode on screen {%- endcomment -%}
|
||||
get modeStatus() {
|
||||
if (this.hasMode) {
|
||||
return this.mode;
|
||||
} else {
|
||||
return this.isPreferDark ? ModeToggle.DARK_MODE : ModeToggle.LIGHT_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
setDark() {
|
||||
document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.DARK_MODE);
|
||||
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.DARK_MODE);
|
||||
}
|
||||
|
||||
setLight() {
|
||||
document.documentElement.setAttribute(ModeToggle.MODE_ATTR, ModeToggle.LIGHT_MODE);
|
||||
sessionStorage.setItem(ModeToggle.MODE_KEY, ModeToggle.LIGHT_MODE);
|
||||
}
|
||||
|
||||
clearMode() {
|
||||
document.documentElement.removeAttribute(ModeToggle.MODE_ATTR);
|
||||
sessionStorage.removeItem(ModeToggle.MODE_KEY);
|
||||
}
|
||||
|
||||
{%- comment -%}
|
||||
Notify another plugins that the theme mode has changed
|
||||
{%- endcomment -%}
|
||||
notify() {
|
||||
window.postMessage(
|
||||
{
|
||||
direction: ModeToggle.ID,
|
||||
message: this.modeStatus
|
||||
},
|
||||
'*'
|
||||
);
|
||||
}
|
||||
|
||||
flipMode() {
|
||||
if (this.hasMode) {
|
||||
this.clearMode();
|
||||
} else {
|
||||
if (this.isPreferDark) {
|
||||
this.setLight();
|
||||
} else {
|
||||
this.setDark();
|
||||
}
|
||||
}
|
||||
|
||||
this.notify();
|
||||
}
|
||||
}
|
||||
|
||||
const modeToggle = new ModeToggle();
|
||||
</script>
|
||||
@@ -19,29 +19,31 @@
|
||||
{% capture not_found %}<p class="mt-5">{{ site.data.locales[include.lang].search.no_results }}</p>{% endcapture %}
|
||||
|
||||
<script>
|
||||
{%- comment -%} Note: dependent library will be loaded in `js-selector.html` {%- endcomment -%}
|
||||
SimpleJekyllSearch({
|
||||
searchInput: document.getElementById('search-input'),
|
||||
resultsContainer: document.getElementById('search-results'),
|
||||
json: '{{ '/assets/js/data/search.json' | relative_url }}',
|
||||
searchResultTemplate: '{{ result_elem | strip_newlines }}',
|
||||
noResultsText: '{{ not_found }}',
|
||||
templateMiddleware: function(prop, value, template) {
|
||||
if (prop === 'categories') {
|
||||
if (value === '') {
|
||||
return `${value}`;
|
||||
} else {
|
||||
return `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${value}</div>`;
|
||||
{% comment %} Note: dependent library will be loaded in `js-selector.html` {% endcomment %}
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
SimpleJekyllSearch({
|
||||
searchInput: document.getElementById('search-input'),
|
||||
resultsContainer: document.getElementById('search-results'),
|
||||
json: '{{ '/assets/js/data/search.json' | relative_url }}',
|
||||
searchResultTemplate: '{{ result_elem | strip_newlines }}',
|
||||
noResultsText: '{{ not_found }}',
|
||||
templateMiddleware: function(prop, value, template) {
|
||||
if (prop === 'categories') {
|
||||
if (value === '') {
|
||||
return `${value}`;
|
||||
} else {
|
||||
return `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${value}</div>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prop === 'tags') {
|
||||
if (value === '') {
|
||||
return `${value}`;
|
||||
} else {
|
||||
return `<div><i class="fa fa-tag fa-fw"></i>${value}</div>`;
|
||||
if (prop === 'tags') {
|
||||
if (value === '') {
|
||||
return `${value}`;
|
||||
} else {
|
||||
return `<div><i class="fa fa-tag fa-fw"></i>${value}</div>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
{%- endif -%}
|
||||
</a>
|
||||
|
||||
<h1 class="site-title">
|
||||
<a href="{{ '/' | relative_url }}">{{ site.title }}</a>
|
||||
</h1>
|
||||
<a class="site-title d-block" href="{{ '/' | relative_url }}">{{ site.title }}</a>
|
||||
<p class="site-subtitle fst-italic mb-0">{{ site.tagline }}</p>
|
||||
</header>
|
||||
<!-- .profile-wrapper -->
|
||||
|
||||
10
_includes/toc-status.html
Normal file
10
_includes/toc-status.html
Normal file
@@ -0,0 +1,10 @@
|
||||
{% comment %}
|
||||
Determine TOC state and return it through variable "enable_toc"
|
||||
{% endcomment %}
|
||||
|
||||
{% assign enable_toc = false %}
|
||||
{% if site.toc and page.toc %}
|
||||
{% if page.content contains '<h2' or page.content contains '<h3' %}
|
||||
{% assign enable_toc = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
@@ -1,12 +1,7 @@
|
||||
{% assign enable_toc = false %}
|
||||
{% if site.toc and page.toc %}
|
||||
{% if page.content contains '<h2' or page.content contains '<h3' %}
|
||||
{% assign enable_toc = true %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% include toc-status.html %}
|
||||
|
||||
{% if enable_toc %}
|
||||
<section id="toc-wrapper" class="d-none ps-0 pe-4">
|
||||
<section id="toc-wrapper" class="ps-0 pe-4">
|
||||
<h2 class="panel-heading ps-3 mb-2">{{- site.data.locales[include.lang].panel.toc -}}</h2>
|
||||
<nav id="toc"></nav>
|
||||
</section>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||
import { categoryCollapse } from './modules/plugins';
|
||||
import { categoryCollapse } from './modules/components';
|
||||
|
||||
basic();
|
||||
initSidebar();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||
import { initLocaleDatetime, loadImg } from './modules/plugins';
|
||||
import { initLocaleDatetime, loadImg } from './modules/components';
|
||||
|
||||
loadImg();
|
||||
initLocaleDatetime();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||
import { initLocaleDatetime } from './modules/plugins';
|
||||
import { initLocaleDatetime } from './modules/components';
|
||||
|
||||
initSidebar();
|
||||
initTopbar();
|
||||
|
||||
@@ -3,4 +3,8 @@ export { initClipboard } from './components/clipboard';
|
||||
export { loadImg } from './components/img-loading';
|
||||
export { imgPopup } from './components/img-popup';
|
||||
export { initLocaleDatetime } from './components/locale-datetime';
|
||||
export { toc } from './components/toc';
|
||||
export { initToc } from './components/toc';
|
||||
export { loadMermaid } from './components/mermaid';
|
||||
export { modeWatcher } from './components/mode-toggle';
|
||||
export { back2top } from './components/back-to-top';
|
||||
export { loadTooptip } from './components/tooltip-loader';
|
||||
@@ -4,7 +4,6 @@
|
||||
* Dependencies: https://github.com/biati-digital/glightbox
|
||||
*/
|
||||
|
||||
const html = document.documentElement;
|
||||
const lightImages = '.popup:not(.dark)';
|
||||
const darkImages = '.popup:not(.light)';
|
||||
let selector = lightImages;
|
||||
@@ -33,26 +32,17 @@ export function imgPopup() {
|
||||
document.querySelector('.popup.dark') === null
|
||||
);
|
||||
|
||||
if (
|
||||
(html.hasAttribute('data-mode') &&
|
||||
html.getAttribute('data-mode') === 'dark') ||
|
||||
(!html.hasAttribute('data-mode') &&
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||
) {
|
||||
if (Theme.visualState === Theme.DARK) {
|
||||
selector = darkImages;
|
||||
}
|
||||
|
||||
let current = GLightbox({ selector: `${selector}` });
|
||||
|
||||
if (hasDualImages && document.getElementById('mode-toggle')) {
|
||||
if (hasDualImages && Theme.switchable) {
|
||||
let reverse = null;
|
||||
|
||||
window.addEventListener('message', (event) => {
|
||||
if (
|
||||
event.source === window &&
|
||||
event.data &&
|
||||
event.data.direction === ModeToggle.ID
|
||||
) {
|
||||
if (event.source === window && event.data && event.data.id === Theme.ID) {
|
||||
updateImages(current, reverse);
|
||||
}
|
||||
});
|
||||
|
||||
60
_javascript/modules/components/mermaid.js
Normal file
60
_javascript/modules/components/mermaid.js
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Mermaid-js loader
|
||||
*/
|
||||
|
||||
const MERMAID = 'mermaid';
|
||||
const themeMapper = Theme.getThemeMapper('default', 'dark');
|
||||
|
||||
function refreshTheme(event) {
|
||||
if (event.source === window && event.data && event.data.id === Theme.ID) {
|
||||
// Re-render the SVG › <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344>
|
||||
const mermaidList = document.getElementsByClassName(MERMAID);
|
||||
|
||||
[...mermaidList].forEach((elem) => {
|
||||
const svgCode = elem.previousSibling.children.item(0).innerHTML;
|
||||
elem.textContent = svgCode;
|
||||
elem.removeAttribute('data-processed');
|
||||
});
|
||||
|
||||
const newTheme = themeMapper[Theme.visualState];
|
||||
|
||||
mermaid.initialize({ theme: newTheme });
|
||||
mermaid.init(null, `.${MERMAID}`);
|
||||
}
|
||||
}
|
||||
|
||||
function setNode(elem) {
|
||||
const svgCode = elem.textContent;
|
||||
const backup = elem.parentElement;
|
||||
backup.classList.add('d-none');
|
||||
// Create mermaid node
|
||||
const mermaid = document.createElement('pre');
|
||||
mermaid.classList.add(MERMAID);
|
||||
const text = document.createTextNode(svgCode);
|
||||
mermaid.appendChild(text);
|
||||
backup.after(mermaid);
|
||||
}
|
||||
|
||||
export function loadMermaid() {
|
||||
if (
|
||||
typeof mermaid === 'undefined' ||
|
||||
typeof mermaid.initialize !== 'function'
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const initTheme = themeMapper[Theme.visualState];
|
||||
|
||||
let mermaidConf = {
|
||||
theme: initTheme
|
||||
};
|
||||
|
||||
const basicList = document.getElementsByClassName('language-mermaid');
|
||||
[...basicList].forEach(setNode);
|
||||
|
||||
mermaid.initialize(mermaidConf);
|
||||
|
||||
if (Theme.switchable) {
|
||||
window.addEventListener('message', refreshTheme);
|
||||
}
|
||||
}
|
||||
15
_javascript/modules/components/mode-toggle.js
Normal file
15
_javascript/modules/components/mode-toggle.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Add listener for theme mode toggle
|
||||
*/
|
||||
|
||||
const $toggle = document.getElementById('mode-toggle');
|
||||
|
||||
export function modeWatcher() {
|
||||
if (!$toggle) {
|
||||
return;
|
||||
}
|
||||
|
||||
$toggle.addEventListener('click', () => {
|
||||
Theme.flip();
|
||||
});
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* Add listener for theme mode toggle
|
||||
*/
|
||||
const toggle = document.getElementById('mode-toggle');
|
||||
|
||||
export function modeWatcher() {
|
||||
if (!toggle) {
|
||||
return;
|
||||
}
|
||||
|
||||
toggle.addEventListener('click', () => {
|
||||
modeToggle.flipMode();
|
||||
});
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* Expand or close the sidebar in mobile screens.
|
||||
*/
|
||||
|
||||
const ATTR_DISPLAY = 'sidebar-display';
|
||||
|
||||
class SidebarUtil {
|
||||
static isExpanded = false;
|
||||
|
||||
static toggle() {
|
||||
if (SidebarUtil.isExpanded === false) {
|
||||
document.body.setAttribute(ATTR_DISPLAY, '');
|
||||
} else {
|
||||
document.body.removeAttribute(ATTR_DISPLAY);
|
||||
}
|
||||
|
||||
SidebarUtil.isExpanded = !SidebarUtil.isExpanded;
|
||||
}
|
||||
}
|
||||
|
||||
export function sidebarExpand() {
|
||||
document
|
||||
.getElementById('sidebar-trigger')
|
||||
.addEventListener('click', SidebarUtil.toggle);
|
||||
|
||||
document.getElementById('mask').addEventListener('click', SidebarUtil.toggle);
|
||||
}
|
||||
@@ -1,15 +1,33 @@
|
||||
export function toc() {
|
||||
if (document.querySelector('main h2, main h3')) {
|
||||
// see: https://github.com/tscanlin/tocbot#usage
|
||||
tocbot.init({
|
||||
tocSelector: '#toc',
|
||||
contentSelector: '.content',
|
||||
ignoreSelector: '[data-toc-skip]',
|
||||
headingSelector: 'h2, h3, h4',
|
||||
orderedList: false,
|
||||
scrollSmooth: false
|
||||
});
|
||||
import { TocMobile as mobile } from './toc/toc-mobile';
|
||||
import { TocDesktop as desktop } from './toc/toc-desktop';
|
||||
|
||||
document.getElementById('toc-wrapper').classList.remove('d-none');
|
||||
const desktopMode = matchMedia('(min-width: 1200px)');
|
||||
|
||||
function refresh(e) {
|
||||
if (e.matches) {
|
||||
if (mobile.popupOpened) {
|
||||
mobile.hidePopup();
|
||||
}
|
||||
|
||||
desktop.refresh();
|
||||
} else {
|
||||
mobile.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (document.querySelector('main>article[data-toc="true"]') === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid create multiple instances of Tocbot. Ref: <https://github.com/tscanlin/tocbot/issues/203>
|
||||
if (desktopMode.matches) {
|
||||
desktop.init();
|
||||
} else {
|
||||
mobile.init();
|
||||
}
|
||||
|
||||
desktopMode.onchange = refresh;
|
||||
}
|
||||
|
||||
export { init as initToc };
|
||||
|
||||
22
_javascript/modules/components/toc/toc-desktop.js
Normal file
22
_javascript/modules/components/toc/toc-desktop.js
Normal file
@@ -0,0 +1,22 @@
|
||||
export class TocDesktop {
|
||||
/* Tocbot options Ref: https://github.com/tscanlin/tocbot#usage */
|
||||
static options = {
|
||||
tocSelector: '#toc',
|
||||
contentSelector: '.content',
|
||||
ignoreSelector: '[data-toc-skip]',
|
||||
headingSelector: 'h2, h3, h4',
|
||||
orderedList: false,
|
||||
scrollSmooth: false,
|
||||
headingsOffset: 16 * 2 // 2rem
|
||||
};
|
||||
|
||||
static refresh() {
|
||||
tocbot.refresh(this.options);
|
||||
}
|
||||
|
||||
static init() {
|
||||
if (document.getElementById('toc-wrapper')) {
|
||||
tocbot.init(this.options);
|
||||
}
|
||||
}
|
||||
}
|
||||
125
_javascript/modules/components/toc/toc-mobile.js
Normal file
125
_javascript/modules/components/toc/toc-mobile.js
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* TOC button, topbar and popup for mobile devices
|
||||
*/
|
||||
|
||||
const $tocBar = document.getElementById('toc-bar');
|
||||
const $soloTrigger = document.getElementById('toc-solo-trigger');
|
||||
const $triggers = document.getElementsByClassName('toc-trigger');
|
||||
const $popup = document.getElementById('toc-popup');
|
||||
const $btnClose = document.getElementById('toc-popup-close');
|
||||
|
||||
const SCROLL_LOCK = 'overflow-hidden';
|
||||
const CLOSING = 'closing';
|
||||
|
||||
export class TocMobile {
|
||||
static #invisible = true;
|
||||
static #barHeight = 16 * 3; // 3rem
|
||||
|
||||
static options = {
|
||||
tocSelector: '#toc-popup-content',
|
||||
contentSelector: '.content',
|
||||
ignoreSelector: '[data-toc-skip]',
|
||||
headingSelector: 'h2, h3, h4',
|
||||
orderedList: false,
|
||||
scrollSmooth: false,
|
||||
collapseDepth: 4,
|
||||
headingsOffset: this.#barHeight
|
||||
};
|
||||
|
||||
static initBar() {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
$tocBar.classList.toggle('invisible', entry.isIntersecting);
|
||||
});
|
||||
},
|
||||
{ rootMargin: `-${this.#barHeight}px 0px 0px 0px` }
|
||||
);
|
||||
|
||||
observer.observe($soloTrigger);
|
||||
this.#invisible = false;
|
||||
}
|
||||
|
||||
static listenAnchors() {
|
||||
const $anchors = document.getElementsByClassName('toc-link');
|
||||
[...$anchors].forEach((anchor) => {
|
||||
anchor.onclick = () => this.hidePopup();
|
||||
});
|
||||
}
|
||||
|
||||
static refresh() {
|
||||
if (this.#invisible) {
|
||||
this.initComponents();
|
||||
}
|
||||
tocbot.refresh(this.options);
|
||||
this.listenAnchors();
|
||||
}
|
||||
|
||||
static get popupOpened() {
|
||||
return $popup.open;
|
||||
}
|
||||
|
||||
static showPopup() {
|
||||
this.lockScroll(true);
|
||||
$popup.showModal();
|
||||
const activeItem = $popup.querySelector('li.is-active-li');
|
||||
activeItem.scrollIntoView({ block: 'center' });
|
||||
}
|
||||
|
||||
static hidePopup() {
|
||||
$popup.toggleAttribute(CLOSING);
|
||||
|
||||
$popup.addEventListener(
|
||||
'animationend',
|
||||
() => {
|
||||
$popup.toggleAttribute(CLOSING);
|
||||
$popup.close();
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
|
||||
this.lockScroll(false);
|
||||
}
|
||||
|
||||
static lockScroll(enable) {
|
||||
document.documentElement.classList.toggle(SCROLL_LOCK, enable);
|
||||
document.body.classList.toggle(SCROLL_LOCK, enable);
|
||||
}
|
||||
|
||||
static clickBackdrop(event) {
|
||||
if ($popup.hasAttribute(CLOSING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const rect = event.target.getBoundingClientRect();
|
||||
if (
|
||||
event.clientX < rect.left ||
|
||||
event.clientX > rect.right ||
|
||||
event.clientY < rect.top ||
|
||||
event.clientY > rect.bottom
|
||||
) {
|
||||
this.hidePopup();
|
||||
}
|
||||
}
|
||||
|
||||
static initComponents() {
|
||||
this.initBar();
|
||||
|
||||
[...$triggers].forEach((trigger) => {
|
||||
trigger.onclick = () => this.showPopup();
|
||||
});
|
||||
|
||||
$popup.onclick = (e) => this.clickBackdrop(e);
|
||||
$btnClose.onclick = () => this.hidePopup();
|
||||
$popup.oncancel = (e) => {
|
||||
e.preventDefault();
|
||||
this.hidePopup();
|
||||
};
|
||||
}
|
||||
|
||||
static init() {
|
||||
tocbot.init(this.options);
|
||||
this.listenAnchors();
|
||||
this.initComponents();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { back2top } from '../components/back-to-top';
|
||||
import { loadTooptip } from '../components/tooltip-loader';
|
||||
import { back2top, loadTooptip, modeWatcher } from '../components';
|
||||
|
||||
export function basic() {
|
||||
modeWatcher();
|
||||
back2top();
|
||||
loadTooptip();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
import { modeWatcher } from '../components/mode-watcher';
|
||||
import { sidebarExpand } from '../components/sidebar';
|
||||
const ATTR_DISPLAY = 'sidebar-display';
|
||||
const $sidebar = document.getElementById('sidebar');
|
||||
const $trigger = document.getElementById('sidebar-trigger');
|
||||
const $mask = document.getElementById('mask');
|
||||
|
||||
class SidebarUtil {
|
||||
static #isExpanded = false;
|
||||
|
||||
static toggle() {
|
||||
this.#isExpanded = !this.#isExpanded;
|
||||
document.body.toggleAttribute(ATTR_DISPLAY, this.#isExpanded);
|
||||
$sidebar.classList.toggle('z-2', this.#isExpanded);
|
||||
$mask.classList.toggle('d-none', !this.#isExpanded);
|
||||
}
|
||||
}
|
||||
|
||||
export function initSidebar() {
|
||||
modeWatcher();
|
||||
sidebarExpand();
|
||||
$trigger.onclick = $mask.onclick = () => SidebarUtil.toggle();
|
||||
}
|
||||
|
||||
135
_javascript/modules/theme.js
Normal file
135
_javascript/modules/theme.js
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* Theme management class
|
||||
*
|
||||
* To reduce flickering during page load, this script should be loaded synchronously.
|
||||
*/
|
||||
class Theme {
|
||||
static #modeKey = 'mode';
|
||||
static #modeAttr = 'data-mode';
|
||||
static #darkMedia = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
static switchable = !document.documentElement.hasAttribute(this.#modeAttr);
|
||||
|
||||
static get DARK() {
|
||||
return 'dark';
|
||||
}
|
||||
|
||||
static get LIGHT() {
|
||||
return 'light';
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} Theme mode identifier
|
||||
*/
|
||||
static get ID() {
|
||||
return 'theme-mode';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current visual state of the theme.
|
||||
*
|
||||
* @returns {string} The current visual state, either the mode if it exists,
|
||||
* or the system dark mode state ('dark' or 'light').
|
||||
*/
|
||||
static get visualState() {
|
||||
if (this.#hasMode) {
|
||||
return this.#mode;
|
||||
} else {
|
||||
return this.#sysDark ? this.DARK : this.LIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
static get #mode() {
|
||||
return sessionStorage.getItem(this.#modeKey);
|
||||
}
|
||||
|
||||
static get #isDarkMode() {
|
||||
return this.#mode === this.DARK;
|
||||
}
|
||||
|
||||
static get #hasMode() {
|
||||
return this.#mode !== null;
|
||||
}
|
||||
|
||||
static get #sysDark() {
|
||||
return this.#darkMedia.matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps theme modes to provided values
|
||||
* @param {string} light Value for light mode
|
||||
* @param {string} dark Value for dark mode
|
||||
* @returns {Object} Mapped values
|
||||
*/
|
||||
static getThemeMapper(light, dark) {
|
||||
return {
|
||||
[this.LIGHT]: light,
|
||||
[this.DARK]: dark
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the theme based on system preferences or stored mode
|
||||
*/
|
||||
static init() {
|
||||
if (!this.switchable) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.#darkMedia.addEventListener('change', () => {
|
||||
const lastMode = this.#mode;
|
||||
this.#clearMode();
|
||||
|
||||
if (lastMode !== this.visualState) {
|
||||
this.#notify();
|
||||
}
|
||||
});
|
||||
|
||||
if (!this.#hasMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.#isDarkMode) {
|
||||
this.#setDark();
|
||||
} else {
|
||||
this.#setLight();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flips the current theme mode
|
||||
*/
|
||||
static flip() {
|
||||
if (this.#hasMode) {
|
||||
this.#clearMode();
|
||||
} else {
|
||||
this.#sysDark ? this.#setLight() : this.#setDark();
|
||||
}
|
||||
this.#notify();
|
||||
}
|
||||
|
||||
static #setDark() {
|
||||
document.documentElement.setAttribute(this.#modeAttr, this.DARK);
|
||||
sessionStorage.setItem(this.#modeKey, this.DARK);
|
||||
}
|
||||
|
||||
static #setLight() {
|
||||
document.documentElement.setAttribute(this.#modeAttr, this.LIGHT);
|
||||
sessionStorage.setItem(this.#modeKey, this.LIGHT);
|
||||
}
|
||||
|
||||
static #clearMode() {
|
||||
document.documentElement.removeAttribute(this.#modeAttr);
|
||||
sessionStorage.removeItem(this.#modeKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies other plugins that the theme mode has changed
|
||||
*/
|
||||
static #notify() {
|
||||
window.postMessage({ id: this.ID }, '*');
|
||||
}
|
||||
}
|
||||
|
||||
Theme.init();
|
||||
|
||||
export default Theme;
|
||||
@@ -1,9 +1,15 @@
|
||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||
import { loadImg, imgPopup, initClipboard } from './modules/plugins';
|
||||
import {
|
||||
loadImg,
|
||||
imgPopup,
|
||||
initClipboard,
|
||||
loadMermaid
|
||||
} from './modules/components';
|
||||
|
||||
loadImg();
|
||||
imgPopup();
|
||||
initSidebar();
|
||||
initTopbar();
|
||||
initClipboard();
|
||||
loadMermaid();
|
||||
basic();
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||
import { basic, initTopbar, initSidebar } from './modules/layouts';
|
||||
|
||||
import {
|
||||
loadImg,
|
||||
imgPopup,
|
||||
initLocaleDatetime,
|
||||
initClipboard,
|
||||
toc
|
||||
} from './modules/plugins';
|
||||
initToc,
|
||||
loadMermaid
|
||||
} from './modules/components';
|
||||
|
||||
loadImg();
|
||||
toc();
|
||||
initToc();
|
||||
imgPopup();
|
||||
initSidebar();
|
||||
initLocaleDatetime();
|
||||
initClipboard();
|
||||
initTopbar();
|
||||
loadMermaid();
|
||||
basic();
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
import { pwa, baseurl } from '../../_config.yml';
|
||||
import Toast from 'bootstrap/js/src/toast';
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
if (pwa.enabled) {
|
||||
const swUrl = `${baseurl}/sw.min.js`;
|
||||
// Get Jekyll config from URL parameters
|
||||
const src = new URL(document.currentScript.src);
|
||||
const register = src.searchParams.get('register');
|
||||
const baseUrl = src.searchParams.get('baseurl');
|
||||
|
||||
if (register) {
|
||||
const swUrl = `${baseUrl}/sw.min.js`;
|
||||
const notification = document.getElementById('notification');
|
||||
const btnRefresh = notification.querySelector('.toast-body>button');
|
||||
const popupWindow = Toast.getOrCreateInstance(notification);
|
||||
|
||||
navigator.serviceWorker.register(swUrl).then((registration) => {
|
||||
// In case the user ignores the notification
|
||||
// Restore the update window that was last manually closed by the user
|
||||
if (registration.waiting) {
|
||||
popupWindow.show();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { baseurl } from '../../_config.yml';
|
||||
|
||||
importScripts(`${baseurl}/assets/js/data/swconf.js`);
|
||||
importScripts('./assets/js/data/swconf.js');
|
||||
|
||||
const purge = swconf.purge;
|
||||
const interceptor = swconf.interceptor;
|
||||
|
||||
@@ -68,14 +68,18 @@ layout: compress
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
<div id="mask"></div>
|
||||
<div id="mask" class="d-none position-fixed w-100 h-100 z-1"></div>
|
||||
|
||||
{% if site.pwa.enabled %}
|
||||
{% include_cached notification.html lang=lang %}
|
||||
{% endif %}
|
||||
|
||||
<!-- JavaScripts -->
|
||||
{% include js-selector.html lang=lang %}
|
||||
<!-- Embedded scripts -->
|
||||
|
||||
{% for _include in layout.script_includes %}
|
||||
{% assign _include_path = _include | append: '.html' %}
|
||||
{% include {{ _include_path }} %}
|
||||
{% endfor %}
|
||||
|
||||
{% include_cached search-loader.html lang=lang %}
|
||||
</body>
|
||||
|
||||
@@ -5,38 +5,45 @@ refactor: true
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
{% assign pinned = site.posts | where: 'pin', 'true' %}
|
||||
{% assign default = site.posts | where_exp: 'item', 'item.pin != true and item.hidden != true' %}
|
||||
{% assign all_pinned = site.posts | where: 'pin', 'true' %}
|
||||
{% assign all_normal = site.posts | where_exp: 'item', 'item.pin != true and item.hidden != true' %}
|
||||
|
||||
{% assign posts = '' | split: '' %}
|
||||
|
||||
<!-- Get pinned posts -->
|
||||
<!-- Get pinned posts on current page -->
|
||||
|
||||
{% assign offset = paginator.page | minus: 1 | times: paginator.per_page %}
|
||||
{% assign pinned_num = pinned.size | minus: offset %}
|
||||
{% assign visible_start = paginator.page | minus: 1 | times: paginator.per_page %}
|
||||
{% assign visible_end = visible_start | plus: paginator.per_page %}
|
||||
|
||||
{% if pinned_num > 0 %}
|
||||
{% for i in (offset..pinned.size) limit: pinned_num %}
|
||||
{% assign posts = posts | push: pinned[i] %}
|
||||
{% if all_pinned.size > visible_start %}
|
||||
{% if all_pinned.size > visible_end %}
|
||||
{% assign pinned_size = paginator.per_page %}
|
||||
{% else %}
|
||||
{% assign pinned_size = all_pinned.size | minus: visible_start %}
|
||||
{% endif %}
|
||||
|
||||
{% for i in (visible_start..all_pinned.size) limit: pinned_size %}
|
||||
{% assign posts = posts | push: all_pinned[i] %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% assign pinned_num = 0 %}
|
||||
{% assign pinned_size = 0 %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Get default posts -->
|
||||
<!-- Get normal posts on current page -->
|
||||
|
||||
{% assign default_beg = offset | minus: pinned.size %}
|
||||
{% assign normal_size = paginator.posts | size | minus: pinned_size %}
|
||||
|
||||
{% if default_beg < 0 %}
|
||||
{% assign default_beg = 0 %}
|
||||
{% endif %}
|
||||
{% if normal_size > 0 %}
|
||||
{% if pinned_size > 0 %}
|
||||
{% assign normal_start = 0 %}
|
||||
{% else %}
|
||||
{% assign normal_start = visible_start | minus: all_pinned.size %}
|
||||
{% endif %}
|
||||
|
||||
{% assign default_num = paginator.posts | size | minus: pinned_num %}
|
||||
{% assign default_end = default_beg | plus: default_num | minus: 1 %}
|
||||
{% assign normal_end = normal_start | plus: normal_size | minus: 1 %}
|
||||
|
||||
{% if default_num > 0 %}
|
||||
{% for i in (default_beg..default_end) %}
|
||||
{% assign posts = posts | push: default[i] %}
|
||||
{% for i in (normal_start..normal_end) %}
|
||||
{% assign posts = posts | push: all_normal[i] %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
@@ -6,12 +6,15 @@ panel_includes:
|
||||
tail_includes:
|
||||
- related-posts
|
||||
- post-nav
|
||||
- comments
|
||||
script_includes:
|
||||
- comment
|
||||
---
|
||||
|
||||
{% include lang.html %}
|
||||
|
||||
<article class="px-1">
|
||||
{% include toc-status.html %}
|
||||
|
||||
<article class="px-1" data-toc="{{ enable_toc }}">
|
||||
<header>
|
||||
<h1 data-toc-skip>{{ page.title }}</h1>
|
||||
{% if page.description %}
|
||||
@@ -95,6 +98,30 @@ tail_includes:
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% if enable_toc %}
|
||||
<div id="toc-bar" class="d-flex align-items-center justify-content-between invisible">
|
||||
<span class="label text-truncate">{{ page.title }}</span>
|
||||
<button type="button" class="toc-trigger btn me-1">
|
||||
<i class="fa-solid fa-list-ul fa-fw"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button id="toc-solo-trigger" type="button" class="toc-trigger btn btn-outline-secondary btn-sm">
|
||||
<span class="label ps-2 pe-1">{{- site.data.locales[lang].panel.toc -}}</span>
|
||||
<i class="fa-solid fa-angle-right fa-fw"></i>
|
||||
</button>
|
||||
|
||||
<dialog id="toc-popup" class="p-0">
|
||||
<div class="header d-flex flex-row align-items-center justify-content-between">
|
||||
<div class="label text-truncate py-2 ms-4">{{- page.title -}}</div>
|
||||
<button id="toc-popup-close" type="button" class="btn mx-1 my-1 opacity-75">
|
||||
<i class="fas fa-close"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div id="toc-popup-content" class="px-4 py-3 pb-4"></div>
|
||||
</dialog>
|
||||
{% endif %}
|
||||
|
||||
<div class="content">
|
||||
{{ content }}
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
@use '../colors/typography-dark';
|
||||
@use '../colors/typography-light';
|
||||
@use 'module';
|
||||
@use 'variables';
|
||||
|
||||
/* The common styles */
|
||||
|
||||
html {
|
||||
@@ -6,22 +11,22 @@ html {
|
||||
@media (prefers-color-scheme: light) {
|
||||
&:not([data-mode]),
|
||||
&[data-mode='light'] {
|
||||
@include light-scheme;
|
||||
@include typography-light.light-scheme;
|
||||
}
|
||||
|
||||
&[data-mode='dark'] {
|
||||
@include dark-scheme;
|
||||
@include typography-dark.dark-scheme;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
&:not([data-mode]),
|
||||
&[data-mode='dark'] {
|
||||
@include dark-scheme;
|
||||
@include typography-dark.dark-scheme;
|
||||
}
|
||||
|
||||
&[data-mode='light'] {
|
||||
@include light-scheme;
|
||||
@include typography-light.light-scheme;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,17 +37,17 @@ body {
|
||||
env(safe-area-inset-bottom) env(safe-area-inset-left);
|
||||
color: var(--text-color);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-family: $font-family-base;
|
||||
font-family: variables.$font-family-base;
|
||||
}
|
||||
|
||||
/* --- Typography --- */
|
||||
|
||||
@for $i from 1 through 5 {
|
||||
h#{$i} {
|
||||
@extend %heading;
|
||||
@extend %heading !optional;
|
||||
|
||||
@if $i > 1 {
|
||||
@extend %anchor;
|
||||
@extend %anchor !optional;
|
||||
}
|
||||
|
||||
@if $i < 5 {
|
||||
@@ -70,7 +75,7 @@ body {
|
||||
}
|
||||
|
||||
a {
|
||||
@extend %link-color;
|
||||
@extend %link-color !optional;
|
||||
|
||||
text-decoration: none;
|
||||
}
|
||||
@@ -104,7 +109,7 @@ blockquote {
|
||||
padding: 1rem 1rem 1rem 3rem;
|
||||
color: var(--prompt-text-color);
|
||||
|
||||
@extend %rounded;
|
||||
@extend %rounded !optional;
|
||||
|
||||
&::before {
|
||||
text-align: center;
|
||||
@@ -117,10 +122,10 @@ blockquote {
|
||||
}
|
||||
}
|
||||
|
||||
@include prompt('tip', '\f0eb', $fa-style: 'regular');
|
||||
@include prompt('info', '\f06a', $rotate: 180);
|
||||
@include prompt('warning', '\f06a');
|
||||
@include prompt('danger', '\f071');
|
||||
@include module.prompt('tip', '\f0eb', $fa-style: 'regular');
|
||||
@include module.prompt('info', '\f06a', $rotate: 180);
|
||||
@include module.prompt('warning', '\f06a');
|
||||
@include module.prompt('danger', '\f071');
|
||||
}
|
||||
|
||||
kbd {
|
||||
@@ -134,7 +139,7 @@ kbd {
|
||||
padding-top: 0.1rem;
|
||||
color: var(--kbd-text-color);
|
||||
background-color: var(--kbd-bg-color);
|
||||
border-radius: $radius-sm;
|
||||
border-radius: variables.$radius-sm;
|
||||
border: solid 1px var(--kbd-wrap-color);
|
||||
box-shadow: inset 0 -2px 0 var(--kbd-wrap-color);
|
||||
}
|
||||
@@ -146,21 +151,21 @@ hr {
|
||||
|
||||
footer {
|
||||
background-color: var(--main-bg);
|
||||
height: $footer-height;
|
||||
height: variables.$footer-height;
|
||||
border-top: 1px solid var(--main-border-color);
|
||||
|
||||
@extend %text-xs;
|
||||
@extend %text-xs !optional;
|
||||
|
||||
a {
|
||||
@extend %text-highlight;
|
||||
@extend %text-highlight !optional;
|
||||
|
||||
&:hover {
|
||||
@extend %link-hover;
|
||||
@extend %link-hover !optional;
|
||||
}
|
||||
}
|
||||
|
||||
em {
|
||||
@extend %text-highlight;
|
||||
@extend %text-highlight !optional;
|
||||
}
|
||||
|
||||
p {
|
||||
@@ -173,7 +178,7 @@ footer {
|
||||
i {
|
||||
&.far,
|
||||
&.fas {
|
||||
@extend %no-cursor;
|
||||
@extend %no-cursor !optional;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +215,7 @@ i {
|
||||
font-family: inherit;
|
||||
line-height: inherit;
|
||||
|
||||
@include label(inherit);
|
||||
@include module.label(inherit);
|
||||
}
|
||||
|
||||
.post-tag {
|
||||
@@ -231,10 +236,10 @@ i {
|
||||
color: inherit;
|
||||
|
||||
&:hover {
|
||||
@extend %link-hover;
|
||||
@extend %link-hover !optional;
|
||||
}
|
||||
|
||||
@extend %no-bottom-border;
|
||||
@extend %no-bottom-border !optional;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,27 +252,27 @@ i {
|
||||
margin-bottom: 0.3rem;
|
||||
}
|
||||
|
||||
@extend %sup-fn-target;
|
||||
@extend %sup-fn-target !optional;
|
||||
|
||||
> p {
|
||||
margin-left: 0.25em;
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
|
||||
@include module.mt-mb(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footnote {
|
||||
@at-root a#{&} {
|
||||
@include ml-mr(1px);
|
||||
@include pl-pr(2px);
|
||||
@include module.ml-mr(1px);
|
||||
@include module.pl-pr(2px);
|
||||
|
||||
border-bottom-style: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
sup {
|
||||
@extend %sup-fn-target;
|
||||
@extend %sup-fn-target !optional;
|
||||
}
|
||||
|
||||
.reversefootnote {
|
||||
@@ -297,7 +302,7 @@ sup {
|
||||
border-bottom: solid 2px rgba(210, 215, 217, 0.75);
|
||||
|
||||
th {
|
||||
@extend %table-cell;
|
||||
@extend %table-cell !optional;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +319,7 @@ sup {
|
||||
}
|
||||
|
||||
td {
|
||||
@extend %table-cell;
|
||||
@extend %table-cell !optional;
|
||||
}
|
||||
}
|
||||
} /* tbody */
|
||||
@@ -329,7 +334,7 @@ sup {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
@extend %rounded;
|
||||
@extend %rounded !optional;
|
||||
|
||||
&:not(.no-bg) {
|
||||
background: var(--img-bg);
|
||||
@@ -340,7 +345,7 @@ sup {
|
||||
-o-object-fit: cover;
|
||||
object-fit: cover;
|
||||
|
||||
@extend %rounded;
|
||||
@extend %rounded !optional;
|
||||
|
||||
@at-root #post-list & {
|
||||
width: 100%;
|
||||
@@ -349,14 +354,14 @@ sup {
|
||||
}
|
||||
|
||||
.post-preview {
|
||||
@extend %rounded;
|
||||
@extend %rounded !optional;
|
||||
|
||||
border: 0;
|
||||
background: var(--card-bg);
|
||||
box-shadow: var(--card-shadow);
|
||||
|
||||
&::before {
|
||||
@extend %rounded;
|
||||
@extend %rounded !optional;
|
||||
|
||||
content: '';
|
||||
width: 100%;
|
||||
@@ -384,7 +389,7 @@ main {
|
||||
p {
|
||||
> a.popup {
|
||||
&:not(.normal):not(.left):not(.right) {
|
||||
@include align-center;
|
||||
@include module.align-center;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -393,22 +398,22 @@ main {
|
||||
#tags,
|
||||
#archives {
|
||||
a:not(:hover) {
|
||||
@extend %no-bottom-border;
|
||||
@extend %no-bottom-border !optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
@extend %text-sm;
|
||||
@extend %text-sm !optional;
|
||||
|
||||
a {
|
||||
&:not([class]):hover {
|
||||
@extend %link-hover;
|
||||
@extend %link-hover !optional;
|
||||
}
|
||||
}
|
||||
|
||||
em {
|
||||
@extend %normal-font-style;
|
||||
@extend %normal-font-style !optional;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -419,18 +424,18 @@ main {
|
||||
|
||||
a {
|
||||
&.popup {
|
||||
@extend %no-cursor;
|
||||
@extend %img-caption;
|
||||
@include mt-mb(0.5rem);
|
||||
@extend %no-cursor !optional;
|
||||
@extend %img-caption !optional;
|
||||
@include module.mt-mb(0.5rem);
|
||||
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
&:not(.img-link) {
|
||||
@extend %link-underline;
|
||||
@extend %link-underline !optional;
|
||||
|
||||
&:hover {
|
||||
@extend %link-hover;
|
||||
@extend %link-hover !optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -497,7 +502,7 @@ main {
|
||||
} /* .content */
|
||||
|
||||
.tag:hover {
|
||||
@extend %tag-hover;
|
||||
@extend %tag-hover !optional;
|
||||
}
|
||||
|
||||
.post-tag {
|
||||
@@ -566,7 +571,7 @@ main {
|
||||
margin-bottom: 1rem;
|
||||
aspect-ratio: 16 / 9;
|
||||
|
||||
@extend %rounded;
|
||||
@extend %rounded !optional;
|
||||
|
||||
&.twitch {
|
||||
aspect-ratio: 310 / 189;
|
||||
@@ -582,14 +587,14 @@ main {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
@extend %img-caption;
|
||||
@extend %img-caption !optional;
|
||||
}
|
||||
|
||||
.embed-audio {
|
||||
width: 100%;
|
||||
display: block;
|
||||
|
||||
@extend %img-caption;
|
||||
@extend %img-caption !optional;
|
||||
}
|
||||
|
||||
/* --- buttons --- */
|
||||
@@ -680,15 +685,14 @@ $btn-border-width: 3px;
|
||||
$btn-mb: 0.5rem;
|
||||
|
||||
#sidebar {
|
||||
@include pl-pr(0);
|
||||
@include module.pl-pr(0);
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
width: $sidebar-width;
|
||||
z-index: 99;
|
||||
width: variables.$sidebar-width;
|
||||
background: var(--sidebar-bg);
|
||||
border-right: 1px solid var(--sidebar-border-color);
|
||||
|
||||
@@ -708,7 +712,7 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
a {
|
||||
@extend %sidebar-links;
|
||||
@extend %sidebar-links !optional;
|
||||
}
|
||||
|
||||
#avatar {
|
||||
@@ -729,8 +733,8 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
.profile-wrapper {
|
||||
@include mt-mb(2.5rem);
|
||||
@extend %clickable-transition;
|
||||
@include module.mt-mb(2.5rem);
|
||||
@extend %clickable-transition !optional;
|
||||
|
||||
padding-left: 2.5rem;
|
||||
padding-right: 1.25rem;
|
||||
@@ -738,6 +742,9 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
@extend %clickable-transition !optional;
|
||||
@extend %sidebar-link-hover !optional;
|
||||
|
||||
font-family: inherit;
|
||||
font-weight: 900;
|
||||
font-size: 1.75rem;
|
||||
@@ -745,13 +752,8 @@ $btn-mb: 0.5rem;
|
||||
letter-spacing: 0.25px;
|
||||
margin-top: 1.25rem;
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
a {
|
||||
@extend %clickable-transition;
|
||||
@extend %sidebar-link-hover;
|
||||
|
||||
color: var(--site-title-color);
|
||||
}
|
||||
width: fit-content;
|
||||
color: var(--site-title-color);
|
||||
}
|
||||
|
||||
.site-subtitle {
|
||||
@@ -771,11 +773,11 @@ $btn-mb: 0.5rem;
|
||||
li.nav-item {
|
||||
opacity: 0.9;
|
||||
width: 100%;
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
|
||||
@include module.pl-pr(1.5rem);
|
||||
|
||||
a.nav-link {
|
||||
@include pt-pb(0.6rem);
|
||||
@include module.pt-pb(0.6rem);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -844,12 +846,12 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
a {
|
||||
@extend %button;
|
||||
@extend %sidebar-link-hover;
|
||||
@extend %clickable-transition;
|
||||
@extend %button !optional;
|
||||
@extend %sidebar-link-hover !optional;
|
||||
@extend %clickable-transition !optional;
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: $sb-btn-gap;
|
||||
margin-right: variables.$sb-btn-gap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -858,14 +860,14 @@ $btn-mb: 0.5rem;
|
||||
}
|
||||
|
||||
#mode-toggle {
|
||||
@extend %button;
|
||||
@extend %sidebar-links;
|
||||
@extend %sidebar-link-hover;
|
||||
@extend %button !optional;
|
||||
@extend %sidebar-links !optional;
|
||||
@extend %sidebar-link-hover !optional;
|
||||
}
|
||||
|
||||
.icon-border {
|
||||
@extend %no-cursor;
|
||||
@include ml-mr(calc(($sb-btn-gap - $btn-border-width) / 2));
|
||||
@extend %no-cursor !optional;
|
||||
@include module.ml-mr(calc((variables.$sb-btn-gap - $btn-border-width) / 2));
|
||||
|
||||
background-color: var(--sidebar-btn-color);
|
||||
content: '';
|
||||
@@ -905,14 +907,12 @@ $btn-mb: 0.5rem;
|
||||
/* --- top-bar --- */
|
||||
|
||||
#topbar-wrapper {
|
||||
height: $topbar-height;
|
||||
height: variables.$topbar-height;
|
||||
background-color: var(--topbar-bg);
|
||||
}
|
||||
|
||||
#topbar {
|
||||
button i {
|
||||
color: #999999;
|
||||
}
|
||||
@extend %btn-color !optional;
|
||||
|
||||
#breadcrumb {
|
||||
font-size: 1rem;
|
||||
@@ -920,7 +920,7 @@ $btn-mb: 0.5rem;
|
||||
padding-left: 0.5rem;
|
||||
|
||||
a:hover {
|
||||
@extend %link-hover;
|
||||
@extend %link-hover !optional;
|
||||
}
|
||||
|
||||
span {
|
||||
@@ -935,43 +935,43 @@ $btn-mb: 0.5rem;
|
||||
} /* #topbar */
|
||||
|
||||
::-webkit-input-placeholder {
|
||||
@include placeholder;
|
||||
@include module.placeholder;
|
||||
}
|
||||
|
||||
::-moz-placeholder {
|
||||
@include placeholder;
|
||||
@include module.placeholder;
|
||||
}
|
||||
|
||||
:-ms-input-placeholder {
|
||||
@include placeholder;
|
||||
@include module.placeholder;
|
||||
}
|
||||
|
||||
::-ms-input-placeholder {
|
||||
@include placeholder;
|
||||
@include module.placeholder;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
@include placeholder;
|
||||
@include module.placeholder;
|
||||
}
|
||||
|
||||
:focus::-webkit-input-placeholder {
|
||||
@include placeholder-focus;
|
||||
@include module.placeholder-focus;
|
||||
}
|
||||
|
||||
:focus::-moz-placeholder {
|
||||
@include placeholder-focus;
|
||||
@include module.placeholder-focus;
|
||||
}
|
||||
|
||||
:focus:-ms-input-placeholder {
|
||||
@include placeholder-focus;
|
||||
@include module.placeholder-focus;
|
||||
}
|
||||
|
||||
:focus::-ms-input-placeholder {
|
||||
@include placeholder-focus;
|
||||
@include module.placeholder-focus;
|
||||
}
|
||||
|
||||
:focus::placeholder {
|
||||
@include placeholder-focus;
|
||||
@include module.placeholder-focus;
|
||||
}
|
||||
|
||||
search {
|
||||
@@ -1000,7 +1000,7 @@ search {
|
||||
display: none;
|
||||
white-space: nowrap;
|
||||
|
||||
@extend %cursor-pointer;
|
||||
@extend %cursor-pointer !optional;
|
||||
}
|
||||
|
||||
#search-input {
|
||||
@@ -1038,7 +1038,7 @@ search {
|
||||
padding-right: 0.2rem;
|
||||
}
|
||||
|
||||
@extend %link-color;
|
||||
@extend %link-color !optional;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1047,15 +1047,15 @@ search {
|
||||
|
||||
a {
|
||||
font-size: 1.4rem;
|
||||
line-height: 2.5rem;
|
||||
line-height: 1.5rem;
|
||||
|
||||
&:hover {
|
||||
@extend %link-hover;
|
||||
@extend %link-hover !optional;
|
||||
}
|
||||
|
||||
@extend %link-color;
|
||||
@extend %no-bottom-border;
|
||||
@extend %heading;
|
||||
@extend %link-color !optional;
|
||||
@extend %no-bottom-border !optional;
|
||||
@extend %heading !optional;
|
||||
}
|
||||
|
||||
> article {
|
||||
@@ -1073,8 +1073,9 @@ search {
|
||||
}
|
||||
|
||||
> p {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@extend %text-ellipsis !optional;
|
||||
|
||||
white-space: break-spaces;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
@@ -1090,23 +1091,11 @@ search {
|
||||
color: var(--topbar-text-color);
|
||||
text-align: center;
|
||||
width: 70%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: keep-all;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#mask {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0 0 0 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: 1;
|
||||
|
||||
@at-root [#{$sidebar-display}] & {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- basic wrappers --- */
|
||||
@@ -1114,7 +1103,7 @@ search {
|
||||
#main-wrapper {
|
||||
position: relative;
|
||||
|
||||
@include pl-pr(0);
|
||||
@include module.pl-pr(0);
|
||||
|
||||
> .container {
|
||||
min-height: 100vh;
|
||||
@@ -1124,7 +1113,7 @@ search {
|
||||
#topbar-wrapper.row,
|
||||
#main-wrapper > .container > .row,
|
||||
#search-result-wrapper > .row {
|
||||
@include ml-mr(0);
|
||||
@include module.ml-mr(0);
|
||||
}
|
||||
|
||||
#tail-wrapper {
|
||||
@@ -1142,12 +1131,12 @@ search {
|
||||
cursor: pointer;
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
bottom: calc($footer-height-large - $back2top-size / 2);
|
||||
bottom: calc(variables.$footer-height-large - variables.$back2top-size / 2);
|
||||
background: var(--button-bg);
|
||||
color: var(--btn-backtotop-color);
|
||||
padding: 0;
|
||||
width: $back2top-size;
|
||||
height: $back2top-size;
|
||||
width: variables.$back2top-size;
|
||||
height: variables.$back2top-size;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--btn-backtotop-border-color);
|
||||
transition: opacity 0.5s ease-in-out, transform 0.2s ease-out;
|
||||
@@ -1158,7 +1147,7 @@ search {
|
||||
}
|
||||
|
||||
i {
|
||||
line-height: $back2top-size;
|
||||
line-height: variables.$back2top-size;
|
||||
position: relative;
|
||||
bottom: 2px;
|
||||
}
|
||||
@@ -1232,7 +1221,7 @@ search {
|
||||
main {
|
||||
.content {
|
||||
> blockquote[class^='prompt-'] {
|
||||
@include ml-mr(-1rem);
|
||||
@include module.ml-mr(-1rem);
|
||||
|
||||
border-radius: 0;
|
||||
max-width: none;
|
||||
@@ -1252,12 +1241,12 @@ search {
|
||||
}
|
||||
|
||||
#topbar {
|
||||
@extend %full-width;
|
||||
@extend %full-width !optional;
|
||||
}
|
||||
|
||||
#main-wrapper > .container {
|
||||
@extend %full-width;
|
||||
@include pl-pr(0);
|
||||
@extend %full-width !optional;
|
||||
@include module.pl-pr(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1276,7 +1265,7 @@ search {
|
||||
footer {
|
||||
@include slide;
|
||||
|
||||
height: $footer-height-large;
|
||||
height: variables.$footer-height-large;
|
||||
padding: 1.5rem 0;
|
||||
}
|
||||
|
||||
@@ -1286,7 +1275,7 @@ search {
|
||||
}
|
||||
|
||||
#main-wrapper {
|
||||
transform: translateX($sidebar-width);
|
||||
transform: translateX(variables.$sidebar-width);
|
||||
}
|
||||
|
||||
#back-to-top {
|
||||
@@ -1297,8 +1286,8 @@ search {
|
||||
#sidebar {
|
||||
@include slide;
|
||||
|
||||
transform: translateX(-$sidebar-width); /* hide */
|
||||
-webkit-transform: translateX(-$sidebar-width);
|
||||
transform: translateX(-(variables.$sidebar-width)); /* hide */
|
||||
-webkit-transform: translateX(-(variables.$sidebar-width));
|
||||
}
|
||||
|
||||
#main-wrapper {
|
||||
@@ -1361,7 +1350,7 @@ search {
|
||||
}
|
||||
|
||||
#main-wrapper {
|
||||
margin-left: $sidebar-width;
|
||||
margin-left: variables.$sidebar-width;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
@@ -1375,11 +1364,11 @@ search {
|
||||
}
|
||||
|
||||
search {
|
||||
max-width: $search-max-width;
|
||||
max-width: variables.$search-max-width;
|
||||
}
|
||||
|
||||
#search-result-wrapper {
|
||||
max-width: $main-content-max-width;
|
||||
max-width: variables.$main-content-max-width;
|
||||
justify-content: start !important;
|
||||
}
|
||||
|
||||
@@ -1396,7 +1385,7 @@ search {
|
||||
/* button 'back-to-Top' position */
|
||||
#back-to-top {
|
||||
right: 5%;
|
||||
bottom: calc($footer-height - $back2top-size / 2);
|
||||
bottom: calc(variables.$footer-height - variables.$back2top-size / 2);
|
||||
}
|
||||
|
||||
#topbar-title {
|
||||
@@ -1473,7 +1462,7 @@ search {
|
||||
|
||||
@media all and (min-width: 1400px) {
|
||||
#back-to-top {
|
||||
right: calc((100vw - $sidebar-width - 1140px) / 2 + 3rem);
|
||||
right: calc((100vw - variables.$sidebar-width - 1140px) / 2 + 3rem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1481,23 +1470,23 @@ search {
|
||||
$icon-gap: 1rem;
|
||||
|
||||
#main-wrapper {
|
||||
margin-left: $sidebar-width-large;
|
||||
margin-left: variables.$sidebar-width-large;
|
||||
}
|
||||
|
||||
#topbar-wrapper {
|
||||
left: $sidebar-width-large;
|
||||
left: variables.$sidebar-width-large;
|
||||
}
|
||||
|
||||
search {
|
||||
margin-right: calc(
|
||||
$main-content-max-width / 4 - $search-max-width - 0.75rem
|
||||
variables.$main-content-max-width / 4 - variables.$search-max-width - 0.75rem
|
||||
);
|
||||
}
|
||||
|
||||
#main-wrapper > .container {
|
||||
max-width: $main-content-max-width;
|
||||
padding-left: 1.75rem !important;
|
||||
padding-right: 1.75rem !important;
|
||||
max-width: variables.$main-content-max-width;
|
||||
|
||||
@include module.pl-pr(1.75rem, true);
|
||||
}
|
||||
|
||||
main.col-12,
|
||||
@@ -1507,12 +1496,12 @@ search {
|
||||
|
||||
#back-to-top {
|
||||
right: calc(
|
||||
(100vw - $sidebar-width-large - $main-content-max-width) / 2 + 2rem
|
||||
(100vw - variables.$sidebar-width-large - variables.$main-content-max-width) / 2 + 2rem
|
||||
);
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
width: $sidebar-width-large;
|
||||
width: variables.$sidebar-width-large;
|
||||
|
||||
.profile-wrapper {
|
||||
margin-top: 3.5rem;
|
||||
@@ -1522,7 +1511,7 @@ search {
|
||||
|
||||
ul {
|
||||
li.nav-item {
|
||||
@include pl-pr(2.75rem);
|
||||
@include module.pl-pr(2.75rem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1531,11 +1520,11 @@ search {
|
||||
margin-bottom: 1.75rem;
|
||||
|
||||
a:not(:last-child) {
|
||||
margin-right: $sb-btn-gap-lg;
|
||||
margin-right: variables.$sb-btn-gap-lg;
|
||||
}
|
||||
|
||||
.icon-border {
|
||||
@include ml-mr(calc(($sb-btn-gap-lg - $btn-border-width) / 2));
|
||||
@include module.ml-mr(calc((variables.$sb-btn-gap-lg - $btn-border-width) / 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@use 'variables';
|
||||
|
||||
/*
|
||||
* Mainly scss modules, only imported to `assets/css/main.scss`
|
||||
*/
|
||||
@@ -7,7 +9,8 @@
|
||||
%heading {
|
||||
color: var(--heading-color);
|
||||
font-weight: 400;
|
||||
font-family: $font-family-heading;
|
||||
font-family: variables.$font-family-heading;
|
||||
scroll-margin-top: 3.5rem;
|
||||
}
|
||||
|
||||
%anchor {
|
||||
@@ -81,7 +84,7 @@
|
||||
}
|
||||
|
||||
%rounded {
|
||||
border-radius: $radius-lg;
|
||||
border-radius: variables.$radius-lg;
|
||||
}
|
||||
|
||||
%img-caption {
|
||||
@@ -111,6 +114,16 @@
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
@mixin text-ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
%text-ellipsis {
|
||||
@include text-ellipsis;
|
||||
}
|
||||
|
||||
%text-highlight {
|
||||
color: var(--text-muted-highlight-color);
|
||||
font-weight: 600;
|
||||
@@ -134,6 +147,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
%btn-color {
|
||||
button i {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- scss mixin --------- */
|
||||
|
||||
@mixin mt-mb($value) {
|
||||
@@ -151,9 +170,14 @@
|
||||
padding-bottom: $val;
|
||||
}
|
||||
|
||||
@mixin pl-pr($val) {
|
||||
padding-left: $val;
|
||||
padding-right: $val;
|
||||
@mixin pl-pr($val, $important: false) {
|
||||
@if $important {
|
||||
padding-left: $val !important;
|
||||
padding-right: $val !important;
|
||||
} @else {
|
||||
padding-left: $val;
|
||||
padding-right: $val;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin placeholder {
|
||||
|
||||
@@ -2,29 +2,31 @@
|
||||
* The syntax highlight.
|
||||
*/
|
||||
|
||||
@import 'colors/syntax-light';
|
||||
@import 'colors/syntax-dark';
|
||||
@use '../colors/syntax-light';
|
||||
@use '../colors/syntax-dark';
|
||||
@use 'module';
|
||||
@use 'variables';
|
||||
|
||||
html {
|
||||
@media (prefers-color-scheme: light) {
|
||||
&:not([data-mode]),
|
||||
&[data-mode='light'] {
|
||||
@include light-syntax;
|
||||
@include syntax-light.light-syntax;
|
||||
}
|
||||
|
||||
&[data-mode='dark'] {
|
||||
@include dark-syntax;
|
||||
@include syntax-dark.dark-syntax;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
&:not([data-mode]),
|
||||
&[data-mode='dark'] {
|
||||
@include dark-syntax;
|
||||
@include syntax-dark.dark-syntax;
|
||||
}
|
||||
|
||||
&[data-mode='light'] {
|
||||
@include light-syntax;
|
||||
@include syntax-light.light-syntax;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,19 +49,19 @@ html {
|
||||
}
|
||||
|
||||
.highlight {
|
||||
@extend %rounded;
|
||||
@extend %code-snippet-bg;
|
||||
@extend %rounded !optional;
|
||||
@extend %code-snippet-bg !optional;
|
||||
|
||||
overflow: auto;
|
||||
padding-bottom: 0.75rem;
|
||||
|
||||
@at-root figure#{&} {
|
||||
@extend %code-snippet-bg;
|
||||
@extend %code-snippet-bg !optional;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-bottom: 0;
|
||||
font-size: $code-font-size;
|
||||
font-size: variables.$code-font-size;
|
||||
line-height: 1.4rem;
|
||||
word-wrap: normal; /* Fixed Safari overflow-x */
|
||||
}
|
||||
@@ -101,10 +103,10 @@ code {
|
||||
color: var(--code-color);
|
||||
|
||||
&.highlighter-rouge {
|
||||
font-size: $code-font-size;
|
||||
font-size: variables.$code-font-size;
|
||||
padding: 3px 5px;
|
||||
word-break: break-word;
|
||||
border-radius: $radius-sm;
|
||||
border-radius: variables.$radius-sm;
|
||||
background-color: var(--inline-code-bg);
|
||||
}
|
||||
|
||||
@@ -130,7 +132,7 @@ code {
|
||||
}
|
||||
|
||||
td.rouge-code {
|
||||
@extend %code-snippet-padding;
|
||||
@extend %code-snippet-padding !optional;
|
||||
|
||||
/*
|
||||
Prevent some browser extends from
|
||||
@@ -144,13 +146,13 @@ td.rouge-code {
|
||||
}
|
||||
|
||||
div[class^='language-'] {
|
||||
@extend %rounded;
|
||||
@extend %code-snippet-bg;
|
||||
@extend %rounded !optional;
|
||||
@extend %code-snippet-bg !optional;
|
||||
|
||||
box-shadow: var(--language-border-color) 0 0 0 1px;
|
||||
|
||||
.content > & {
|
||||
@include ml-mr(-1rem);
|
||||
@include module.ml-mr(-1rem);
|
||||
|
||||
border-radius: 0;
|
||||
}
|
||||
@@ -179,23 +181,23 @@ div {
|
||||
}
|
||||
|
||||
.code-header {
|
||||
@extend %no-cursor;
|
||||
@extend %no-cursor !optional;
|
||||
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: $code-header-height;
|
||||
height: variables.$code-header-height;
|
||||
margin-left: 0.75rem;
|
||||
margin-right: 0.25rem;
|
||||
|
||||
/* the label block */
|
||||
span {
|
||||
line-height: $code-header-height;
|
||||
line-height: variables.$code-header-height;
|
||||
|
||||
/* label icon */
|
||||
i {
|
||||
font-size: 1rem;
|
||||
width: $code-icon-width;
|
||||
width: variables.$code-icon-width;
|
||||
color: var(--code-header-icon-color);
|
||||
|
||||
&.small {
|
||||
@@ -219,12 +221,12 @@ div {
|
||||
|
||||
/* clipboard */
|
||||
button {
|
||||
@extend %cursor-pointer;
|
||||
@extend %rounded;
|
||||
@extend %cursor-pointer !optional;
|
||||
@extend %rounded !optional;
|
||||
|
||||
border: 1px solid transparent;
|
||||
height: $code-header-height;
|
||||
width: $code-header-height;
|
||||
height: variables.$code-header-height;
|
||||
width: variables.$code-header-height;
|
||||
padding: 0;
|
||||
background-color: inherit;
|
||||
|
||||
@@ -259,13 +261,13 @@ div {
|
||||
@media all and (min-width: 576px) {
|
||||
div[class^='language-'] {
|
||||
.content > & {
|
||||
@include ml-mr(0);
|
||||
@include module.ml-mr(0);
|
||||
|
||||
border-radius: $radius-lg;
|
||||
border-radius: variables.$radius-lg;
|
||||
}
|
||||
|
||||
.code-header {
|
||||
@include ml-mr(0);
|
||||
@include module.ml-mr(0);
|
||||
|
||||
$dot-margin: 1rem;
|
||||
|
||||
@@ -273,19 +275,19 @@ div {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
margin-left: $dot-margin;
|
||||
width: $code-dot-size;
|
||||
height: $code-dot-size;
|
||||
width: variables.$code-dot-size;
|
||||
height: variables.$code-dot-size;
|
||||
border-radius: 50%;
|
||||
background-color: var(--code-header-muted-color);
|
||||
box-shadow: ($code-dot-size + $code-dot-gap) 0 0
|
||||
box-shadow: (variables.$code-dot-size + variables.$code-dot-gap) 0 0
|
||||
var(--code-header-muted-color),
|
||||
($code-dot-size + $code-dot-gap) * 2 0 0
|
||||
(variables.$code-dot-size + variables.$code-dot-gap) * 2 0 0
|
||||
var(--code-header-muted-color);
|
||||
}
|
||||
|
||||
span {
|
||||
// center the text of label
|
||||
margin-left: calc(($dot-margin + $code-dot-size) / 2 * -1);
|
||||
margin-left: calc(($dot-margin + variables.$code-dot-size) / 2 * -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
--btn-border-color: #2e2f31;
|
||||
--btn-backtotop-color: var(--text-color);
|
||||
--btn-backtotop-border-color: #212122;
|
||||
--btn-box-shadow: var(--main-bg);
|
||||
--card-header-bg: #292929;
|
||||
--checkbox-color: rgb(118, 120, 121);
|
||||
--checkbox-checked-color: var(--link-color);
|
||||
@@ -60,6 +59,7 @@
|
||||
|
||||
/* Posts */
|
||||
--toc-highlight: rgb(116, 178, 243);
|
||||
--toc-popup-border-color: #373737;
|
||||
--tag-hover: rgb(43, 56, 62);
|
||||
--tb-odd-bg: #252526; /* odd rows of the posts' table */
|
||||
--tb-even-bg: rgb(31, 31, 34); /* even rows of the posts' table */
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
--btn-border-color: #e9ecef;
|
||||
--btn-backtotop-color: #686868;
|
||||
--btn-backtotop-border-color: #f1f1f1;
|
||||
--btn-box-shadow: #eaeaea;
|
||||
--checkbox-color: #c5c5c5;
|
||||
--checkbox-checked-color: #07a8f7;
|
||||
--img-bg: radial-gradient(
|
||||
@@ -63,6 +62,7 @@
|
||||
|
||||
/* Posts */
|
||||
--toc-highlight: #0550ae;
|
||||
--toc-popup-border-color: lightgray;
|
||||
--btn-share-color: gray;
|
||||
--btn-share-hover-color: #0d6efd;
|
||||
--card-bg: white;
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
margin-left: -$timeline-width;
|
||||
|
||||
&::before {
|
||||
@extend %timeline;
|
||||
@extend %timeline !optional;
|
||||
|
||||
height: 72px;
|
||||
left: 79px;
|
||||
@@ -31,7 +31,7 @@
|
||||
}
|
||||
|
||||
&:first-child::before {
|
||||
@extend %timeline;
|
||||
@extend %timeline !optional;
|
||||
|
||||
height: 32px;
|
||||
top: 24px;
|
||||
@@ -58,9 +58,8 @@
|
||||
li {
|
||||
font-size: 1.1rem;
|
||||
line-height: 3rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@extend %text-ellipsis !optional;
|
||||
|
||||
&:nth-child(odd) {
|
||||
background-color: var(--main-bg, #ffffff);
|
||||
@@ -75,7 +74,7 @@
|
||||
}
|
||||
|
||||
&::before {
|
||||
@extend %timeline;
|
||||
@extend %timeline !optional;
|
||||
|
||||
top: 0;
|
||||
left: 77px;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@use '../addon/variables';
|
||||
|
||||
/*
|
||||
Style for Tab Categories
|
||||
*/
|
||||
@@ -12,11 +14,11 @@
|
||||
|
||||
&.card,
|
||||
.list-group {
|
||||
@extend %rounded;
|
||||
@extend %rounded !optional;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
$radius: calc($radius-lg - 1px);
|
||||
$radius: calc(variables.$radius-lg - 1px);
|
||||
|
||||
padding: 0.75rem;
|
||||
border-radius: $radius;
|
||||
@@ -29,7 +31,7 @@
|
||||
}
|
||||
|
||||
i {
|
||||
@extend %category-icon-color;
|
||||
@extend %category-icon-color !optional;
|
||||
|
||||
font-size: 86%; /* fontawesome icons */
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@use '../addon/module';
|
||||
|
||||
/*
|
||||
Style for page Category and Tag
|
||||
*/
|
||||
@@ -28,7 +30,7 @@
|
||||
|
||||
/* post's title */
|
||||
> a {
|
||||
@extend %no-bottom-border;
|
||||
@extend %no-bottom-border !optional;
|
||||
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
@@ -48,7 +50,7 @@
|
||||
#page-tag,
|
||||
#access-lastmod {
|
||||
a:hover {
|
||||
@extend %link-hover;
|
||||
@extend %link-hover !optional;
|
||||
|
||||
margin-bottom: -1px; /* Avoid jumping */
|
||||
}
|
||||
@@ -63,9 +65,7 @@
|
||||
}
|
||||
|
||||
> a {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@include module.text-ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@use '../addon/variables';
|
||||
|
||||
/*
|
||||
Style for Homepage
|
||||
*/
|
||||
@@ -20,14 +22,14 @@
|
||||
background: none;
|
||||
|
||||
%img-radius {
|
||||
border-radius: $radius-lg $radius-lg 0 0;
|
||||
border-radius: variables.$radius-lg variables.$radius-lg 0 0;
|
||||
}
|
||||
|
||||
.preview-img {
|
||||
@extend %img-radius;
|
||||
@extend %img-radius !optional;
|
||||
|
||||
img {
|
||||
@extend %img-radius;
|
||||
@extend %img-radius !optional;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +38,7 @@
|
||||
padding: 1rem;
|
||||
|
||||
.card-title {
|
||||
@extend %text-clip;
|
||||
@extend %text-clip !optional;
|
||||
|
||||
color: var(--heading-color) !important;
|
||||
font-size: 1.25rem;
|
||||
@@ -47,10 +49,10 @@
|
||||
}
|
||||
|
||||
.card-text.content {
|
||||
@extend %muted;
|
||||
@extend %muted !optional;
|
||||
|
||||
p {
|
||||
@extend %text-clip;
|
||||
@extend %text-clip !optional;
|
||||
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
@@ -58,7 +60,7 @@
|
||||
}
|
||||
|
||||
.post-meta {
|
||||
@extend %muted;
|
||||
@extend %muted !optional;
|
||||
|
||||
i {
|
||||
&:not(:first-child) {
|
||||
@@ -67,16 +69,15 @@
|
||||
}
|
||||
|
||||
em {
|
||||
@extend %normal-font-style;
|
||||
@extend %normal-font-style !optional;
|
||||
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
> div:first-child {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@extend %text-ellipsis !optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -131,7 +132,7 @@
|
||||
/* Tablet */
|
||||
@media all and (min-width: 768px) {
|
||||
%img-radius {
|
||||
border-radius: 0 $radius-lg $radius-lg 0;
|
||||
border-radius: 0 variables.$radius-lg variables.$radius-lg 0;
|
||||
}
|
||||
|
||||
#post-list {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
/*
|
||||
Post-specific style
|
||||
*/
|
||||
@use '../addon/module';
|
||||
@use '../addon/variables';
|
||||
|
||||
/**
|
||||
* Post-specific styles
|
||||
*/
|
||||
|
||||
%btn-post-nav {
|
||||
width: 50%;
|
||||
@@ -16,7 +19,7 @@
|
||||
|
||||
header {
|
||||
.post-desc {
|
||||
@extend %heading;
|
||||
@extend %heading !optional;
|
||||
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.6;
|
||||
@@ -29,7 +32,7 @@ header {
|
||||
|
||||
em,
|
||||
time {
|
||||
@extend %text-highlight;
|
||||
@extend %text-highlight !optional;
|
||||
}
|
||||
|
||||
em {
|
||||
@@ -45,7 +48,7 @@ header {
|
||||
}
|
||||
|
||||
.post-tail-wrapper {
|
||||
@extend %text-sm;
|
||||
@extend %text-sm !optional;
|
||||
|
||||
margin-top: 6rem;
|
||||
border-bottom: 1px double var(--main-border-color);
|
||||
@@ -54,20 +57,20 @@ header {
|
||||
line-height: 1.2rem;
|
||||
|
||||
> a {
|
||||
@extend %text-highlight;
|
||||
@extend %text-highlight !optional;
|
||||
|
||||
&:hover {
|
||||
@extend %link-hover;
|
||||
@extend %link-hover !optional;
|
||||
}
|
||||
}
|
||||
|
||||
span:last-child {
|
||||
@extend %text-sm;
|
||||
@extend %text-sm !optional;
|
||||
}
|
||||
} /* .license-wrapper */
|
||||
|
||||
.post-meta a:not(:hover) {
|
||||
@extend %link-underline;
|
||||
@extend %link-underline !optional;
|
||||
}
|
||||
|
||||
.share-wrapper {
|
||||
@@ -87,17 +90,17 @@ header {
|
||||
i {
|
||||
color: var(--btn-share-color);
|
||||
|
||||
@extend %icon-size;
|
||||
@extend %icon-size !optional;
|
||||
}
|
||||
|
||||
> * {
|
||||
@extend %icon-size;
|
||||
@extend %icon-size !optional;
|
||||
|
||||
margin-left: 0.5rem;
|
||||
|
||||
&:hover {
|
||||
i {
|
||||
@extend %btn-share-hovor;
|
||||
@extend %btn-share-hover !optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,7 +110,7 @@ header {
|
||||
border: none;
|
||||
line-height: inherit;
|
||||
|
||||
@extend %cursor-pointer;
|
||||
@extend %cursor-pointer !optional;
|
||||
}
|
||||
} /* .share-icons */
|
||||
} /* .share-wrapper */
|
||||
@@ -131,16 +134,16 @@ header {
|
||||
|
||||
.post-tag {
|
||||
&:hover {
|
||||
@extend %link-hover;
|
||||
@extend %tag-hover;
|
||||
@extend %no-bottom-border;
|
||||
@extend %link-hover !optional;
|
||||
@extend %tag-hover !optional;
|
||||
@extend %no-bottom-border !optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.post-navigation {
|
||||
.btn {
|
||||
@extend %btn-post-nav;
|
||||
@extend %btn-post-nav !optional;
|
||||
|
||||
&:not(:hover) {
|
||||
color: var(--link-color);
|
||||
@@ -153,7 +156,7 @@ header {
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
@extend %btn-post-nav;
|
||||
@extend %btn-post-nav !optional;
|
||||
|
||||
pointer-events: auto;
|
||||
cursor: not-allowed;
|
||||
@@ -173,12 +176,12 @@ header {
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-radius: $radius-lg 0 0 $radius-lg;
|
||||
border-radius: variables.$radius-lg 0 0 variables.$radius-lg;
|
||||
left: 0.5px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 $radius-lg $radius-lg 0;
|
||||
border-radius: 0 variables.$radius-lg variables.$radius-lg 0;
|
||||
right: 0.5px;
|
||||
}
|
||||
}
|
||||
@@ -228,6 +231,7 @@ header {
|
||||
}
|
||||
}
|
||||
|
||||
/* TOC panel */
|
||||
#toc-wrapper {
|
||||
border-left: 1px solid rgba(158, 158, 158, 0.17);
|
||||
position: -webkit-sticky;
|
||||
@@ -257,9 +261,8 @@ header {
|
||||
|
||||
.toc-link {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@extend %text-ellipsis !optional;
|
||||
|
||||
&:hover {
|
||||
color: var(--toc-highlight);
|
||||
@@ -290,25 +293,229 @@ header {
|
||||
}
|
||||
}
|
||||
|
||||
/* --- TOC button, bar and popup in mobile/tablet --- */
|
||||
|
||||
#toc-bar {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
margin: 0 -1rem;
|
||||
height: variables.$topbar-height;
|
||||
background: var(--main-bg);
|
||||
border-bottom: 1px solid var(--main-border-color);
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
@extend %btn-color !optional;
|
||||
|
||||
.label {
|
||||
@extend %heading !optional;
|
||||
|
||||
margin-left: 0.25rem;
|
||||
padding: 0 0.75rem;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
&.invisible {
|
||||
top: -(variables.$topbar-height);
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
#toc-solo-trigger {
|
||||
color: var(--text-muted-color);
|
||||
border-color: var(--btn-border-color);
|
||||
border-radius: variables.$radius-lg;
|
||||
|
||||
.label {
|
||||
font-size: 1rem;
|
||||
font-family: variables.$font-family-heading;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: none;
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin slide-in {
|
||||
from {
|
||||
opacity: 0.7;
|
||||
transform: translateY(-(variables.$topbar-height));
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin slide-out {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(-(variables.$topbar-height));
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes slide-in {
|
||||
@include slide-in;
|
||||
}
|
||||
|
||||
@keyframes slide-in {
|
||||
@include slide-in;
|
||||
}
|
||||
|
||||
@-webkit-keyframes slide-out {
|
||||
@include slide-out;
|
||||
}
|
||||
|
||||
@keyframes slide-out {
|
||||
@include slide-out;
|
||||
}
|
||||
|
||||
#toc-popup {
|
||||
$slide-in: slide-in 0.3s ease-out;
|
||||
$slide-out: slide-out 0.3s ease-out;
|
||||
$curtain-height: 2rem;
|
||||
$backdrop: blur(5px);
|
||||
|
||||
border-color: var(--toc-popup-border-color);
|
||||
border-width: 1px;
|
||||
border-radius: variables.$radius-lg;
|
||||
color: var(--text-color);
|
||||
background: var(--card-bg);
|
||||
margin-top: variables.$topbar-height;
|
||||
min-width: 20rem;
|
||||
font-size: 1.05rem;
|
||||
|
||||
@media all and (min-width: 576px) {
|
||||
max-width: 32rem;
|
||||
}
|
||||
|
||||
&[open] {
|
||||
-webkit-animation: $slide-in;
|
||||
animation: $slide-in;
|
||||
}
|
||||
|
||||
&[closing] {
|
||||
-webkit-animation: $slide-out;
|
||||
animation: $slide-out;
|
||||
}
|
||||
|
||||
@media all and (min-width: 850px) {
|
||||
left: variables.$sidebar-width;
|
||||
}
|
||||
|
||||
.header {
|
||||
@extend %btn-color !optional;
|
||||
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: inherit;
|
||||
border-bottom: 1px solid var(--main-border-color);
|
||||
|
||||
.label {
|
||||
font-family: variables.$font-family-heading;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
> i {
|
||||
font-size: 1.25rem;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
|
||||
li {
|
||||
ul,
|
||||
& + li {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
line-height: 1.5;
|
||||
padding: 0.375rem 0;
|
||||
padding-right: 1.125rem;
|
||||
|
||||
&.toc-link::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@for $i from 2 through 4 {
|
||||
.node-name--H#{$i} {
|
||||
padding-left: 1.125rem * ($i - 1);
|
||||
}
|
||||
}
|
||||
|
||||
.is-active-link {
|
||||
color: var(--toc-highlight) !important;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&::-webkit-backdrop {
|
||||
-webkit-backdrop-filter: $backdrop;
|
||||
backdrop-filter: $backdrop;
|
||||
}
|
||||
|
||||
&::backdrop {
|
||||
-webkit-backdrop-filter: $backdrop;
|
||||
backdrop-filter: $backdrop;
|
||||
}
|
||||
|
||||
&::after {
|
||||
display: flex;
|
||||
content: '';
|
||||
position: relative;
|
||||
background: linear-gradient(transparent, var(--card-bg) 70%);
|
||||
height: $curtain-height;
|
||||
}
|
||||
|
||||
#toc-popup-content {
|
||||
overflow: auto;
|
||||
max-height: calc(100vh - 4 * variables.$topbar-height);
|
||||
font-family: variables.$font-family-heading;
|
||||
margin-bottom: -$curtain-height;
|
||||
}
|
||||
}
|
||||
|
||||
/* --- Related Posts --- */
|
||||
|
||||
#related-posts {
|
||||
> h3 {
|
||||
@include label(1.1rem, 600);
|
||||
@include module.label(1.1rem, 600);
|
||||
}
|
||||
|
||||
time {
|
||||
@extend %normal-font-style;
|
||||
@extend %text-xs;
|
||||
@extend %normal-font-style !optional;
|
||||
@extend %text-xs !optional;
|
||||
|
||||
color: var(--text-muted-color);
|
||||
}
|
||||
|
||||
p {
|
||||
@extend %text-ellipsis !optional;
|
||||
|
||||
font-size: 0.9rem;
|
||||
margin-bottom: 0.5rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: break-spaces;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
@@ -316,7 +523,7 @@ header {
|
||||
|
||||
.card {
|
||||
h4 {
|
||||
@extend %text-clip;
|
||||
@extend %text-clip !optional;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,14 +535,15 @@ header {
|
||||
|
||||
.utterances {
|
||||
max-width: 100%;
|
||||
min-height: 269px;
|
||||
}
|
||||
|
||||
%btn-share-hovor {
|
||||
%btn-share-hover {
|
||||
color: var(--btn-share-hover-color) !important;
|
||||
}
|
||||
|
||||
.share-label {
|
||||
@include label(inherit, 400, inherit);
|
||||
@include module.label(inherit, 400, inherit);
|
||||
|
||||
&::after {
|
||||
content: ':';
|
||||
@@ -362,9 +570,20 @@ header {
|
||||
/* Hide SideBar and TOC */
|
||||
@media all and (max-width: 849px) {
|
||||
.post-navigation {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
margin-left: -0.5rem;
|
||||
margin-right: -0.5rem;
|
||||
@include module.pl-pr(0);
|
||||
@include module.ml-mr(-0.5rem);
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 1200px) {
|
||||
h2,
|
||||
h3,
|
||||
h4 {
|
||||
scroll-margin-top: 2rem;
|
||||
}
|
||||
|
||||
#toc-bar,
|
||||
#toc-solo-trigger {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
@import 'dist/bootstrap';
|
||||
@import 'main';
|
||||
@use 'dist/bootstrap';
|
||||
@use 'main';
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
@import 'colors/typography-light';
|
||||
@import 'colors/typography-dark';
|
||||
@import 'addon/variables';
|
||||
@import 'variables-hook';
|
||||
@import 'addon/module';
|
||||
@import 'addon/syntax';
|
||||
@import 'addon/commons';
|
||||
@import 'layout/home';
|
||||
@import 'layout/post';
|
||||
@import 'layout/tags';
|
||||
@import 'layout/archives';
|
||||
@import 'layout/categories';
|
||||
@import 'layout/category-tag';
|
||||
@use 'colors/typography-light';
|
||||
@use 'colors/typography-dark';
|
||||
@use 'addon/variables';
|
||||
@use 'variables-hook';
|
||||
@use 'addon/module';
|
||||
@use 'addon/syntax';
|
||||
@use 'addon/commons';
|
||||
@use 'layout/home';
|
||||
@use 'layout/post';
|
||||
@use 'layout/tags';
|
||||
@use 'layout/archives';
|
||||
@use 'layout/categories';
|
||||
@use 'layout/category-tag';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
---
|
||||
|
||||
@import 'main
|
||||
@use 'main
|
||||
{%- if jekyll.environment == 'production' -%}
|
||||
.bundle
|
||||
{%- endif -%}
|
||||
|
||||
@@ -34,7 +34,7 @@ permalink: /feed.xml
|
||||
<updated>{{ post.date | date_to_xmlschema }}</updated>
|
||||
{% endif %}
|
||||
<id>{{ post_absolute_url }}</id>
|
||||
<content src="{{ post_absolute_url }}" />
|
||||
<content type="text/html" src="{{ post_absolute_url }}" />
|
||||
<author>
|
||||
<name>{{ post.author | default: site.social.name }}</name>
|
||||
</author>
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## [7.1.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.1.0...v7.1.1) (2024-09-23)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **i18n:** correct fr-FR translations ([#1949](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1949)) ([367262e](https://github.com/cotes2020/jekyll-theme-chirpy/commit/367262e74d1005bddf1328bb2b3a2b9e152c0086))
|
||||
* **pwa:** site baseurl not passed to `app.js` ([#1955](https://github.com/cotes2020/jekyll-theme-chirpy/issues/1955)) ([5a63244](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5a63244721d21b1ad3a0ae83420723a2f0379e8b))
|
||||
|
||||
## [7.1.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.0.1...v7.1.0) (2024-08-27)
|
||||
|
||||
### Features
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = "jekyll-theme-chirpy"
|
||||
spec.version = "7.1.0"
|
||||
spec.version = "7.1.1"
|
||||
spec.authors = ["Cotes Chung"]
|
||||
spec.email = ["cotes.chung@gmail.com"]
|
||||
|
||||
|
||||
18
package.json
18
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jekyll-theme-chirpy",
|
||||
"version": "7.1.0",
|
||||
"version": "7.1.1",
|
||||
"description": "A minimal, responsive, and feature-rich Jekyll theme for technical writing.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -30,23 +30,23 @@
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@babel/plugin-transform-class-properties": "^7.25.4",
|
||||
"@babel/plugin-transform-private-methods": "^7.25.7",
|
||||
"@babel/preset-env": "^7.25.4",
|
||||
"@commitlint/cli": "^19.4.0",
|
||||
"@commitlint/config-conventional": "^19.2.2",
|
||||
"@commitlint/cli": "^19.5.0",
|
||||
"@commitlint/config-conventional": "^19.5.0",
|
||||
"@rollup/plugin-babel": "^6.0.4",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@rollup/plugin-yaml": "^4.1.2",
|
||||
"@semantic-release/changelog": "^6.0.3",
|
||||
"@semantic-release/exec": "^6.0.3",
|
||||
"@semantic-release/git": "^10.0.1",
|
||||
"concurrently": "^8.2.2",
|
||||
"concurrently": "^9.0.1",
|
||||
"conventional-changelog-conventionalcommits": "^8.0.0",
|
||||
"husky": "^9.1.5",
|
||||
"husky": "^9.1.6",
|
||||
"purgecss": "^6.0.0",
|
||||
"rollup": "^4.21.0",
|
||||
"semantic-release": "^24.1.0",
|
||||
"stylelint": "^16.8.2",
|
||||
"rollup": "^4.21.3",
|
||||
"semantic-release": "^24.1.1",
|
||||
"stylelint": "^16.9.0",
|
||||
"stylelint-config-standard-scss": "^13.1.0"
|
||||
},
|
||||
"prettier": {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import babel from '@rollup/plugin-babel';
|
||||
import terser from '@rollup/plugin-terser';
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||
import yaml from '@rollup/plugin-yaml';
|
||||
import fs from 'fs';
|
||||
import pkg from './package.json';
|
||||
|
||||
@@ -35,27 +34,34 @@ function insertFrontmatter() {
|
||||
};
|
||||
}
|
||||
|
||||
function build(filename, { src = SRC_DEFAULT, jekyll = false } = {}) {
|
||||
function build(
|
||||
filename,
|
||||
{ src = SRC_DEFAULT, jekyll = false, outputName = null } = {}
|
||||
) {
|
||||
const input = `${src}/${filename}.js`;
|
||||
|
||||
return {
|
||||
input: `${src}/${filename}.js`,
|
||||
input,
|
||||
output: {
|
||||
file: `${DIST}/${filename}.min.js`,
|
||||
format: 'iife',
|
||||
name: 'Chirpy',
|
||||
...(outputName !== null && { name: outputName }),
|
||||
banner,
|
||||
sourcemap: !isProd
|
||||
sourcemap: !isProd && !jekyll
|
||||
},
|
||||
watch: {
|
||||
include: `${src}/**`
|
||||
include: input
|
||||
},
|
||||
plugins: [
|
||||
babel({
|
||||
babelHelpers: 'bundled',
|
||||
presets: ['@babel/env'],
|
||||
plugins: ['@babel/plugin-transform-class-properties']
|
||||
plugins: [
|
||||
'@babel/plugin-transform-class-properties',
|
||||
'@babel/plugin-transform-private-methods'
|
||||
]
|
||||
}),
|
||||
nodeResolve(),
|
||||
yaml(),
|
||||
isProd && terser(),
|
||||
jekyll && insertFrontmatter()
|
||||
]
|
||||
@@ -71,6 +77,7 @@ export default [
|
||||
build('page'),
|
||||
build('post'),
|
||||
build('misc'),
|
||||
build('theme', { src: `${SRC_DEFAULT}/modules`, outputName: 'Theme' }),
|
||||
build('app', { src: SRC_PWA, jekyll: true }),
|
||||
build('sw', { src: SRC_PWA, jekyll: true })
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user