mirror of
https://github.com/cotes2020/jekyll-theme-chirpy.git
synced 2025-12-18 13:44:15 +00:00
Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e41d874b3 | ||
|
|
774ee93d78 | ||
|
|
8a4d0bc4ee | ||
|
|
1b93f6db9b | ||
|
|
32051dad03 | ||
|
|
c174f62f26 | ||
|
|
e741aa43cf | ||
|
|
e0c3fafa47 | ||
|
|
1b4e318dc1 | ||
|
|
2f00d41861 | ||
|
|
0360c9e90b | ||
|
|
d87c2de675 | ||
|
|
f55cc31dbd | ||
|
|
7630356a94 | ||
|
|
6c112c641a | ||
|
|
976e1a184b | ||
|
|
7ea3545ba3 | ||
|
|
8280adb901 | ||
|
|
4180992272 | ||
|
|
a16aa7d41e | ||
|
|
8e55e4dcb2 | ||
|
|
b4019f3517 | ||
|
|
2966fc174d | ||
|
|
3df83fd0d9 | ||
|
|
82ba82e6da | ||
|
|
5265b03974 | ||
|
|
11647697bb | ||
|
|
5756b8fc26 | ||
|
|
35c794cf58 | ||
|
|
c69914effc | ||
|
|
65f960c31a | ||
|
|
d51345e297 | ||
|
|
2f844978aa | ||
|
|
42dea8ee29 | ||
|
|
86b13c917f | ||
|
|
4ef3cd8efc | ||
|
|
c7f967529c | ||
|
|
74ed06321c | ||
|
|
d4f7f39ece | ||
|
|
c1bd9eb9ee | ||
|
|
6f461132c0 | ||
|
|
03e302cbf6 | ||
|
|
8a064a5e5a | ||
|
|
740bd84c51 | ||
|
|
93f616b25d | ||
|
|
e6b87d2811 | ||
|
|
73749067c5 | ||
|
|
fd0df8320f | ||
|
|
fbcdf8ce85 | ||
|
|
fac6116af1 | ||
|
|
5a63244721 | ||
|
|
3ab3b844d2 | ||
|
|
367262e74d | ||
|
|
cbc93193e1 | ||
|
|
a784f0a0f9 | ||
|
|
a2bf5dc58e | ||
|
|
8b7dba71e3 | ||
|
|
fc3d101258 | ||
|
|
604e01eb36 | ||
|
|
31e19c6d0f | ||
|
|
5f4dab1745 | ||
|
|
8cfd721494 | ||
|
|
64c7262245 | ||
|
|
707a209424 | ||
|
|
80bd7928a0 | ||
|
|
befc4ce9c5 | ||
|
|
bf6c996c4e | ||
|
|
99eaf6089e | ||
|
|
efd2941ce0 | ||
|
|
7f83c3d00d | ||
|
|
d74bfaeda2 | ||
|
|
23729c9c8f | ||
|
|
e347d0632f | ||
|
|
35fdea0c4f | ||
|
|
5c5910f1fc | ||
|
|
b641b36480 | ||
|
|
979f86cf64 | ||
|
|
8c30f0a9c3 | ||
|
|
e4db1a176f | ||
|
|
e3a78b6243 | ||
|
|
8673e1335f | ||
|
|
a07a57ec92 | ||
|
|
db9e58bab2 | ||
|
|
e6532ad864 | ||
|
|
fbba0a4204 | ||
|
|
c876731901 | ||
|
|
9ca7519239 | ||
|
|
0709854dc8 | ||
|
|
f1d35832f4 | ||
|
|
cf853f14e4 | ||
|
|
7ca9c59784 | ||
|
|
250880c088 | ||
|
|
88b844ce80 | ||
|
|
3b46629dc0 | ||
|
|
1e3d4a6323 | ||
|
|
1c5fa0880d | ||
|
|
64ae7a3671 | ||
|
|
0102abae06 | ||
|
|
6cb1a5ac52 | ||
|
|
90a4cc76bb |
29
.devcontainer/devcontainer.json
Normal file
29
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "Jekyll",
|
||||||
|
"image": "mcr.microsoft.com/devcontainers/jekyll:2-bullseye",
|
||||||
|
"onCreateCommand": "git config --global --add safe.directory ${containerWorkspaceFolder}",
|
||||||
|
"postCreateCommand": "bash .devcontainer/post-create.sh",
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"settings": {
|
||||||
|
"terminal.integrated.defaultProfile.linux": "zsh"
|
||||||
|
},
|
||||||
|
"extensions": [
|
||||||
|
// Liquid tags auto-complete
|
||||||
|
"killalau.vscode-liquid-snippets",
|
||||||
|
// Liquid syntax highlighting and formatting
|
||||||
|
"Shopify.theme-check-vscode",
|
||||||
|
// Shell
|
||||||
|
"timonwong.shellcheck",
|
||||||
|
"mkhl.shfmt",
|
||||||
|
// Common formatter
|
||||||
|
"EditorConfig.EditorConfig",
|
||||||
|
"esbenp.prettier-vscode",
|
||||||
|
"stylelint.vscode-stylelint",
|
||||||
|
"yzhang.markdown-all-in-one",
|
||||||
|
// Git
|
||||||
|
"mhutchie.git-graph"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
.devcontainer/post-create.sh
Normal file
18
.devcontainer/post-create.sh
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if [ -f package.json ]; then
|
||||||
|
bash -i -c "nvm install --lts && nvm install-latest-npm"
|
||||||
|
npm i
|
||||||
|
npm run build
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install dependencies for shfmt extension
|
||||||
|
curl -sS https://webi.sh/shfmt | sh &>/dev/null
|
||||||
|
|
||||||
|
# Add OMZ plugins
|
||||||
|
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting
|
||||||
|
git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
|
||||||
|
sed -i -E "s/^(plugins=\()(git)(\))/\1\2 zsh-syntax-highlighting zsh-autosuggestions\3/" ~/.zshrc
|
||||||
|
|
||||||
|
# Avoid git log use less
|
||||||
|
echo -e "\nunset LESS" >>~/.zshrc
|
||||||
13
.github/dependabot.yml
vendored
13
.github/dependabot.yml
vendored
@@ -8,11 +8,10 @@ updates:
|
|||||||
directory: "/"
|
directory: "/"
|
||||||
versioning-strategy: increase
|
versioning-strategy: increase
|
||||||
groups:
|
groups:
|
||||||
npm:
|
prod-deps:
|
||||||
update-types:
|
dependency-type: production
|
||||||
- "major"
|
dev-deps:
|
||||||
- "minor"
|
dependency-type: development
|
||||||
- "patch"
|
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
- package-ecosystem: "github-actions"
|
- package-ecosystem: "github-actions"
|
||||||
@@ -23,3 +22,7 @@ updates:
|
|||||||
- "major"
|
- "major"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
|
- package-ecosystem: "devcontainers"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: weekly
|
||||||
|
|||||||
9
.github/workflows/cd.yml
vendored
9
.github/workflows/cd.yml
vendored
@@ -2,13 +2,12 @@ name: CD
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches: [production]
|
||||||
- production
|
tags-ignore: ["**"]
|
||||||
tags-ignore:
|
|
||||||
- "**"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
|
if: ${{ ! startsWith(github.event.head_commit.message, 'chore(release)') }}
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
issues: write
|
issues: write
|
||||||
@@ -24,7 +23,7 @@ jobs:
|
|||||||
|
|
||||||
- uses: actions/setup-node@v4
|
- uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: latest
|
node-version: lts/*
|
||||||
|
|
||||||
- run: npm install
|
- run: npm install
|
||||||
- run: npx semantic-release
|
- run: npx semantic-release
|
||||||
|
|||||||
24
.github/workflows/ci.yml
vendored
24
.github/workflows/ci.yml
vendored
@@ -1,17 +1,25 @@
|
|||||||
name: "CI"
|
name: CI
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- "master"
|
- master
|
||||||
- "hotfix/**"
|
- "hotfix/*"
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- ".github/**"
|
- ".github/**"
|
||||||
- "!.github/workflows/ci.yml"
|
- "!.github/workflows/ci.yml"
|
||||||
- ".gitignore"
|
- .gitignore
|
||||||
- "docs/**"
|
- "docs/**"
|
||||||
- "README.md"
|
- README.md
|
||||||
- "LICENSE"
|
- LICENSE
|
||||||
pull_request:
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- ".github/**"
|
||||||
|
- "!.github/workflows/ci.yml"
|
||||||
|
- .gitignore
|
||||||
|
- "docs/**"
|
||||||
|
- README.md
|
||||||
|
- LICENSE
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -36,10 +44,10 @@ jobs:
|
|||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: latest
|
node-version: lts/*
|
||||||
|
|
||||||
- name: Build Assets
|
- name: Build Assets
|
||||||
run: npm i && npm run build
|
run: npm i && npm run build
|
||||||
|
|
||||||
- name: Test Site
|
- name: Test Site
|
||||||
run: bash tools/test
|
run: bash tools/test.sh
|
||||||
|
|||||||
8
.github/workflows/commitlint.yml
vendored
8
.github/workflows/commitlint.yml
vendored
@@ -1,5 +1,11 @@
|
|||||||
name: Lint Commit Messages
|
name: Lint Commit Messages
|
||||||
on: pull_request
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- "hotfix/*"
|
||||||
|
pull_request:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
commitlint:
|
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
|
required: true
|
||||||
BUILDER:
|
BUILDER:
|
||||||
required: true
|
required: true
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
launch:
|
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
|
pull-requests: write
|
||||||
|
|
||||||
env:
|
env:
|
||||||
STALE_LABEL: stale
|
STALE_LABEL: inactive
|
||||||
EXEMPT_LABELS: "pending,planning,in progress"
|
EXEMPT_LABELS: "pending,planning,in progress"
|
||||||
MESSAGE: >
|
MESSAGE: >
|
||||||
This conversation has been automatically marked as stale because it has not had recent activity.
|
This conversation has been automatically marked as stale because it has not had recent activity.
|
||||||
|
|||||||
23
.github/workflows/style-lint.yml
vendored
23
.github/workflows/style-lint.yml
vendored
@@ -1,23 +0,0 @@
|
|||||||
name: "Style Lint"
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: ["master", "hotfix/**"]
|
|
||||||
paths: ["_sass/**/*.scss"]
|
|
||||||
pull_request:
|
|
||||||
paths: ["_sass/**/*.scss"]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
stylelint:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Node
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: latest
|
|
||||||
- run: npm i
|
|
||||||
- run: npm test
|
|
||||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -17,10 +17,11 @@ package-lock.json
|
|||||||
|
|
||||||
# IDE configurations
|
# IDE configurations
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode/*
|
||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
_sass/dist
|
_sass/vendors
|
||||||
assets/js/dist
|
assets/js/dist
|
||||||
|
|||||||
5
.husky/commit-msg
Executable file → Normal file
5
.husky/commit-msg
Executable file → Normal file
@@ -1,4 +1 @@
|
|||||||
#!/bin/sh
|
npx --no -- commitlint --edit $1
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
|
||||||
|
|
||||||
npx --no -- commitlint --edit ${1}
|
|
||||||
|
|||||||
31
.stylelintrc.json
Normal file
31
.stylelintrc.json
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"ignoreFiles": ["_sass/vendors/**"],
|
||||||
|
"extends": "stylelint-config-standard-scss",
|
||||||
|
"rules": {
|
||||||
|
"no-descending-specificity": null,
|
||||||
|
"shorthand-property-no-redundant-values": null,
|
||||||
|
"at-rule-no-vendor-prefix": null,
|
||||||
|
"property-no-vendor-prefix": null,
|
||||||
|
"selector-no-vendor-prefix": null,
|
||||||
|
"value-no-vendor-prefix": null,
|
||||||
|
"color-function-notation": "legacy",
|
||||||
|
"alpha-value-notation": "number",
|
||||||
|
"selector-not-notation": "simple",
|
||||||
|
"color-hex-length": "long",
|
||||||
|
"declaration-block-single-line-max-declarations": 3,
|
||||||
|
"scss/operator-no-newline-after": null,
|
||||||
|
"rule-empty-line-before": [
|
||||||
|
"always",
|
||||||
|
{
|
||||||
|
"ignore": ["after-comment", "first-nested"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"value-keyword-case": [
|
||||||
|
"lower",
|
||||||
|
{
|
||||||
|
"ignoreProperties": ["/^\\$/"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"media-feature-range-notation": "prefix"
|
||||||
|
}
|
||||||
|
}
|
||||||
12
.vscode/extensions.json
vendored
12
.vscode/extensions.json
vendored
@@ -1,13 +1,3 @@
|
|||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": ["ms-vscode-remote.remote-containers"]
|
||||||
// Liquid tags auto-complete
|
|
||||||
"killalau.vscode-liquid-snippets",
|
|
||||||
// Liquid syntax highlighting and formatting
|
|
||||||
"Shopify.theme-check-vscode",
|
|
||||||
// Common formatter
|
|
||||||
"esbenp.prettier-vscode",
|
|
||||||
"foxundermoon.shell-format",
|
|
||||||
"stylelint.vscode-stylelint",
|
|
||||||
"yzhang.markdown-all-in-one"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
@@ -2,7 +2,6 @@
|
|||||||
// Prettier
|
// Prettier
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"prettier.trailingComma": "none",
|
|
||||||
// Shopify Liquid
|
// Shopify Liquid
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.html": "liquid"
|
"*.html": "liquid"
|
||||||
@@ -15,13 +14,17 @@
|
|||||||
"editor.defaultFormatter": "Shopify.theme-check-vscode"
|
"editor.defaultFormatter": "Shopify.theme-check-vscode"
|
||||||
},
|
},
|
||||||
"[shellscript]": {
|
"[shellscript]": {
|
||||||
"editor.defaultFormatter": "foxundermoon.shell-format"
|
"editor.defaultFormatter": "mkhl.shfmt"
|
||||||
},
|
},
|
||||||
// Disable vscode built-in stylelint
|
// Disable vscode built-in stylelint
|
||||||
"css.validate": false,
|
"css.validate": false,
|
||||||
"scss.validate": false,
|
"scss.validate": false,
|
||||||
"less.validate": false,
|
"less.validate": false,
|
||||||
// Stylint extension settings
|
// Stylint extension settings
|
||||||
"stylelint.snippet": ["css", "less", "postcss", "scss"],
|
"stylelint.snippet": ["css", "scss"],
|
||||||
"stylelint.validate": ["css", "less", "postcss", "scss"]
|
"stylelint.validate": ["css", "scss"],
|
||||||
|
// Run tasks in macOS
|
||||||
|
"terminal.integrated.profiles.osx": {
|
||||||
|
"zsh": { "path": "/bin/zsh", "args": ["-l", "-i"] }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
64
.vscode/tasks.json
vendored
Normal file
64
.vscode/tasks.json
vendored
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "Run Jekyll Server",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "./tools/run.sh",
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"detail": "Runs the Jekyll server with live reload."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Build Jekyll Site",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "./tools/test.sh",
|
||||||
|
"group": {
|
||||||
|
"kind": "build"
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"detail": "Build the Jekyll site for production."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Build JS (watch)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "npm run watch:js",
|
||||||
|
"group": {
|
||||||
|
"kind": "build"
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"detail": "Build JS files in watch mode."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Build CSS",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "npm run build:css",
|
||||||
|
"group": {
|
||||||
|
"kind": "build"
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"detail": "Build CSS files."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Build JS & CSS",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "npm run build",
|
||||||
|
"group": {
|
||||||
|
"kind": "build"
|
||||||
|
},
|
||||||
|
"problemMatcher": [],
|
||||||
|
"detail": "Build JS & CSS for production."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Run Jekyll Server + Build JS (watch)",
|
||||||
|
"dependsOn": ["Run Jekyll Server", "Build JS (watch)"],
|
||||||
|
"group": {
|
||||||
|
"kind": "build"
|
||||||
|
},
|
||||||
|
"detail": "Runs both the Jekyll server with live reload and build JS files in watch mode."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
9
Gemfile
9
Gemfile
@@ -4,6 +4,11 @@ source "https://rubygems.org"
|
|||||||
|
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
group :test do
|
gem "html-proofer", "~> 5.0", group: :test
|
||||||
gem "html-proofer", "~> 5.0"
|
|
||||||
|
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
||||||
|
gem "tzinfo", ">= 1", "< 3"
|
||||||
|
gem "tzinfo-data"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
gem "wdm", "~> 0.2.0", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -6,11 +6,11 @@
|
|||||||
|
|
||||||
A minimal, responsive, and feature-rich Jekyll theme for technical writing.
|
A minimal, responsive, and feature-rich Jekyll theme for technical writing.
|
||||||
|
|
||||||
[][gem]
|
[][ci]
|
||||||
[][ci]
|
[][codacy]
|
||||||
[][codacy]
|
[][license]
|
||||||
[][license]
|
[][gem]
|
||||||
[](https://996.icu)
|
[][open-container]
|
||||||
|
|
||||||
[**Live Demo** →][demo]
|
[**Live Demo** →][demo]
|
||||||
|
|
||||||
@@ -72,6 +72,7 @@ This project is published under [MIT License][license].
|
|||||||
[ci]: https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml?query=event%3Apush+branch%3Amaster
|
[ci]: https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml?query=event%3Apush+branch%3Amaster
|
||||||
[codacy]: https://app.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade
|
[codacy]: https://app.codacy.com/gh/cotes2020/jekyll-theme-chirpy/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade
|
||||||
[license]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE
|
[license]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE
|
||||||
|
[open-container]: https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/cotes2020/jekyll-theme-chirpy
|
||||||
[jekyllrb]: https://jekyllrb.com/
|
[jekyllrb]: https://jekyllrb.com/
|
||||||
[clipartmax]: https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/
|
[clipartmax]: https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/
|
||||||
[demo]: https://cotes2020.github.io/chirpy-demo/
|
[demo]: https://cotes2020.github.io/chirpy-demo/
|
||||||
|
|||||||
35
_config.yml
35
_config.yml
@@ -16,20 +16,20 @@ timezone: Asia/Shanghai
|
|||||||
|
|
||||||
title: Chirpy # the main title
|
title: Chirpy # the main title
|
||||||
|
|
||||||
tagline: A text-focused Jekyll theme # it will display as the sub-title
|
tagline: A text-focused Jekyll theme # it will display as the subtitle
|
||||||
|
|
||||||
description: >- # used by seo meta and the atom feed
|
description: >- # used by seo meta and the atom feed
|
||||||
A minimal, responsive and feature-rich Jekyll theme for technical writing.
|
A minimal, responsive and feature-rich Jekyll theme for technical writing.
|
||||||
|
|
||||||
# Fill in the protocol & hostname for your site.
|
# Fill in the protocol & hostname for your site.
|
||||||
# e.g. 'https://username.github.io', note that it does not end with a '/'.
|
# E.g. 'https://username.github.io', note that it does not end with a '/'.
|
||||||
url: ""
|
url: ""
|
||||||
|
|
||||||
github:
|
github:
|
||||||
username: github_username # change to your github username
|
username: github_username # change to your GitHub username
|
||||||
|
|
||||||
twitter:
|
twitter:
|
||||||
username: twitter_username # change to your twitter username
|
username: twitter_username # change to your Twitter username
|
||||||
|
|
||||||
social:
|
social:
|
||||||
# Change to your full name.
|
# Change to your full name.
|
||||||
@@ -38,8 +38,8 @@ social:
|
|||||||
email: example@domain.com # change to your email address
|
email: example@domain.com # change to your email address
|
||||||
links:
|
links:
|
||||||
# The first element serves as the copyright owner's link
|
# The first element serves as the copyright owner's link
|
||||||
- https://twitter.com/username # change to your twitter homepage
|
- https://twitter.com/username # change to your Twitter homepage
|
||||||
- https://github.com/username # change to your github homepage
|
- https://github.com/username # change to your GitHub homepage
|
||||||
# Uncomment below to add more social links
|
# Uncomment below to add more social links
|
||||||
# - https://www.facebook.com/username
|
# - https://www.facebook.com/username
|
||||||
# - https://www.linkedin.com/in/username
|
# - https://www.linkedin.com/in/username
|
||||||
@@ -70,8 +70,10 @@ analytics:
|
|||||||
domain: # fill in your Matomo domain
|
domain: # fill in your Matomo domain
|
||||||
cloudflare:
|
cloudflare:
|
||||||
id: # fill in your Cloudflare Web Analytics token
|
id: # fill in your Cloudflare Web Analytics token
|
||||||
|
fathom:
|
||||||
|
id: # fill in your Fathom Site ID
|
||||||
|
|
||||||
# Pageviews settings
|
# Page views settings
|
||||||
pageviews:
|
pageviews:
|
||||||
provider: # now only supports 'goatcounter'
|
provider: # now only supports 'goatcounter'
|
||||||
|
|
||||||
@@ -83,8 +85,8 @@ pageviews:
|
|||||||
#
|
#
|
||||||
# Available options:
|
# Available options:
|
||||||
#
|
#
|
||||||
# light - Use the light color scheme
|
# light — Use the light color scheme
|
||||||
# dark - Use the dark color scheme
|
# dark — Use the dark color scheme
|
||||||
#
|
#
|
||||||
theme_mode: # [light | dark]
|
theme_mode: # [light | dark]
|
||||||
|
|
||||||
@@ -106,7 +108,7 @@ social_preview_image: # string, local or CORS resources
|
|||||||
toc: true
|
toc: true
|
||||||
|
|
||||||
comments:
|
comments:
|
||||||
# Global switch for the post comment system. Keeping it empty means disabled.
|
# Global switch for the post-comment system. Keeping it empty means disabled.
|
||||||
provider: # [disqus | utterances | giscus]
|
provider: # [disqus | utterances | giscus]
|
||||||
# The provider options are as follows:
|
# The provider options are as follows:
|
||||||
disqus:
|
disqus:
|
||||||
@@ -136,9 +138,9 @@ assets:
|
|||||||
env: # [development | production]
|
env: # [development | production]
|
||||||
|
|
||||||
pwa:
|
pwa:
|
||||||
enabled: true # the option for PWA feature (installable)
|
enabled: true # The option for PWA feature (installable)
|
||||||
cache:
|
cache:
|
||||||
enabled: true # the option for PWA offline cache
|
enabled: true # The option for PWA offline cache
|
||||||
# Paths defined here will be excluded from the PWA cache.
|
# Paths defined here will be excluded from the PWA cache.
|
||||||
# Usually its value is the `baseurl` of another website that
|
# Usually its value is the `baseurl` of another website that
|
||||||
# shares the same domain name as the current website.
|
# shares the same domain name as the current website.
|
||||||
@@ -190,10 +192,6 @@ defaults:
|
|||||||
values:
|
values:
|
||||||
layout: page
|
layout: page
|
||||||
permalink: /:title/
|
permalink: /:title/
|
||||||
- scope:
|
|
||||||
path: assets/js/dist
|
|
||||||
values:
|
|
||||||
swcache: true
|
|
||||||
|
|
||||||
sass:
|
sass:
|
||||||
style: compressed
|
style: compressed
|
||||||
@@ -214,8 +212,9 @@ exclude:
|
|||||||
- tools
|
- tools
|
||||||
- README.md
|
- README.md
|
||||||
- LICENSE
|
- LICENSE
|
||||||
- "*.config.js"
|
- purgecss.js
|
||||||
- package*.json
|
- rollup.config.js
|
||||||
|
- "package*.json"
|
||||||
|
|
||||||
jekyll-archives:
|
jekyll-archives:
|
||||||
enabled: [categories, tags]
|
enabled: [categories, tags]
|
||||||
|
|||||||
@@ -26,3 +26,15 @@
|
|||||||
# - type: stack-overflow
|
# - type: stack-overflow
|
||||||
# icon: 'fab fa-stack-overflow'
|
# icon: 'fab fa-stack-overflow'
|
||||||
# url: '' # Fill with your stackoverflow homepage
|
# url: '' # Fill with your stackoverflow homepage
|
||||||
|
#
|
||||||
|
# - type: bluesky
|
||||||
|
# icon: 'fa-brands fa-bluesky'
|
||||||
|
# url: '' # Fill with your Bluesky profile link
|
||||||
|
#
|
||||||
|
# - type: reddit
|
||||||
|
# icon: 'fa-brands fa-reddit'
|
||||||
|
# url: '' # Fill with your Reddit profile link
|
||||||
|
#
|
||||||
|
# - type: threads
|
||||||
|
# icon: 'fa-brands fa-threads'
|
||||||
|
# url: '' # Fill with your Threads profile link
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: باستخدام :PLATFORM السمة :THEME
|
meta: باستخدام :PLATFORM السمة :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: عذرا, الرابط التالي غير صالح أو انه يشير إلى صفحة غير موجودة.
|
statement: عذرا, الرابط التالي غير صالح أو انه يشير إلى صفحة غير موجودة.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: يتوفر اصدار جديد للمحتوى.
|
update_found: يتوفر اصدار جديد للمحتوى.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Създадено чрез :PLATFORM и :THEME тема
|
meta: Създадено чрез :PLATFORM и :THEME тема
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Съжалявам, но на този URL адрес няма налично съдържание.
|
statement: Съжалявам, но на този URL адрес няма налично съдържание.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Налична е нова версия на съдържанието.
|
update_found: Налична е нова версия на съдържанието.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Použití :PLATFORM s motivem :THEME
|
meta: Použití :PLATFORM s motivem :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Omlouváme se, adresu URL jsme špatně umístili nebo odkazuje na něco, co neexistuje.
|
statement: Omlouváme se, adresu URL jsme špatně umístili nebo odkazuje na něco, co neexistuje.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Je k dispozici nová verze obsahu.
|
update_found: Je k dispozici nová verze obsahu.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ copyright:
|
|||||||
meta: Powered by :PLATFORM with :THEME theme
|
meta: Powered by :PLATFORM with :THEME theme
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Entschuldigung, dieser Link verweist auf keine vorhandene Ressource.
|
statement: Entschuldigung, dieser Link verweist auf keine vorhandene Ressource.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Eine neue Version ist verfügbar.
|
update_found: Eine neue Version ist verfügbar.
|
||||||
@@ -76,7 +76,7 @@ df:
|
|||||||
post:
|
post:
|
||||||
strftime: "%d.%m.%Y"
|
strftime: "%d.%m.%Y"
|
||||||
dayjs: "DD.MM.YYYY"
|
dayjs: "DD.MM.YYYY"
|
||||||
|
|
||||||
# categories page
|
# categories page
|
||||||
categories:
|
categories:
|
||||||
category_measure:
|
category_measure:
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Αξιοποιώντας την :PLATFORM theme :THEME
|
meta: Αξιοποιώντας την :PLATFORM theme :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Συγνώμη, έχουμε τοποθετήσει λάθος αυτήν την διεύθυνση URL ή υποδεικνύει κάτι που δεν υπάρχει.
|
statement: Συγνώμη, έχουμε τοποθετήσει λάθος αυτήν την διεύθυνση URL ή υποδεικνύει κάτι που δεν υπάρχει.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Υπάρχει διαθέσιμη μια νέα έκδοση του περιεχομένου.
|
update_found: Υπάρχει διαθέσιμη μια νέα έκδοση του περιεχομένου.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Using the :THEME theme for :PLATFORM.
|
meta: Using the :THEME theme for :PLATFORM.
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
|
statement: Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: A new version of content is available.
|
update_found: A new version of content is available.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Hecho con :PLATFORM usando el tema :THEME
|
meta: Hecho con :PLATFORM usando el tema :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Lo sentimos, hemos perdido esa URL o apunta a algo que no existe.
|
statement: Lo sentimos, hemos perdido esa URL o apunta a algo que no existe.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Hay una nueva versión de contenido disponible.
|
update_found: Hay una nueva versión de contenido disponible.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ copyright:
|
|||||||
meta: Käytetään :PLATFORM iä Teema :THEME
|
meta: Käytetään :PLATFORM iä Teema :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Valitettavasti tällä URL-osoitteella ei ole saatavilla sisältöä.
|
statement: Valitettavasti tällä URL-osoitteella ei ole saatavilla sisältöä.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Uusi versio sisällöstä on saatavilla.
|
update_found: Uusi versio sisällöstä on saatavilla.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ tabs:
|
|||||||
categories: Catégories
|
categories: Catégories
|
||||||
tags: Tags
|
tags: Tags
|
||||||
archives: Archives
|
archives: Archives
|
||||||
about: A propos de
|
about: À propos
|
||||||
|
|
||||||
# the text displayed in the search bar & search results
|
# the text displayed in the search bar & search results
|
||||||
search:
|
search:
|
||||||
@@ -32,18 +32,18 @@ copyright:
|
|||||||
license:
|
license:
|
||||||
template: Cet article est sous licence :LICENSE_NAME par l'auteur.
|
template: Cet article est sous licence :LICENSE_NAME par l'auteur.
|
||||||
name: CC BY 4.0
|
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
|
# Displayed in the footer
|
||||||
brief: Certains droits réservés.
|
brief: Certains droits réservés.
|
||||||
verbose: >-
|
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.
|
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
|
meta: Propulsé par :PLATFORM avec le thème :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Désolé, nous avons égaré cette URL ou elle pointe vers quelque chose qui n'existe pas.
|
statement: Désolé, nous avons égaré cette URL ou elle pointe vers quelque chose qui n'existe pas.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Une nouvelle version du contenu est disponible.
|
update_found: Une nouvelle version du contenu est disponible.
|
||||||
|
|||||||
@@ -14,24 +14,23 @@ tabs:
|
|||||||
categories: Kategóriák
|
categories: Kategóriák
|
||||||
tags: Címkék
|
tags: Címkék
|
||||||
archives: Archívum
|
archives: Archívum
|
||||||
about: Rólam
|
about: Bemutatkozás
|
||||||
|
|
||||||
# the text displayed in the search bar & search results
|
# the text displayed in the search bar & search results
|
||||||
search:
|
search:
|
||||||
hint: keresés
|
hint: keresés
|
||||||
cancel: Mégse
|
cancel: Mégse
|
||||||
no_results: Oops! Nincs találat a keresésre.
|
no_results: Hoppá! Nincs találat a keresésre.
|
||||||
|
|
||||||
panel:
|
panel:
|
||||||
lastmod: Legutóbb frissítve
|
lastmod: Legutóbb frissítve
|
||||||
trending_tags: Népszerű Címkék
|
trending_tags: Népszerű Címkék
|
||||||
toc: Tartalom
|
toc: Tartalom
|
||||||
links: Blog linkek
|
|
||||||
|
|
||||||
copyright:
|
copyright:
|
||||||
# Shown at the bottom of the post
|
# Shown at the bottom of the post
|
||||||
license:
|
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
|
name: CC BY 4.0
|
||||||
link: https://creativecommons.org/licenses/by/4.0/
|
link: https://creativecommons.org/licenses/by/4.0/
|
||||||
|
|
||||||
@@ -42,10 +41,10 @@ copyright:
|
|||||||
Creative Commons Attribution 4.0 International (CC BY 4.0) licenccel rendelkeznek,
|
Creative Commons Attribution 4.0 International (CC BY 4.0) licenccel rendelkeznek,
|
||||||
hacsak másképp nincs jelezve.
|
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:
|
not_found:
|
||||||
statment: Sajnáljuk, az URL-t rosszul helyeztük el, vagy valami nem létezőre mutat.
|
statement: Sajnáljuk, az URL-t rosszul helyeztük el, vagy valami nem létezőre mutat.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Elérhető a tartalom új verziója.
|
update_found: Elérhető a tartalom új verziója.
|
||||||
@@ -73,7 +72,21 @@ post:
|
|||||||
title: Link másolása
|
title: Link másolása
|
||||||
succeed: Link sikeresen másolva!
|
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 page
|
||||||
categories:
|
categories:
|
||||||
category_measure: kategória
|
category_measure:
|
||||||
post_measure: bejegyzés
|
singular: kategória
|
||||||
|
plural: kategória
|
||||||
|
post_measure:
|
||||||
|
singular: bejegyzés
|
||||||
|
plural: bejegyzés
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Didukung oleh :PLATFORM dengan tema :THEME
|
meta: Didukung oleh :PLATFORM dengan tema :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Maaf, kami gagal menemukan URL itu atau memang mengarah ke sesuatu yang tidak ada.
|
statement: Maaf, kami gagal menemukan URL itu atau memang mengarah ke sesuatu yang tidak ada.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Versi konten baru tersedia.
|
update_found: Versi konten baru tersedia.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ copyright:
|
|||||||
|
|
||||||
meta: Servizio offerto da :PLATFORM con tema :THEME
|
meta: Servizio offerto da :PLATFORM con tema :THEME
|
||||||
not_found:
|
not_found:
|
||||||
statment: Ci scusiamo, non è stato possibile trovare l'URL in questione. Potrebbe puntare ad una pagina non esistente.
|
statement: Ci scusiamo, non è stato possibile trovare l'URL in questione. Potrebbe puntare ad una pagina non esistente.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Nuova versione del contenuto disponibile.
|
update_found: Nuova versione del contenuto disponibile.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Powered by :PLATFORM with :THEME theme
|
meta: Powered by :PLATFORM with :THEME theme
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: 해당 URL은 존재하지 않습니다.
|
statement: 해당 URL은 존재하지 않습니다.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: 새 버전의 콘텐츠를 사용할 수 있습니다.
|
update_found: 새 버전의 콘텐츠를 사용할 수 있습니다.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Powered by :PLATFORM with :THEME theme
|
meta: Powered by :PLATFORM with :THEME theme
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: ဝမ်းနည်းပါသည်၊ ကျွန်ုပ်တို့သည် အဆိုပါ URL ကို မှားယွင်းစွာ နေရာချထားခြင်း သို့မဟုတ် ၎င်းသည် မရှိသောအရာကို ညွှန်ပြနေပါသည်။
|
statement: ဝမ်းနည်းပါသည်၊ ကျွန်ုပ်တို့သည် အဆိုပါ URL ကို မှားယွင်းစွာ နေရာချထားခြင်း သို့မဟုတ် ၎င်းသည် မရှိသောအရာကို ညွှန်ပြနေပါသည်။
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: အကြောင်းအရာဗားရှင်းအသစ်ကို ရနိုင်ပါပြီ။
|
update_found: အကြောင်းအရာဗားရှင်းအသစ်ကို ရနိုင်ပါပြီ။
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Feito com :PLATFORM usando o tema :THEME
|
meta: Feito com :PLATFORM usando o tema :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Desculpe, a página não foi encontrada.
|
statement: Desculpe, a página não foi encontrada.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Uma nova versão do conteúdo está disponível.
|
update_found: Uma nova versão do conteúdo está disponível.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ copyright:
|
|||||||
meta: Использует тему :THEME для :PLATFORM
|
meta: Использует тему :THEME для :PLATFORM
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Извините, мы перепутали URL-адрес или он указывает на что-то несуществующее.
|
statement: Извините, мы перепутали URL-адрес или он указывает на что-то несуществующее.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Доступна новая версия контента.
|
update_found: Доступна новая версия контента.
|
||||||
@@ -76,7 +76,7 @@ df:
|
|||||||
post:
|
post:
|
||||||
strftime: "%d.%m.%Y"
|
strftime: "%d.%m.%Y"
|
||||||
dayjs: "DD.MM.YYYY"
|
dayjs: "DD.MM.YYYY"
|
||||||
|
|
||||||
# categories page
|
# categories page
|
||||||
categories:
|
categories:
|
||||||
category_measure:
|
category_measure:
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Uporabljena :PLATFORM tema :THEME #Using the :PLATFORM theme :THEME
|
meta: Uporabljena :PLATFORM tema :THEME #Using the :PLATFORM theme :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Oprostite, hiperpovezava je neustrezna ali vsebina ne obstajata. #Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
|
statement: Oprostite, hiperpovezava je neustrezna ali vsebina ne obstajata. #Sorry, we've misplaced that URL or it's pointing to something that doesn't exist.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Novejša različica vsebine je na voljo. #A new version of content is available.
|
update_found: Novejša različica vsebine je na voljo. #A new version of content is available.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Byggd med :PLATFORM och temat :THEME
|
meta: Byggd med :PLATFORM och temat :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Ursäkta, vi har tappat bort den här webbadressen eller så pekar den på något som inte längre finns.
|
statement: Ursäkta, vi har tappat bort den här webbadressen eller så pekar den på något som inte längre finns.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Det finns en ny version av innehållet.
|
update_found: Det finns en ny version av innehållet.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: กำลังใช้ธีมของ :PLATFORM ชื่อ :THEME
|
meta: กำลังใช้ธีมของ :PLATFORM ชื่อ :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: ขออภัย เราวาง URL นั้นไว้ผิดที่ หรือมันชี้ไปยังสิ่งที่ไม่มีอยู่
|
statement: ขออภัย เราวาง URL นั้นไว้ผิดที่ หรือมันชี้ไปยังสิ่งที่ไม่มีอยู่
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: มีเวอร์ชันใหม่ของเนื้อหา
|
update_found: มีเวอร์ชันใหม่ของเนื้อหา
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: :PLATFORM ve :THEME teması
|
meta: :PLATFORM ve :THEME teması
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Üzgünüz, bu linki yanlış yerleştirdik veya var olmayan bir şeye işaret ediyor.
|
statement: Üzgünüz, bu linki yanlış yerleştirdik veya var olmayan bir şeye işaret ediyor.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: İçeriğin yeni bir sürümü mevcut.
|
update_found: İçeriğin yeni bir sürümü mevcut.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ copyright:
|
|||||||
meta: Powered by :PLATFORM with :THEME theme
|
meta: Powered by :PLATFORM with :THEME theme
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Вибачте, це посилання вказує на ресурс, що не існує.
|
statement: Вибачте, це посилання вказує на ресурс, що не існує.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Доступна нова версія вмісту.
|
update_found: Доступна нова версія вмісту.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ copyright:
|
|||||||
meta: Trang web này được tạo bởi :PLATFORM với chủ đề :THEME
|
meta: Trang web này được tạo bởi :PLATFORM với chủ đề :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: Xin lỗi, chúng tôi đã đặt nhầm URL hoặc đường dẫn trỏ đến một trang nào đó không tồn tại.
|
statement: Xin lỗi, chúng tôi đã đặt nhầm URL hoặc đường dẫn trỏ đến một trang nào đó không tồn tại.
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: Đã có phiên bản mới của nội dung.
|
update_found: Đã có phiên bản mới của nội dung.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ copyright:
|
|||||||
meta: 本站采用 :PLATFORM 主题 :THEME
|
meta: 本站采用 :PLATFORM 主题 :THEME
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: 抱歉,我们放错了该 URL,或者它指向了不存在的内容。
|
statement: 抱歉,我们放错了该 URL,或者它指向了不存在的内容。
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: 发现新版本的内容。
|
update_found: 发现新版本的内容。
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ copyright:
|
|||||||
meta: 本網站使用 :PLATFORM 產生,採用 :THEME 主題
|
meta: 本網站使用 :PLATFORM 產生,採用 :THEME 主題
|
||||||
|
|
||||||
not_found:
|
not_found:
|
||||||
statment: 抱歉,您可能正在存取一個已被移動的 URL,或者它從未存在。
|
statement: 抱歉,您可能正在存取一個已被移動的 URL,或者它從未存在。
|
||||||
|
|
||||||
notification:
|
notification:
|
||||||
update_found: 發現新版本更新。
|
update_found: 發現新版本更新。
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ mermaid:
|
|||||||
dayjs:
|
dayjs:
|
||||||
js:
|
js:
|
||||||
common: /assets/lib/dayjs/dayjs.min.js
|
common: /assets/lib/dayjs/dayjs.min.js
|
||||||
locale: /assets/lib/dayjs/locale/en.min.js
|
locale: /assets/lib/dayjs/locale/en.js
|
||||||
relativeTime: /assets/lib/dayjs/plugin/relativeTime.min.js
|
relativeTime: /assets/lib/dayjs/plugin/relativeTime.js
|
||||||
localizedFormat: /assets/lib/dayjs/plugin/localizedFormat.min.js
|
localizedFormat: /assets/lib/dayjs/plugin/localizedFormat.js
|
||||||
|
|
||||||
glightbox:
|
glightbox:
|
||||||
css: /assets/lib/glightbox/glightbox.min.css
|
css: /assets/lib/glightbox/glightbox.min.css
|
||||||
|
|||||||
@@ -20,24 +20,24 @@ webfonts: https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Sour
|
|||||||
# Libraries
|
# Libraries
|
||||||
|
|
||||||
toc:
|
toc:
|
||||||
css: https://cdn.jsdelivr.net/npm/tocbot@4.27.20/dist/tocbot.min.css
|
css: https://cdn.jsdelivr.net/npm/tocbot@4.32.2/dist/tocbot.min.css
|
||||||
js: https://cdn.jsdelivr.net/npm/tocbot@4.27.20/dist/tocbot.min.js
|
js: https://cdn.jsdelivr.net/npm/tocbot@4.32.2/dist/tocbot.min.js
|
||||||
|
|
||||||
fontawesome:
|
fontawesome:
|
||||||
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/css/all.min.css
|
css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.7.1/css/all.min.css
|
||||||
|
|
||||||
search:
|
search:
|
||||||
js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js
|
js: https://cdn.jsdelivr.net/npm/simple-jekyll-search@1.10.0/dest/simple-jekyll-search.min.js
|
||||||
|
|
||||||
mermaid:
|
mermaid:
|
||||||
js: https://cdn.jsdelivr.net/npm/mermaid@10.9.0/dist/mermaid.min.js
|
js: https://cdn.jsdelivr.net/npm/mermaid@11.4.0/dist/mermaid.min.js
|
||||||
|
|
||||||
dayjs:
|
dayjs:
|
||||||
js:
|
js:
|
||||||
common: https://cdn.jsdelivr.net/npm/dayjs@1.11.11/dayjs.min.js
|
common: https://cdn.jsdelivr.net/npm/dayjs@1.11.13/dayjs.min.js
|
||||||
locale: https://cdn.jsdelivr.net/npm/dayjs@1.11.11/locale/:LOCALE.min.js
|
locale: https://cdn.jsdelivr.net/npm/dayjs@1.11.13/locale/:LOCALE.js
|
||||||
relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1.11.11/plugin/relativeTime.min.js
|
relativeTime: https://cdn.jsdelivr.net/npm/dayjs@1.11.13/plugin/relativeTime.js
|
||||||
localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1.11.11/plugin/localizedFormat.min.js
|
localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1.11.13/plugin/localizedFormat.js
|
||||||
|
|
||||||
glightbox:
|
glightbox:
|
||||||
css: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/css/glightbox.min.css
|
css: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/css/glightbox.min.css
|
||||||
|
|||||||
@@ -36,3 +36,15 @@ platforms:
|
|||||||
# link: "https://fosstodon.org/"
|
# link: "https://fosstodon.org/"
|
||||||
# - label: photog.social
|
# - label: photog.social
|
||||||
# link: "https://photog.social/"
|
# link: "https://photog.social/"
|
||||||
|
#
|
||||||
|
# - type: Bluesky
|
||||||
|
# icon: "fa-brands fa-bluesky"
|
||||||
|
# link: "https://bsky.app/intent/compose?text=TITLE%20URL"
|
||||||
|
#
|
||||||
|
# - type: Reddit
|
||||||
|
# icon: "fa-brands fa-square-reddit"
|
||||||
|
# link: "https://www.reddit.com/submit?url=URL&title=TITLE"
|
||||||
|
#
|
||||||
|
# - type: Threads
|
||||||
|
# icon: "fa-brands fa-square-threads"
|
||||||
|
# link: "https://www.threads.net/intent/post?text=TITLE%20URL"
|
||||||
|
|||||||
@@ -4,4 +4,3 @@
|
|||||||
src="https://static.cloudflareinsights.com/beacon.min.js"
|
src="https://static.cloudflareinsights.com/beacon.min.js"
|
||||||
data-cf-beacon='{"token": "{{ site.analytics.cloudflare.id }}"}'
|
data-cf-beacon='{"token": "{{ site.analytics.cloudflare.id }}"}'
|
||||||
></script>
|
></script>
|
||||||
<!-- End Cloudflare Web Analytics -->
|
|
||||||
|
|||||||
6
_includes/analytics/fathom.html
Normal file
6
_includes/analytics/fathom.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<!-- Fathom -->
|
||||||
|
<script
|
||||||
|
src="https://cdn.usefathom.com/script.js"
|
||||||
|
data-site="{{ site.analytics.fathom.id }}"
|
||||||
|
defer
|
||||||
|
></script>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
<script defer src="https://www.googletagmanager.com/gtag/js?id={{ site.analytics.google.id }}"></script>
|
<script defer src="https://www.googletagmanager.com/gtag/js?id={{ site.analytics.google.id }}"></script>
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener('DOMContentLoaded', function (event) {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
window.dataLayer = window.dataLayer || [];
|
window.dataLayer = window.dataLayer || [];
|
||||||
function gtag() {
|
function gtag() {
|
||||||
dataLayer.push(arguments);
|
dataLayer.push(arguments);
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
<!-- Matomo -->
|
<!-- Matomo -->
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
var _paq = window._paq = window._paq || [];
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
_paq.push(['trackPageView']);
|
var _paq = (window._paq = window._paq || []);
|
||||||
_paq.push(['enableLinkTracking']);
|
_paq.push(['trackPageView']);
|
||||||
(function() {
|
_paq.push(['enableLinkTracking']);
|
||||||
var u="//{{ site.analytics.matomo.domain }}/";
|
var u="//{{ site.analytics.matomo.domain }}/";
|
||||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||||
_paq.push(['setSiteId', {{ site.analytics.matomo.id }}]);
|
_paq.push(['setSiteId', {{ site.analytics.matomo.id }}]);
|
||||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
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);
|
g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||||
})();
|
});
|
||||||
</script>
|
</script>
|
||||||
<!-- End Matomo Code -->
|
|
||||||
|
|||||||
@@ -1,38 +1,25 @@
|
|||||||
<!-- The Disqus lazy loading. -->
|
<script>
|
||||||
|
|
||||||
<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">
|
|
||||||
var disqus_config = function () {
|
var disqus_config = function () {
|
||||||
this.page.url = '{{ page.url | absolute_url }}';
|
this.page.url = '{{ page.url | absolute_url }}';
|
||||||
this.page.identifier = '{{ page.url }}';
|
this.page.identifier = '{{ page.url }}';
|
||||||
};
|
};
|
||||||
|
|
||||||
{%- comment -%} Lazy loading {%- endcomment -%}
|
function addDisqus() {
|
||||||
var disqus_observer = new IntersectionObserver(
|
let disqusThread = document.createElement('div');
|
||||||
function (entries) {
|
let paragraph = document.createElement('p');
|
||||||
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);
|
|
||||||
})();
|
|
||||||
|
|
||||||
disqus_observer.disconnect();
|
disqusThread.id = 'disqus_thread';
|
||||||
}
|
paragraph.className = 'text-center text-muted small';
|
||||||
},
|
paragraph.innerHTML = 'Comments powered by <a href="https://disqus.com/">Disqus</a>.';
|
||||||
{ threshold: [0] }
|
disqusThread.appendChild(paragraph);
|
||||||
);
|
|
||||||
|
|
||||||
disqus_observer.observe(document.getElementById('disqus_thread'));
|
const footer = document.querySelector('footer');
|
||||||
|
footer.insertAdjacentElement("beforebegin", disqusThread);
|
||||||
|
}
|
||||||
|
|
||||||
{%- comment -%} Auto switch theme {%- endcomment -%}
|
{%- comment -%} Auto switch theme {%- endcomment -%}
|
||||||
function reloadDisqus() {
|
function reloadDisqus(event) {
|
||||||
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
if (event.source === window && event.data && event.data.id === Theme.ID) {
|
||||||
{%- comment -%} Disqus hasn't been loaded {%- endcomment -%}
|
{%- comment -%} Disqus hasn't been loaded {%- endcomment -%}
|
||||||
if (typeof DISQUS === 'undefined') {
|
if (typeof DISQUS === 'undefined') {
|
||||||
return;
|
return;
|
||||||
@@ -44,7 +31,27 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.getElementById('mode-toggle')) {
|
addDisqus();
|
||||||
window.addEventListener('message', reloadDisqus);
|
|
||||||
|
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>
|
</script>
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
<!-- https://giscus.app/ -->
|
<!-- https://giscus.app/ -->
|
||||||
<script type="text/javascript">
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
const origin = 'https://giscus.app';
|
const themeMapper = Theme.getThemeMapper('light', 'dark_dimmed');
|
||||||
const lightTheme = 'light';
|
const initTheme = themeMapper[Theme.visualState];
|
||||||
const darkTheme = 'dark_dimmed';
|
|
||||||
|
|
||||||
let initTheme = lightTheme;
|
let lang = '{{ site.comments.giscus.lang | default: lang }}';
|
||||||
const html = document.documentElement;
|
{%- comment -%} https://github.com/giscus/giscus/tree/main/locales {%- endcomment -%}
|
||||||
|
if (lang.length > 2 && !lang.startsWith('zh')) {
|
||||||
if (
|
lang = lang.slice(0, 2);
|
||||||
(html.hasAttribute('data-mode') &&
|
|
||||||
html.getAttribute('data-mode') === 'dark') ||
|
|
||||||
(!html.hasAttribute('data-mode') &&
|
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
|
||||||
) {
|
|
||||||
initTheme = darkTheme;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let giscusAttributes = {
|
let giscusAttributes = {
|
||||||
@@ -29,36 +22,33 @@
|
|||||||
'data-emit-metadata': '0',
|
'data-emit-metadata': '0',
|
||||||
'data-theme': initTheme,
|
'data-theme': initTheme,
|
||||||
'data-input-position': '{{ site.comments.giscus.input_position | default: 'bottom' }}',
|
'data-input-position': '{{ site.comments.giscus.input_position | default: 'bottom' }}',
|
||||||
'data-lang': '{{ site.comments.giscus.lang | default: lang }}',
|
'data-lang': lang,
|
||||||
'data-loading': 'lazy',
|
'data-loading': 'lazy',
|
||||||
crossorigin: 'anonymous',
|
crossorigin: 'anonymous',
|
||||||
async: ''
|
async: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
let giscusScript = document.createElement('script');
|
let giscusNode = document.createElement('script');
|
||||||
Object.entries(giscusAttributes).forEach(([key, value]) =>
|
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) => {
|
addEventListener('message', (event) => {
|
||||||
if (
|
if (event.source === window && event.data && event.data.id === Theme.ID) {
|
||||||
event.source === window &&
|
const newTheme = themeMapper[Theme.visualState];
|
||||||
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;
|
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
setConfig: {
|
setConfig: {
|
||||||
theme: theme
|
theme: newTheme
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const giscus = document.getElementsByClassName('giscus-frame')[0].contentWindow;
|
const giscus =
|
||||||
giscus.postMessage({ giscus: message }, origin);
|
document.getElementsByClassName('giscus-frame')[0].contentWindow;
|
||||||
|
giscus.postMessage({ giscus: message }, 'https://giscus.app');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -1,49 +1,38 @@
|
|||||||
<!-- https://utteranc.es/ -->
|
<!-- https://utteranc.es/ -->
|
||||||
<script
|
<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">
|
|
||||||
(function () {
|
(function () {
|
||||||
const origin = 'https://utteranc.es';
|
const origin = 'https://utteranc.es';
|
||||||
const lightTheme = 'github-light';
|
const themeMapper = Theme.getThemeMapper('github-light', 'github-dark');
|
||||||
const darkTheme = 'github-dark';
|
const initTheme = themeMapper[Theme.visualState];
|
||||||
let initTheme = lightTheme;
|
|
||||||
const html = document.documentElement;
|
|
||||||
|
|
||||||
if (
|
let script = document.createElement('script');
|
||||||
(html.hasAttribute('data-mode') && html.getAttribute('data-mode') === 'dark') ||
|
script.src = 'https://utteranc.es/client.js';
|
||||||
(!html.hasAttribute('data-mode') && window.matchMedia('(prefers-color-scheme: dark)').matches)
|
script.setAttribute('repo', '{{ site.comments.utterances.repo }}');
|
||||||
) {
|
script.setAttribute('issue-term', '{{ site.comments.utterances.issue_term }}');
|
||||||
initTheme = darkTheme;
|
script.setAttribute('theme', initTheme);
|
||||||
}
|
script.crossOrigin = 'anonymous';
|
||||||
|
script.async = true;
|
||||||
|
|
||||||
|
const $footer = document.querySelector('footer');
|
||||||
|
$footer.insertAdjacentElement('beforebegin', script);
|
||||||
|
|
||||||
addEventListener('message', (event) => {
|
addEventListener('message', (event) => {
|
||||||
let theme;
|
let newTheme;
|
||||||
|
|
||||||
{%- comment -%} credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347> {%- endcomment -%}
|
{%- comment -%}
|
||||||
if (event.origin === origin) {
|
Credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347>
|
||||||
{%- comment -%} page initial {%- endcomment -%}
|
{%- endcomment -%}
|
||||||
theme = initTheme;
|
if (event.source === window && event.data && event.data.id === Theme.ID) {
|
||||||
} else if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
newTheme = themeMapper[Theme.visualState];
|
||||||
{%- comment -%} global theme mode changed {%- endcomment -%}
|
|
||||||
const mode = event.data.message;
|
const message = {
|
||||||
theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
|
type: 'set-theme',
|
||||||
} else {
|
theme: newTheme
|
||||||
return;
|
};
|
||||||
|
|
||||||
|
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>
|
</script>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<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: light)" content="#f7f7f7">
|
||||||
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e">
|
<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="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||||
<meta
|
<meta
|
||||||
name="viewport"
|
name="viewport"
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
|
|
||||||
<!-- Bootstrap -->
|
<!-- Bootstrap -->
|
||||||
{% unless jekyll.environment == 'production' %}
|
{% unless jekyll.environment == 'production' %}
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
|
||||||
{% endunless %}
|
{% endunless %}
|
||||||
|
|
||||||
<!-- Theme style -->
|
<!-- Theme style -->
|
||||||
@@ -97,11 +97,30 @@
|
|||||||
<link rel="stylesheet" href="{{ site.data.origin[type].glightbox.css | relative_url }}">
|
<link rel="stylesheet" href="{{ site.data.origin[type].glightbox.css | relative_url }}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- JavaScript -->
|
<!-- Scripts -->
|
||||||
|
|
||||||
{% unless site.theme_mode %}
|
<script src="{{ '/assets/js/dist/theme.min.js' | relative_url }}"></script>
|
||||||
{% include mode-toggle.html %}
|
|
||||||
{% 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 %}
|
{% include metadata-hook.html %}
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
<!-- layout specified -->
|
<!-- layout specified -->
|
||||||
|
|
||||||
{% assign js_dist = '/assets/js/dist/' %}
|
|
||||||
|
|
||||||
{% if page.layout == 'post' or page.layout == 'page' or page.layout == 'home' %}
|
{% if page.layout == 'post' or page.layout == 'page' or page.layout == 'home' %}
|
||||||
{% assign urls = urls | append: ',' | append: site.data.origin[type]['lazy-polyfill'].js %}
|
{% assign urls = urls | append: ',' | append: site.data.origin[type]['lazy-polyfill'].js %}
|
||||||
|
|
||||||
@@ -62,13 +60,14 @@
|
|||||||
{% assign js = 'commons' %}
|
{% assign js = 'commons' %}
|
||||||
{% endcase %}
|
{% endcase %}
|
||||||
|
|
||||||
{% capture script %}{{ js_dist }}{{ js }}.min.js{% endcapture %}
|
{% 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 %}
|
{% if page.math %}
|
||||||
<!-- MathJax -->
|
<!-- MathJax -->
|
||||||
<script src="{{ '/assets/js/data/mathjax.js' | relative_url }}"></script>
|
<script async 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="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>
|
<script id="MathJax-script" async src="{{ site.data.origin[type].mathjax.js | relative_url }}"></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@@ -85,23 +84,3 @@
|
|||||||
{% endcase %}
|
{% endcase %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page.mermaid %}
|
|
||||||
{% include mermaid.html %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if jekyll.environment == 'production' %}
|
|
||||||
<!-- PWA -->
|
|
||||||
{% if site.pwa.enabled %}
|
|
||||||
<script defer src="{{ 'app.min.js' | prepend: js_dist | 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 urls = include.urls | split: ',' %}
|
||||||
|
|
||||||
{% assign combined_urls = nil %}
|
{% assign combined_urls = null %}
|
||||||
|
|
||||||
{% assign domain = 'https://cdn.jsdelivr.net/' %}
|
{% assign domain = 'https://cdn.jsdelivr.net/' %}
|
||||||
|
|
||||||
@@ -15,12 +15,12 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% elsif url contains '//' %}
|
{% elsif url contains '//' %}
|
||||||
<script src="{{ url }}"></script>
|
<script defer src="{{ url }}"></script>
|
||||||
{% else %}
|
{% else %}
|
||||||
<script src="{{ url | relative_url }}"></script>
|
<script defer src="{{ url | relative_url }}"></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if combined_urls %}
|
{% if combined_urls %}
|
||||||
<script src="{{ combined_urls }}"></script>
|
<script defer src="{{ combined_urls }}"></script>
|
||||||
{% endif %}
|
{% 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>
|
|
||||||
@@ -1,19 +1,21 @@
|
|||||||
<!-- Display GoatCounter pageviews -->
|
<!-- Display GoatCounter pageviews -->
|
||||||
<script>
|
<script>
|
||||||
let pv = document.getElementById('pageviews');
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const pv = document.getElementById('pageviews');
|
||||||
|
|
||||||
if (pv !== null) {
|
if (pv !== null) {
|
||||||
const uri = location.pathname.replace(/\/$/, '');
|
const uri = location.pathname.replace(/\/$/, '');
|
||||||
const url = `https://{{ site.analytics.goatcounter.id }}.goatcounter.com/counter/${encodeURIComponent(uri)}.json`;
|
const url = `https://{{ site.analytics.goatcounter.id }}.goatcounter.com/counter/${encodeURIComponent(uri)}.json`;
|
||||||
|
|
||||||
fetch(url)
|
fetch(url)
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
const count = data.count.replace(/\s/g, '');
|
const count = data.count.replace(/\s/g, '');
|
||||||
pv.innerText = new Intl.NumberFormat().format(count);
|
pv.innerText = new Intl.NumberFormat().format(count);
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
pv.innerText = '1';
|
pv.innerText = '1';
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -19,29 +19,31 @@
|
|||||||
{% capture not_found %}<p class="mt-5">{{ site.data.locales[include.lang].search.no_results }}</p>{% endcapture %}
|
{% capture not_found %}<p class="mt-5">{{ site.data.locales[include.lang].search.no_results }}</p>{% endcapture %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
{%- comment -%} Note: dependent library will be loaded in `js-selector.html` {%- endcomment -%}
|
{% comment %} Note: dependent library will be loaded in `js-selector.html` {% endcomment %}
|
||||||
SimpleJekyllSearch({
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
searchInput: document.getElementById('search-input'),
|
SimpleJekyllSearch({
|
||||||
resultsContainer: document.getElementById('search-results'),
|
searchInput: document.getElementById('search-input'),
|
||||||
json: '{{ '/assets/js/data/search.json' | relative_url }}',
|
resultsContainer: document.getElementById('search-results'),
|
||||||
searchResultTemplate: '{{ result_elem | strip_newlines }}',
|
json: '{{ '/assets/js/data/search.json' | relative_url }}',
|
||||||
noResultsText: '{{ not_found }}',
|
searchResultTemplate: '{{ result_elem | strip_newlines }}',
|
||||||
templateMiddleware: function(prop, value, template) {
|
noResultsText: '{{ not_found }}',
|
||||||
if (prop === 'categories') {
|
templateMiddleware: function(prop, value, template) {
|
||||||
if (value === '') {
|
if (prop === 'categories') {
|
||||||
return `${value}`;
|
if (value === '') {
|
||||||
} else {
|
return `${value}`;
|
||||||
return `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${value}</div>`;
|
} else {
|
||||||
|
return `<div class="me-sm-4"><i class="far fa-folder fa-fw"></i>${value}</div>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (prop === 'tags') {
|
if (prop === 'tags') {
|
||||||
if (value === '') {
|
if (value === '') {
|
||||||
return `${value}`;
|
return `${value}`;
|
||||||
} else {
|
} else {
|
||||||
return `<div><i class="fa fa-tag fa-fw"></i>${value}</div>`;
|
return `<div><i class="fa fa-tag fa-fw"></i>${value}</div>`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -11,9 +11,7 @@
|
|||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<h1 class="site-title">
|
<a class="site-title d-block" href="{{ '/' | relative_url }}">{{ site.title }}</a>
|
||||||
<a href="{{ '/' | relative_url }}">{{ site.title }}</a>
|
|
||||||
</h1>
|
|
||||||
<p class="site-subtitle fst-italic mb-0">{{ site.tagline }}</p>
|
<p class="site-subtitle fst-italic mb-0">{{ site.tagline }}</p>
|
||||||
</header>
|
</header>
|
||||||
<!-- .profile-wrapper -->
|
<!-- .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,13 +1,9 @@
|
|||||||
{% assign enable_toc = false %}
|
{% include toc-status.html %}
|
||||||
{% if site.toc and page.toc %}
|
|
||||||
{% if page.content contains '<h2' or page.content contains '<h3' %}
|
|
||||||
{% assign enable_toc = true %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if enable_toc %}
|
{% if enable_toc %}
|
||||||
<section id="toc-wrapper" class="d-none ps-0 pe-4">
|
<div class="toc-border-cover z-3"></div>
|
||||||
<h2 class="panel-heading ps-3 mb-2">{{- site.data.locales[include.lang].panel.toc -}}</h2>
|
<section id="toc-wrapper" class="invisible position-sticky ps-0 pe-4 pb-4">
|
||||||
|
<h2 class="panel-heading ps-3 pb-2 mb-0">{{- site.data.locales[include.lang].panel.toc -}}</h2>
|
||||||
<nav id="toc"></nav>
|
<nav id="toc"></nav>
|
||||||
</section>
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
Chirpy v<%= pkg.version %> | © 2019 <%= pkg.author %> | <%= pkg.license %> Licensed | <%= pkg.homepage %>
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||||
import { categoryCollapse } from './modules/plugins';
|
import { categoryCollapse } from './modules/components';
|
||||||
|
|
||||||
basic();
|
basic();
|
||||||
initSidebar();
|
initSidebar();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||||
import { initLocaleDatetime, loadImg } from './modules/plugins';
|
import { initLocaleDatetime, loadImg } from './modules/components';
|
||||||
|
|
||||||
loadImg();
|
loadImg();
|
||||||
initLocaleDatetime();
|
initLocaleDatetime();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||||
import { initLocaleDatetime } from './modules/plugins';
|
import { initLocaleDatetime } from './modules/components';
|
||||||
|
|
||||||
initSidebar();
|
initSidebar();
|
||||||
initTopbar();
|
initTopbar();
|
||||||
|
|||||||
@@ -3,4 +3,8 @@ export { initClipboard } from './components/clipboard';
|
|||||||
export { loadImg } from './components/img-loading';
|
export { loadImg } from './components/img-loading';
|
||||||
export { imgPopup } from './components/img-popup';
|
export { imgPopup } from './components/img-popup';
|
||||||
export { initLocaleDatetime } from './components/locale-datetime';
|
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,12 +4,47 @@
|
|||||||
* Dependencies: https://github.com/biati-digital/glightbox
|
* Dependencies: https://github.com/biati-digital/glightbox
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const IMG_CLASS = 'popup';
|
const lightImages = '.popup:not(.dark)';
|
||||||
|
const darkImages = '.popup:not(.light)';
|
||||||
|
let selector = lightImages;
|
||||||
|
|
||||||
|
function updateImages(current, reverse) {
|
||||||
|
if (selector === lightImages) {
|
||||||
|
selector = darkImages;
|
||||||
|
} else {
|
||||||
|
selector = lightImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reverse === null) {
|
||||||
|
reverse = GLightbox({ selector: `${selector}` });
|
||||||
|
}
|
||||||
|
|
||||||
|
[current, reverse] = [reverse, current];
|
||||||
|
}
|
||||||
|
|
||||||
export function imgPopup() {
|
export function imgPopup() {
|
||||||
if (document.getElementsByClassName(IMG_CLASS).length === 0) {
|
if (document.querySelector('.popup') === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLightbox({ selector: `.${IMG_CLASS}` });
|
const hasDualImages = !(
|
||||||
|
document.querySelector('.popup.light') === null &&
|
||||||
|
document.querySelector('.popup.dark') === null
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Theme.visualState === Theme.DARK) {
|
||||||
|
selector = darkImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
let current = GLightbox({ selector: `${selector}` });
|
||||||
|
|
||||||
|
if (hasDualImages && Theme.switchable) {
|
||||||
|
let reverse = null;
|
||||||
|
|
||||||
|
window.addEventListener('message', (event) => {
|
||||||
|
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).textContent;
|
||||||
|
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,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* This script make #search-result-wrapper switch to unloaded or shown automatically.
|
* This script make #search-result-wrapper switch to unload or shown automatically.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const btnSbTrigger = document.getElementById('sidebar-trigger');
|
const btnSbTrigger = document.getElementById('sidebar-trigger');
|
||||||
|
|||||||
@@ -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,36 @@
|
|||||||
export function toc() {
|
import { TocMobile as mobile } from './toc/toc-mobile';
|
||||||
if (document.querySelector('main h2, main h3')) {
|
import { TocDesktop as desktop } from './toc/toc-desktop';
|
||||||
// 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
|
|
||||||
});
|
|
||||||
|
|
||||||
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
const $tocWrapper = document.getElementById('toc-wrapper');
|
||||||
|
$tocWrapper.classList.remove('invisible');
|
||||||
|
|
||||||
|
desktopMode.onchange = refresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { init as initToc };
|
||||||
|
|||||||
20
_javascript/modules/components/toc/toc-desktop.js
Normal file
20
_javascript/modules/components/toc/toc-desktop.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
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() {
|
||||||
|
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 { back2top, loadTooptip, modeWatcher } from '../components';
|
||||||
import { loadTooptip } from '../components/tooltip-loader';
|
|
||||||
|
|
||||||
export function basic() {
|
export function basic() {
|
||||||
|
modeWatcher();
|
||||||
back2top();
|
back2top();
|
||||||
loadTooptip();
|
loadTooptip();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,19 @@
|
|||||||
import { modeWatcher } from '../components/mode-watcher';
|
const ATTR_DISPLAY = 'sidebar-display';
|
||||||
import { sidebarExpand } from '../components/sidebar';
|
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() {
|
export function initSidebar() {
|
||||||
modeWatcher();
|
$trigger.onclick = $mask.onclick = () => SidebarUtil.toggle();
|
||||||
sidebarExpand();
|
|
||||||
}
|
}
|
||||||
|
|||||||
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 { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||||
import { loadImg, imgPopup, initClipboard } from './modules/plugins';
|
import {
|
||||||
|
loadImg,
|
||||||
|
imgPopup,
|
||||||
|
initClipboard,
|
||||||
|
loadMermaid
|
||||||
|
} from './modules/components';
|
||||||
|
|
||||||
loadImg();
|
loadImg();
|
||||||
imgPopup();
|
imgPopup();
|
||||||
initSidebar();
|
initSidebar();
|
||||||
initTopbar();
|
initTopbar();
|
||||||
initClipboard();
|
initClipboard();
|
||||||
|
loadMermaid();
|
||||||
basic();
|
basic();
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
import { basic, initTopbar, initSidebar } from './modules/layouts';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
loadImg,
|
loadImg,
|
||||||
imgPopup,
|
imgPopup,
|
||||||
initLocaleDatetime,
|
initLocaleDatetime,
|
||||||
initClipboard,
|
initClipboard,
|
||||||
toc
|
initToc,
|
||||||
} from './modules/plugins';
|
loadMermaid
|
||||||
|
} from './modules/components';
|
||||||
|
|
||||||
loadImg();
|
loadImg();
|
||||||
toc();
|
initToc();
|
||||||
imgPopup();
|
imgPopup();
|
||||||
initSidebar();
|
initSidebar();
|
||||||
initLocaleDatetime();
|
initLocaleDatetime();
|
||||||
initClipboard();
|
initClipboard();
|
||||||
initTopbar();
|
initTopbar();
|
||||||
|
loadMermaid();
|
||||||
basic();
|
basic();
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
---
|
|
||||||
permalink: /:basename
|
|
||||||
---
|
|
||||||
@@ -1,15 +1,19 @@
|
|||||||
import { pwa, baseurl } from '../../_config.yml';
|
|
||||||
import Toast from 'bootstrap/js/src/toast';
|
import Toast from 'bootstrap/js/src/toast';
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
if (pwa.enabled) {
|
// Get Jekyll config from URL parameters
|
||||||
const swUrl = `${baseurl}/sw.min.js`;
|
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 notification = document.getElementById('notification');
|
||||||
const btnRefresh = notification.querySelector('.toast-body>button');
|
const btnRefresh = notification.querySelector('.toast-body>button');
|
||||||
const popupWindow = Toast.getOrCreateInstance(notification);
|
const popupWindow = Toast.getOrCreateInstance(notification);
|
||||||
|
|
||||||
navigator.serviceWorker.register(swUrl).then((registration) => {
|
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) {
|
if (registration.waiting) {
|
||||||
popupWindow.show();
|
popupWindow.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,23 @@
|
|||||||
import { baseurl } from '../../_config.yml';
|
importScripts('./assets/js/data/swconf.js');
|
||||||
|
|
||||||
importScripts(`${baseurl}/assets/js/data/swconf.js`);
|
|
||||||
|
|
||||||
const purge = swconf.purge;
|
const purge = swconf.purge;
|
||||||
|
const interceptor = swconf.interceptor;
|
||||||
|
|
||||||
function verifyUrl(url) {
|
function verifyUrl(url) {
|
||||||
const requestPath = new URL(url).pathname;
|
const requestUrl = new URL(url);
|
||||||
|
const requestPath = requestUrl.pathname;
|
||||||
|
|
||||||
for (const path of swconf.denyPaths) {
|
if (!requestUrl.protocol.startsWith('http')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const prefix of interceptor.urlPrefixes) {
|
||||||
|
if (requestUrl.href.startsWith(prefix)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const path of interceptor.paths) {
|
||||||
if (requestPath.startsWith(path)) {
|
if (requestPath.startsWith(path)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ layout: compress
|
|||||||
</main>
|
</main>
|
||||||
|
|
||||||
<!-- panel -->
|
<!-- panel -->
|
||||||
<aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 mb-5 text-muted">
|
<aside aria-label="Panel" id="panel-wrapper" class="col-xl-3 ps-2 text-muted">
|
||||||
<div class="access">
|
<div class="access">
|
||||||
{% include_cached update-list.html lang=lang %}
|
{% include_cached update-list.html lang=lang %}
|
||||||
{% include_cached trending-tags.html lang=lang %}
|
{% include_cached trending-tags.html lang=lang %}
|
||||||
@@ -68,14 +68,18 @@ layout: compress
|
|||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="mask"></div>
|
<div id="mask" class="d-none position-fixed w-100 h-100 z-1"></div>
|
||||||
|
|
||||||
{% if site.pwa.enabled %}
|
{% if site.pwa.enabled %}
|
||||||
{% include_cached notification.html lang=lang %}
|
{% include_cached notification.html lang=lang %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- JavaScripts -->
|
<!-- Embedded scripts -->
|
||||||
{% include js-selector.html lang=lang %}
|
|
||||||
|
{% for _include in layout.script_includes %}
|
||||||
|
{% assign _include_path = _include | append: '.html' %}
|
||||||
|
{% include {{ _include_path }} %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% include_cached search-loader.html lang=lang %}
|
{% include_cached search-loader.html lang=lang %}
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -5,38 +5,45 @@ refactor: true
|
|||||||
|
|
||||||
{% include lang.html %}
|
{% include lang.html %}
|
||||||
|
|
||||||
{% assign pinned = site.posts | where: 'pin', 'true' %}
|
{% assign all_pinned = site.posts | where: 'pin', 'true' %}
|
||||||
{% assign default = site.posts | where_exp: 'item', 'item.pin != true and item.hidden != true' %}
|
{% assign all_normal = site.posts | where_exp: 'item', 'item.pin != true and item.hidden != true' %}
|
||||||
|
|
||||||
{% assign posts = '' | split: '' %}
|
{% assign posts = '' | split: '' %}
|
||||||
|
|
||||||
<!-- Get pinned posts -->
|
<!-- Get pinned posts on current page -->
|
||||||
|
|
||||||
{% assign offset = paginator.page | minus: 1 | times: paginator.per_page %}
|
{% assign visible_start = paginator.page | minus: 1 | times: paginator.per_page %}
|
||||||
{% assign pinned_num = pinned.size | minus: offset %}
|
{% assign visible_end = visible_start | plus: paginator.per_page %}
|
||||||
|
|
||||||
{% if pinned_num > 0 %}
|
{% if all_pinned.size > visible_start %}
|
||||||
{% for i in (offset..pinned.size) limit: pinned_num %}
|
{% if all_pinned.size > visible_end %}
|
||||||
{% assign posts = posts | push: pinned[i] %}
|
{% 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 %}
|
{% endfor %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% assign pinned_num = 0 %}
|
{% assign pinned_size = 0 %}
|
||||||
{% endif %}
|
{% 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 %}
|
{% if normal_size > 0 %}
|
||||||
{% assign default_beg = 0 %}
|
{% if pinned_size > 0 %}
|
||||||
{% endif %}
|
{% 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 normal_end = normal_start | plus: normal_size | minus: 1 %}
|
||||||
{% assign default_end = default_beg | plus: default_num | minus: 1 %}
|
|
||||||
|
|
||||||
{% if default_num > 0 %}
|
{% for i in (normal_start..normal_end) %}
|
||||||
{% for i in (default_beg..default_end) %}
|
{% assign posts = posts | push: all_normal[i] %}
|
||||||
{% assign posts = posts | push: default[i] %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,15 @@ panel_includes:
|
|||||||
tail_includes:
|
tail_includes:
|
||||||
- related-posts
|
- related-posts
|
||||||
- post-nav
|
- post-nav
|
||||||
- comments
|
script_includes:
|
||||||
|
- comment
|
||||||
---
|
---
|
||||||
|
|
||||||
{% include lang.html %}
|
{% include lang.html %}
|
||||||
|
|
||||||
<article class="px-1">
|
{% include toc-status.html %}
|
||||||
|
|
||||||
|
<article class="px-1" data-toc="{{ enable_toc }}">
|
||||||
<header>
|
<header>
|
||||||
<h1 data-toc-skip>{{ page.title }}</h1>
|
<h1 data-toc-skip>{{ page.title }}</h1>
|
||||||
{% if page.description %}
|
{% if page.description %}
|
||||||
@@ -95,6 +98,30 @@ tail_includes:
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</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">
|
<div class="content">
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -18,16 +18,16 @@ image:
|
|||||||
|
|
||||||
<!-- markdownlint-capture -->
|
<!-- markdownlint-capture -->
|
||||||
<!-- markdownlint-disable -->
|
<!-- markdownlint-disable -->
|
||||||
# H1 - heading
|
# H1 — heading
|
||||||
{: .mt-4 .mb-0 }
|
{: .mt-4 .mb-0 }
|
||||||
|
|
||||||
## H2 - heading
|
## H2 — heading
|
||||||
{: data-toc-skip='' .mt-4 .mb-0 }
|
{: data-toc-skip='' .mt-4 .mb-0 }
|
||||||
|
|
||||||
### H3 - heading
|
### H3 — heading
|
||||||
{: data-toc-skip='' .mt-4 .mb-0 }
|
{: data-toc-skip='' .mt-4 .mb-0 }
|
||||||
|
|
||||||
#### H4 - heading
|
#### H4 — heading
|
||||||
{: data-toc-skip='' .mt-4 }
|
{: data-toc-skip='' .mt-4 }
|
||||||
<!-- markdownlint-restore -->
|
<!-- markdownlint-restore -->
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ tags: [TAG] # TAG names should always be lowercase
|
|||||||
|
|
||||||
### Timezone of Date
|
### Timezone of Date
|
||||||
|
|
||||||
In order to accurately record the release date of a post, you should not only set up the `timezone` of `_config.yml`{: .filepath} but also provide the post's timezone in variable `date` of its Front Matter block. Format: `+/-TTTT`, e.g. `+0800`.
|
To accurately record the release date of a post, you should not only set up the `timezone` of `_config.yml`{: .filepath} but also provide the post's timezone in variable `date` of its Front Matter block. Format: `+/-TTTT`, e.g. `+0800`.
|
||||||
|
|
||||||
### Categories and Tags
|
### Categories and Tags
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ toc: false
|
|||||||
|
|
||||||
## Comments
|
## Comments
|
||||||
|
|
||||||
The global switch of comments is defined by variable `comments.active` in the file `_config.yml`{: .filepath}. After selecting a comment system for this variable, comments will be turned on for all posts.
|
The global setting for comments is defined by the `comments.provider` option in the `_config.yml`{: .filepath} file. Once a comment system is selected for this variable, comments will be enabled for all posts.
|
||||||
|
|
||||||
If you want to close the comment for a specific post, add the following to the **Front Matter** of the post:
|
If you want to close the comment for a specific post, add the following to the **Front Matter** of the post:
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ _Image Caption_
|
|||||||
|
|
||||||
#### Size
|
#### Size
|
||||||
|
|
||||||
In order to prevent the page content layout from shifting when the image is loaded, we should set the width and height for each image.
|
To prevent the page content layout from shifting when the image is loaded, we should set the width and height for each image.
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
{: width="700" height="400" }
|
{: width="700" height="400" }
|
||||||
@@ -284,7 +284,7 @@ If you want to embed a video file directly, use the following syntax:
|
|||||||
{% include embed/video.html src='{URL}' %}
|
{% include embed/video.html src='{URL}' %}
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `URL` is an URL to a video file e.g. `/path/to/sample/video.mp4`.
|
Where `URL` is a URL to a video file e.g. `/path/to/sample/video.mp4`.
|
||||||
|
|
||||||
You can also specify additional attributes for the embedded video file. Here is a full list of attributes allowed.
|
You can also specify additional attributes for the embedded video file. Here is a full list of attributes allowed.
|
||||||
|
|
||||||
@@ -295,7 +295,7 @@ You can also specify additional attributes for the embedded video file. Here is
|
|||||||
- `muted=true` — audio will be initially silenced
|
- `muted=true` — audio will be initially silenced
|
||||||
- `types` — specify the extensions of additional video formats separated by `|`. Ensure these files exist in the same directory as your primary video file.
|
- `types` — specify the extensions of additional video formats separated by `|`. Ensure these files exist in the same directory as your primary video file.
|
||||||
|
|
||||||
Consider an example utilizing all of the above:
|
Consider an example using all of the above:
|
||||||
|
|
||||||
```liquid
|
```liquid
|
||||||
{%
|
{%
|
||||||
@@ -318,14 +318,14 @@ If you want to embed an audio file directly, use the following syntax:
|
|||||||
{% include embed/audio.html src='{URL}' %}
|
{% include embed/audio.html src='{URL}' %}
|
||||||
```
|
```
|
||||||
|
|
||||||
Where `URL` is an URL to an audio file e.g. `/path/to/audio.mp3`.
|
Where `URL` is a URL to an audio file e.g. `/path/to/audio.mp3`.
|
||||||
|
|
||||||
You can also specify additional attributes for the embedded audio file. Here is a full list of attributes allowed.
|
You can also specify additional attributes for the embedded audio file. Here is a full list of attributes allowed.
|
||||||
|
|
||||||
- `title='Text'` — title for an audio that appears below the audio and looks same as for images
|
- `title='Text'` — title for an audio that appears below the audio and looks same as for images
|
||||||
- `types` — specify the extensions of additional audio formats separated by `|`. Ensure these files exist in the same directory as your primary audio file.
|
- `types` — specify the extensions of additional audio formats separated by `|`. Ensure these files exist in the same directory as your primary audio file.
|
||||||
|
|
||||||
Consider an example utilizing all of the above:
|
Consider an example using all of the above:
|
||||||
|
|
||||||
```liquid
|
```liquid
|
||||||
{%
|
{%
|
||||||
@@ -365,7 +365,7 @@ There are several types of prompts: `tip`, `info`, `warning`, and `danger`. They
|
|||||||
```
|
```
|
||||||
{: .nolineno }
|
{: .nolineno }
|
||||||
|
|
||||||
### Filepath Hightlight
|
### Filepath Highlight
|
||||||
|
|
||||||
```md
|
```md
|
||||||
`/path/to/a/file.extend`{: .filepath}
|
`/path/to/a/file.extend`{: .filepath}
|
||||||
@@ -433,8 +433,6 @@ If you want to display the **Liquid** snippet, surround the liquid code with `{%
|
|||||||
|
|
||||||
Or adding `render_with_liquid: false` (Requires Jekyll 4.0 or higher) to the post's YAML block.
|
Or adding `render_with_liquid: false` (Requires Jekyll 4.0 or higher) to the post's YAML block.
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## Mathematics
|
## Mathematics
|
||||||
|
|
||||||
We use [**MathJax**][mathjax] to generate mathematics. For website performance reasons, the mathematical feature won't be loaded by default. But it can be enabled by:
|
We use [**MathJax**][mathjax] to generate mathematics. For website performance reasons, the mathematical feature won't be loaded by default. But it can be enabled by:
|
||||||
|
|||||||
@@ -11,56 +11,74 @@ pin: true
|
|||||||
media_subpath: '/posts/20180809'
|
media_subpath: '/posts/20180809'
|
||||||
---
|
---
|
||||||
|
|
||||||
## Prerequisites
|
## Creating a Site Repository
|
||||||
|
|
||||||
Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of the basic environment. [Git](https://git-scm.com/) also needs to be installed.
|
When creating your site repository, you have two options depending on your needs:
|
||||||
|
|
||||||
## Installation
|
### Option 1. Using the Starter (Recommended)
|
||||||
|
|
||||||
### Creating a New Site
|
This approach simplifies upgrades, isolates unnecessary files, and is perfect for users who want to focus on writing with minimal configuration.
|
||||||
|
|
||||||
There are two ways to create a new repository for this theme:
|
1. Sign in to GitHub and navigate to the [**starter**][starter].
|
||||||
|
2. Click the <kbd>Use this template</kbd> button and then select <kbd>Create a new repository</kbd>.
|
||||||
|
3. Name the new repository `<username>.github.io`, replacing `username` with your lowercase GitHub username.
|
||||||
|
|
||||||
- [**Using the Chirpy Starter**](#option-1-using-the-chirpy-starter) — Easy to upgrade, isolates irrelevant project files so you can focus on writing.
|
### Option 2. Forking the Theme
|
||||||
- [**GitHub Fork**](#option-2-github-fork) — Convenient for custom development, but difficult to upgrade. Unless you are familiar with Jekyll and are determined to tweak or contribute to this project, this approach is not recommended.
|
|
||||||
|
|
||||||
#### Option 1. Using the Chirpy Starter
|
This approach is convenient for modifying features or UI design, but presents challenges during upgrades. So don't try this unless you are familiar with Jekyll and plan to heavily modify this theme.
|
||||||
|
|
||||||
Sign in to GitHub and browse to [**Chirpy Starter**][starter], click the button <kbd>Use this template</kbd> > <kbd>Create a new repository</kbd>, and name the new repository `USERNAME.github.io`, where `USERNAME` represents your GitHub username.
|
1. Sign in to GitHub.
|
||||||
|
2. [Fork the theme repository](https://github.com/cotes2020/jekyll-theme-chirpy/fork).
|
||||||
|
3. Name the new repository `<username>.github.io`, replacing `username` with your lowercase GitHub username.
|
||||||
|
|
||||||
#### Option 2. GitHub Fork
|
## Setting up the Environment
|
||||||
|
|
||||||
Sign in to GitHub to [fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork), and then rename it to `USERNAME.github.io` (`USERNAME` means your username).
|
Once your repository is created, it's time to set up your development environment. There are two primary methods:
|
||||||
|
|
||||||
Next, clone the repository to your local machine, make sure it has [Node.js][nodejs] installed, then go to the root directory of the repo and run the following command:
|
### Using Dev Containers (Recommended for Windows)
|
||||||
|
|
||||||
```console
|
Dev Containers offer an isolated environment using Docker, which prevents conflicts with your system and ensures all dependencies are managed within the container.
|
||||||
$ bash tools/init
|
|
||||||
```
|
|
||||||
|
|
||||||
> If you don't want to deploy your site on GitHub Pages, append option `--no-gh` at the end of the above command.
|
**Steps**:
|
||||||
{: .prompt-info }
|
|
||||||
|
|
||||||
The above command will:
|
1. Install Docker:
|
||||||
|
- On Windows/macOS, install [Docker Desktop][docker-desktop].
|
||||||
|
- On Linux, install [Docker Engine][docker-engine].
|
||||||
|
2. Install [VS Code][vscode] and the [Dev Containers extension][dev-containers].
|
||||||
|
3. Clone your repository:
|
||||||
|
- For Docker Desktop: Start VS Code and [clone your repo in a container volume][dc-clone-in-vol].
|
||||||
|
- For Docker Engine: Clone your repo locally, then [open it in a container][dc-open-in-container] via VS Code.
|
||||||
|
4. Wait for the Dev Containers setup to complete.
|
||||||
|
|
||||||
1. Check out the code to the [latest tag][latest-tag] (to ensure the stability of your site: as the code for the default branch is under development).
|
### Setting up Natively (Recommended for Unix-like OS)
|
||||||
2. Remove non-essential sample files and take care of GitHub-related files.
|
|
||||||
3. Build CSS/JS assets files and then make them tracked by Git.
|
|
||||||
4. Automatically create a new commit to save the changes above.
|
|
||||||
|
|
||||||
### Installing Dependencies
|
For Unix-like systems, you can set up the environment natively for optimal performance, though you can also use Dev Containers as an alternative.
|
||||||
|
|
||||||
Before running local server for the first time, go to the root directory of your site and run:
|
**Steps**:
|
||||||
|
|
||||||
```console
|
1. Follow the [Jekyll installation guide](https://jekyllrb.com/docs/installation/) to install Jekyll and ensure [Git](https://git-scm.com/) is installed.
|
||||||
$ bundle
|
2. Clone your repository to your local machine.
|
||||||
```
|
3. If you forked the theme, install [Node.js][nodejs] and run `bash tools/init.sh` in the root directory to initialize the repository.
|
||||||
|
4. Run command `bundle` in the root of your repository to install the dependencies.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Start the Jekyll Server
|
||||||
|
|
||||||
|
To run the site locally, use the following command:
|
||||||
|
|
||||||
|
```terminal
|
||||||
|
$ bundle exec jekyll s
|
||||||
|
```
|
||||||
|
|
||||||
|
> If you are using Dev Containers, you must run that command in the **VS Code** Terminal.
|
||||||
|
{: .prompt-info }
|
||||||
|
|
||||||
|
After a few seconds, the local server will be available at <http://127.0.0.1:4000>.
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
Update the variables of `_config.yml`{: .filepath} as needed. Some of them are typical options:
|
Update the variables in `_config.yml`{: .filepath} as needed. Some typical options include:
|
||||||
|
|
||||||
- `url`
|
- `url`
|
||||||
- `avatar`
|
- `avatar`
|
||||||
@@ -69,70 +87,63 @@ Update the variables of `_config.yml`{: .filepath} as needed. Some of them are t
|
|||||||
|
|
||||||
### Social Contact Options
|
### Social Contact Options
|
||||||
|
|
||||||
Social contact options are displayed at the bottom of the sidebar. You can turn on/off the specified contacts in file `_data/contact.yml`{: .filepath }.
|
Social contact options are displayed at the bottom of the sidebar. You can enable or disable specific contacts in the `_data/contact.yml`{: .filepath} file.
|
||||||
|
|
||||||
### Customizing Stylesheet
|
### Customizing the Stylesheet
|
||||||
|
|
||||||
If you need to customize the stylesheet, copy the theme's `assets/css/jekyll-theme-chirpy.scss`{: .filepath} to the same path on your Jekyll site, and then add the custom style at the end of it.
|
To customize the stylesheet, copy the theme's `assets/css/jekyll-theme-chirpy.scss`{: .filepath} file to the same path in your Jekyll site, and add your custom styles at the end of the file.
|
||||||
|
|
||||||
Starting with version `6.2.0`, if you want to overwrite the SASS variables defined in `_sass/addon/variables.scss`{: .filepath}, copy the main sass file `_sass/main.scss`{: .filepath} into the `_sass`{: .filepath} directory in your site's source, then create a new file `_sass/variables-hook.scss`{: .filepath} and assign new value.
|
### Customizing Static Assets
|
||||||
|
|
||||||
### Customing Static Assets
|
Static assets configuration was introduced in version `5.1.0`. The CDN of the static assets is defined in `_data/origin/cors.yml`{: .filepath }. You can replace some of them based on the network conditions in the region where your website is published.
|
||||||
|
|
||||||
Static assets configuration was introduced in version `5.1.0`. The CDN of the static assets is defined by file `_data/origin/cors.yml`{: .filepath }, and you can replace some of them according to the network conditions in the region where your website is published.
|
If you prefer to self-host the static assets, refer to the [_chirpy-static-assets_](https://github.com/cotes2020/chirpy-static-assets#readme) repository.
|
||||||
|
|
||||||
Also, if you'd like to self-host the static assets, please refer to the [_chirpy-static-assets_](https://github.com/cotes2020/chirpy-static-assets#readme).
|
|
||||||
|
|
||||||
### Running Local Server
|
|
||||||
|
|
||||||
You may want to preview the site contents before publishing, so just run it by:
|
|
||||||
|
|
||||||
```console
|
|
||||||
$ bundle exec jekyll s
|
|
||||||
```
|
|
||||||
|
|
||||||
After a few seconds, the local service will be published at _<http://127.0.0.1:4000>_.
|
|
||||||
|
|
||||||
## Deployment
|
## Deployment
|
||||||
|
|
||||||
Before the deployment begins, check out the file `_config.yml`{: .filepath} and make sure the `url` is configured correctly. Furthermore, if you prefer the [**project site**](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites) and don't use a custom domain, or you want to visit your website with a base URL on a web server other than **GitHub Pages**, remember to change the `baseurl` to your project name that starts with a slash, e.g, `/project-name`.
|
Before deploying, check the `_config.yml`{: .filepath} file and ensure the `url` is configured correctly. If you prefer a [**project site**](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites) and don't use a custom domain, or if you want to visit your website with a base URL on a web server other than **GitHub Pages**, remember to set the `baseurl` to your project name, starting with a slash, e.g., `/project-name`.
|
||||||
|
|
||||||
Now you can choose _ONE_ of the following methods to deploy your Jekyll site.
|
Now you can choose _ONE_ of the following methods to deploy your Jekyll site.
|
||||||
|
|
||||||
### Deploy by Using GitHub Actions
|
### Deploy Using Github Actions
|
||||||
|
|
||||||
There are a few things to get ready for.
|
Prepare the following:
|
||||||
|
|
||||||
- If you're on the GitHub Free plan, keep your site repository public.
|
- If you're on the GitHub Free plan, keep your site repository public.
|
||||||
- If you have committed `Gemfile.lock`{: .filepath} to the repository, and your local machine is not running Linux, go to the root of your site and update the platform list of the lock-file:
|
- If you have committed `Gemfile.lock`{: .filepath} to the repository, and your local machine is not running Linux, update the platform list of the lock file:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ bundle lock --add-platform x86_64-linux
|
$ bundle lock --add-platform x86_64-linux
|
||||||
```
|
```
|
||||||
|
|
||||||
Next, configure the _Pages_ service.
|
Next, configure the _Pages_ service:
|
||||||
|
|
||||||
1. Browse to your repository on GitHub. Select the tab _Settings_, then click _Pages_ in the left navigation bar. Then, in the **Source** section (under _Build and deployment_), select [**GitHub Actions**][pages-workflow-src] from the dropdown menu.
|
1. Go to your repository on GitHub. Select the _Settings_ tab, then click _Pages_ in the left navigation bar. In the **Source** section (under _Build and deployment_), select [**GitHub Actions**][pages-workflow-src] from the dropdown menu.
|
||||||
{: .light .border .normal w='375' h='140' }
|
{: .light .border .normal w='375' h='140' }
|
||||||
{: .dark .normal w='375' h='140' }
|
{: .dark .normal w='375' h='140' }
|
||||||
|
|
||||||
2. Push any commits to GitHub to trigger the _Actions_ workflow. In the _Actions_ tab of your repository, you should see the workflow _Build and Deploy_ running. Once the build is complete and successful, the site will be deployed automatically.
|
2. Push any commits to GitHub to trigger the _Actions_ workflow. In the _Actions_ tab of your repository, you should see the workflow _Build and Deploy_ running. Once the build is complete and successful, the site will be deployed automatically.
|
||||||
|
|
||||||
At this point, you can go to the URL indicated by GitHub to access your site.
|
You can now visit the URL provided by GitHub to access your site.
|
||||||
|
|
||||||
### Manually Build and Deploy
|
### Manual Build and Deployment
|
||||||
|
|
||||||
On self-hosted servers, you cannot enjoy the convenience of **GitHub Actions**. Therefore, you should build the site on your local machine and then upload the site files to the server.
|
For self-hosted servers, you will need to build the site on your local machine and then upload the site files to the server.
|
||||||
|
|
||||||
Go to the root of the source project, and build your site as follows:
|
Navigate to the root of the source project, and build your site with the following command:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ JEKYLL_ENV=production bundle exec jekyll b
|
$ JEKYLL_ENV=production bundle exec jekyll b
|
||||||
```
|
```
|
||||||
|
|
||||||
Unless you specified the output path, the generated site files will be placed in folder `_site`{: .filepath} of the project's root directory. Now you should upload those files to the target server.
|
Unless you specified the output path, the generated site files will be placed in the `_site`{: .filepath} folder of the project's root directory. Upload these files to your target server.
|
||||||
|
|
||||||
[nodejs]: https://nodejs.org/
|
[nodejs]: https://nodejs.org/
|
||||||
[starter]: https://github.com/cotes2020/chirpy-starter
|
[starter]: https://github.com/cotes2020/chirpy-starter
|
||||||
[pages-workflow-src]: https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow
|
[pages-workflow-src]: https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow
|
||||||
[latest-tag]: https://github.com/cotes2020/jekyll-theme-chirpy/tags
|
[docker-desktop]: https://www.docker.com/products/docker-desktop/
|
||||||
|
[docker-engine]: https://docs.docker.com/engine/install/
|
||||||
|
[vscode]: https://code.visualstudio.com/
|
||||||
|
[dev-containers]: https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
|
||||||
|
[dc-clone-in-vol]: https://code.visualstudio.com/docs/devcontainers/containers#_quick-start-open-a-git-repository-or-github-pr-in-an-isolated-container-volume
|
||||||
|
[dc-open-in-container]: https://code.visualstudio.com/docs/devcontainers/containers#_quick-start-open-an-existing-folder-in-a-container
|
||||||
|
|||||||
73
_sass/abstracts/_breakpoints.scss
Normal file
73
_sass/abstracts/_breakpoints.scss
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
@use 'sass:map';
|
||||||
|
|
||||||
|
$-breakpoints: (
|
||||||
|
// 1 column
|
||||||
|
sm: 576px,
|
||||||
|
md: 768px,
|
||||||
|
// 2 columns
|
||||||
|
lg: 850px,
|
||||||
|
// 3 columns
|
||||||
|
xl: 1200px,
|
||||||
|
xxl: 1400px,
|
||||||
|
xxxl: 1650px
|
||||||
|
);
|
||||||
|
|
||||||
|
@function get($breakpoint) {
|
||||||
|
@return map.get($-breakpoints, $breakpoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Less than the given width */
|
||||||
|
@mixin lt($width) {
|
||||||
|
@media all and (max-width: calc(#{$width} - 1px)) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Less than or equal to the given width */
|
||||||
|
@mixin lte($width) {
|
||||||
|
@media all and (max-width: $width) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin sm {
|
||||||
|
@media all and (min-width: get(sm)) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin md {
|
||||||
|
@media all and (min-width: get(md)) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin lg {
|
||||||
|
@media all and (min-width: get(lg)) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin xl {
|
||||||
|
@media all and (min-width: get(xl)) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin xxl {
|
||||||
|
@media all and (min-width: get(xxl)) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin xxxl {
|
||||||
|
@media all and (min-width: get(xxxl)) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin between($min, $max) {
|
||||||
|
@media all and (min-width: $min) and (max-width: $max) {
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
4
_sass/abstracts/_index.scss
Normal file
4
_sass/abstracts/_index.scss
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
@forward 'variables';
|
||||||
|
@forward 'mixins';
|
||||||
|
@forward 'placeholders';
|
||||||
|
@forward 'breakpoints';
|
||||||
80
_sass/abstracts/_mixins.scss
Normal file
80
_sass/abstracts/_mixins.scss
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
@mixin text-ellipsis {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin mt-mb($value) {
|
||||||
|
margin-top: $value;
|
||||||
|
margin-bottom: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin ml-mr($value) {
|
||||||
|
margin-left: $value;
|
||||||
|
margin-right: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin pt-pb($val) {
|
||||||
|
padding-top: $val;
|
||||||
|
padding-bottom: $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 {
|
||||||
|
color: var(--text-muted-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin placeholder-focus {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin label($font-size: 1rem, $font-weight: 600, $color: var(--label-color)) {
|
||||||
|
color: $color;
|
||||||
|
font-size: $font-size;
|
||||||
|
font-weight: $font-weight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin align-center {
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin prompt($type, $fa-content, $fa-style: 'solid', $rotate: 0) {
|
||||||
|
&.prompt-#{$type} {
|
||||||
|
background-color: var(--prompt-#{$type}-bg);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: $fa-content;
|
||||||
|
color: var(--prompt-#{$type}-icon-color);
|
||||||
|
font: var(--fa-font-#{$fa-style});
|
||||||
|
|
||||||
|
@if $rotate != 0 {
|
||||||
|
transform: rotate(#{$rotate}deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin slide($append: null) {
|
||||||
|
$basic: transform 0.4s ease;
|
||||||
|
|
||||||
|
@if $append {
|
||||||
|
transition: $basic, $append;
|
||||||
|
} @else {
|
||||||
|
transition: $basic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin max-w-100 {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
@@ -1,24 +1,11 @@
|
|||||||
/*
|
@use 'variables' as v;
|
||||||
* Mainly scss modules, only imported to `assets/css/main.scss`
|
@use 'mixins' as mx;
|
||||||
*/
|
|
||||||
|
|
||||||
/* ---------- scss placeholder --------- */
|
|
||||||
|
|
||||||
%heading {
|
%heading {
|
||||||
color: var(--heading-color);
|
color: var(--heading-color);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
font-family: $font-family-heading;
|
font-family: v.$font-family-heading;
|
||||||
}
|
scroll-margin-top: 3.5rem;
|
||||||
|
|
||||||
%section {
|
|
||||||
main & {
|
|
||||||
margin-top: 2.5rem;
|
|
||||||
margin-bottom: 1.25rem;
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
outline: none; /* avoid outline in Safari */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%anchor {
|
%anchor {
|
||||||
@@ -92,7 +79,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
%rounded {
|
%rounded {
|
||||||
border-radius: $base-radius;
|
border-radius: v.$radius-lg;
|
||||||
}
|
}
|
||||||
|
|
||||||
%img-caption {
|
%img-caption {
|
||||||
@@ -122,8 +109,12 @@
|
|||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%text-ellipsis {
|
||||||
|
@include mx.text-ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
%text-highlight {
|
%text-highlight {
|
||||||
color: var(--text-muted-hightlight-color);
|
color: var(--text-muted-highlight-color);
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,56 +136,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------- scss mixin --------- */
|
%btn-color {
|
||||||
|
button i {
|
||||||
@mixin mt-mb($value) {
|
color: #999999;
|
||||||
margin-top: $value;
|
|
||||||
margin-bottom: $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin ml-mr($value) {
|
|
||||||
margin-left: $value;
|
|
||||||
margin-right: $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin pt-pb($val) {
|
|
||||||
padding-top: $val;
|
|
||||||
padding-bottom: $val;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin pl-pr($val) {
|
|
||||||
padding-left: $val;
|
|
||||||
padding-right: $val;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin placeholder {
|
|
||||||
color: var(--text-muted-color) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin placeholder-focus {
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin label($font-size: 1rem, $font-weight: 600, $color: var(--label-color)) {
|
|
||||||
color: $color;
|
|
||||||
font-size: $font-size;
|
|
||||||
font-weight: $font-weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin align-center {
|
|
||||||
position: relative;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin prompt($type, $fa-content, $fa-style: 'solid') {
|
|
||||||
&.prompt-#{$type} {
|
|
||||||
background-color: var(--prompt-#{$type}-bg);
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
content: $fa-content;
|
|
||||||
color: var(--prompt-#{$type}-icon-color);
|
|
||||||
font: var(--fa-font-#{$fa-style});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
%code-snippet-bg {
|
||||||
|
background-color: var(--highlight-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
%code-snippet-padding {
|
||||||
|
padding-left: 1rem;
|
||||||
|
padding-right: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
%max-w-100 {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
%panel-border {
|
||||||
|
border-left: 1px solid var(--main-border-color);
|
||||||
|
}
|
||||||
@@ -1,7 +1,3 @@
|
|||||||
/*
|
|
||||||
* The SCSS variables
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* sidebar */
|
/* sidebar */
|
||||||
|
|
||||||
$sidebar-width: 260px !default; /* the basic width */
|
$sidebar-width: 260px !default; /* the basic width */
|
||||||
@@ -16,7 +12,8 @@ $search-max-width: 200px !default;
|
|||||||
$footer-height: 5rem !default;
|
$footer-height: 5rem !default;
|
||||||
$footer-height-large: 6rem !default; /* screen width: < 850px */
|
$footer-height-large: 6rem !default; /* screen width: < 850px */
|
||||||
$main-content-max-width: 1250px !default;
|
$main-content-max-width: 1250px !default;
|
||||||
$base-radius: 0.625rem !default;
|
$radius-sm: 6px !default;
|
||||||
|
$radius-lg: 10px !default;
|
||||||
$back2top-size: 2.75rem !default;
|
$back2top-size: 2.75rem !default;
|
||||||
|
|
||||||
/* syntax highlight */
|
/* syntax highlight */
|
||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user