Compare commits
253 commits
Author | SHA1 | Date | |
---|---|---|---|
13f0eb7280 | |||
d549f0cb87 | |||
cd45cc4a60 | |||
75b7685363 | |||
d8e552fd18 | |||
59019bdaa8 | |||
245289e9ad | |||
0c8e50fb0e | |||
6dbf715aa5 | |||
8a9e09466c | |||
e7dd94c311 | |||
7fa39d2f17 | |||
b6723d6264 | |||
f650f0a582 | |||
7849a547cb | |||
89ddb9e9cd | |||
777ef6db0b | |||
9f587e71e7 | |||
e3f34bc6b7 | |||
4a02ad7692 | |||
17d29037ed | |||
dcf4b27a7a | |||
cef6f9be05 | |||
3b99e02782 | |||
e88eab0942 | |||
3e67e3a310 | |||
99dd009236 | |||
771c31cf6c | |||
cfb7af6313 | |||
22021775b6 | |||
8c239f8039 | |||
b0f2e6967c | |||
|
597b7f054d | ||
1892da053d | |||
4bdbf6d9da | |||
f489cd0531 | |||
7d0ea7f93c | |||
c2c1533c68 | |||
e81ba8b0aa | |||
02bbfa90fc | |||
94428ce0b2 | |||
dd99a9b433 | |||
bce4c71cce | |||
fe46634caa | |||
83e59fb385 | |||
a3a04dffa0 | |||
91c83197db | |||
2ea71d8f73 | |||
d216e1a03a | |||
288d1913c5 | |||
eead5f22b6 | |||
edf3c165e2 | |||
3ed4068a7a | |||
1fe8819a62 | |||
0127f66910 | |||
83abc30953 | |||
c842599b98 | |||
b099d6493a | |||
e15d0bc7ba | |||
c3fe15207b | |||
7b5e366190 | |||
1fa85ad116 | |||
cd795de254 | |||
1072e90309 | |||
0207c69dbb | |||
51162e0e83 | |||
8b1448ece2 | |||
75d8a58d5a | |||
3d7143e248 | |||
46c29e2d36 | |||
10482e2043 | |||
9b182762ac | |||
a80fa4eb04 | |||
1a1b06f8b6 | |||
45df394a6c | |||
2ac5780dd7 | |||
aaacb23922 | |||
ed410399da | |||
05847520e3 | |||
2258c29d38 | |||
74ebe95d84 | |||
3b986e5083 | |||
638dd5f9df | |||
a177cd0ebd | |||
0f3cc1cad7 | |||
dda7b9798d | |||
1a2bb1a04b | |||
ee7a1c179c | |||
a572d95fbc | |||
484213fe0c | |||
377d05a32c | |||
2b94110af6 | |||
43aeb033ec | |||
77266430d2 | |||
df3e411f6a | |||
22864c548c | |||
3e054ea47d | |||
642d32128a | |||
e16fbdea5a | |||
eda0c75632 | |||
d071e85a14 | |||
0b5346c623 | |||
|
d51345e297 | ||
|
2f844978aa | ||
|
42dea8ee29 | ||
|
86b13c917f | ||
c357435a9e | |||
c0d583aa9e | |||
effb91dff2 | |||
|
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 | ||
|
83689021be | ||
|
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 | ||
|
20987f2afe | ||
|
39e4338839 | ||
|
33a1fa7cae | ||
|
00a27a1b85 | ||
|
5cdde7dbc5 | ||
|
c4b58e3502 | ||
|
9630fd647f | ||
|
90a4cc76bb | ||
|
e33547fe5d | ||
|
09b300bc62 | ||
|
9ffd997c3b | ||
|
37827d81e5 | ||
|
febc01db52 | ||
|
b2245492e6 | ||
|
f87fdd0ea0 | ||
|
fdbd7f02e3 | ||
|
75891e714f | ||
|
363a3d936b | ||
|
ddb48eda52 | ||
|
c17fba44f5 | ||
|
12c340e98b | ||
|
dcb0add47b | ||
|
f1c6d2a817 | ||
|
05ebfb705e | ||
|
8608147fb5 | ||
|
76d58fe0ff | ||
|
b77767f76e | ||
|
e0950fc973 | ||
|
778ebdf250 | ||
|
796c386037 | ||
|
72d93b132f | ||
|
e09831ba3e | ||
|
05e3689d17 | ||
|
d4a6d640bd | ||
|
2cfa54847a | ||
|
cd37f63a01 | ||
|
015d5670a1 | ||
|
63c51384df | ||
|
662cd331e3 | ||
|
d013c11c8d | ||
|
fe7afa379f | ||
|
c85e9e2394 | ||
|
bf16d6039a | ||
|
8c1be9f2f3 | ||
|
7808ee157c | ||
|
1914c786a0 | ||
|
44f552cbce | ||
|
7d48d32c7b | ||
|
9f8aeaadbf | ||
|
61bdca2db4 | ||
|
23be4162b3 | ||
|
01076cb1c2 | ||
|
3cc1510071 | ||
|
950839175a | ||
|
13bf51e03d | ||
|
ce96d7e251 | ||
|
c5d5e1f75a | ||
|
319a082940 | ||
|
6044df4ff1 | ||
|
700fd5bad7 | ||
|
8e5fbb7a74 | ||
|
834931486d | ||
|
f865336c89 | ||
|
0f8e782bfd | ||
|
547b95cc7a | ||
|
2a7b56bb36 | ||
|
25c4166722 | ||
|
25b2ffa9ba | ||
|
8a2afae6ca | ||
|
6112b15b8e | ||
|
e24a0c73ba | ||
|
0f5abc82a2 | ||
|
4ddd5c4370 | ||
|
9592146ca3 | ||
|
8a1568c27a | ||
|
f8390d4384 | ||
|
e4363871b5 | ||
|
b641b3f1f2 | ||
|
5dbda0c09f |
216 changed files with 3209 additions and 1719 deletions
18
.cpanel.yml
18
.cpanel.yml
|
@ -1,18 +0,0 @@
|
||||||
deployment:
|
|
||||||
tasks:
|
|
||||||
- /bin/cp _site/404.html ~/public_html
|
|
||||||
- /bin/cp _site/feed.xml ~/public_html
|
|
||||||
- /bin/cp _site/index.html ~/public_html
|
|
||||||
- /bin/cp _site/redirects.json ~/public_html
|
|
||||||
- /bin/cp _site/robots.txt ~/public_html
|
|
||||||
- /bin/cp _site/sitemap.xml ~/public_html
|
|
||||||
- /bin/cp _site/sw.min.js ~/public_html
|
|
||||||
- /bin/cp -R _site/about ~/public_html
|
|
||||||
- /bin/cp -R _site/archives ~/public_html
|
|
||||||
- /bin/cp -R _site/assets ~/public_html
|
|
||||||
- /bin/cp -R _site/categories ~/public_html
|
|
||||||
- /bin/cp -R _site/donate ~/public_html
|
|
||||||
- /bin/cp -R _site/norobots ~/public_html
|
|
||||||
- /bin/cp -R _site/now ~/public_html
|
|
||||||
- /bin/cp -R _site/posts ~/public_html
|
|
||||||
- /bin/cp -R _site/tags ~/public_html
|
|
64
.forgejo/workflows/build_and_test.yml
Normal file
64
.forgejo/workflows/build_and_test.yml
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
name: "Build and Deploy Test Version (with Drafts) - next.asandikci.com"
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
paths-ignore:
|
||||||
|
- .gitignore
|
||||||
|
- README.md
|
||||||
|
- LICENSE
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
# Allow one concurrent deployment
|
||||||
|
concurrency:
|
||||||
|
group: "pages"
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-drafts-and-deploy:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: git.asandikci.com/docker-images/website_builder:latest
|
||||||
|
steps:
|
||||||
|
- name: Git Clone
|
||||||
|
run: |
|
||||||
|
git clone https://git.asandikci.com/asandikci.com/web
|
||||||
|
ls -la ./web
|
||||||
|
|
||||||
|
- name: Build Site (with Drafts!)
|
||||||
|
run: |
|
||||||
|
cd web
|
||||||
|
bundle install
|
||||||
|
bundle exec jekyll b --drafts
|
||||||
|
ls -la
|
||||||
|
pwd
|
||||||
|
env:
|
||||||
|
JEKYLL_ENV: "production"
|
||||||
|
|
||||||
|
# TODO: WILL BE FIXED
|
||||||
|
# - name: Test Site
|
||||||
|
# run: |
|
||||||
|
# cd web
|
||||||
|
# bundle exec htmlproofer _site \
|
||||||
|
# \-\-disable-external \
|
||||||
|
# \-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/"
|
||||||
|
|
||||||
|
- name: Deploy
|
||||||
|
run: |
|
||||||
|
mkdir deploy && cd deploy
|
||||||
|
cp -rfv ../web/_site .
|
||||||
|
cd _site
|
||||||
|
|
||||||
|
# CURRENTLY USING PURE STFP FOR AUTH ONLY
|
||||||
|
# TODO: CHANGE THIS
|
||||||
|
echo '${{ secrets.SFTP_PASSWORD }}' > ~/.passwd
|
||||||
|
chmod 0400 ~/.passwd
|
||||||
|
sshpass -f ~/.passwd sftp -oBatchMode=no -o StrictHostKeyChecking=accept-new -b - ${{ secrets.SFTP_USERNAME }}@${{ vars.SFTP_HOST }} << !
|
||||||
|
bye
|
||||||
|
!
|
||||||
|
lftp --user ${{ secrets.SFTP_USERNAME }} --password ${{ secrets.SFTP_PASSWORD }} sftp://${{ vars.SFTP_HOST }} -e "mirror -R --delete . www/"
|
67
.forgejo/workflows/deploy_prod.yml
Normal file
67
.forgejo/workflows/deploy_prod.yml
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
name: "Build and Deploy PRODUCTION Version - asandikci.com"
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
# Allow one concurrent deployment
|
||||||
|
concurrency:
|
||||||
|
group: "pages"
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push-prod:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: git.asandikci.com/docker-images/website_builder:latest
|
||||||
|
steps:
|
||||||
|
- name: Git Clone
|
||||||
|
run: |
|
||||||
|
git clone https://git.asandikci.com/asandikci.com/web
|
||||||
|
ls -la ./web
|
||||||
|
|
||||||
|
- name: Build Site
|
||||||
|
run: |
|
||||||
|
cd web
|
||||||
|
bundle install
|
||||||
|
bundle exec jekyll b
|
||||||
|
env:
|
||||||
|
JEKYLL_ENV: "production"
|
||||||
|
|
||||||
|
- name: Push to "website" branch
|
||||||
|
run: |
|
||||||
|
mkdir website_branch && cd website_branch
|
||||||
|
git clone https://git.asandikci.com/asandikci.com/web
|
||||||
|
cd web
|
||||||
|
git checkout website
|
||||||
|
rm -rfv ./_site/
|
||||||
|
cp -rfv ../../web/_site .
|
||||||
|
git config --global user.name "Aliberk Sandıkçı (CI)"
|
||||||
|
git config --global user.email git+ci@asandikci.com
|
||||||
|
git add -A
|
||||||
|
git commit --all --message "Updated! [CI]"
|
||||||
|
git push https://asandikci:${{ secrets.PUSH_KEY }}@git.asandikci.com/asandikci.com/web
|
||||||
|
|
||||||
|
|
||||||
|
publish:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: git.asandikci.com/docker-images/website_builder:latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout & Deploy
|
||||||
|
run: |
|
||||||
|
git clone https://git.asandikci.com/asandikci.com/web
|
||||||
|
cd web
|
||||||
|
git checkout website
|
||||||
|
cd _site
|
||||||
|
echo '${{ secrets.SFTP_PASSWORD_PROD }}' > ~/.passwd
|
||||||
|
chmod 0400 ~/.passwd
|
||||||
|
sshpass -f ~/.passwd sftp -oBatchMode=no -o StrictHostKeyChecking=accept-new -b - ${{ secrets.SFTP_USERNAME_PROD }}@${{ vars.SFTP_HOST_PROD }} << !
|
||||||
|
put -r . www/
|
||||||
|
bye
|
||||||
|
!
|
||||||
|
|
||||||
|
## TODO: WILL BE REPLACED WITH NEW LFTP SETUP !!!
|
|
@ -1,73 +0,0 @@
|
||||||
name: "Build and Deploy"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
paths-ignore:
|
|
||||||
- .gitignore
|
|
||||||
- README.md
|
|
||||||
- LICENSE
|
|
||||||
|
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pages: write
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
# Allow one concurrent deployment
|
|
||||||
concurrency:
|
|
||||||
group: "pages"
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
# submodules: true
|
|
||||||
# If using the 'assets' git submodule from Chirpy Starter, uncomment above
|
|
||||||
# (See: https://github.com/cotes2020/chirpy-starter/tree/main/assets)
|
|
||||||
|
|
||||||
- name: Setup Pages
|
|
||||||
id: pages
|
|
||||||
uses: actions/configure-pages@v4
|
|
||||||
|
|
||||||
- name: Setup Ruby
|
|
||||||
uses: ruby/setup-ruby@v1
|
|
||||||
with:
|
|
||||||
ruby-version: 3.2
|
|
||||||
bundler-cache: true
|
|
||||||
|
|
||||||
- name: Build site
|
|
||||||
run: bundle exec jekyll b -d "_site${{ steps.pages.outputs.base_path }}"
|
|
||||||
env:
|
|
||||||
JEKYLL_ENV: "production"
|
|
||||||
|
|
||||||
- name: Test site
|
|
||||||
run: |
|
|
||||||
bundle exec htmlproofer _site \
|
|
||||||
\-\-disable-external=true \
|
|
||||||
\-\-ignore-urls "/^http:\/\/127.0.0.1/,/^http:\/\/0.0.0.0/,/^http:\/\/localhost/"
|
|
||||||
|
|
||||||
- name: Upload site artifact
|
|
||||||
uses: actions/upload-pages-artifact@v3
|
|
||||||
with:
|
|
||||||
path: "_site${{ steps.pages.outputs.base_path }}"
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
environment:
|
|
||||||
name: github-pages
|
|
||||||
url: ${{ steps.deployment.outputs.page_url }}
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
needs: build
|
|
||||||
steps:
|
|
||||||
- name: Deploy to GitHub Pages
|
|
||||||
id: deployment
|
|
||||||
uses: actions/deploy-pages@v4
|
|
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -5,7 +5,8 @@ Gemfile.lock
|
||||||
|
|
||||||
# Jekyll cache
|
# Jekyll cache
|
||||||
.jekyll-cache
|
.jekyll-cache
|
||||||
# _site
|
.jekyll-metadata
|
||||||
|
_site
|
||||||
|
|
||||||
# RubyGems
|
# RubyGems
|
||||||
*.gem
|
*.gem
|
||||||
|
@ -16,5 +17,10 @@ package-lock.json
|
||||||
|
|
||||||
# IDE configurations
|
# IDE configurations
|
||||||
.idea
|
.idea
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
|
#_sass/dist
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
. "$(dirname "$0")/_/husky.sh"
|
|
||||||
|
|
||||||
npx --no -- commitlint --edit ${1}
|
|
8
.markdownlint.json
Normal file
8
.markdownlint.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"commands-show-output": false,
|
||||||
|
"blanks-around-fences": false,
|
||||||
|
"line-length": false,
|
||||||
|
"no-inline-html": {
|
||||||
|
"allowed_elements": ["kbd", "sub"]
|
||||||
|
}
|
||||||
|
}
|
11
.vscode/extensions.json
vendored
11
.vscode/extensions.json
vendored
|
@ -1,12 +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"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
14
.vscode/settings.json
vendored
14
.vscode/settings.json
vendored
|
@ -2,23 +2,29 @@
|
||||||
// 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"
|
||||||
},
|
},
|
||||||
|
"[markdown]": {
|
||||||
|
"editor.defaultFormatter": "yzhang.markdown-all-in-one"
|
||||||
|
},
|
||||||
// Formatter
|
// Formatter
|
||||||
"[html][liquid]": {
|
"[html][liquid]": {
|
||||||
"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."
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
6
Dockerfile
Normal file
6
Dockerfile
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
FROM bitnami/minideb:bookworm-arm64
|
||||||
|
|
||||||
|
RUN apt update -y
|
||||||
|
RUN apt upgrade -y
|
||||||
|
RUN apt install nodejs sshpass ruby jekyll ruby-html-proofer -y
|
||||||
|
|
13
Gemfile
13
Gemfile
|
@ -4,20 +4,11 @@ source "https://rubygems.org"
|
||||||
|
|
||||||
gemspec
|
gemspec
|
||||||
|
|
||||||
group :test do
|
gem "html-proofer", "~> 5.0", group: :test
|
||||||
gem "html-proofer", "~> 4.4"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
|
||||||
# and associated library.
|
|
||||||
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
||||||
gem "tzinfo", ">= 1", "< 3"
|
gem "tzinfo", ">= 1", "< 3"
|
||||||
gem "tzinfo-data"
|
gem "tzinfo-data"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Performance-booster for watching directories on Windows
|
gem "wdm", "~> 0.2.0", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||||
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
|
|
||||||
|
|
||||||
# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
|
|
||||||
# do not have a Java counterpart.
|
|
||||||
gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
|
|
||||||
|
|
25
README.md
25
README.md
|
@ -1,14 +1,16 @@
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
<div align="center">
|
<div align="center">
|
||||||
|
|
||||||
|
<!-- markdownlint-disable-next-line -->
|
||||||
# Chirpy Jekyll Theme
|
# Chirpy Jekyll Theme
|
||||||
|
|
||||||
A minimal, responsive, and feature-rich Jekyll theme for technical writing.
|
A minimal, responsive, and feature-rich Jekyll theme for technical writing.
|
||||||
|
|
||||||
[![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy?color=brightgreen)][gem]
|
[![CI](https://img.shields.io/github/actions/workflow/status/cotes2020/jekyll-theme-chirpy/ci.yml?logo=github)][ci]
|
||||||
[![CI](https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml/badge.svg?branch=master&event=push)][ci]
|
[![Codacy Badge](https://img.shields.io/codacy/grade/4e556876a3c54d5e8f2d2857c4f43894?logo=codacy)][codacy]
|
||||||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/4e556876a3c54d5e8f2d2857c4f43894)][codacy]
|
[![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy?color=goldenrod)][license]
|
||||||
[![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg)][license]
|
[![Gem Version](https://img.shields.io/gem/v/jekyll-theme-chirpy?&logo=RubyGems&logoColor=ghostwhite&label=gem&color=orange)][gem]
|
||||||
[![996.icu](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg)](https://996.icu)
|
[![Open in Dev Containers](https://img.shields.io/badge/Dev_Containers-Open-deepskyblue?logo=linuxcontainers)][open-container]
|
||||||
|
|
||||||
[**Live Demo** →][demo]
|
[**Live Demo** →][demo]
|
||||||
|
|
||||||
|
@ -18,7 +20,7 @@
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Dark / Light Theme Mode
|
- Dark Theme
|
||||||
- Localized UI language
|
- Localized UI language
|
||||||
- Pinned Posts on Home Page
|
- Pinned Posts on Home Page
|
||||||
- Hierarchical Categories
|
- Hierarchical Categories
|
||||||
|
@ -28,13 +30,13 @@
|
||||||
- Syntax Highlighting
|
- Syntax Highlighting
|
||||||
- Mathematical Expressions
|
- Mathematical Expressions
|
||||||
- Mermaid Diagrams & Flowcharts
|
- Mermaid Diagrams & Flowcharts
|
||||||
- Dark / Light Mode Images
|
- Dark Mode Images
|
||||||
- Embed Videos
|
- Embed Media
|
||||||
- Disqus / Giscus / Utterances Comments
|
- Comment Systems
|
||||||
- Built-in Search
|
- Built-in Search
|
||||||
- Atom Feeds
|
- Atom Feeds
|
||||||
- PWA
|
- PWA
|
||||||
- Google Analytics / GoatCounter
|
- Web Analytics
|
||||||
- SEO & Performance Optimization
|
- SEO & Performance Optimization
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
@ -54,7 +56,7 @@ For details, see the "[Contributing Guidelines][contribute-guide]".
|
||||||
Thanks to [all the contributors][contributors] involved in the development of the project!
|
Thanks to [all the contributors][contributors] involved in the development of the project!
|
||||||
|
|
||||||
[![all-contributors](https://contrib.rocks/image?repo=cotes2020/jekyll-theme-chirpy&columns=16)][contributors]
|
[![all-contributors](https://contrib.rocks/image?repo=cotes2020/jekyll-theme-chirpy&columns=16)][contributors]
|
||||||
<sub> —— Made with [contrib.rocks](https://contrib.rocks)</sub>
|
<sub> — Made with [contrib.rocks](https://contrib.rocks)</sub>
|
||||||
|
|
||||||
### Third-Party Assets
|
### Third-Party Assets
|
||||||
|
|
||||||
|
@ -70,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/
|
||||||
|
|
37
_config.yml
37
_config.yml
|
@ -1,13 +1,13 @@
|
||||||
# The Site Configuration
|
# The Site Configuration
|
||||||
theme: jekyll-theme-chirpy
|
theme: jekyll-theme-chirpy
|
||||||
lang: en
|
lang: en
|
||||||
timezone: Europe/Istanbul
|
timezone: Europe/Istanbul
|
||||||
|
|
||||||
# See for Jekyll SEO Tag Settings: https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md
|
# See for Jekyll SEO Tag Settings: https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md
|
||||||
|
|
||||||
title: Aliberk Sandıkçı
|
title: Aliberk Sandıkçı
|
||||||
tagline: Personal Website & Blog
|
tagline: Personal Website & Blog
|
||||||
description: >-
|
description: >-
|
||||||
Personal Website & Blog of Aliberk Sandıkçı
|
Personal Website & Blog of Aliberk Sandıkçı
|
||||||
|
|
||||||
url: "https://asandikci.com"
|
url: "https://asandikci.com"
|
||||||
|
@ -15,18 +15,28 @@ baseurl: "/"
|
||||||
|
|
||||||
forgejo:
|
forgejo:
|
||||||
username: asandikci
|
username: asandikci
|
||||||
domain: 'git.aliberksandikci.com.tr'
|
domain: "git.asandikci.com"
|
||||||
|
|
||||||
|
github:
|
||||||
|
username: asandikci
|
||||||
|
|
||||||
social:
|
social:
|
||||||
name: Aliberk Sandıkçı
|
name: Aliberk Sandıkçı
|
||||||
email: contact@aliberksandikci.com.tr
|
email: contact@aliberksandikci.com.tr
|
||||||
links:
|
links:
|
||||||
- https://git.aliberksandikci.com.tr/asandikci
|
- https://git.asandikci.com/asandikci
|
||||||
|
- https://github.com/asandikci
|
||||||
- https://mastodon.social/@asandikci
|
- https://mastodon.social/@asandikci
|
||||||
- https://www.linkedin.com/in/asandikci
|
- https://www.linkedin.com/in/asandikci
|
||||||
|
|
||||||
theme_mode: # [light | dark]
|
theme_mode: # [light | dark]
|
||||||
|
|
||||||
|
# Web Analytics Settings
|
||||||
|
analytics:
|
||||||
|
umami:
|
||||||
|
id: 80f4b239-3529-46be-b7a1-df82c6967a87
|
||||||
|
domain: https://analytics.yayindasin.org
|
||||||
|
|
||||||
# the avatar on sidebar, support local or CORS resources
|
# the avatar on sidebar, support local or CORS resources
|
||||||
avatar: https://asandikci.com/assets/img/pp.png
|
avatar: https://asandikci.com/assets/img/pp.png
|
||||||
|
|
||||||
|
@ -38,8 +48,9 @@ social_preview_image: # string, local or CORS resources
|
||||||
toc: true
|
toc: true
|
||||||
|
|
||||||
comments:
|
comments:
|
||||||
active: # The global switch for posts comments, e.g., 'disqus'. Keep it empty means disable
|
# Global switch for the post-comment system. Keeping it empty means disabled.
|
||||||
# The active options are as follows:
|
provider: # [disqus | utterances | giscus]
|
||||||
|
# The provider options are as follows:
|
||||||
disqus:
|
disqus:
|
||||||
shortname: # fill with the Disqus shortname. › https://help.disqus.com/en/articles/1717111-what-s-a-shortname
|
shortname: # fill with the Disqus shortname. › https://help.disqus.com/en/articles/1717111-what-s-a-shortname
|
||||||
# utterances settings › https://utteranc.es/
|
# utterances settings › https://utteranc.es/
|
||||||
|
@ -53,6 +64,7 @@ comments:
|
||||||
category:
|
category:
|
||||||
category_id:
|
category_id:
|
||||||
mapping: # optional, default to 'pathname'
|
mapping: # optional, default to 'pathname'
|
||||||
|
strict: # optional, default to '0'
|
||||||
input_position: # optional, default to 'bottom'
|
input_position: # optional, default to 'bottom'
|
||||||
lang: # optional, default to the value of `site.lang`
|
lang: # optional, default to the value of `site.lang`
|
||||||
reactions_enabled: # optional, default to the value of `1`
|
reactions_enabled: # optional, default to the value of `1`
|
||||||
|
@ -66,9 +78,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.
|
||||||
|
@ -80,6 +92,7 @@ paginate: 10
|
||||||
# ------------ The following options are not recommended to be modified ------------------
|
# ------------ The following options are not recommended to be modified ------------------
|
||||||
|
|
||||||
kramdown:
|
kramdown:
|
||||||
|
footnote_backlink: "↩︎"
|
||||||
syntax_highlighter: rouge
|
syntax_highlighter: rouge
|
||||||
syntax_highlighter_opts: # Rouge Options › https://github.com/jneen/rouge#full-options
|
syntax_highlighter_opts: # Rouge Options › https://github.com/jneen/rouge#full-options
|
||||||
css_class: highlight
|
css_class: highlight
|
||||||
|
@ -116,10 +129,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
|
||||||
|
@ -140,7 +149,7 @@ exclude:
|
||||||
- tools
|
- tools
|
||||||
- README.md
|
- README.md
|
||||||
- LICENSE
|
- LICENSE
|
||||||
- rollup.config.js
|
- "*.config.js"
|
||||||
- package*.json
|
- package*.json
|
||||||
|
|
||||||
jekyll-archives:
|
jekyll-archives:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
- type: forgejo
|
- type: forgejo
|
||||||
icon: "fa-solid fa-code-branch"
|
icon: "fa-solid fa-code-branch"
|
||||||
url: 'https://git.aliberksandikci.com.tr/'
|
url: 'https://git.asandikci.com/'
|
||||||
|
|
||||||
- type: xmpp
|
- type: xmpp
|
||||||
icon: 'fa fa-xmpp'
|
icon: 'fa fa-xmpp'
|
||||||
|
@ -28,10 +28,27 @@
|
||||||
icon: 'fa fa-instagram'
|
icon: 'fa fa-instagram'
|
||||||
url: 'https://instagram.com/aliberksandikci'
|
url: 'https://instagram.com/aliberksandikci'
|
||||||
|
|
||||||
- type: codeberg
|
# - type: codeberg
|
||||||
icon: 'fl-codeberg'
|
# icon: 'fl-codeberg'
|
||||||
url: 'https://codeberg.org/asandikci'
|
# url: 'https://codeberg.org/asandikci'
|
||||||
|
|
||||||
|
- type: github
|
||||||
|
icon: 'fab fa-github'
|
||||||
|
url: 'https://github.com/asandikci'
|
||||||
|
|
||||||
- type: rss
|
- type: rss
|
||||||
icon: "fas fa-rss"
|
icon: "fas fa-rss"
|
||||||
noblank: true
|
noblank: true
|
||||||
|
|
||||||
|
#
|
||||||
|
# - 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: 發現新版本更新。
|
||||||
|
|
18
_data/media.yml
Normal file
18
_data/media.yml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
- extension: mp3
|
||||||
|
mime_type: mpeg
|
||||||
|
- extension: mov
|
||||||
|
mime_type: quicktime
|
||||||
|
- extension: avi
|
||||||
|
mime_type: x-msvideo
|
||||||
|
- extension: mkv
|
||||||
|
mime_type: x-matroska
|
||||||
|
- extension: ogv
|
||||||
|
mime_type: ogg
|
||||||
|
- extension: weba
|
||||||
|
mime_type: webm
|
||||||
|
- extension: 3gp
|
||||||
|
mime_type: 3gpp
|
||||||
|
- extension: 3g2
|
||||||
|
mime_type: 3gpp2
|
||||||
|
- extension: mid
|
||||||
|
mime_type: midi
|
|
@ -4,13 +4,6 @@ webfonts: /assets/lib/fonts/main.css
|
||||||
|
|
||||||
# Libraries
|
# Libraries
|
||||||
|
|
||||||
jquery:
|
|
||||||
js: /assets/lib/jquery/jquery.min.js
|
|
||||||
|
|
||||||
bootstrap:
|
|
||||||
css: /assets/lib/bootstrap/bootstrap.min.css
|
|
||||||
js: /assets/lib/bootstrap/bootstrap.bundle.min.js
|
|
||||||
|
|
||||||
toc:
|
toc:
|
||||||
css: /assets/lib/tocbot/tocbot.min.css
|
css: /assets/lib/tocbot/tocbot.min.css
|
||||||
js: /assets/lib/tocbot/tocbot.min.js
|
js: /assets/lib/tocbot/tocbot.min.js
|
||||||
|
@ -27,13 +20,13 @@ 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
|
||||||
|
|
||||||
magnific-popup:
|
glightbox:
|
||||||
css: /assets/lib/magnific-popup/magnific-popup.css
|
css: /assets/lib/glightbox/glightbox.min.css
|
||||||
js: /assets/lib/magnific-popup/jquery.magnific-popup.min.js
|
js: /assets/lib/glightbox/glightbox.min.js
|
||||||
|
|
||||||
lazy-polyfill:
|
lazy-polyfill:
|
||||||
css: /assets/lib/loading-attribute-polyfill/loading-attribute-polyfill.min.css
|
css: /assets/lib/loading-attribute-polyfill/loading-attribute-polyfill.min.css
|
||||||
|
|
|
@ -1,32 +1,27 @@
|
||||||
# CDNs
|
# Resource Hints
|
||||||
|
resource_hints:
|
||||||
cdns:
|
|
||||||
# Google Fonts
|
|
||||||
- url: https://fonts.googleapis.com
|
- url: https://fonts.googleapis.com
|
||||||
|
links:
|
||||||
|
- rel: preconnect
|
||||||
|
- rel: dns-prefetch
|
||||||
- url: https://fonts.gstatic.com
|
- url: https://fonts.gstatic.com
|
||||||
args: crossorigin
|
links:
|
||||||
- url: https://fonts.googleapis.com
|
- rel: preconnect
|
||||||
# jsDelivr CDN
|
opts: [crossorigin]
|
||||||
|
- rel: dns-prefetch
|
||||||
- url: https://cdn.jsdelivr.net
|
- url: https://cdn.jsdelivr.net
|
||||||
# polyfill.io for math (cdnjs.cloudflare.com/polyfill)
|
links:
|
||||||
- url: https://cdnjs.cloudflare.com
|
- rel: preconnect
|
||||||
|
- rel: dns-prefetch
|
||||||
|
|
||||||
# fonts
|
# Web Fonts
|
||||||
|
webfonts: https://fonts.googleapis.com/css2?family=Lato:wght@300;400&family=Source+Sans+Pro:wght@400;600;700;900&display=swap
|
||||||
webfonts: https://fonts.googleapis.com/css2?family=Lato&family=Source+Sans+Pro:wght@400;600;700;900&display=swap
|
|
||||||
|
|
||||||
# Libraries
|
# Libraries
|
||||||
|
|
||||||
jquery:
|
|
||||||
js: https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js
|
|
||||||
|
|
||||||
bootstrap:
|
|
||||||
css: https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css
|
|
||||||
js: https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js
|
|
||||||
|
|
||||||
toc:
|
toc:
|
||||||
css: https://cdn.jsdelivr.net/npm/tocbot@4.25.0/dist/tocbot.min.css
|
css: https://cdn.jsdelivr.net/npm/tocbot@4.29.0/dist/tocbot.min.css
|
||||||
js: https://cdn.jsdelivr.net/npm/tocbot@4.25.0/dist/tocbot.min.js
|
js: https://cdn.jsdelivr.net/npm/tocbot@4.29.0/dist/tocbot.min.js
|
||||||
|
|
||||||
fontlogos:
|
fontlogos:
|
||||||
css: https://cdn.jsdelivr.net/npm/font-logos@1/assets/font-logos.css
|
css: https://cdn.jsdelivr.net/npm/font-logos@1/assets/font-logos.css
|
||||||
|
@ -35,7 +30,7 @@ forkawesome:
|
||||||
css: https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css
|
css: https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css
|
||||||
|
|
||||||
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.6.0/css/all.min.css
|
||||||
|
|
||||||
ballooncss:
|
ballooncss:
|
||||||
css: https://unpkg.com/balloon-css/balloon.min.css
|
css: https://unpkg.com/balloon-css/balloon.min.css
|
||||||
|
@ -44,18 +39,18 @@ 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.8.0/dist/mermaid.min.js
|
js: https://cdn.jsdelivr.net/npm/mermaid@11.0.2/dist/mermaid.min.js
|
||||||
|
|
||||||
dayjs:
|
dayjs:
|
||||||
js:
|
js:
|
||||||
common: https://cdn.jsdelivr.net/npm/dayjs@1.11.10/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.10/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.10/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.10/plugin/localizedFormat.min.js
|
localizedFormat: https://cdn.jsdelivr.net/npm/dayjs@1.11.13/plugin/localizedFormat.js
|
||||||
|
|
||||||
magnific-popup:
|
glightbox:
|
||||||
css: https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/magnific-popup.min.css
|
css: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/css/glightbox.min.css
|
||||||
js: https://cdn.jsdelivr.net/npm/magnific-popup@1.1.0/dist/jquery.magnific-popup.min.js
|
js: https://cdn.jsdelivr.net/npm/glightbox@3.3.0/dist/js/glightbox.min.js
|
||||||
|
|
||||||
lazy-polyfill:
|
lazy-polyfill:
|
||||||
css: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.min.css
|
css: https://cdn.jsdelivr.net/npm/loading-attribute-polyfill@2.1.1/dist/loading-attribute-polyfill.min.css
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
platforms:
|
platforms:
|
||||||
|
|
||||||
- type: Linkedin
|
- type: Linkedin
|
||||||
icon: "fab fa-linkedin"
|
icon: "fab fa-linkedin"
|
||||||
link: "https://www.linkedin.com/sharing/share-offsite/?url=URL"
|
link: "https://www.linkedin.com/sharing/share-offsite/?url=URL"
|
||||||
|
@ -15,7 +14,7 @@ platforms:
|
||||||
- label: fosstodon.org
|
- label: fosstodon.org
|
||||||
link: "https://fosstodon.org/"
|
link: "https://fosstodon.org/"
|
||||||
- label: mastodon.com.tr
|
- label: mastodon.com.tr
|
||||||
link: "https://mastodon.com.tr/"
|
link: "https://mastodon.com.tr/"
|
||||||
|
|
||||||
- type: Twitter
|
- type: Twitter
|
||||||
icon: "fa-brands fa-square-x-twitter"
|
icon: "fa-brands fa-square-x-twitter"
|
||||||
|
@ -28,3 +27,50 @@ platforms:
|
||||||
- type: Telegram
|
- type: Telegram
|
||||||
icon: "fab fa-telegram"
|
icon: "fab fa-telegram"
|
||||||
link: "https://t.me/share/url?url=URL&text=TITLE"
|
link: "https://t.me/share/url?url=URL&text=TITLE"
|
||||||
|
|
||||||
|
- 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"
|
||||||
|
|
||||||
|
# Uncomment below if you need to.
|
||||||
|
#
|
||||||
|
# - type: Linkedin
|
||||||
|
# icon: "fab fa-linkedin"
|
||||||
|
# link: "https://www.linkedin.com/sharing/share-offsite/?url=URL"
|
||||||
|
#
|
||||||
|
# - type: Weibo
|
||||||
|
# icon: "fab fa-weibo"
|
||||||
|
# link: "https://service.weibo.com/share/share.php?title=TITLE&url=URL"
|
||||||
|
#
|
||||||
|
# - type: Mastodon
|
||||||
|
# icon: "fa-brands fa-mastodon"
|
||||||
|
# # See: https://github.com/justinribeiro/share-to-mastodon#properties
|
||||||
|
# instances:
|
||||||
|
# - label: mastodon.social
|
||||||
|
# link: "https://mastodon.social/"
|
||||||
|
# - label: mastodon.online
|
||||||
|
# link: "https://mastodon.online/"
|
||||||
|
# - label: fosstodon.org
|
||||||
|
# link: "https://fosstodon.org/"
|
||||||
|
# - label: 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"
|
||||||
|
|
56
_drafts/2024-07-22-pardus-ve-windows.md
Normal file
56
_drafts/2024-07-22-pardus-ve-windows.md
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
---
|
||||||
|
title: "Pardus/Linux Yanına Windows Kurulumu"
|
||||||
|
date: 2024-07-22 10:00:00 +3000
|
||||||
|
categories: Linux
|
||||||
|
tags: pardus linux
|
||||||
|
author: asandikci
|
||||||
|
image:
|
||||||
|
path: https://4.bp.blogspot.com/-7lTiQNNrJjI/WAojkdqEvNI/AAAAAAAAAVI/IcAysrVEssYmTxQIi7t6nCRy5TtQXCXHACLcB/w1200-h630-p-k-no-nu/112159e69714e8cab4e1ab16f57447cb5e2559476e001.jpg
|
||||||
|
alt: "Pardus ve Windows"
|
||||||
|
---
|
||||||
|
|
||||||
|
GNU/Linux - Pardus işletim sistemi bir bilgisayar kullanıcısının isteyebileceği her türlü programı/kolaylığı sağlamakta. Lakin çeşitli programların yapımcıları tarafından Linux için desteklenmemesi (Adobe Programları gibi) veya oyunlarda bulunan çeşitli hile engelleme sistemlerinin Linux için portlanmamış olması (Valorant, LOL, Roblox vb.) sebebi ile Windows bir makineye hâlen bağımlılığınız bulunuyor olabilir. Bu tarz bir durumda **Pardus ile Windows'u birlikte kullanmak** gibi çok güzel bir seçeneğe sahibiz. Eğer Pardus'u denemek için indirdiyseniz silip Windows kurmadan önce bu seçeneği bir değerlendirin derim. Eğer yeterince disk alanınız varsa (ben en az 256GiB öneriyorum) **dual boot** dediğimiz iki sistemi aynı anda kullanma işlemini gerçekleştirmeniz için bu yazıyı yazmak istedim. Kolaylıklar dilerim
|
||||||
|
|
||||||
|
### Not
|
||||||
|
|
||||||
|
Bu yazı, Pardus'un yanına -> Windows kurmak içindir. Eğer Windows'un yanına -> Pardus kurmak istiyorsanız, Pardus sitesindeki yazıyı takip edebiliirsiniz: https://www.pardus.org.tr/windows-ile-dual-boot-olusturma/
|
||||||
|
|
||||||
|
### Windows'a bağımlığınızın olup olmadığını öğrenin !
|
||||||
|
|
||||||
|
Linux'te oynayabileceğiniz / oynayamayacağınız oyunlar: https://protondb.com
|
||||||
|
Desteklenen / Desteklenmeyen anticheat sistemleri: https://areweanticheatyet.com/
|
||||||
|
Popüler uygulamalara alternatifler: https://alternativeto.net
|
||||||
|
|
||||||
|
# Ön Gereklilikler
|
||||||
|
|
||||||
|
- En az 1 USB Bellek
|
||||||
|
- Pardus/Linux Kurulu bir makine (**64 Bit**)
|
||||||
|
- Mümkünse Ortalama/Hızlı bir internet bağlantısı _veya_ sabır
|
||||||
|
|
||||||
|
## Uyarı
|
||||||
|
|
||||||
|
- Sisteminizdeki önemli dosyaları yedek almanızı öneriyorum. Bu işlem kurulu olan Pardus sistemine _ufak bir ihtimal de olsa_ zarar verebilir
|
||||||
|
|
||||||
|
### Tahmini Süre
|
||||||
|
|
||||||
|
- 2-3 Saat (imaj dosyalarının indirilmesi hariç)
|
||||||
|
|
||||||
|
# Adımlar
|
||||||
|
|
||||||
|
- **Ventoy** programını Pardus mağaza üzerinden indiriniz ve Ventoy programını USB belleğinize kurunuz.
|
||||||
|
- Pardus/Linux sisteminizin yerini azaltmak için GParted uygulamasının **imaj (.iso)** dosyasını indiriniz, dosyanın doğruluğunu kontrol ediniz ve Ventoy'a (USB belleğinize) atınız.
|
||||||
|
- indirme linki: <https://downloads.sourceforge.net/gparted/gparted-live-1.6.0-3-amd64.iso>
|
||||||
|
- dosya kontrol linki: <https://gparted.org/gparted-live/stable/CHECKSUMS.TXT>
|
||||||
|
- tüm indirme seçenekleri: <https://gparted.org/download.php>
|
||||||
|
- Windows veya Pardus'un yanına kurmak istediğiniz herhangi bir İmaj (.iso) dosyasını indirin. Bu imaj dosyasını da Ventoy'a (USB Belleğinize) atınız
|
||||||
|
- Son olarak olası bir sıkıntıda GRUB (başlatma) ekranına erişim için BootRepair uygulamasının imaj dosyasını indirip USB Belleğe atınız (zorunlu değil ama kurtarma adımları için hayat kurtarabilir). İndirme linki: <https://sourceforge.net/projects/boot-repair-cd/files/latest/download>
|
||||||
|
|
||||||
|
- Tüm İndirme ve USB Belleğe atma işlemleri bittiğinde dosyaları doğrulamak için mümkünse Hash değerlerini kontrol edin. Veya en azından `sync` komutunu herhangi bir terminalde çalıştırarak komutun sonlanmasını bekleyin (duruma göre 15dk+ bekletebilir). Bu komut tüm verilerin USB Belleğe yazıldığında emin olmanızı sağlar. Sonrasında USB Belleğinizi isterseniz çıkarabilirsiniz.
|
||||||
|
- USB Belleğinizi cihazınıza takın. Bilgisayarınızı Yeniden başlatın ve Boot Tuşuna basarak cihazınızın başlatma menüsüne girin. Sonrasında _Ventoy_, _USB_ veya USB belleğinizin markasının isminin olduğu seçeneği seçiniz.
|
||||||
|
- Eğer her şey yolunda giderse içinde 3 tane .iso dosyasının bulunduğu bir ekran açılmış olacak. İlk önce Gparted (`gparted-live*.iso`) dosyasını seçiniz.
|
||||||
|
|
||||||
|
### Sıradaki adımlar Kısaca (sonradan güncellenecek)
|
||||||
|
|
||||||
|
- GParted üzerinden Pardus'un kurulu olduğu diski küçültün
|
||||||
|
- Windows'u kalan boş alana kurun
|
||||||
|
- Kurulum sonrasında ya BootRepair uygulamasını kullanın ya da Pardus'a bir şekilde girip boot-repair komutunu kullanın
|
14
_drafts/2024-07-31-tusas-gezisi.md
Normal file
14
_drafts/2024-07-31-tusas-gezisi.md
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
title: "TUSAŞ Gezisi"
|
||||||
|
date: 2024-07-31 10:00:00 +3000
|
||||||
|
categories: Trip
|
||||||
|
tags: tusaş trip
|
||||||
|
author: asandikci
|
||||||
|
image:
|
||||||
|
path: https://trthaberstatic.cdn.wp.trt.com.tr/resimler/2022000/tusas-trt-haber-2022093.jpg
|
||||||
|
alt: "Türk Havacılık ve Uzay Sanayii AŞ"
|
||||||
|
---
|
||||||
|
|
||||||
|
Geçtiğimiz gün, 2024 tercih dönemi kapsamında bilgilendirme amaçlı TUSAŞ'ın düzenlediği geziye okulum İzmir Fen Lisesi adına katıldım. Her ne kadar havacılık konusunda pek bir bilgim olmasa da aldığım notlardan ve geziye dair deneyimlerim ile ilgili ufak bir yazı yazmak istedim. İyi okumalar
|
||||||
|
|
||||||
|
7 otobüs olarak TUSAŞ'a doğru yola çıktık. Girişte telefonlarımız toplandı ve otobüslerden inip konferans salonuna geçtik.
|
7
_includes/analytics/cloudflare.html
Normal file
7
_includes/analytics/cloudflare.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<!-- Cloudflare Web Analytics -->
|
||||||
|
<script
|
||||||
|
defer
|
||||||
|
src="https://static.cloudflareinsights.com/beacon.min.js"
|
||||||
|
data-cf-beacon='{"token": "{{ site.analytics.cloudflare.id }}"}'
|
||||||
|
></script>
|
||||||
|
<!-- End Cloudflare Web Analytics -->
|
7
_includes/analytics/fathom.html
Normal file
7
_includes/analytics/fathom.html
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<!-- Fathom -->
|
||||||
|
<script
|
||||||
|
src="https://cdn.usefathom.com/script.js"
|
||||||
|
data-site="{{ site.analytics.fathom.id }}"
|
||||||
|
defer>
|
||||||
|
</script>
|
||||||
|
<!-- End Fathom Code -->
|
6
_includes/analytics/goatcounter.html
Normal file
6
_includes/analytics/goatcounter.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<!-- GoatCounter -->
|
||||||
|
<script
|
||||||
|
async
|
||||||
|
src="https://gc.zgo.at/count.js"
|
||||||
|
data-goatcounter="https://{{ site.analytics.goatcounter.id }}.goatcounter.com/count"
|
||||||
|
></script>
|
13
_includes/analytics/google.html
Normal file
13
_includes/analytics/google.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
|
<script defer src="https://www.googletagmanager.com/gtag/js?id={{ site.analytics.google.id }}"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function (event) {
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag() {
|
||||||
|
dataLayer.push(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtag('js', new Date());
|
||||||
|
gtag('config', '{{ site.analytics.google.id }}');
|
||||||
|
});
|
||||||
|
</script>
|
14
_includes/analytics/matomo.html
Normal file
14
_includes/analytics/matomo.html
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<!-- Matomo -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
var _paq = window._paq = window._paq || [];
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
|
_paq.push(['enableLinkTracking']);
|
||||||
|
(function() {
|
||||||
|
var u="//{{ site.analytics.matomo.domain }}/";
|
||||||
|
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||||
|
_paq.push(['setSiteId', {{ site.analytics.matomo.id }}]);
|
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
|
g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- End Matomo Code -->
|
6
_includes/analytics/umami.html
Normal file
6
_includes/analytics/umami.html
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<!-- Umami -->
|
||||||
|
<script
|
||||||
|
defer
|
||||||
|
src="{{ site.analytics.umami.domain }}/script.js"
|
||||||
|
data-website-id="{{ site.analytics.umami.id }}"
|
||||||
|
></script>
|
|
@ -1,5 +1,5 @@
|
||||||
<!-- The comments switcher -->
|
<!-- The comments switcher -->
|
||||||
{% if page.comments and site.comments.active %}
|
{% if page.comments and site.comments.provider %}
|
||||||
{% capture path %}comments/{{ site.comments.active }}.html{% endcapture %}
|
{% capture path %}comments/{{ site.comments.provider }}.html{% endcapture %}
|
||||||
{% include {{ path }} %}
|
{% include {{ path }} %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
this.page.identifier = '{{ page.url }}';
|
this.page.identifier = '{{ page.url }}';
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Lazy loading */
|
{%- comment -%} Lazy loading {%- endcomment -%}
|
||||||
var disqus_observer = new IntersectionObserver(
|
var disqus_observer = new IntersectionObserver(
|
||||||
function (entries) {
|
function (entries) {
|
||||||
if (entries[0].isIntersecting) {
|
if (entries[0].isIntersecting) {
|
||||||
|
@ -28,12 +28,12 @@
|
||||||
{ threshold: [0] }
|
{ threshold: [0] }
|
||||||
);
|
);
|
||||||
|
|
||||||
disqus_observer.observe(document.querySelector('#disqus_thread'));
|
disqus_observer.observe(document.getElementById('disqus_thread'));
|
||||||
|
|
||||||
/* Auto switch theme */
|
{%- comment -%} Auto switch theme {%- endcomment -%}
|
||||||
function reloadDisqus() {
|
function reloadDisqus() {
|
||||||
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
||||||
/* Disqus hasn't been loaded */
|
{%- comment -%} Disqus hasn't been loaded {%- endcomment -%}
|
||||||
if (typeof DISQUS === 'undefined') {
|
if (typeof DISQUS === 'undefined') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (document.querySelector('.mode-toggle')) {
|
if (document.getElementById('mode-toggle')) {
|
||||||
window.addEventListener('message', reloadDisqus);
|
window.addEventListener('message', reloadDisqus);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
(function () {
|
(function () {
|
||||||
const origin = 'https://giscus.app';
|
const origin = 'https://giscus.app';
|
||||||
const iframe = 'iframe.giscus-frame';
|
|
||||||
const lightTheme = 'light';
|
const lightTheme = 'light';
|
||||||
const darkTheme = 'dark_dimmed';
|
const darkTheme = 'dark_dimmed';
|
||||||
|
|
||||||
|
@ -18,6 +17,12 @@
|
||||||
initTheme = darkTheme;
|
initTheme = darkTheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let lang = '{{ site.comments.giscus.lang | default: lang }}';
|
||||||
|
{%- comment -%} https://github.com/giscus/giscus/tree/main/locales {%- endcomment -%}
|
||||||
|
if (lang.length > 2 && !lang.startsWith('zh')) {
|
||||||
|
lang = lang.slice(0, 2);
|
||||||
|
}
|
||||||
|
|
||||||
let giscusAttributes = {
|
let giscusAttributes = {
|
||||||
src: 'https://giscus.app/client.js',
|
src: 'https://giscus.app/client.js',
|
||||||
'data-repo': '{{ site.comments.giscus.repo}}',
|
'data-repo': '{{ site.comments.giscus.repo}}',
|
||||||
|
@ -25,11 +30,12 @@
|
||||||
'data-category': '{{ site.comments.giscus.category }}',
|
'data-category': '{{ site.comments.giscus.category }}',
|
||||||
'data-category-id': '{{ site.comments.giscus.category_id }}',
|
'data-category-id': '{{ site.comments.giscus.category_id }}',
|
||||||
'data-mapping': '{{ site.comments.giscus.mapping | default: 'pathname' }}',
|
'data-mapping': '{{ site.comments.giscus.mapping | default: 'pathname' }}',
|
||||||
|
'data-strict' : '{{ site.comments.giscus.strict | default: '0' }}',
|
||||||
'data-reactions-enabled': '{{ site.comments.giscus.reactions_enabled | default: '1' }}',
|
'data-reactions-enabled': '{{ site.comments.giscus.reactions_enabled | default: '1' }}',
|
||||||
'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: ''
|
||||||
|
@ -47,7 +53,7 @@
|
||||||
event.data &&
|
event.data &&
|
||||||
event.data.direction === ModeToggle.ID
|
event.data.direction === ModeToggle.ID
|
||||||
) {
|
) {
|
||||||
/* global theme mode changed */
|
{%- comment -%} global theme mode changed {%- endcomment -%}
|
||||||
const mode = event.data.message;
|
const mode = event.data.message;
|
||||||
const theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
|
const theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
|
||||||
|
|
||||||
|
@ -57,7 +63,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const giscus = document.querySelector(iframe).contentWindow;
|
const giscus = document.getElementsByClassName('giscus-frame')[0].contentWindow;
|
||||||
giscus.postMessage({ giscus: message }, origin);
|
giscus.postMessage({ giscus: message }, origin);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
(function () {
|
(function () {
|
||||||
const origin = 'https://utteranc.es';
|
const origin = 'https://utteranc.es';
|
||||||
const iframe = 'iframe.utterances-frame';
|
|
||||||
const lightTheme = 'github-light';
|
const lightTheme = 'github-light';
|
||||||
const darkTheme = 'github-dark';
|
const darkTheme = 'github-dark';
|
||||||
let initTheme = lightTheme;
|
let initTheme = lightTheme;
|
||||||
|
@ -26,12 +25,12 @@
|
||||||
addEventListener('message', (event) => {
|
addEventListener('message', (event) => {
|
||||||
let theme;
|
let theme;
|
||||||
|
|
||||||
/* credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347> */
|
{%- comment -%} credit to <https://github.com/utterance/utterances/issues/170#issuecomment-594036347> {%- endcomment -%}
|
||||||
if (event.origin === origin) {
|
if (event.origin === origin) {
|
||||||
/* page initial */
|
{%- comment -%} page initial {%- endcomment -%}
|
||||||
theme = initTheme;
|
theme = initTheme;
|
||||||
} else if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
} else if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
||||||
/* global theme mode changed */
|
{%- comment -%} global theme mode changed {%- endcomment -%}
|
||||||
const mode = event.data.message;
|
const mode = event.data.message;
|
||||||
theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
|
theme = mode === ModeToggle.DARK_MODE ? darkTheme : lightTheme;
|
||||||
} else {
|
} else {
|
||||||
|
@ -43,7 +42,7 @@
|
||||||
theme: theme
|
theme: theme
|
||||||
};
|
};
|
||||||
|
|
||||||
const utterances = document.querySelector(iframe).contentWindow;
|
const utterances = document.getElementsByClassName('utterances-frame')[0].contentWindow;
|
||||||
utterances.postMessage(message, origin);
|
utterances.postMessage(message, origin);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
35
_includes/embed/audio.html
Normal file
35
_includes/embed/audio.html
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{% assign src = include.src | strip %}
|
||||||
|
{% assign title = include.title | strip %}
|
||||||
|
{% assign types = include.types | default: '' | strip | split: '|' %}
|
||||||
|
|
||||||
|
{% unless src contains '://' %}
|
||||||
|
{%- capture src -%}
|
||||||
|
{% include media-url.html src=src subpath=page.media_subpath %}
|
||||||
|
{%- endcapture -%}
|
||||||
|
{% endunless %}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<audio class="embed-audio" controls>
|
||||||
|
{% assign extension = src | split: '.' | last %}
|
||||||
|
{% assign types = extension | concat: types %}
|
||||||
|
|
||||||
|
{% assign ext_size = extension | size %}
|
||||||
|
{% assign src_size = src | size %}
|
||||||
|
{% assign slice_size = src_size | minus: ext_size %}
|
||||||
|
|
||||||
|
{% assign filepath = src | slice: 0, slice_size %}
|
||||||
|
|
||||||
|
{% for type in types %}
|
||||||
|
{% assign src = filepath | append: type %}
|
||||||
|
{% assign media_item = site.data.media | find: 'extension', type %}
|
||||||
|
{% assign mime_type = media_item.mime_type | default: type %}
|
||||||
|
<source src="{{ src }}" type="audio/{{ mime_type }}">
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
Your browser does not support the audio tag. Here is a
|
||||||
|
<a href="{{ src | strip }}">link to the audio file</a> instead.
|
||||||
|
</audio>
|
||||||
|
{% if title %}
|
||||||
|
<em>{{ title }}</em>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
|
@ -1,10 +1,9 @@
|
||||||
<iframe
|
<iframe
|
||||||
class="embed-video bilibili"
|
class="embed-video"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
src="https://player.bilibili.com/player.html?bvid={{ include.id }}"
|
src="https://player.bilibili.com/player.html?bvid={{ include.id }}"
|
||||||
scrolling="no"
|
scrolling="no"
|
||||||
border="0"
|
frameborder="0"
|
||||||
frameborder="no"
|
|
||||||
framespacing="0"
|
framespacing="0"
|
||||||
allowfullscreen="true"
|
allowfullscreen="true"
|
||||||
></iframe>
|
></iframe>
|
||||||
|
|
59
_includes/embed/video.html
Normal file
59
_includes/embed/video.html
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
{% assign video_url = include.src %}
|
||||||
|
{% assign title = include.title %}
|
||||||
|
{% assign poster_url = include.poster %}
|
||||||
|
{% assign types = include.types | default: '' | strip | split: '|' %}
|
||||||
|
|
||||||
|
{% unless video_url contains '://' %}
|
||||||
|
{%- capture video_url -%}
|
||||||
|
{% include media-url.html src=video_url subpath=page.media_subpath %}
|
||||||
|
{%- endcapture -%}
|
||||||
|
{% endunless %}
|
||||||
|
|
||||||
|
{% if poster_url %}
|
||||||
|
{% unless poster_url contains '://' %}
|
||||||
|
{%- capture poster_url -%}
|
||||||
|
{% include media-url.html src=poster_url subpath=page.media_subpath %}
|
||||||
|
{%- endcapture -%}
|
||||||
|
{% endunless %}
|
||||||
|
{% assign poster = 'poster="' | append: poster_url | append: '"' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% assign attributes = 'controls' %}
|
||||||
|
|
||||||
|
{% if include.autoplay %}
|
||||||
|
{% assign attributes = attributes | append: ' ' | append: 'autoplay' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if include.loop %}
|
||||||
|
{% assign attributes = attributes | append: ' ' | append: 'loop' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if include.muted %}
|
||||||
|
{% assign attributes = attributes | append: ' ' | append: 'muted' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<video class="embed-video file" {{ poster }} {{ attributes }}>
|
||||||
|
{% assign extension = video_url | split: '.' | last %}
|
||||||
|
{% assign types = extension | concat: types %}
|
||||||
|
|
||||||
|
{% assign ext_size = extension | size %}
|
||||||
|
{% assign src_size = video_url | size %}
|
||||||
|
{% assign slice_size = src_size | minus: ext_size %}
|
||||||
|
|
||||||
|
{% assign filepath = video_url | slice: 0, slice_size %}
|
||||||
|
|
||||||
|
{% for type in types %}
|
||||||
|
{% assign src = filepath | append: type %}
|
||||||
|
{% assign media_item = site.data.media | find: 'extension', type %}
|
||||||
|
{% assign mime_type = media_item.mime_type | default: type %}
|
||||||
|
<source src="{{ src }}" type="video/{{ mime_type }}">
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
Your browser does not support the video tag. Here is a
|
||||||
|
<a href="{{ video_url | strip }}">link to the video file</a> instead.
|
||||||
|
</video>
|
||||||
|
{% if title %}
|
||||||
|
<em>{{ title }}</em>
|
||||||
|
{% endif %}
|
||||||
|
</p>
|
|
@ -1,5 +1,5 @@
|
||||||
<iframe
|
<iframe
|
||||||
class="embed-video youtube"
|
class="embed-video"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
src="https://www.youtube.com/embed/{{ include.id }}"
|
src="https://www.youtube.com/embed/{{ include.id }}"
|
||||||
title="YouTube video player"
|
title="YouTube video player"
|
||||||
|
|
|
@ -34,7 +34,14 @@
|
||||||
{%- endcapture -%}
|
{%- endcapture -%}
|
||||||
|
|
||||||
{%- capture _theme -%}
|
{%- capture _theme -%}
|
||||||
<a href="https://github.com/cotes2020/jekyll-theme-chirpy" target="_blank" rel="noopener">Chirpy</a>
|
<a
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="top"
|
||||||
|
title="v{{ theme.version }}"
|
||||||
|
href="https://github.com/cotes2020/jekyll-theme-chirpy"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>Chirpy</a>
|
||||||
{%- endcapture -%}
|
{%- endcapture -%}
|
||||||
|
|
||||||
{{ site.data.locales[include.lang].meta | replace: ':PLATFORM', _platform | replace: ':THEME', _theme }}
|
{{ site.data.locales[include.lang].meta | replace: ':PLATFORM', _platform | replace: ':THEME', _theme }}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
<!-- GoatCounter -->
|
|
||||||
|
|
||||||
<script
|
|
||||||
data-goatcounter="https://{{ site.goatcounter.id }}.goatcounter.com/count"
|
|
||||||
async
|
|
||||||
src="https://gc.zgo.at/count.js"
|
|
||||||
></script>
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
<!--
|
|
||||||
The GA snippet
|
|
||||||
-->
|
|
||||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
|
||||||
<script defer src="https://www.googletagmanager.com/gtag/js?id={{ site.google_analytics.id }}"></script>
|
|
||||||
<script>
|
|
||||||
document.addEventListener("DOMContentLoaded", function(event) {
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
function gtag(){dataLayer.push(arguments);}
|
|
||||||
|
|
||||||
gtag('js', new Date());
|
|
||||||
gtag('config', '{{ site.google_analytics.id }}');
|
|
||||||
});
|
|
||||||
</script>
|
|
|
@ -1,120 +1,128 @@
|
||||||
<head>
|
<head>
|
||||||
<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
|
||||||
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e">
|
name="theme-color"
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
media="(prefers-color-scheme: light)"
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
content="#f7f7f7"
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
name="theme-color"
|
||||||
|
media="(prefers-color-scheme: dark)"
|
||||||
|
content="#1b1b1e"
|
||||||
|
/>
|
||||||
|
<meta name="mobile-web-app-capable" content="yes" />
|
||||||
|
<meta
|
||||||
|
name="apple-mobile-web-app-status-bar-style"
|
||||||
|
content="black-translucent"
|
||||||
|
/>
|
||||||
<meta
|
<meta
|
||||||
name="viewport"
|
name="viewport"
|
||||||
content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover"
|
content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover"
|
||||||
>
|
/>
|
||||||
|
|
||||||
{%- capture seo_tags -%}
|
{%- capture seo_tags -%} {% seo title=false %} {%- endcapture -%}
|
||||||
{% seo title=false %}
|
|
||||||
{%- endcapture -%}
|
|
||||||
|
|
||||||
<!-- Setup Open Graph image -->
|
<!-- Setup Open Graph image -->
|
||||||
|
|
||||||
{% if page.image %}
|
{% if page.image %} {% assign src = page.image.path | default: page.image %}
|
||||||
{% assign src = page.image.path | default: page.image %}
|
{% unless src contains '://' %} {%- capture img_url -%} {% include
|
||||||
|
media-url.html src=src subpath=page.media_subpath absolute=true %} {%-
|
||||||
{% unless src contains '://' %}
|
endcapture -%} {%- capture old_url -%}{{ src | absolute_url }}{%- endcapture
|
||||||
{%- capture img_url -%}
|
-%} {%- capture new_url -%}{{ img_url }}{%- endcapture -%} {% assign seo_tags
|
||||||
{% include img-url.html src=src img_path=page.img_path absolute=true %}
|
= seo_tags | replace: old_url, new_url %} {% endunless %} {% elsif
|
||||||
{%- endcapture -%}
|
site.social_preview_image %} {%- capture img_url -%} {% include media-url.html
|
||||||
|
src=site.social_preview_image absolute=true %} {%- endcapture -%} {%- capture
|
||||||
{%- capture old_url -%}{{ src | absolute_url }}{%- endcapture -%}
|
og_image -%}
|
||||||
{%- capture new_url -%}{{ img_url }}{%- endcapture -%}
|
<meta property="og:image" content="{{ img_url }}" />
|
||||||
|
{%- endcapture -%} {%- capture twitter_image -%}
|
||||||
{% assign seo_tags = seo_tags | replace: old_url, new_url %}
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
{% endunless %}
|
<meta property="twitter:image" content="{{ img_url }}" />
|
||||||
|
{%- endcapture -%} {% assign old_meta_clip = '
|
||||||
{% elsif site.social_preview_image %}
|
<meta name="twitter:card" content="summary" />
|
||||||
{%- capture img_url -%}
|
' %} {% assign new_meta_clip = og_image | append: twitter_image %} {% assign
|
||||||
{% include img-url.html src=site.social_preview_image absolute=true %}
|
seo_tags = seo_tags | replace: old_meta_clip, new_meta_clip %} {% endif %} {{
|
||||||
{%- endcapture -%}
|
seo_tags }}
|
||||||
|
|
||||||
{%- capture og_image -%}
|
|
||||||
<meta property="og:image" content="{{ img_url }}" />
|
|
||||||
{%- endcapture -%}
|
|
||||||
|
|
||||||
{%- capture twitter_image -%}
|
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
|
||||||
<meta property="twitter:image" content="{{ img_url }}" />
|
|
||||||
{%- endcapture -%}
|
|
||||||
|
|
||||||
{% assign old_meta_clip = '<meta name="twitter:card" content="summary" />' %}
|
|
||||||
{% assign new_meta_clip = og_image | append: twitter_image %}
|
|
||||||
{% assign seo_tags = seo_tags | replace: old_meta_clip, new_meta_clip %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{{ seo_tags }}
|
|
||||||
|
|
||||||
<title>
|
<title>
|
||||||
{%- unless page.layout == 'home' -%}
|
{%- unless page.layout == 'home' -%} {{ page.title | append: ' | ' }} {%-
|
||||||
{{ page.title | append: ' | ' }}
|
endunless -%} {{ site.title }}
|
||||||
{%- endunless -%}
|
|
||||||
{{ site.title }}
|
|
||||||
</title>
|
</title>
|
||||||
|
|
||||||
{% include_cached favicons.html %}
|
{% include_cached favicons.html %}
|
||||||
|
|
||||||
{% if site.resources.ignore_env != jekyll.environment and site.resources.self_hosted %}
|
<!-- Resource Hints -->
|
||||||
<link href="{{ site.data.origin[type].webfonts | relative_url }}" rel="stylesheet">
|
{% unless site.assets.self_host.enabled %} {% for hint in
|
||||||
|
site.data.origin.cors.resource_hints %} {% for link in hint.links %} <link
|
||||||
{% else %}
|
rel="{{ link.rel }}" href="{{ hint.url }}" {{ link.opts | join: ' ' }}> {%
|
||||||
{% for cdn in site.data.origin[type].cdns %}
|
endfor %} {% endfor %} {% endunless %}
|
||||||
<link rel="preconnect" href="{{ cdn.url }}" {{ cdn.args }}>
|
|
||||||
<link rel="dns-prefetch" href="{{ cdn.url }}" {{ cdn.args }}>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ site.data.origin[type].webfonts | relative_url }}">
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- GA -->
|
|
||||||
{% if jekyll.environment == 'production' and site.google_analytics.id != empty and site.google_analytics.id %}
|
|
||||||
<link rel="preconnect" href="https://www.google-analytics.com" crossorigin="use-credentials">
|
|
||||||
<link rel="dns-prefetch" href="https://www.google-analytics.com">
|
|
||||||
|
|
||||||
<link rel="preconnect" href="https://www.googletagmanager.com" crossorigin="anonymous">
|
|
||||||
<link rel="dns-prefetch" href="https://www.googletagmanager.com">
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<!-- Bootstrap -->
|
<!-- Bootstrap -->
|
||||||
<link rel="stylesheet" href="{{ site.data.origin[type].bootstrap.css | relative_url }}">
|
{% unless jekyll.environment == 'production' %}
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"
|
||||||
|
/>
|
||||||
|
{% endunless %}
|
||||||
|
|
||||||
<!-- Font Logos -->
|
<!-- Font Logos -->
|
||||||
<link rel="stylesheet" href="{{ site.data.origin[type].fontlogos.css | relative_url }}" >
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="{{ site.data.origin[type].fontlogos.css | relative_url }}"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Font Awesome -->
|
<!-- Font Awesome Icons -->
|
||||||
<link rel="stylesheet" href="{{ site.data.origin[type].fontawesome.css | relative_url }}">
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="{{ site.data.origin[type].fontawesome.css | relative_url }}"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Fork Awesome -->
|
<!-- Fork Awesome [added by asandikci] -->
|
||||||
<link rel="stylesheet" href="{{ site.data.origin[type].forkawesome.css | relative_url }}" integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="{{ site.data.origin[type].forkawesome.css | relative_url }}"
|
||||||
|
integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY="
|
||||||
|
crossorigin="anonymous"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Balloon CSS -->
|
<!-- Balloon CSS [added by asandikci] -->
|
||||||
<link rel="stylesheet" href="{{ site.data.origin[type].ballooncss.css | relative_url }}">
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="{{ site.data.origin[type].ballooncss.css | relative_url }}"
|
||||||
|
/>
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ '/assets/css/:THEME.css' | replace: ':THEME', site.theme | relative_url }}">
|
<!-- Theme style -->
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="{{ '/assets/css/:THEME.css' | replace: ':THEME', site.theme | relative_url }}"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- Web Font -->
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="{{ site.data.origin[type].webfonts | relative_url }}"
|
||||||
|
/>
|
||||||
|
|
||||||
{% if site.toc and page.toc %}
|
{% if site.toc and page.toc %}
|
||||||
<link rel="stylesheet" href="{{ site.data.origin[type].toc.css | relative_url }}">
|
<link
|
||||||
{% endif %}
|
rel="stylesheet"
|
||||||
|
href="{{ site.data.origin[type].toc.css | relative_url }}"
|
||||||
{% if page.layout == 'post' or page.layout == 'page' or page.layout == 'home' %}
|
/>
|
||||||
<link rel="stylesheet" href="{{ site.data.origin[type]['lazy-polyfill'].css | relative_url }}">
|
{% endif %} {% if page.layout == 'post' or page.layout == 'page' or
|
||||||
{% endif %}
|
page.layout == 'home' %}
|
||||||
|
<link
|
||||||
{% if page.layout == 'page' or page.layout == 'post' %}
|
rel="stylesheet"
|
||||||
<!-- Manific Popup -->
|
href="{{ site.data.origin[type]['lazy-polyfill'].css | relative_url }}"
|
||||||
<link rel="stylesheet" href="{{ site.data.origin[type].magnific-popup.css | relative_url }}">
|
/>
|
||||||
|
{% endif %} {% if page.layout == 'page' or page.layout == 'post' %}
|
||||||
|
<!-- Image Popup -->
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="{{ site.data.origin[type].glightbox.css | relative_url }}"
|
||||||
|
/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- JavaScript -->
|
<!-- JavaScript -->
|
||||||
|
|
||||||
{% unless site.theme_mode %}
|
{% unless site.theme_mode %} {% include mode-toggle.html %} {% endunless %} {%
|
||||||
{% include mode-toggle.html %}
|
include metadata-hook.html %}
|
||||||
{% endunless %}
|
|
||||||
|
|
||||||
{% include metadata-hook.html %}
|
|
||||||
</head>
|
</head>
|
||||||
|
|
|
@ -3,17 +3,10 @@
|
||||||
<!-- commons -->
|
<!-- commons -->
|
||||||
<script src="/assets/js/user/copy.js"></script>
|
<script src="/assets/js/user/copy.js"></script>
|
||||||
|
|
||||||
{% assign urls = site.data.origin[type].jquery.js
|
{% assign urls = site.data.origin[type].search.js %}
|
||||||
| append: ','
|
|
||||||
| append: site.data.origin[type].bootstrap.js
|
|
||||||
| append: ','
|
|
||||||
| append: site.data.origin[type].search.js
|
|
||||||
%}
|
|
||||||
|
|
||||||
<!-- 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 %}
|
||||||
|
|
||||||
|
@ -21,7 +14,7 @@
|
||||||
<!-- image lazy-loading & popup & clipboard -->
|
<!-- image lazy-loading & popup & clipboard -->
|
||||||
{% assign urls = urls
|
{% assign urls = urls
|
||||||
| append: ','
|
| append: ','
|
||||||
| append: site.data.origin[type]['magnific-popup'].js
|
| append: site.data.origin[type].glightbox.js
|
||||||
| append: ','
|
| append: ','
|
||||||
| append: site.data.origin[type].clipboard.js
|
| append: site.data.origin[type].clipboard.js
|
||||||
%}
|
%}
|
||||||
|
@ -34,7 +27,7 @@
|
||||||
or page.layout == 'category'
|
or page.layout == 'category'
|
||||||
or page.layout == 'tag'
|
or page.layout == 'tag'
|
||||||
%}
|
%}
|
||||||
{% assign locale = site.lang | split: '-' | first %}
|
{% assign locale = include.lang | split: '-' | first %}
|
||||||
|
|
||||||
{% assign urls = urls
|
{% assign urls = urls
|
||||||
| append: ','
|
| append: ','
|
||||||
|
@ -68,47 +61,50 @@
|
||||||
{% 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 defer src="{{ script | relative_url }}"></script>
|
|
||||||
|
<script src="{{ script | relative_url }}"></script>
|
||||||
|
|
||||||
{% if page.math %}
|
{% if page.math %}
|
||||||
<!-- MathJax -->
|
<!-- MathJax -->
|
||||||
<script>
|
<script src="{{ '/assets/js/data/mathjax.js' | relative_url }}"></script>
|
||||||
/* see: <https://docs.mathjax.org/en/latest/options/input/tex.html#tex-options> */
|
|
||||||
MathJax = {
|
|
||||||
tex: {
|
|
||||||
/* start/end delimiter pairs for in-line math */
|
|
||||||
inlineMath: [
|
|
||||||
['$', '$'],
|
|
||||||
['\\(', '\\)']
|
|
||||||
],
|
|
||||||
/* start/end delimiter pairs for display math */
|
|
||||||
displayMath: [
|
|
||||||
['$$', '$$'],
|
|
||||||
['\\[', '\\]']
|
|
||||||
],
|
|
||||||
/* equation numbering */
|
|
||||||
tags: 'ams'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<script src="https://cdnjs.cloudflare.com/polyfill/v3/polyfill.min.js?features=es6"></script>
|
<script 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 %}
|
||||||
|
|
||||||
|
<!-- Pageviews -->
|
||||||
|
{% if page.layout == 'post' %}
|
||||||
|
{% assign provider = site.pageviews.provider %}
|
||||||
|
|
||||||
|
{% if provider and provider != empty %}
|
||||||
|
{% case provider %}
|
||||||
|
{% when 'goatcounter' %}
|
||||||
|
{% if site.analytics[provider].id != empty and site.analytics[provider].id %}
|
||||||
|
{% include pageviews/{{ provider }}.html %}
|
||||||
|
{% endif %}
|
||||||
|
{% endcase %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if page.mermaid %}
|
||||||
|
{% include mermaid.html %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% if jekyll.environment == 'production' %}
|
{% if jekyll.environment == 'production' %}
|
||||||
<!-- PWA -->
|
<!-- PWA -->
|
||||||
{% if site.pwa.enabled %}
|
{% if site.pwa.enabled %}
|
||||||
<script defer src="{{ 'app.min.js' | prepend: js_dist | relative_url }}"></script>
|
<script
|
||||||
|
defer
|
||||||
|
src="{{ 'app.min.js' | relative_url }}?baseurl={{ site.baseurl | default: '' }}®ister={{ site.pwa.cache.enabled }}"
|
||||||
|
></script>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- GA -->
|
<!-- Web Analytics -->
|
||||||
{% if site.google_analytics.id != empty and site.google_analytics.id %}
|
{% for analytics in site.analytics %}
|
||||||
{% include google-analytics.html %}
|
{% capture str %}{{ analytics }}{% endcapture %}
|
||||||
{% endif %}
|
{% assign type = str | split: '{' | first %}
|
||||||
|
{% if site.analytics[type].id and site.analytics[type].id != empty %}
|
||||||
<!-- GoatCounter -->
|
{% include analytics/{{ type }}.html %}
|
||||||
{% if site.goatcounter.id != empty and site.goatcounter.id %}
|
{% endif %}
|
||||||
{% include goatcounter.html %}
|
{% endfor %}
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
{% comment %}
|
{% comment %}
|
||||||
Detect appearance language and return it through variable "lang"
|
Detect appearance language and return it through variable "lang"
|
||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% if site.data.locales[site.lang] %}
|
{% if site.data.locales[page.lang] %}
|
||||||
|
{% assign lang = page.lang %}
|
||||||
|
{% elsif site.data.locales[site.lang] %}
|
||||||
{% assign lang = site.lang %}
|
{% assign lang = site.lang %}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% assign lang = 'en' %}
|
{% assign lang = 'en' %}
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
{%- comment -%}
|
{%- comment -%}
|
||||||
Generate image final URL based on `site.img_cdn`, `page.img_path`
|
Generate media resource final URL based on `site.cdn`, `page.media_subpath`
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
src - required, basic image path
|
src - required, basic media resources path
|
||||||
img_path - optional, relative path of image
|
subpath - optional, relative path of media resources
|
||||||
absolute - optional, boolean, if true, generate absolute URL
|
absolute - optional, boolean, if true, generate absolute URL
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
image URL
|
media resources URL
|
||||||
{%- endcomment -%}
|
{%- endcomment -%}
|
||||||
|
|
||||||
{% assign url = include.src %}
|
{% assign url = include.src %}
|
||||||
|
|
||||||
{%- if url -%}
|
{%- if url -%}
|
||||||
{% unless url contains ':' %}
|
{% unless url contains ':' %}
|
||||||
{%- comment -%} Add page image path prefix {%- endcomment -%}
|
{%- comment -%} Add media resources subpath prefix {%- endcomment -%}
|
||||||
{% assign url = include.img_path | default: '' | append: '/' | append: url %}
|
{% assign url = include.subpath | default: '' | append: '/' | append: url %}
|
||||||
|
|
||||||
{%- comment -%} Prepend CND URL {%- endcomment -%}
|
{%- comment -%} Prepend CND URL {%- endcomment -%}
|
||||||
{% if site.img_cdn %}
|
{% if site.cdn %}
|
||||||
{% assign url = site.img_cdn | append: '/' | append: url %}
|
{% assign url = site.cdn | append: '/' | append: url %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% assign url = url | replace: '///', '/' | replace: '//', '/' | replace: ':/', '://' %}
|
{% assign url = url | replace: '///', '/' | replace: '//', '/' | replace: ':/', '://' %}
|
|
@ -1,29 +1,33 @@
|
||||||
<!-- mermaid-js loader -->
|
<!-- mermaid-js loader -->
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
(function () {
|
function updateMermaid(event) {
|
||||||
function updateMermaid(event) {
|
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
||||||
if (event.source === window && event.data && event.data.direction === ModeToggle.ID) {
|
const mode = event.data.message;
|
||||||
const mode = event.data.message;
|
|
||||||
|
|
||||||
if (typeof mermaid === 'undefined') {
|
if (typeof mermaid === 'undefined') {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
let expectedTheme = mode === ModeToggle.DARK_MODE ? 'dark' : 'default';
|
|
||||||
let config = { theme: expectedTheme };
|
|
||||||
|
|
||||||
/* Re-render the SVG › <https://github.com/mermaid-js/mermaid/issues/311#issuecomment-332557344> */
|
|
||||||
$('.mermaid').each(function () {
|
|
||||||
let svgCode = $(this).prev().children().html();
|
|
||||||
$(this).removeAttr('data-processed');
|
|
||||||
$(this).html(svgCode);
|
|
||||||
});
|
|
||||||
|
|
||||||
mermaid.initialize(config);
|
|
||||||
mermaid.init(undefined, '.mermaid');
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
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';
|
let initTheme = 'default';
|
||||||
const html = document.documentElement;
|
const html = document.documentElement;
|
||||||
|
|
||||||
|
@ -35,15 +39,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let mermaidConf = {
|
let mermaidConf = {
|
||||||
theme: initTheme /* <default|dark|forest|neutral> */
|
theme: initTheme {%- comment -%} <default | dark | forest | neutral> {%- endcomment -%}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Create mermaid tag */
|
{%- comment -%} Create mermaid tag {%- endcomment -%}
|
||||||
document.querySelectorAll('pre>code.language-mermaid').forEach((elem) => {
|
const basicList = document.getElementsByClassName('language-mermaid');
|
||||||
|
[...basicList].forEach((elem) => {
|
||||||
const svgCode = elem.textContent;
|
const svgCode = elem.textContent;
|
||||||
const backup = elem.parentElement;
|
const backup = elem.parentElement;
|
||||||
backup.classList.add('unloaded');
|
backup.classList.add('d-none');
|
||||||
/* create mermaid node */
|
{%- comment -%} create mermaid node {%- endcomment -%}
|
||||||
let mermaid = document.createElement('pre');
|
let mermaid = document.createElement('pre');
|
||||||
mermaid.classList.add('mermaid');
|
mermaid.classList.add('mermaid');
|
||||||
const text = document.createTextNode(svgCode);
|
const text = document.createTextNode(svgCode);
|
||||||
|
@ -52,7 +57,6 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
mermaid.initialize(mermaidConf);
|
mermaid.initialize(mermaidConf);
|
||||||
|
|
||||||
window.addEventListener('message', updateMermaid);
|
window.addEventListener('message', updateMermaid);
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -19,45 +19,32 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
if (this.hasMode) {
|
|
||||||
if (this.isDarkMode) {
|
|
||||||
if (!this.isSysDarkPrefer) {
|
|
||||||
this.setDark();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.isSysDarkPrefer) {
|
|
||||||
this.setLight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
/* always follow the system prefers */
|
{%- comment -%} always follow the system prefers {%- endcomment -%}
|
||||||
this.sysDarkPrefers.addEventListener('change', () => {
|
this.sysDarkPrefers.addEventListener('change', () => {
|
||||||
if (self.hasMode) {
|
if (self.hasMode) {
|
||||||
if (self.isDarkMode) {
|
|
||||||
if (!self.isSysDarkPrefer) {
|
|
||||||
self.setDark();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (self.isSysDarkPrefer) {
|
|
||||||
self.setLight();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.clearMode();
|
self.clearMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.notify();
|
self.notify();
|
||||||
});
|
});
|
||||||
} /* constructor() */
|
|
||||||
|
if (!this.hasMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isDarkMode) {
|
||||||
|
this.setDark();
|
||||||
|
} else {
|
||||||
|
this.setLight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get sysDarkPrefers() {
|
get sysDarkPrefers() {
|
||||||
return window.matchMedia('(prefers-color-scheme: dark)');
|
return window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
}
|
}
|
||||||
|
|
||||||
get isSysDarkPrefer() {
|
get isPreferDark() {
|
||||||
return this.sysDarkPrefers.matches;
|
return this.sysDarkPrefers.matches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,10 +52,6 @@
|
||||||
return this.mode === ModeToggle.DARK_MODE;
|
return this.mode === ModeToggle.DARK_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isLightMode() {
|
|
||||||
return this.mode === ModeToggle.LIGHT_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
get hasMode() {
|
get hasMode() {
|
||||||
return this.mode != null;
|
return this.mode != null;
|
||||||
}
|
}
|
||||||
|
@ -77,12 +60,12 @@
|
||||||
return sessionStorage.getItem(ModeToggle.MODE_KEY);
|
return sessionStorage.getItem(ModeToggle.MODE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the current mode on screen */
|
{%- comment -%} get the current mode on screen {%- endcomment -%}
|
||||||
get modeStatus() {
|
get modeStatus() {
|
||||||
if (this.isDarkMode || (!this.hasMode && this.isSysDarkPrefer)) {
|
if (this.hasMode) {
|
||||||
return ModeToggle.DARK_MODE;
|
return this.mode;
|
||||||
} else {
|
} else {
|
||||||
return ModeToggle.LIGHT_MODE;
|
return this.isPreferDark ? ModeToggle.DARK_MODE : ModeToggle.LIGHT_MODE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +84,9 @@
|
||||||
sessionStorage.removeItem(ModeToggle.MODE_KEY);
|
sessionStorage.removeItem(ModeToggle.MODE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Notify another plugins that the theme mode has changed */
|
{%- comment -%}
|
||||||
|
Notify another plugins that the theme mode has changed
|
||||||
|
{%- endcomment -%}
|
||||||
notify() {
|
notify() {
|
||||||
window.postMessage(
|
window.postMessage(
|
||||||
{
|
{
|
||||||
|
@ -114,21 +99,9 @@
|
||||||
|
|
||||||
flipMode() {
|
flipMode() {
|
||||||
if (this.hasMode) {
|
if (this.hasMode) {
|
||||||
if (this.isSysDarkPrefer) {
|
this.clearMode();
|
||||||
if (this.isLightMode) {
|
|
||||||
this.clearMode();
|
|
||||||
} else {
|
|
||||||
this.setLight();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.isDarkMode) {
|
|
||||||
this.clearMode();
|
|
||||||
} else {
|
|
||||||
this.setDark();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (this.isSysDarkPrefer) {
|
if (this.isPreferDark) {
|
||||||
this.setLight();
|
this.setLight();
|
||||||
} else {
|
} else {
|
||||||
this.setDark();
|
this.setDark();
|
||||||
|
@ -136,8 +109,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.notify();
|
this.notify();
|
||||||
} /* flipMode() */
|
}
|
||||||
} /* ModeToggle */
|
}
|
||||||
|
|
||||||
const modeToggle = new ModeToggle();
|
const modeToggle = new ModeToggle();
|
||||||
</script>
|
</script>
|
||||||
|
|
19
_includes/pageviews/goatcounter.html
Normal file
19
_includes/pageviews/goatcounter.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<!-- Display GoatCounter pageviews -->
|
||||||
|
<script>
|
||||||
|
let pv = document.getElementById('pageviews');
|
||||||
|
|
||||||
|
if (pv !== null) {
|
||||||
|
const uri = location.pathname.replace(/\/$/, '');
|
||||||
|
const url = `https://{{ site.analytics.goatcounter.id }}.goatcounter.com/counter/${encodeURIComponent(uri)}.json`;
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((data) => {
|
||||||
|
const count = data.count.replace(/\s/g, '');
|
||||||
|
pv.innerText = new Intl.NumberFormat().format(count);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
pv.innerText = '1';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
16
_includes/post-description.html
Normal file
16
_includes/post-description.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{%- comment -%}
|
||||||
|
Get post description or generate it from the post content.
|
||||||
|
{%- endcomment -%}
|
||||||
|
|
||||||
|
{%- assign max_length = include.max_length | default: 200 -%}
|
||||||
|
|
||||||
|
{%- capture description -%}
|
||||||
|
{%- if post.description -%}
|
||||||
|
{{- post.description -}}
|
||||||
|
{%- else -%}
|
||||||
|
{%- include no-linenos.html content=post.content -%}
|
||||||
|
{{- content | markdownify | strip_html -}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endcapture -%}
|
||||||
|
|
||||||
|
{{- description | strip | truncate: max_length | escape -}}
|
|
@ -97,7 +97,7 @@
|
||||||
{% assign _lazyload = true %}
|
{% assign _lazyload = true %}
|
||||||
|
|
||||||
{%- capture _img_url -%}
|
{%- capture _img_url -%}
|
||||||
{% include img-url.html src=_src img_path=page.img_path %}
|
{% include media-url.html src=_src subpath=page.media_subpath %}
|
||||||
{%- endcapture -%}
|
{%- endcapture -%}
|
||||||
|
|
||||||
{% assign _path_prefix = _img_url | remove: _src %}
|
{% assign _path_prefix = _img_url | remove: _src %}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
{% assign match_posts = match_posts | push: site.tags[tag] | uniq %}
|
{% assign match_posts = match_posts | push: site.tags[tag] | uniq %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
|
{% assign match_posts = match_posts | reverse %}
|
||||||
{% assign last_index = match_posts.size | minus: 1 %}
|
{% assign last_index = match_posts.size | minus: 1 %}
|
||||||
{% assign score_list = '' | split: '' %}
|
{% assign score_list = '' | split: '' %}
|
||||||
|
|
||||||
|
@ -81,10 +82,7 @@
|
||||||
{% include datetime.html date=post.date lang=include.lang %}
|
{% include datetime.html date=post.date lang=include.lang %}
|
||||||
<h4 class="pt-0 my-2">{{ post.title }}</h4>
|
<h4 class="pt-0 my-2">{{ post.title }}</h4>
|
||||||
<div class="text-muted">
|
<div class="text-muted">
|
||||||
<p>
|
<p>{% include post-description.html %}</p>
|
||||||
{% include no-linenos.html content=post.content %}
|
|
||||||
{{ content | markdownify | strip_html | truncate: 200 | escape }}
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
{% 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>
|
||||||
/* Note: dependent library will be loaded in `js-selector.html` */
|
{%- comment -%} Note: dependent library will be loaded in `js-selector.html` {%- endcomment -%}
|
||||||
SimpleJekyllSearch({
|
SimpleJekyllSearch({
|
||||||
searchInput: document.getElementById('search-input'),
|
searchInput: document.getElementById('search-input'),
|
||||||
resultsContainer: document.getElementById('search-results'),
|
resultsContainer: document.getElementById('search-results'),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<!-- The Search results -->
|
<!-- The Search results -->
|
||||||
|
|
||||||
<div id="search-result-wrapper" class="d-flex justify-content-center unloaded">
|
<div id="search-result-wrapper" class="d-flex justify-content-center d-none">
|
||||||
<div class="col-11 content">
|
<div class="col-11 content">
|
||||||
<div id="search-hints">
|
<div id="search-hints">
|
||||||
{% include_cached trending-tags.html %}
|
{% include_cached trending-tags.html %}
|
||||||
|
|
|
@ -5,15 +5,13 @@
|
||||||
<a href="{{ '/' | relative_url }}" id="avatar" class="rounded-circle">
|
<a href="{{ '/' | relative_url }}" id="avatar" class="rounded-circle">
|
||||||
{%- if site.avatar != empty and site.avatar -%}
|
{%- if site.avatar != empty and site.avatar -%}
|
||||||
{%- capture avatar_url -%}
|
{%- capture avatar_url -%}
|
||||||
{% include img-url.html src=site.avatar %}
|
{% include media-url.html src=site.avatar %}
|
||||||
{%- endcapture -%}
|
{%- endcapture -%}
|
||||||
<img src="{{- avatar_url -}}" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
|
<img src="{{- avatar_url -}}" width="112" height="112" alt="avatar" onerror="this.style.display='none'">
|
||||||
{%- 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 -->
|
||||||
|
@ -44,7 +42,7 @@
|
||||||
|
|
||||||
<div class="sidebar-bottom d-flex flex-wrap align-items-center w-100">
|
<div class="sidebar-bottom d-flex flex-wrap align-items-center w-100">
|
||||||
{% unless site.theme_mode %}
|
{% unless site.theme_mode %}
|
||||||
<button type="button" class="mode-toggle btn" aria-label="Switch Mode">
|
<button type="button" class="btn btn-link nav-link" aria-label="Switch Mode" id="mode-toggle">
|
||||||
<i class="fas fa-adjust"></i>
|
<i class="fas fa-adjust"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|
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,8 @@
|
||||||
{% 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="ps-0 pe-4">
|
<section id="toc-wrapper" class="ps-0 pe-4">
|
||||||
<h2 class="panel-heading ps-3 pt-2 mb-2">{{- site.data.locales[include.lang].panel.toc -}}</h2>
|
<h2 class="panel-heading ps-3 mb-2">{{- site.data.locales[include.lang].panel.toc -}}</h2>
|
||||||
<nav id="toc"></nav>
|
<nav id="toc"></nav>
|
||||||
</section>
|
</section>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
<i class="fas fa-search fa-fw"></i>
|
<i class="fas fa-search fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<search class="align-items-center ms-3 ms-lg-0">
|
<search id="search" class="align-items-center ms-3 ms-lg-0">
|
||||||
<i class="fas fa-search fa-fw"></i>
|
<i class="fas fa-search fa-fw"></i>
|
||||||
<input
|
<input
|
||||||
class="form-control"
|
class="form-control"
|
||||||
|
|
|
@ -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';
|
||||||
|
|
||||||
basic();
|
|
||||||
initSidebar();
|
initSidebar();
|
||||||
initTopbar();
|
initTopbar();
|
||||||
|
basic();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
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/plugins';
|
||||||
|
|
||||||
basic();
|
loadImg();
|
||||||
|
initLocaleDatetime();
|
||||||
initSidebar();
|
initSidebar();
|
||||||
initTopbar();
|
initTopbar();
|
||||||
initLocaleDatetime();
|
basic();
|
||||||
loadImg();
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
import { basic, initSidebar, initTopbar } from './modules/layouts';
|
||||||
import { initLocaleDatetime } from './modules/plugins';
|
import { initLocaleDatetime } from './modules/plugins';
|
||||||
|
|
||||||
basic();
|
|
||||||
initSidebar();
|
initSidebar();
|
||||||
initTopbar();
|
initTopbar();
|
||||||
initLocaleDatetime();
|
initLocaleDatetime();
|
||||||
|
basic();
|
||||||
|
|
|
@ -3,18 +3,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function back2top() {
|
export function back2top() {
|
||||||
const $window = $(window);
|
const btn = document.getElementById('back-to-top');
|
||||||
const $btn = $('#back-to-top');
|
|
||||||
|
|
||||||
$window.on('scroll', () => {
|
window.addEventListener('scroll', () => {
|
||||||
if ($window.scrollTop() > 50) {
|
if (window.scrollY > 50) {
|
||||||
$btn.fadeIn();
|
btn.classList.add('show');
|
||||||
} else {
|
} else {
|
||||||
$btn.fadeOut();
|
btn.classList.remove('show');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$btn.on('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
$window.scrollTop(0);
|
window.scrollTo({ top: 0 });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
/**
|
/**
|
||||||
* Tab 'Categories' expand/close effect.
|
* Tab 'Categories' expand/close effect.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import 'bootstrap/js/src/collapse.js';
|
||||||
|
|
||||||
const childPrefix = 'l_';
|
const childPrefix = 'l_';
|
||||||
const parentPrefix = 'h_';
|
const parentPrefix = 'h_';
|
||||||
const collapse = $('.collapse');
|
const children = document.getElementsByClassName('collapse');
|
||||||
|
|
||||||
export function categoryCollapse() {
|
export function categoryCollapse() {
|
||||||
/* close up top-category */
|
[...children].forEach((elem) => {
|
||||||
collapse.on('hide.bs.collapse', function () {
|
const id = parentPrefix + elem.id.substring(childPrefix.length);
|
||||||
/* Bootstrap collapse events. */ const parentId =
|
const parent = document.getElementById(id);
|
||||||
parentPrefix + $(this).attr('id').substring(childPrefix.length);
|
|
||||||
if (parentId) {
|
|
||||||
$(`#${parentId} .far.fa-folder-open`).attr(
|
|
||||||
'class',
|
|
||||||
'far fa-folder fa-fw'
|
|
||||||
);
|
|
||||||
$(`#${parentId} i.fas`).addClass('rotate');
|
|
||||||
$(`#${parentId}`).removeClass('hide-border-bottom');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/* expand the top category */
|
// collapse sub-categories
|
||||||
collapse.on('show.bs.collapse', function () {
|
elem.addEventListener('hide.bs.collapse', () => {
|
||||||
const parentId =
|
if (parent) {
|
||||||
parentPrefix + $(this).attr('id').substring(childPrefix.length);
|
parent.querySelector('.far.fa-folder-open').className =
|
||||||
if (parentId) {
|
'far fa-folder fa-fw';
|
||||||
$(`#${parentId} .far.fa-folder`).attr(
|
parent.querySelector('.fas.fa-angle-down').classList.add('rotate');
|
||||||
'class',
|
parent.classList.remove('hide-border-bottom');
|
||||||
'far fa-folder-open fa-fw'
|
}
|
||||||
);
|
});
|
||||||
$(`#${parentId} i.fas`).removeClass('rotate');
|
|
||||||
$(`#${parentId}`).addClass('hide-border-bottom');
|
// expand sub-categories
|
||||||
}
|
elem.addEventListener('show.bs.collapse', () => {
|
||||||
|
if (parent) {
|
||||||
|
parent.querySelector('.far.fa-folder').className =
|
||||||
|
'far fa-folder-open fa-fw';
|
||||||
|
parent.querySelector('.fas.fa-angle-down').classList.remove('rotate');
|
||||||
|
parent.classList.add('hide-border-bottom');
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,107 +2,113 @@
|
||||||
* Clipboard functions
|
* Clipboard functions
|
||||||
*
|
*
|
||||||
* Dependencies:
|
* Dependencies:
|
||||||
* - popper.js (https://github.com/popperjs/popper-core)
|
* clipboard.js (https://github.com/zenorocha/clipboard.js)
|
||||||
* - clipboard.js (https://github.com/zenorocha/clipboard.js)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import Tooltip from 'bootstrap/js/src/tooltip';
|
||||||
|
|
||||||
const clipboardSelector = '.code-header>button';
|
const clipboardSelector = '.code-header>button';
|
||||||
|
|
||||||
|
const ICON_DEFAULT = 'far fa-clipboard';
|
||||||
const ICON_SUCCESS = 'fas fa-check';
|
const ICON_SUCCESS = 'fas fa-check';
|
||||||
|
|
||||||
const ATTR_TIMEOUT = 'timeout';
|
const ATTR_TIMEOUT = 'timeout';
|
||||||
const ATTR_TITLE_SUCCEED = 'data-title-succeed';
|
const ATTR_TITLE_SUCCEED = 'data-title-succeed';
|
||||||
const ATTR_TITLE_ORIGIN = 'data-bs-original-title';
|
const ATTR_TITLE_ORIGIN = 'data-bs-original-title';
|
||||||
const TIMEOUT = 2000; // in milliseconds
|
const TIMEOUT = 2000; // in milliseconds
|
||||||
|
|
||||||
function isLocked(node) {
|
function isLocked(node) {
|
||||||
if ($(node)[0].hasAttribute(ATTR_TIMEOUT)) {
|
if (node.hasAttribute(ATTR_TIMEOUT)) {
|
||||||
let timeout = $(node).attr(ATTR_TIMEOUT);
|
let timeout = node.getAttribute(ATTR_TIMEOUT);
|
||||||
if (Number(timeout) > Date.now()) {
|
if (Number(timeout) > Date.now()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function lock(node) {
|
function lock(node) {
|
||||||
$(node).attr(ATTR_TIMEOUT, Date.now() + TIMEOUT);
|
node.setAttribute(ATTR_TIMEOUT, Date.now() + TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unlock(node) {
|
function unlock(node) {
|
||||||
$(node).removeAttr(ATTR_TIMEOUT);
|
node.removeAttribute(ATTR_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIcon(btn) {
|
|
||||||
let iconNode = $(btn).children();
|
|
||||||
return iconNode.attr('class');
|
|
||||||
}
|
|
||||||
|
|
||||||
const ICON_DEFAULT = getIcon(clipboardSelector);
|
|
||||||
|
|
||||||
function showTooltip(btn) {
|
function showTooltip(btn) {
|
||||||
const succeedTitle = $(btn).attr(ATTR_TITLE_SUCCEED);
|
const succeedTitle = btn.getAttribute(ATTR_TITLE_SUCCEED);
|
||||||
$(btn).attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
|
btn.setAttribute(ATTR_TITLE_ORIGIN, succeedTitle);
|
||||||
|
Tooltip.getInstance(btn).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
function hideTooltip(btn) {
|
function hideTooltip(btn) {
|
||||||
$(btn).tooltip('hide').removeAttr(ATTR_TITLE_ORIGIN);
|
Tooltip.getInstance(btn).hide();
|
||||||
|
btn.removeAttribute(ATTR_TITLE_ORIGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSuccessIcon(btn) {
|
function setSuccessIcon(btn) {
|
||||||
let btnNode = $(btn);
|
const icon = btn.children[0];
|
||||||
let iconNode = btnNode.children();
|
icon.setAttribute('class', ICON_SUCCESS);
|
||||||
iconNode.attr('class', ICON_SUCCESS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resumeIcon(btn) {
|
function resumeIcon(btn) {
|
||||||
let btnNode = $(btn);
|
const icon = btn.children[0];
|
||||||
let iconNode = btnNode.children();
|
icon.setAttribute('class', ICON_DEFAULT);
|
||||||
iconNode.attr('class', ICON_DEFAULT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initClipboard() {
|
function setCodeClipboard() {
|
||||||
// Initial the clipboard.js object
|
const clipboardList = document.querySelectorAll(clipboardSelector);
|
||||||
if ($(clipboardSelector).length) {
|
|
||||||
const clipboard = new ClipboardJS(clipboardSelector, {
|
|
||||||
target(trigger) {
|
|
||||||
let codeBlock = trigger.parentNode.nextElementSibling;
|
|
||||||
return codeBlock.querySelector('code .rouge-code');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const clipboardList = document.querySelectorAll(clipboardSelector);
|
if (clipboardList.length === 0) {
|
||||||
[...clipboardList].map(
|
return;
|
||||||
(elem) =>
|
|
||||||
new bootstrap.Tooltip(elem, {
|
|
||||||
placement: 'left'
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
clipboard.on('success', (e) => {
|
|
||||||
e.clearSelection();
|
|
||||||
|
|
||||||
const trigger = e.trigger;
|
|
||||||
if (isLocked(trigger)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setSuccessIcon(trigger);
|
|
||||||
showTooltip(trigger);
|
|
||||||
lock(trigger);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
hideTooltip(trigger);
|
|
||||||
resumeIcon(trigger);
|
|
||||||
unlock(trigger);
|
|
||||||
}, TIMEOUT);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --- Post link sharing --- */
|
// Initial the clipboard.js object
|
||||||
|
const clipboard = new ClipboardJS(clipboardSelector, {
|
||||||
|
target: (trigger) => {
|
||||||
|
const codeBlock = trigger.parentNode.nextElementSibling;
|
||||||
|
return codeBlock.querySelector('code .rouge-code');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
const btnCopyLink = $('#copy-link');
|
[...clipboardList].map(
|
||||||
|
(elem) =>
|
||||||
|
new Tooltip(elem, {
|
||||||
|
placement: 'left'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
btnCopyLink.on('click', (e) => {
|
clipboard.on('success', (e) => {
|
||||||
let target = $(e.target);
|
const trigger = e.trigger;
|
||||||
|
|
||||||
|
e.clearSelection();
|
||||||
|
|
||||||
|
if (isLocked(trigger)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSuccessIcon(trigger);
|
||||||
|
showTooltip(trigger);
|
||||||
|
lock(trigger);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
hideTooltip(trigger);
|
||||||
|
resumeIcon(trigger);
|
||||||
|
unlock(trigger);
|
||||||
|
}, TIMEOUT);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLinkClipboard() {
|
||||||
|
const btnCopyLink = document.getElementById('copy-link');
|
||||||
|
|
||||||
|
if (btnCopyLink === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
btnCopyLink.addEventListener('click', (e) => {
|
||||||
|
const target = e.target;
|
||||||
|
|
||||||
if (isLocked(target)) {
|
if (isLocked(target)) {
|
||||||
return;
|
return;
|
||||||
|
@ -110,21 +116,28 @@ export function initClipboard() {
|
||||||
|
|
||||||
// Copy URL to clipboard
|
// Copy URL to clipboard
|
||||||
navigator.clipboard.writeText(window.location.href).then(() => {
|
navigator.clipboard.writeText(window.location.href).then(() => {
|
||||||
const defaultTitle = target.attr(ATTR_TITLE_ORIGIN);
|
const defaultTitle = target.getAttribute(ATTR_TITLE_ORIGIN);
|
||||||
const succeedTitle = target.attr(ATTR_TITLE_SUCCEED);
|
const succeedTitle = target.getAttribute(ATTR_TITLE_SUCCEED);
|
||||||
|
|
||||||
// Switch tooltip title
|
// Switch tooltip title
|
||||||
target.attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
|
target.setAttribute(ATTR_TITLE_ORIGIN, succeedTitle);
|
||||||
|
Tooltip.getInstance(target).show();
|
||||||
|
|
||||||
lock(target);
|
lock(target);
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
target.attr(ATTR_TITLE_ORIGIN, defaultTitle);
|
target.setAttribute(ATTR_TITLE_ORIGIN, defaultTitle);
|
||||||
unlock(target);
|
unlock(target);
|
||||||
}, TIMEOUT);
|
}, TIMEOUT);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
btnCopyLink.on('mouseleave', function (e) {
|
btnCopyLink.addEventListener('mouseleave', (e) => {
|
||||||
const target = $(e.target);
|
Tooltip.getInstance(e.target).hide();
|
||||||
target.tooltip('hide');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function initClipboard() {
|
||||||
|
setCodeClipboard();
|
||||||
|
setLinkClipboard();
|
||||||
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ const cover = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function removeCover(clzss) {
|
function removeCover(clzss) {
|
||||||
$(this).parent().removeClass(clzss);
|
this.parentElement.classList.remove(clzss);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleImage() {
|
function handleImage() {
|
||||||
|
@ -30,32 +30,38 @@ function handleImage() {
|
||||||
* Switches the LQIP with the real image URL.
|
* Switches the LQIP with the real image URL.
|
||||||
*/
|
*/
|
||||||
function switchLQIP() {
|
function switchLQIP() {
|
||||||
const $img = $(this);
|
const src = this.getAttribute(ATTR_DATA_SRC);
|
||||||
const src = $img.attr(ATTR_DATA_SRC);
|
this.setAttribute('src', encodeURI(src));
|
||||||
|
this.removeAttribute(ATTR_DATA_SRC);
|
||||||
$img.attr('src', encodeURI(src));
|
|
||||||
$img.removeAttr(ATTR_DATA_SRC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadImg() {
|
export function loadImg() {
|
||||||
const $images = $('article img');
|
const images = document.querySelectorAll('article img');
|
||||||
|
|
||||||
if ($images.length) {
|
if (images.length === 0) {
|
||||||
$images.on('load', handleImage);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
images.forEach((img) => {
|
||||||
|
img.addEventListener('load', handleImage);
|
||||||
|
});
|
||||||
|
|
||||||
// Images loaded from the browser cache do not trigger the 'load' event
|
// Images loaded from the browser cache do not trigger the 'load' event
|
||||||
$('article img[loading="lazy"]').each(function () {
|
document.querySelectorAll('article img[loading="lazy"]').forEach((img) => {
|
||||||
if (this.complete) {
|
if (img.complete) {
|
||||||
removeCover.call(this, cover.SHIMMER);
|
removeCover.call(img, cover.SHIMMER);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// LQIPs set by the data URI or WebP will not trigger the 'load' event,
|
// LQIPs set by the data URI or WebP will not trigger the 'load' event,
|
||||||
// so manually convert the URI to the URL of a high-resolution image.
|
// so manually convert the URI to the URL of a high-resolution image.
|
||||||
const $lqips = $(`article img[${ATTR_DATA_LQIP}="true"]`);
|
const lqips = document.querySelectorAll(
|
||||||
|
`article img[${ATTR_DATA_LQIP}="true"]`
|
||||||
|
);
|
||||||
|
|
||||||
if ($lqips.length) {
|
if (lqips.length) {
|
||||||
$lqips.each(switchLQIP);
|
lqips.forEach((lqip) => {
|
||||||
|
switchLQIP.call(lqip);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,60 @@
|
||||||
/**
|
/**
|
||||||
* Set up image popup
|
* Set up image popup
|
||||||
*
|
*
|
||||||
* See: https://github.com/dimsemenov/Magnific-Popup
|
* Dependencies: https://github.com/biati-digital/glightbox
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const html = document.documentElement;
|
||||||
|
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 ($('.popup') <= 0) {
|
if (document.querySelector('.popup') === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.popup').magnificPopup({
|
const hasDualImages = !(
|
||||||
type: 'image',
|
document.querySelector('.popup.light') === null &&
|
||||||
closeOnContentClick: true,
|
document.querySelector('.popup.dark') === null
|
||||||
showCloseBtn: false,
|
);
|
||||||
zoom: {
|
|
||||||
enabled: true,
|
if (
|
||||||
duration: 300,
|
(html.hasAttribute('data-mode') &&
|
||||||
easing: 'ease-in-out'
|
html.getAttribute('data-mode') === 'dark') ||
|
||||||
}
|
(!html.hasAttribute('data-mode') &&
|
||||||
});
|
window.matchMedia('(prefers-color-scheme: dark)').matches)
|
||||||
|
) {
|
||||||
|
selector = darkImages;
|
||||||
|
}
|
||||||
|
|
||||||
|
let current = GLightbox({ selector: `${selector}` });
|
||||||
|
|
||||||
|
if (hasDualImages && document.getElementById('mode-toggle')) {
|
||||||
|
let reverse = null;
|
||||||
|
|
||||||
|
window.addEventListener('message', (event) => {
|
||||||
|
if (
|
||||||
|
event.source === window &&
|
||||||
|
event.data &&
|
||||||
|
event.data.direction === ModeToggle.ID
|
||||||
|
) {
|
||||||
|
updateImages(current, reverse);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,15 +15,15 @@ class LocaleHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
static get locale() {
|
static get locale() {
|
||||||
return $('html').attr('lang').substring(0, 2);
|
return document.documentElement.getAttribute('lang').substring(0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getTimestamp(elem) {
|
static getTimestamp(elem) {
|
||||||
return Number(elem.attr(LocaleHelper.attrTimestamp)); // unix timestamp
|
return Number(elem.getAttribute(this.attrTimestamp)); // unix timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
static getDateFormat(elem) {
|
static getDateFormat(elem) {
|
||||||
return elem.attr(LocaleHelper.attrDateFormat);
|
return elem.getAttribute(this.attrDateFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,21 +31,23 @@ export function initLocaleDatetime() {
|
||||||
dayjs.locale(LocaleHelper.locale);
|
dayjs.locale(LocaleHelper.locale);
|
||||||
dayjs.extend(window.dayjs_plugin_localizedFormat);
|
dayjs.extend(window.dayjs_plugin_localizedFormat);
|
||||||
|
|
||||||
$(`[${LocaleHelper.attrTimestamp}]`).each(function () {
|
document
|
||||||
const date = dayjs.unix(LocaleHelper.getTimestamp($(this)));
|
.querySelectorAll(`[${LocaleHelper.attrTimestamp}]`)
|
||||||
const text = date.format(LocaleHelper.getDateFormat($(this)));
|
.forEach((elem) => {
|
||||||
$(this).text(text);
|
const date = dayjs.unix(LocaleHelper.getTimestamp(elem));
|
||||||
$(this).removeAttr(LocaleHelper.attrTimestamp);
|
const text = date.format(LocaleHelper.getDateFormat(elem));
|
||||||
$(this).removeAttr(LocaleHelper.attrDateFormat);
|
elem.textContent = text;
|
||||||
|
elem.removeAttribute(LocaleHelper.attrTimestamp);
|
||||||
|
elem.removeAttribute(LocaleHelper.attrDateFormat);
|
||||||
|
|
||||||
// setup tooltips
|
// setup tooltips
|
||||||
const tooltip = $(this).attr('data-bs-toggle');
|
if (
|
||||||
if (typeof tooltip === 'undefined' || tooltip !== 'tooltip') {
|
elem.hasAttribute('data-bs-toggle') &&
|
||||||
return;
|
elem.getAttribute('data-bs-toggle') === 'tooltip'
|
||||||
}
|
) {
|
||||||
|
// see: https://day.js.org/docs/en/display/format#list-of-localized-formats
|
||||||
const tooltipText = date.format('llll'); // see: https://day.js.org/docs/en/display/format#list-of-localized-formats
|
const tooltipText = date.format('llll');
|
||||||
$(this).attr('data-bs-title', tooltipText);
|
elem.setAttribute('data-bs-title', tooltipText);
|
||||||
new bootstrap.Tooltip($(this));
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,14 @@
|
||||||
/**
|
/**
|
||||||
* Add listener for theme mode toggle
|
* Add listener for theme mode toggle
|
||||||
*/
|
*/
|
||||||
const $toggleElem = $('.mode-toggle');
|
const toggle = document.getElementById('mode-toggle');
|
||||||
|
|
||||||
export function modeWatcher() {
|
export function modeWatcher() {
|
||||||
if ($toggleElem.length === 0) {
|
if (!toggle) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$toggleElem.off().on('click', (e) => {
|
toggle.addEventListener('click', () => {
|
||||||
const $target = $(e.target);
|
modeToggle.flipMode();
|
||||||
let $btn =
|
|
||||||
$target.prop('tagName') === 'button'.toUpperCase()
|
|
||||||
? $target
|
|
||||||
: $target.parent();
|
|
||||||
|
|
||||||
modeToggle.flipMode(); // modeToggle: `_includes/mode-toggle.html`
|
|
||||||
$btn.trigger('blur'); // remove the clicking outline
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,121 +1,109 @@
|
||||||
/**
|
/**
|
||||||
* 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 = $('#sidebar-trigger');
|
|
||||||
const $btnSearchTrigger = $('#search-trigger');
|
|
||||||
const $btnCancel = $('#search-cancel');
|
|
||||||
const $content = $('#main-wrapper>.container>.row');
|
|
||||||
const $topbarTitle = $('#topbar-title');
|
|
||||||
const $search = $('search');
|
|
||||||
const $resultWrapper = $('#search-result-wrapper');
|
|
||||||
const $results = $('#search-results');
|
|
||||||
const $input = $('#search-input');
|
|
||||||
const $hints = $('#search-hints');
|
|
||||||
const $viewport = $('html,body');
|
|
||||||
|
|
||||||
// class names
|
const btnSbTrigger = document.getElementById('sidebar-trigger');
|
||||||
const C_LOADED = 'loaded';
|
const btnSearchTrigger = document.getElementById('search-trigger');
|
||||||
const C_UNLOADED = 'unloaded';
|
const btnCancel = document.getElementById('search-cancel');
|
||||||
const C_FOCUS = 'input-focus';
|
const content = document.querySelectorAll('#main-wrapper>.container>.row');
|
||||||
const C_FLEX = 'd-flex';
|
const topbarTitle = document.getElementById('topbar-title');
|
||||||
|
const search = document.getElementById('search');
|
||||||
|
const resultWrapper = document.getElementById('search-result-wrapper');
|
||||||
|
const results = document.getElementById('search-results');
|
||||||
|
const input = document.getElementById('search-input');
|
||||||
|
const hints = document.getElementById('search-hints');
|
||||||
|
|
||||||
class ScrollBlocker {
|
// CSS class names
|
||||||
static offset = 0;
|
const LOADED = 'd-block';
|
||||||
static resultVisible = false;
|
const UNLOADED = 'd-none';
|
||||||
|
const FOCUS = 'input-focus';
|
||||||
|
const FLEX = 'd-flex';
|
||||||
|
|
||||||
static on() {
|
/* Actions in mobile screens (Sidebar hidden) */
|
||||||
ScrollBlocker.offset = window.scrollY;
|
|
||||||
$viewport.scrollTop(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static off() {
|
|
||||||
$viewport.scrollTop(ScrollBlocker.offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*--- Actions in mobile screens (Sidebar hidden) ---*/
|
|
||||||
class MobileSearchBar {
|
class MobileSearchBar {
|
||||||
static on() {
|
static on() {
|
||||||
$btnSbTrigger.addClass(C_UNLOADED);
|
btnSbTrigger.classList.add(UNLOADED);
|
||||||
$topbarTitle.addClass(C_UNLOADED);
|
topbarTitle.classList.add(UNLOADED);
|
||||||
$btnSearchTrigger.addClass(C_UNLOADED);
|
btnSearchTrigger.classList.add(UNLOADED);
|
||||||
$search.addClass(C_FLEX);
|
search.classList.add(FLEX);
|
||||||
$btnCancel.addClass(C_LOADED);
|
btnCancel.classList.add(LOADED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static off() {
|
static off() {
|
||||||
$btnCancel.removeClass(C_LOADED);
|
btnCancel.classList.remove(LOADED);
|
||||||
$search.removeClass(C_FLEX);
|
search.classList.remove(FLEX);
|
||||||
$btnSbTrigger.removeClass(C_UNLOADED);
|
btnSbTrigger.classList.remove(UNLOADED);
|
||||||
$topbarTitle.removeClass(C_UNLOADED);
|
topbarTitle.classList.remove(UNLOADED);
|
||||||
$btnSearchTrigger.removeClass(C_UNLOADED);
|
btnSearchTrigger.classList.remove(UNLOADED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResultSwitch {
|
class ResultSwitch {
|
||||||
|
static resultVisible = false;
|
||||||
|
|
||||||
static on() {
|
static on() {
|
||||||
if (!ScrollBlocker.resultVisible) {
|
if (!this.resultVisible) {
|
||||||
// the block method must be called before $(#main-wrapper>.container) unloaded.
|
resultWrapper.classList.remove(UNLOADED);
|
||||||
ScrollBlocker.on();
|
content.forEach((el) => {
|
||||||
$resultWrapper.removeClass(C_UNLOADED);
|
el.classList.add(UNLOADED);
|
||||||
$content.addClass(C_UNLOADED);
|
});
|
||||||
ScrollBlocker.resultVisible = true;
|
this.resultVisible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static off() {
|
static off() {
|
||||||
if (ScrollBlocker.resultVisible) {
|
if (this.resultVisible) {
|
||||||
$results.empty();
|
results.innerHTML = '';
|
||||||
if ($hints.hasClass(C_UNLOADED)) {
|
|
||||||
$hints.removeClass(C_UNLOADED);
|
if (hints.classList.contains(UNLOADED)) {
|
||||||
|
hints.classList.remove(UNLOADED);
|
||||||
}
|
}
|
||||||
$resultWrapper.addClass(C_UNLOADED);
|
|
||||||
$content.removeClass(C_UNLOADED);
|
|
||||||
|
|
||||||
// now the release method must be called after $(#main-wrapper>.container) display
|
resultWrapper.classList.add(UNLOADED);
|
||||||
ScrollBlocker.off();
|
content.forEach((el) => {
|
||||||
|
el.classList.remove(UNLOADED);
|
||||||
$input.val('');
|
});
|
||||||
ScrollBlocker.resultVisible = false;
|
input.textContent = '';
|
||||||
|
this.resultVisible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMobileView() {
|
function isMobileView() {
|
||||||
return $btnCancel.hasClass(C_LOADED);
|
return btnCancel.classList.contains(LOADED);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function displaySearch() {
|
export function displaySearch() {
|
||||||
$btnSearchTrigger.on('click', function () {
|
btnSearchTrigger.addEventListener('click', () => {
|
||||||
MobileSearchBar.on();
|
MobileSearchBar.on();
|
||||||
ResultSwitch.on();
|
ResultSwitch.on();
|
||||||
$input.trigger('focus');
|
input.focus();
|
||||||
});
|
});
|
||||||
|
|
||||||
$btnCancel.on('click', function () {
|
btnCancel.addEventListener('click', () => {
|
||||||
MobileSearchBar.off();
|
MobileSearchBar.off();
|
||||||
ResultSwitch.off();
|
ResultSwitch.off();
|
||||||
});
|
});
|
||||||
|
|
||||||
$input.on('focus', function () {
|
input.addEventListener('focus', () => {
|
||||||
$search.addClass(C_FOCUS);
|
search.classList.add(FOCUS);
|
||||||
});
|
});
|
||||||
|
|
||||||
$input.on('focusout', function () {
|
input.addEventListener('focusout', () => {
|
||||||
$search.removeClass(C_FOCUS);
|
search.classList.remove(FOCUS);
|
||||||
});
|
});
|
||||||
|
|
||||||
$input.on('input', () => {
|
input.addEventListener('input', () => {
|
||||||
if ($input.val() === '') {
|
if (input.value === '') {
|
||||||
if (isMobileView()) {
|
if (isMobileView()) {
|
||||||
$hints.removeClass(C_UNLOADED);
|
hints.classList.remove(UNLOADED);
|
||||||
} else {
|
} else {
|
||||||
ResultSwitch.off();
|
ResultSwitch.off();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ResultSwitch.on();
|
ResultSwitch.on();
|
||||||
if (isMobileView()) {
|
if (isMobileView()) {
|
||||||
$hints.addClass(C_UNLOADED);
|
hints.classList.add(UNLOADED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,24 +2,21 @@
|
||||||
* Expand or close the sidebar in mobile screens.
|
* Expand or close the sidebar in mobile screens.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const $body = $('body');
|
const $sidebar = document.getElementById('sidebar');
|
||||||
const ATTR_DISPLAY = 'sidebar-display';
|
const $trigger = document.getElementById('sidebar-trigger');
|
||||||
|
const $mask = document.getElementById('mask');
|
||||||
|
|
||||||
class SidebarUtil {
|
class SidebarUtil {
|
||||||
static isExpanded = false;
|
static #isExpanded = false;
|
||||||
|
|
||||||
static toggle() {
|
static toggle() {
|
||||||
if (SidebarUtil.isExpanded === false) {
|
this.#isExpanded = !this.#isExpanded;
|
||||||
$body.attr(ATTR_DISPLAY, '');
|
document.body.toggleAttribute('sidebar-display', this.#isExpanded);
|
||||||
} else {
|
$sidebar.classList.toggle('z-2', this.#isExpanded);
|
||||||
$body.removeAttr(ATTR_DISPLAY);
|
$mask.classList.toggle('d-none', !this.#isExpanded);
|
||||||
}
|
|
||||||
|
|
||||||
SidebarUtil.isExpanded = !SidebarUtil.isExpanded;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sidebarExpand() {
|
export function sidebarExpand() {
|
||||||
$('#sidebar-trigger').on('click', SidebarUtil.toggle);
|
$trigger.onclick = $mask.onclick = () => SidebarUtil.toggle();
|
||||||
$('#mask').on('click', SidebarUtil.toggle);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,33 @@
|
||||||
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({
|
const desktopMode = matchMedia('(min-width: 1200px)');
|
||||||
tocSelector: '#toc',
|
|
||||||
contentSelector: '.content',
|
function refresh(e) {
|
||||||
ignoreSelector: '[data-toc-skip]',
|
if (e.matches) {
|
||||||
headingSelector: 'h2, h3, h4',
|
if (mobile.popupOpened) {
|
||||||
orderedList: false,
|
mobile.hidePopup();
|
||||||
scrollSmooth: false
|
}
|
||||||
});
|
|
||||||
|
desktop.refresh();
|
||||||
|
} else {
|
||||||
|
mobile.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
if (document.querySelector('main>article[data-toc="true"]') === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Avoid create multiple instances of Tocbot. Ref: <https://github.com/tscanlin/tocbot/issues/203>
|
||||||
|
if (desktopMode.matches) {
|
||||||
|
desktop.init();
|
||||||
|
} else {
|
||||||
|
mobile.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
desktopMode.onchange = refresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
export { init as initToc };
|
||||||
|
|
22
_javascript/modules/components/toc/toc-desktop.js
Normal file
22
_javascript/modules/components/toc/toc-desktop.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
export class TocDesktop {
|
||||||
|
/* Tocbot options Ref: https://github.com/tscanlin/tocbot#usage */
|
||||||
|
static options = {
|
||||||
|
tocSelector: '#toc',
|
||||||
|
contentSelector: '.content',
|
||||||
|
ignoreSelector: '[data-toc-skip]',
|
||||||
|
headingSelector: 'h2, h3, h4',
|
||||||
|
orderedList: false,
|
||||||
|
scrollSmooth: false,
|
||||||
|
headingsOffset: 16 * 2 // 2rem
|
||||||
|
};
|
||||||
|
|
||||||
|
static refresh() {
|
||||||
|
tocbot.refresh(this.options);
|
||||||
|
}
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
if (document.getElementById('toc-wrapper')) {
|
||||||
|
tocbot.init(this.options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
125
_javascript/modules/components/toc/toc-mobile.js
Normal file
125
_javascript/modules/components/toc/toc-mobile.js
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
/**
|
||||||
|
* TOC button, topbar and popup for mobile devices
|
||||||
|
*/
|
||||||
|
|
||||||
|
const $tocBar = document.getElementById('toc-bar');
|
||||||
|
const $soloTrigger = document.getElementById('toc-solo-trigger');
|
||||||
|
const $triggers = document.getElementsByClassName('toc-trigger');
|
||||||
|
const $popup = document.getElementById('toc-popup');
|
||||||
|
const $btnClose = document.getElementById('toc-popup-close');
|
||||||
|
|
||||||
|
const SCROLL_LOCK = 'overflow-hidden';
|
||||||
|
const CLOSING = 'closing';
|
||||||
|
|
||||||
|
export class TocMobile {
|
||||||
|
static #invisible = true;
|
||||||
|
static #barHeight = 16 * 3; // 3rem
|
||||||
|
|
||||||
|
static options = {
|
||||||
|
tocSelector: '#toc-popup-content',
|
||||||
|
contentSelector: '.content',
|
||||||
|
ignoreSelector: '[data-toc-skip]',
|
||||||
|
headingSelector: 'h2, h3, h4',
|
||||||
|
orderedList: false,
|
||||||
|
scrollSmooth: false,
|
||||||
|
collapseDepth: 4,
|
||||||
|
headingsOffset: this.#barHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
static initBar() {
|
||||||
|
const observer = new IntersectionObserver(
|
||||||
|
(entries) => {
|
||||||
|
entries.forEach((entry) => {
|
||||||
|
$tocBar.classList.toggle('invisible', entry.isIntersecting);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ rootMargin: `-${this.#barHeight}px 0px 0px 0px` }
|
||||||
|
);
|
||||||
|
|
||||||
|
observer.observe($soloTrigger);
|
||||||
|
this.#invisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static listenAnchors() {
|
||||||
|
const $anchors = document.getElementsByClassName('toc-link');
|
||||||
|
[...$anchors].forEach((anchor) => {
|
||||||
|
anchor.onclick = () => this.hidePopup();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static refresh() {
|
||||||
|
if (this.#invisible) {
|
||||||
|
this.initComponents();
|
||||||
|
}
|
||||||
|
tocbot.refresh(this.options);
|
||||||
|
this.listenAnchors();
|
||||||
|
}
|
||||||
|
|
||||||
|
static get popupOpened() {
|
||||||
|
return $popup.open;
|
||||||
|
}
|
||||||
|
|
||||||
|
static showPopup() {
|
||||||
|
this.lockScroll(true);
|
||||||
|
$popup.showModal();
|
||||||
|
const activeItem = $popup.querySelector('li.is-active-li');
|
||||||
|
activeItem.scrollIntoView({ block: 'center' });
|
||||||
|
}
|
||||||
|
|
||||||
|
static hidePopup() {
|
||||||
|
$popup.toggleAttribute(CLOSING);
|
||||||
|
|
||||||
|
$popup.addEventListener(
|
||||||
|
'animationend',
|
||||||
|
() => {
|
||||||
|
$popup.toggleAttribute(CLOSING);
|
||||||
|
$popup.close();
|
||||||
|
},
|
||||||
|
{ once: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
this.lockScroll(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static lockScroll(enable) {
|
||||||
|
document.documentElement.classList.toggle(SCROLL_LOCK, enable);
|
||||||
|
document.body.classList.toggle(SCROLL_LOCK, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
static clickBackdrop(event) {
|
||||||
|
if ($popup.hasAttribute(CLOSING)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rect = event.target.getBoundingClientRect();
|
||||||
|
if (
|
||||||
|
event.clientX < rect.left ||
|
||||||
|
event.clientX > rect.right ||
|
||||||
|
event.clientY < rect.top ||
|
||||||
|
event.clientY > rect.bottom
|
||||||
|
) {
|
||||||
|
this.hidePopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static initComponents() {
|
||||||
|
this.initBar();
|
||||||
|
|
||||||
|
[...$triggers].forEach((trigger) => {
|
||||||
|
trigger.onclick = () => this.showPopup();
|
||||||
|
});
|
||||||
|
|
||||||
|
$popup.onclick = (e) => this.clickBackdrop(e);
|
||||||
|
$btnClose.onclick = () => this.hidePopup();
|
||||||
|
$popup.oncancel = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
this.hidePopup();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static init() {
|
||||||
|
tocbot.init(this.options);
|
||||||
|
this.listenAnchors();
|
||||||
|
this.initComponents();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,11 @@
|
||||||
/**
|
import Tooltip from 'bootstrap/js/src/tooltip';
|
||||||
* Initial Bootstrap Tooltip.
|
|
||||||
*/
|
|
||||||
export function loadTooptip() {
|
export function loadTooptip() {
|
||||||
const tooltipTriggerList = document.querySelectorAll(
|
const tooltipTriggerList = document.querySelectorAll(
|
||||||
'[data-bs-toggle="tooltip"]'
|
'[data-bs-toggle="tooltip"]'
|
||||||
);
|
);
|
||||||
|
|
||||||
[...tooltipTriggerList].map(
|
[...tooltipTriggerList].map(
|
||||||
(tooltipTriggerEl) => new bootstrap.Tooltip(tooltipTriggerEl)
|
(tooltipTriggerEl) => new Tooltip(tooltipTriggerEl)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,4 +3,4 @@ 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';
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
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 } from './modules/plugins';
|
||||||
|
|
||||||
basic();
|
|
||||||
initSidebar();
|
|
||||||
initTopbar();
|
|
||||||
loadImg();
|
loadImg();
|
||||||
imgPopup();
|
imgPopup();
|
||||||
|
initSidebar();
|
||||||
|
initTopbar();
|
||||||
initClipboard();
|
initClipboard();
|
||||||
|
basic();
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
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';
|
} from './modules/plugins';
|
||||||
|
|
||||||
initSidebar();
|
|
||||||
initTopbar();
|
|
||||||
loadImg();
|
loadImg();
|
||||||
|
initToc();
|
||||||
imgPopup();
|
imgPopup();
|
||||||
|
initSidebar();
|
||||||
initLocaleDatetime();
|
initLocaleDatetime();
|
||||||
initClipboard();
|
initClipboard();
|
||||||
toc();
|
initTopbar();
|
||||||
basic();
|
basic();
|
||||||
|
|
|
@ -1,43 +1,44 @@
|
||||||
---
|
import Toast from 'bootstrap/js/src/toast';
|
||||||
layout: compress
|
|
||||||
permalink: /assets/js/dist/:basename.min.js
|
|
||||||
---
|
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
const isEnabled = '{{ site.pwa.enabled }}' === 'true';
|
// Get Jekyll config from URL parameters
|
||||||
|
const src = new URL(document.currentScript.src);
|
||||||
|
const register = src.searchParams.get('register');
|
||||||
|
const baseUrl = src.searchParams.get('baseurl');
|
||||||
|
|
||||||
if (isEnabled) {
|
if (register) {
|
||||||
const swUrl = '{{ '/sw.min.js' | relative_url }}';
|
const swUrl = `${baseUrl}/sw.min.js`;
|
||||||
const $notification = $('#notification');
|
const notification = document.getElementById('notification');
|
||||||
const $btnRefresh = $('#notification .toast-body>button');
|
const btnRefresh = notification.querySelector('.toast-body>button');
|
||||||
|
const popupWindow = Toast.getOrCreateInstance(notification);
|
||||||
|
|
||||||
navigator.serviceWorker.register(swUrl).then((registration) => {
|
navigator.serviceWorker.register(swUrl).then((registration) => {
|
||||||
{% comment %}In case the user ignores the notification{% endcomment %}
|
// Restore the update window that was last manually closed by the user
|
||||||
if (registration.waiting) {
|
if (registration.waiting) {
|
||||||
$notification.toast('show');
|
popupWindow.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
registration.addEventListener('updatefound', () => {
|
registration.addEventListener('updatefound', () => {
|
||||||
registration.installing.addEventListener('statechange', () => {
|
registration.installing.addEventListener('statechange', () => {
|
||||||
if (registration.waiting) {
|
if (registration.waiting) {
|
||||||
if (navigator.serviceWorker.controller) {
|
if (navigator.serviceWorker.controller) {
|
||||||
$notification.toast('show');
|
popupWindow.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$btnRefresh.on('click', () => {
|
btnRefresh.addEventListener('click', () => {
|
||||||
if (registration.waiting) {
|
if (registration.waiting) {
|
||||||
registration.waiting.postMessage('SKIP_WAITING');
|
registration.waiting.postMessage('SKIP_WAITING');
|
||||||
}
|
}
|
||||||
$notification.toast('hide');
|
popupWindow.hide();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let refreshing = false;
|
let refreshing = false;
|
||||||
|
|
||||||
{% comment %}Detect controller change and refresh all the opened tabs{% endcomment %}
|
// Detect controller change and refresh all the opened tabs
|
||||||
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
||||||
if (!refreshing) {
|
if (!refreshing) {
|
||||||
window.location.reload();
|
window.location.reload();
|
|
@ -1,32 +1,23 @@
|
||||||
---
|
importScripts('./assets/js/data/swconf.js');
|
||||||
layout: compress
|
|
||||||
permalink: /:basename.min.js
|
|
||||||
# PWA service worker
|
|
||||||
---
|
|
||||||
|
|
||||||
const swconfUrl = '{{ '/assets/js/data/swconf.js' | relative_url }}';
|
|
||||||
|
|
||||||
importScripts(swconfUrl);
|
|
||||||
const purge = swconf.purge;
|
const purge = swconf.purge;
|
||||||
|
const interceptor = swconf.interceptor;
|
||||||
function verifyHost(url) {
|
|
||||||
for (const host of swconf.allowHosts) {
|
|
||||||
const regex = RegExp(`^http(s)?://${host}/`);
|
|
||||||
if (regex.test(url)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function verifyUrl(url) {
|
function verifyUrl(url) {
|
||||||
if (!verifyHost(url)) {
|
const requestUrl = new URL(url);
|
||||||
|
const requestPath = requestUrl.pathname;
|
||||||
|
|
||||||
|
if (!requestUrl.protocol.startsWith('http')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestPath = new URL(url).pathname;
|
for (const prefix of interceptor.urlPrefixes) {
|
||||||
|
if (requestUrl.href.startsWith(prefix)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const path of swconf.denyPaths) {
|
for (const path of interceptor.paths) {
|
||||||
if (requestPath.startsWith(path)) {
|
if (requestPath.startsWith(path)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -34,10 +25,6 @@ function verifyUrl(url) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!purge) {
|
|
||||||
swconf.allowHosts.push(location.host);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.addEventListener('install', (event) => {
|
self.addEventListener('install', (event) => {
|
||||||
if (purge) {
|
if (purge) {
|
||||||
return;
|
return;
|
||||||
|
@ -75,6 +62,10 @@ self.addEventListener('message', (event) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
self.addEventListener('fetch', (event) => {
|
self.addEventListener('fetch', (event) => {
|
||||||
|
if (event.request.headers.has('range')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
event.respondWith(
|
event.respondWith(
|
||||||
caches.match(event.request).then((response) => {
|
caches.match(event.request).then((response) => {
|
||||||
if (response) {
|
if (response) {
|
||||||
|
@ -88,7 +79,7 @@ self.addEventListener('fetch', (event) => {
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
{% comment %}See: <https://developers.google.com/web/fundamentals/primers/service-workers#cache_and_return_requests>{% endcomment %}
|
// See: <https://developers.google.com/web/fundamentals/primers/service-workers#cache_and_return_requests>
|
||||||
let responseToCache = response.clone();
|
let responseToCache = response.clone();
|
||||||
|
|
||||||
caches.open(swconf.cacheName).then((cache) => {
|
caches.open(swconf.cacheName).then((cache) => {
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue