From 5cbaf24bcb8f62ab5a70697f949460e7251c76e1 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Mon, 6 Feb 2023 22:33:20 +0800 Subject: [PATCH 01/35] refactor(sidebar): improve creation of social links --- _includes/sidebar.html | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/_includes/sidebar.html b/_includes/sidebar.html index c32efb3..c570597 100644 --- a/_includes/sidebar.html +++ b/_includes/sidebar.html @@ -64,34 +64,37 @@ {% endunless %} {% for entry in site.data.contact %} - {% capture url %} - {%- if entry.type == 'github' -%} - https://github.com/{{ site.github.username }} - {%- elsif entry.type == 'twitter' -%} - https://twitter.com/{{ site.twitter.username }} - {%- elsif entry.type == 'email' -%} + {% case entry.type %} + {% when 'github', 'twitter' %} + {%- capture url -%} + https://{{ entry.type }}.com/{{ site[entry.type].username }} + {%- endcapture -%} + {% when 'email' %} {% assign email = site.social.email | split: '@' %} - javascript:location.href = 'mailto:' + ['{{ email[0] }}','{{ email[1] }}'].join('@') - {%- elsif entry.type == 'rss' -%} - {{ "/feed.xml" | relative_url }} - {%- else -%} - {{ entry.url }} - {%- endif -%} - {% endcapture %} + {%- capture url -%} + javascript:location.href = 'mailto:' + ['{{ email[0] }}','{{ email[1] }}'].join('@') + {%- endcapture -%} + {% when 'rss' %} + {% assign url = '/feed.xml' | relative_url %} + {% else %} + {% assign url = entry.url %} + {% endcase %} {% if url %} + {% unless link_types == empty %}rel="{{ link_types }}"{% endunless %}> + {% endif %} From 27f4bf07bcbc7e8f2ca29d025a91eb776a82d9ec Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Mon, 6 Feb 2023 22:35:51 +0800 Subject: [PATCH 02/35] style: format YAML array --- _data/contact.yml | 27 +++++++++++++-------------- _data/share.yml | 18 ++++++++---------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/_data/contact.yml b/_data/contact.yml index a94e555..971969e 100644 --- a/_data/contact.yml +++ b/_data/contact.yml @@ -1,30 +1,29 @@ # The contact options. -- - type: github +- type: github icon: 'fab fa-github' -- - type: twitter + +- type: twitter icon: 'fab fa-twitter' -- - type: email + +- type: email icon: 'fas fa-envelope' noblank: true # open link in current tab -- - type: rss + +- type: rss icon: 'fas fa-rss' noblank: true # Uncomment and complete the url below to enable more contact options -# - -# type: mastodon +# +# - type: mastodon # icon: 'fab fa-mastodon' # icons powered by # url: '' # Fill with your Mastodon account page, rel="me" will be applied for verification -# - -# type: linkedin +# +# - type: linkedin # icon: 'fab fa-linkedin' # icons powered by # url: '' # Fill with your Linkedin homepage -# - -# type: stack-overflow +# +# - type: stack-overflow # icon: 'fab fa-stack-overflow' # url: '' # Fill with your stackoverflow homepage diff --git a/_data/share.yml b/_data/share.yml index 1206f4d..c1d4d63 100644 --- a/_data/share.yml +++ b/_data/share.yml @@ -2,26 +2,24 @@ # Icons from platforms: - - - type: Twitter + - type: Twitter icon: "fab fa-twitter" link: "https://twitter.com/intent/tweet?text=TITLE&url=URL" - - - type: Facebook + + - type: Facebook icon: "fab fa-facebook-square" link: "https://www.facebook.com/sharer/sharer.php?title=TITLE&u=URL" - - - type: Telegram + + - type: Telegram icon: "fab fa-telegram" link: "https://t.me/share/url?url=URL&text=TITLE" # Uncomment below if you need to. - # - - # type: Linkedin + # + # - type: Linkedin # icon: "fab fa-linkedin" # link: "https://www.linkedin.com/sharing/share-offsite/?url=URL" # - # - - # type: Weibo + # - type: Weibo # icon: "fab fa-weibo" # link: "http://service.weibo.com/share/share.php?title=TITLE&url=URL" From 909d136b37fb1522f8ca08b34c4ddcc3f436e3f2 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 11 Feb 2023 23:26:51 +0800 Subject: [PATCH 03/35] docs(github): add security policy (#885) --- .github/SECURITY.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/SECURITY.md diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..5704dc7 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,12 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +|---------| ------------------ | +| 5.x | :white_check_mark: | +| < 5.0.0 | :x: | + +## Reporting a Vulnerability + +If you find a vulnerability, please report it to `cotes.chung@gmail.com`. We will try our best to respond within a week. Thank you for your time! From ecff5630a68120b730314190d42bcb0aa2541fb0 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 11 Feb 2023 23:53:04 +0800 Subject: [PATCH 04/35] chore(security): scan for vulnerabilities --- .github/workflows/codeql.yml | 78 ++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 .github/workflows/codeql.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..25518bb --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,78 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: 'CodeQL' + +on: + push: + branches: [ 'master', 'production' ] + paths: [ '_javascript' ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ 'master' ] + paths: [ '_javascript' ] + schedule: + - cron: '0 0 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'javascript' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Use only 'java' to analyze code written in Java, Kotlin or both + # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both + # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: '${{ matrix.language }}' + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + + # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality + + + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun + + # If the Autobuild fails above, remove it and uncomment the following three lines. + # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. + + # - run: | + # echo "Run, Build Application using script" + # ./location_of_script_within_repo/buildscript.sh + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: '/language:${{ matrix.language }}' From a2d01365de6c1da6d1da4110651f84f389f4ff23 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sun, 12 Feb 2023 00:27:06 +0800 Subject: [PATCH 05/35] chore(github): simplify the creation steps of issue/pr --- .github/ISSUE_TEMPLATE/bug_report.md | 12 ++++-------- .github/ISSUE_TEMPLATE/feature_request.md | 13 ++++-------- .github/ISSUE_TEMPLATE/help_wanted.md | 24 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/question.md | 13 ------------ .github/PULL_REQUEST_TEMPLATE.md | 8 -------- .github/workflows/issue-interceptor.yml | 18 ----------------- 6 files changed, 32 insertions(+), 56 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/help_wanted.md delete mode 100644 .github/workflows/issue-interceptor.yml diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 7c79a52..e5bd773 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,15 +3,11 @@ name: Bug Report about: Create a report to help us improve --- - +We sincerely recommend that you first complete the following checklist: -## Checklist - - - -- [ ] I have read the [tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design. -- [ ] There are no similar reports on [existing issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue) (including closed ones). -- [ ] I found the bug on the latest code of the `master` branch. +- Read the [tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design. +- No similar [issue](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue)(including closed ones) exists +- Found the bug on the latest code of the `master` branch. ## Describe the bug diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 7d866cf..dc52b35 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -4,16 +4,11 @@ about: Suggest an idea for this project labels: enhancement --- - - -## Checklist - - -- [ ] I have read the [contributing guidelines](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/CONTRIBUTING.md). -- [ ] There is no similar request on [existing issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue) (including closed ones). -- [ ] I have read the [project progress](https://github.com/cotes2020/jekyll-theme-chirpy/projects) and know the current progress of the project. -- [ ] I was in the `master` branch of the latest code. +We sincerely recommend that you first complete the following checklist: +- Read the [tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design. +- No similar [issue](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue)(including closed ones) exists +- This PR is built on top of the latest code in the `master` branch. ## Is your feature request related to a problem? Please describe diff --git a/.github/ISSUE_TEMPLATE/help_wanted.md b/.github/ISSUE_TEMPLATE/help_wanted.md new file mode 100644 index 0000000..debe1f5 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/help_wanted.md @@ -0,0 +1,24 @@ +--- +name: Help Wanted +about: Need help +labels: 'help wanted' +--- + +We sincerely recommend that you first complete the following checklist: + +- Read the [tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design. +- No similar [issue](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue)(including closed ones) exists +- Try to find the answer on [Jekyll Forum](https://talk.jekyllrb.com/) and [StackOverflow](https://stackoverflow.com/questions/tagged/jekyll). +- The ask is based on the latest code of the `master` branch. + +## Description + + + +## What you have tried + + diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index c38a93a..42f5747 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -4,17 +4,4 @@ about: Ask whatever you want labels: question --- - - -## Checklist - - - -- [ ] I have read the [newlest tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design. -- [ ] There is no similar question on [existing issues](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue) (including closed ones). -- [ ] I have tried to find the answer on [Jekyll Forum](https://talk.jekyllrb.com/) and [StackOverflow](https://stackoverflow.com/questions/tagged/jekyll). -- [ ] My question is based on the latest code of the `master` branch. - -## Description - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index d26834f..8e41f4f 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -32,11 +32,3 @@ Please describe the tests that you ran to verify your changes. Provide instructi - Ruby version: - Bundler version: - Jekyll version: - -### Checklist - - -- [ ] I have performed a self-review of my code -- [ ] I have commented on my code, particularly in hard-to-understand areas -- [ ] I have made corresponding changes to the documentation -- [ ] My changes generate no new warnings diff --git a/.github/workflows/issue-interceptor.yml b/.github/workflows/issue-interceptor.yml deleted file mode 100644 index 22bafdc..0000000 --- a/.github/workflows/issue-interceptor.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Intercept bad issues - -on: - issues: - types: [opened, edited] - -jobs: - auto_close_issues: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v1 - - name: Auto close issues that did not follow template - uses: lucasbento/auto-close-issues@v1.0.2 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - issue-close-message: ":wave: Hi @${issue.user.login},\n\nThis issue is being automatically closed because it does not follow the issue template. Please DO NOT open another similar issue, try to edit the current issue according to the template, then it will be reopened automatically." - closed-issues-label: "🙁 Not following issue template" From c3a840076e6091fb3789cc2dc7ce8060ebdb574a Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Wed, 15 Feb 2023 04:53:40 +0800 Subject: [PATCH 06/35] refactor: replace the deprecated js api --- _javascript/commons/back-to-top.js | 4 +-- _javascript/commons/mode-toggle.js | 4 +-- _javascript/commons/scroll-helper.js | 4 +-- _javascript/commons/search-display.js | 13 ++++----- _javascript/commons/sidebar.js | 4 +-- _javascript/commons/topbar-switcher.js | 4 +-- _javascript/commons/topbar-title.js | 2 +- _javascript/utils/clipboard.js | 38 ++++++++++---------------- _javascript/utils/locale-datetime.js | 2 +- _javascript/utils/smooth-scroll.js | 18 ++++++------ assets/js/dist/categories.min.js | 2 +- assets/js/dist/commons.min.js | 2 +- assets/js/dist/home.min.js | 2 +- assets/js/dist/misc.min.js | 2 +- assets/js/dist/page.min.js | 2 +- assets/js/dist/post.min.js | 2 +- 16 files changed, 47 insertions(+), 58 deletions(-) diff --git a/_javascript/commons/back-to-top.js b/_javascript/commons/back-to-top.js index e876147..e577e8f 100644 --- a/_javascript/commons/back-to-top.js +++ b/_javascript/commons/back-to-top.js @@ -2,7 +2,7 @@ * Reference: https://bootsnipp.com/snippets/featured/link-to-top-page */ $(function() { - $(window).scroll(() => { + $(window).on('scroll',() => { if ($(this).scrollTop() > 50 && $("#sidebar-trigger").css("display") === "none") { $("#back-to-top").fadeIn(); @@ -11,7 +11,7 @@ $(function() { } }); - $("#back-to-top").click(() => { + $("#back-to-top").on('click',() => { $("body,html").animate({ scrollTop: 0 }, 800); diff --git a/_javascript/commons/mode-toggle.js b/_javascript/commons/mode-toggle.js index 6581f08..a83bc58 100644 --- a/_javascript/commons/mode-toggle.js +++ b/_javascript/commons/mode-toggle.js @@ -2,12 +2,12 @@ * Listener for theme mode toggle */ $(function () { - $(".mode-toggle").click((e) => { + $(".mode-toggle").on('click',(e) => { const $target = $(e.target); let $btn = ($target.prop("tagName") === "button".toUpperCase() ? $target : $target.parent()); - $btn.blur(); // remove the clicking outline + $btn.trigger('blur'); // remove the clicking outline flipMode(); }); }); diff --git a/_javascript/commons/scroll-helper.js b/_javascript/commons/scroll-helper.js index 419418c..55c1b49 100644 --- a/_javascript/commons/scroll-helper.js +++ b/_javascript/commons/scroll-helper.js @@ -11,8 +11,8 @@ const ScrollHelper = (function () { let orientationLocked = false; return { - hideTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, false), - showTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, true), + hideTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, 'false'), + showTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, 'true'), // scroll up diff --git a/_javascript/commons/search-display.js b/_javascript/commons/search-display.js index ddc73c1..536cfbc 100644 --- a/_javascript/commons/search-display.js +++ b/_javascript/commons/search-display.js @@ -79,9 +79,6 @@ $(function () { input.val(""); visible = false; } - }, - isVisible() { - return visible; } }; @@ -91,22 +88,22 @@ $(function () { return btnCancel.hasClass("loaded"); } - btnSearchTrigger.click(function () { + btnSearchTrigger.on('click',function () { mobileSearchBar.on(); resultSwitch.on(); - input.focus(); + input.trigger('focus'); }); - btnCancel.click(function () { + btnCancel.on('click',function () { mobileSearchBar.off(); resultSwitch.off(); }); - input.focus(function () { + input.on('focus',function () { searchWrapper.addClass("input-focus"); }); - input.focusout(function () { + input.on('focusout', function () { searchWrapper.removeClass("input-focus"); }); diff --git a/_javascript/commons/sidebar.js b/_javascript/commons/sidebar.js index 121353f..66d20df 100644 --- a/_javascript/commons/sidebar.js +++ b/_javascript/commons/sidebar.js @@ -22,7 +22,7 @@ $(function () { }()); - $("#sidebar-trigger").click(sidebarUtil.toggle); + $("#sidebar-trigger").on('click', sidebarUtil.toggle); - $("#mask").click(sidebarUtil.toggle); + $("#mask").on('click', sidebarUtil.toggle); }); diff --git a/_javascript/commons/topbar-switcher.js b/_javascript/commons/topbar-switcher.js index 91c857e..e4c2b97 100644 --- a/_javascript/commons/topbar-switcher.js +++ b/_javascript/commons/topbar-switcher.js @@ -21,7 +21,7 @@ $(function () { ScrollHelper.hideTopbar(); if ($searchInput.is(":focus")) { - $searchInput.blur(); /* remove focus */ + $searchInput.trigger('blur'); /* remove focus */ } } else { // Scroll up @@ -73,7 +73,7 @@ $(function () { }); } - $(window).scroll(() => { + $(window).on('scroll',() => { if (didScroll) { return; } diff --git a/_javascript/commons/topbar-title.js b/_javascript/commons/topbar-title.js index fd27a7d..42e3c2d 100644 --- a/_javascript/commons/topbar-title.js +++ b/_javascript/commons/topbar-title.js @@ -60,7 +60,7 @@ $(function () { observer.observe(document.querySelector(titleSelector)); /* Click title will scroll to top */ - $topbarTitle.click(function () { + $topbarTitle.on('click', function () { $("body,html").animate({scrollTop: 0}, 800); }); diff --git a/_javascript/utils/clipboard.js b/_javascript/utils/clipboard.js index 1b5001b..73f33fd 100644 --- a/_javascript/utils/clipboard.js +++ b/_javascript/utils/clipboard.js @@ -97,8 +97,7 @@ $(function () { /* --- Post link sharing --- */ - $('#copy-link').click((e) => { - + $('#copy-link').on('click',(e) => { let target = $(e.target); if (isLocked(target)) { @@ -106,28 +105,19 @@ $(function () { } // Copy URL to clipboard + navigator.clipboard + .writeText(window.location.href) + .then(() => { + const defaultTitle = target.attr(ATTR_TITLE_ORIGIN); + const succeedTitle = target.attr(ATTR_TITLE_SUCCEED); + // Switch tooltip title + target.attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show'); + lock(target); - const url = window.location.href; - const $temp = $(""); - - $("body").append($temp); - $temp.val(url).select(); - document.execCommand("copy"); - $temp.remove(); - - // Switch tooltip title - - const defaultTitle = target.attr(ATTR_TITLE_ORIGIN); - const succeedTitle = target.attr(ATTR_TITLE_SUCCEED); - - target.attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show'); - lock(target); - - setTimeout(() => { - target.attr(ATTR_TITLE_ORIGIN, defaultTitle); - unlock(target); - }, TIMEOUT); - + setTimeout(() => { + target.attr(ATTR_TITLE_ORIGIN, defaultTitle); + unlock(target); + }, TIMEOUT); + }); }); - }); diff --git a/_javascript/utils/locale-datetime.js b/_javascript/utils/locale-datetime.js index 80d86c9..bfd3a66 100644 --- a/_javascript/utils/locale-datetime.js +++ b/_javascript/utils/locale-datetime.js @@ -6,7 +6,7 @@ /* A tool for locale datetime */ const LocaleHelper = (function () { - const locale = $('html').attr('lang').substr(0, 2); + const locale = $('html').attr('lang').substring(0, 2); const attrTimestamp = 'data-ts'; const attrDateFormat = 'data-df'; diff --git a/_javascript/utils/smooth-scroll.js b/_javascript/utils/smooth-scroll.js index f8aba66..2c030e1 100644 --- a/_javascript/utils/smooth-scroll.js +++ b/_javascript/utils/smooth-scroll.js @@ -15,7 +15,7 @@ $(function () { $("a[href*='#']") .not("[href='#']") .not("[href='#0']") - .click(function (event) { + .on('click', function (event) { if (this.pathname.replace(/^\//, "") !== location.pathname.replace(/^\//, "")) { return; @@ -64,28 +64,30 @@ $(function () { $("html").animate({ scrollTop: destOffset }, 500, () => { - $target.focus(); + $target.trigger("focus"); /* clean up old scroll mark */ - if ($(`[${ATTR_SCROLL_FOCUS}=true]`).length) { - $(`[${ATTR_SCROLL_FOCUS}=true]`).attr(ATTR_SCROLL_FOCUS, false); + const $scroll_focus = $(`[${ATTR_SCROLL_FOCUS}=true]`); + if ($scroll_focus.length) { + $scroll_focus.attr(ATTR_SCROLL_FOCUS, "false"); } /* Clean :target links */ - if ($(":target").length) { /* element that visited by the URL with hash */ - $(":target").attr(ATTR_SCROLL_FOCUS, false); + const $target_links = $(":target"); + if ($target_links.length) { /* element that visited by the URL with hash */ + $target_links.attr(ATTR_SCROLL_FOCUS, "false"); } /* set scroll mark to footnotes */ if (toFootnote || toFootnoteRef) { - $target.attr(ATTR_SCROLL_FOCUS, true); + $target.attr(ATTR_SCROLL_FOCUS, "true"); } if ($target.is(":focus")) { /* Checking if the target was focused */ return false; } else { $target.attr("tabindex", "-1"); /* Adding tabindex for elements not focusable */ - $target.focus(); /* Set focus again */ + $target.trigger("focus"); /* Set focus again */ } if (ScrollHelper.hasScrollUpTask()) { diff --git a/assets/js/dist/categories.min.js b/assets/js/dist/categories.min.js index 2c9d0e6..db5a001 100644 --- a/assets/js/dist/categories.min.js +++ b/assets/js/dist/categories.min.js @@ -3,4 +3,4 @@ * © 2019 Cotes Chung * MIT Licensed */ -$(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").click(o=>{o=$(o.target);(o.prop("tagName")==="button".toUpperCase()?o:o.parent()).blur(),flipMode()})});const ScrollHelper=function(){const o=$("body"),e="data-topbar-visible",t=$("#topbar-wrapper").outerHeight();let a=0,r=!1,l=!1;return{hideTopbar:()=>o.attr(e,!1),showTopbar:()=>o.attr(e,!0),addScrollUpTask:()=>{a+=1,r=r||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>t,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const o=$("#sidebar-trigger"),e=$("#search-trigger"),t=$("#search-cancel"),a=$("#main"),r=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let o=0;return{block(){o=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(o)},getOffset(){return o}}}(),p={on(){o.addClass("unloaded"),r.addClass("unloaded"),e.addClass("unloaded"),l.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),l.removeClass("d-flex"),o.removeClass("unloaded"),r.removeClass("unloaded"),e.removeClass("unloaded")}},f=function(){let o=!1;return{on(){o||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),o=!0)},off(){o&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),i.val(""),o=!1)},isVisible(){return o}}}();function u(){return t.hasClass("loaded")}e.click(function(){p.on(),f.on(),i.focus()}),t.click(function(){p.off(),f.off()}),i.focus(function(){l.addClass("input-focus")}),i.focusout(function(){l.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?u()?c.removeClass("unloaded"):f.off():(f.on(),u()&&c.addClass("unloaded"))})}),$(function(){var o=function(){const o="sidebar-display";let e=!1;const t=$("body");return{toggle(){!1===e?t.attr(o,""):t.removeAttr(o),e=!e}}}();$("#sidebar-trigger").click(o.toggle),$("#mask").click(o.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),t=ScrollHelper.getTopbarHeight();let o,a=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var o=screen.orientation.type;"landscape-primary"!==o&&"landscape-secondary"!==o||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).scroll(()=>{o=o||!0}),setInterval(()=>{o&&(!function(){var o=$(this).scrollTop();if(!(Math.abs(a-o)<=t)){if(o>a)ScrollHelper.hideTopbar(),e.is(":focus")&&e.blur();else if(o+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=o}}(),o=!1)},250)}),$(function(){var o="div.post>h1:first-of-type",e=$(o);const n=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=e.text().trim(),r=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&n.text(a);new IntersectionObserver(o=>{var e,t;r?(t=$(window).scrollTop(),e=l{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",o=>{o=$(o.target);(o.prop("tagName")==="button".toUpperCase()?o:o.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const o=$("body"),e="data-topbar-visible",t=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>o.attr(e,"false"),showTopbar:()=>o.attr(e,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>t,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const o=$("#sidebar-trigger"),e=$("#search-trigger"),t=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let o=0;return{block(){o=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(o)},getOffset(){return o}}}(),p={on(){o.addClass("unloaded"),a.addClass("unloaded"),e.addClass("unloaded"),l.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),l.removeClass("d-flex"),o.removeClass("unloaded"),a.removeClass("unloaded"),e.removeClass("unloaded")}},f=function(){let o=!1;return{on(){o||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),o=!0)},off(){o&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),i.val(""),o=!1)}}}();function u(){return t.hasClass("loaded")}e.on("click",function(){p.on(),f.on(),i.trigger("focus")}),t.on("click",function(){p.off(),f.off()}),i.on("focus",function(){l.addClass("input-focus")}),i.on("focusout",function(){l.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?u()?c.removeClass("unloaded"):f.off():(f.on(),u()&&c.addClass("unloaded"))})}),$(function(){var o=function(){const o="sidebar-display";let e=!1;const t=$("body");return{toggle(){!1===e?t.attr(o,""):t.removeAttr(o),e=!e}}}();$("#sidebar-trigger").on("click",o.toggle),$("#mask").on("click",o.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),t=ScrollHelper.getTopbarHeight();let o,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var o=screen.orientation.type;"landscape-primary"!==o&&"landscape-secondary"!==o||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{o=o||!0}),setInterval(()=>{o&&(!function(){var o=$(this).scrollTop();if(!(Math.abs(r-o)<=t)){if(o>r)ScrollHelper.hideTopbar(),e.is(":focus")&&e.trigger("blur");else if(o+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=o}}(),o=!1)},250)}),$(function(){var o="div.post>h1:first-of-type",e=$(o);const n=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let r=e.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(o=>{var e,t;a?(t=$(window).scrollTop(),e=l{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").click(o=>{o=$(o.target);(o.prop("tagName")==="button".toUpperCase()?o:o.parent()).blur(),flipMode()})});const ScrollHelper=function(){const o=$("body"),e="data-topbar-visible",t=$("#topbar-wrapper").outerHeight();let l=0,r=!1,a=!1;return{hideTopbar:()=>o.attr(e,!1),showTopbar:()=>o.attr(e,!0),addScrollUpTask:()=>{l+=1,r=r||!0},popScrollUpTask:()=>--l,hasScrollUpTask:()=>0!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>t,orientationLocked:()=>!0===a,lockOrientation:()=>a=!0,unLockOrientation:()=>a=!1}}();$(function(){const o=$("#sidebar-trigger"),e=$("#search-trigger"),t=$("#search-cancel"),l=$("#main"),r=$("#topbar-title"),a=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let o=0;return{block(){o=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(o)},getOffset(){return o}}}(),p={on(){o.addClass("unloaded"),r.addClass("unloaded"),e.addClass("unloaded"),a.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),a.removeClass("d-flex"),o.removeClass("unloaded"),r.removeClass("unloaded"),e.removeClass("unloaded")}},u=function(){let o=!1;return{on(){o||(d.block(),n.removeClass("unloaded"),l.addClass("unloaded"),o=!0)},off(){o&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),l.removeClass("unloaded"),d.release(),i.val(""),o=!1)},isVisible(){return o}}}();function f(){return t.hasClass("loaded")}e.click(function(){p.on(),u.on(),i.focus()}),t.click(function(){p.off(),u.off()}),i.focus(function(){a.addClass("input-focus")}),i.focusout(function(){a.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var o=function(){const o="sidebar-display";let e=!1;const t=$("body");return{toggle(){!1===e?t.attr(o,""):t.removeAttr(o),e=!e}}}();$("#sidebar-trigger").click(o.toggle),$("#mask").click(o.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),t=ScrollHelper.getTopbarHeight();let o,l=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var o=screen.orientation.type;"landscape-primary"!==o&&"landscape-secondary"!==o||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).scroll(()=>{o=o||!0}),setInterval(()=>{o&&(!function(){var o=$(this).scrollTop();if(!(Math.abs(l-o)<=t)){if(o>l)ScrollHelper.hideTopbar(),e.is(":focus")&&e.blur();else if(o+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}l=o}}(),o=!1)},250)}),$(function(){var o="div.post>h1:first-of-type",e=$(o);const n=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let l=e.text().trim(),r=!1,a=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(l)&&(l=l.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&n.text(l);new IntersectionObserver(o=>{var e,t;r?(t=$(window).scrollTop(),e=a{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",o=>{o=$(o.target);(o.prop("tagName")==="button".toUpperCase()?o:o.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const o=$("body"),e="data-topbar-visible",t=$("#topbar-wrapper").outerHeight();let r=0,l=!1,n=!1;return{hideTopbar:()=>o.attr(e,"false"),showTopbar:()=>o.attr(e,"true"),addScrollUpTask:()=>{r+=1,l=l||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0!0===l,unlockTopbar:()=>l=!1,getTopbarHeight:()=>t,orientationLocked:()=>!0===n,lockOrientation:()=>n=!0,unLockOrientation:()=>n=!1}}();$(function(){const o=$("#sidebar-trigger"),e=$("#search-trigger"),t=$("#search-cancel"),r=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),a=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let o=0;return{block(){o=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(o)},getOffset(){return o}}}(),p={on(){o.addClass("unloaded"),l.addClass("unloaded"),e.addClass("unloaded"),n.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),n.removeClass("d-flex"),o.removeClass("unloaded"),l.removeClass("unloaded"),e.removeClass("unloaded")}},u=function(){let o=!1;return{on(){o||(d.block(),a.removeClass("unloaded"),r.addClass("unloaded"),o=!0)},off(){o&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),a.addClass("unloaded"),r.removeClass("unloaded"),d.release(),i.val(""),o=!1)}}}();function f(){return t.hasClass("loaded")}e.on("click",function(){p.on(),u.on(),i.trigger("focus")}),t.on("click",function(){p.off(),u.off()}),i.on("focus",function(){n.addClass("input-focus")}),i.on("focusout",function(){n.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var o=function(){const o="sidebar-display";let e=!1;const t=$("body");return{toggle(){!1===e?t.attr(o,""):t.removeAttr(o),e=!e}}}();$("#sidebar-trigger").on("click",o.toggle),$("#mask").on("click",o.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),t=ScrollHelper.getTopbarHeight();let o,r=0;function l(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var o=screen.orientation.type;"landscape-primary"!==o&&"landscape-secondary"!==o||l()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&l()}),$(window).on("scroll",()=>{o=o||!0}),setInterval(()=>{o&&(!function(){var o=$(this).scrollTop();if(!(Math.abs(r-o)<=t)){if(o>r)ScrollHelper.hideTopbar(),e.is(":focus")&&e.trigger("blur");else if(o+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=o}}(),o=!1)},250)}),$(function(){var o="div.post>h1:first-of-type",e=$(o);const a=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!a.is(":hidden")){const s=a.text().trim();let r=e.text().trim(),l=!1,n=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&a.text(r);new IntersectionObserver(o=>{var e,t;l?(t=$(window).scrollTop(),e=n{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").click(e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).blur(),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let a=0,l=!1,r=!1;return{hideTopbar:()=>e.attr(t,!1),showTopbar:()=>e.attr(t,!0),addScrollUpTask:()=>{a+=1,l=l||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0!0===l,unlockTopbar:()=>l=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===r,lockOrientation:()=>r=!0,unLockOrientation:()=>r=!1}}(),LocaleHelper=($(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#main"),l=$("#topbar-title"),r=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),l.addClass("unloaded"),t.addClass("unloaded"),r.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),r.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),i.val(""),e=!1)},isVisible(){return e}}}();function f(){return o.hasClass("loaded")}t.click(function(){p.on(),u.on(),i.focus()}),o.click(function(){p.off(),u.off()}),i.focus(function(){r.addClass("input-focus")}),i.focusout(function(){r.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,a=0;function l(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||l()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&l()}),$(window).scroll(()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(a-e)<=o)){if(e>a)ScrollHelper.hideTopbar(),t.is(":focus")&&t.blur();else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=t.text().trim(),l=!1,r=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(a);new IntersectionObserver(e=>{var t,o;l?(o=$(window).scrollTop(),t=re,attrTimestamp:()=>t,attrDateFormat:()=>o,getTimestamp:e=>Number(e.attr(t)),getDateFormat:e=>e.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var e=dayjs.unix(LocaleHelper.getTimestamp($(this))),t=e.format(LocaleHelper.getDateFormat($(this))),t=($(this).text(t),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==t&&"tooltip"===t&&(t=e.format("llll"),$(this).attr("data-original-title",t))})}); +$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let a=0,r=!1,l=!1;return{hideTopbar:()=>e.attr(t,"false"),showTopbar:()=>e.attr(t,"true"),addScrollUpTask:()=>{a+=1,r=r||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}(),LocaleHelper=($(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#main"),r=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),r.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),r.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),i.val(""),e=!1)}}}();function f(){return o.hasClass("loaded")}t.on("click",function(){p.on(),u.on(),i.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),i.on("focus",function(){l.addClass("input-focus")}),i.on("focusout",function(){l.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").on("click",e.toggle),$("#mask").on("click",e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,a=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).on("scroll",()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(a-e)<=o)){if(e>a)ScrollHelper.hideTopbar(),t.is(":focus")&&t.trigger("blur");else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=t.text().trim(),r=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(a);new IntersectionObserver(e=>{var t,o;r?(o=$(window).scrollTop(),t=le,attrTimestamp:()=>t,attrDateFormat:()=>o,getTimestamp:e=>Number(e.attr(t)),getDateFormat:e=>e.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var e=dayjs.unix(LocaleHelper.getTimestamp($(this))),t=e.format(LocaleHelper.getDateFormat($(this))),t=($(this).text(t),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==t&&"tooltip"===t&&(t=e.format("llll"),$(this).attr("data-original-title",t))})}); diff --git a/assets/js/dist/misc.min.js b/assets/js/dist/misc.min.js index b85d184..3190dd8 100644 --- a/assets/js/dist/misc.min.js +++ b/assets/js/dist/misc.min.js @@ -3,4 +3,4 @@ * © 2019 Cotes Chung * MIT Licensed */ -$(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").click(e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).blur(),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let a=0,l=!1,r=!1;return{hideTopbar:()=>e.attr(t,!1),showTopbar:()=>e.attr(t,!0),addScrollUpTask:()=>{a+=1,l=l||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0!0===l,unlockTopbar:()=>l=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===r,lockOrientation:()=>r=!0,unLockOrientation:()=>r=!1}}(),LocaleHelper=($(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#main"),l=$("#topbar-title"),r=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),l.addClass("unloaded"),t.addClass("unloaded"),r.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),r.removeClass("d-flex"),e.removeClass("unloaded"),l.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),i.val(""),e=!1)},isVisible(){return e}}}();function f(){return o.hasClass("loaded")}t.click(function(){p.on(),u.on(),i.focus()}),o.click(function(){p.off(),u.off()}),i.focus(function(){r.addClass("input-focus")}),i.focusout(function(){r.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,a=0;function l(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||l()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&l()}),$(window).scroll(()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(a-e)<=o)){if(e>a)ScrollHelper.hideTopbar(),t.is(":focus")&&t.blur();else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=t.text().trim(),l=!1,r=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(a);new IntersectionObserver(e=>{var t,o;l?(o=$(window).scrollTop(),t=re,attrTimestamp:()=>t,attrDateFormat:()=>o,getTimestamp:e=>Number(e.attr(t)),getDateFormat:e=>e.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var e=dayjs.unix(LocaleHelper.getTimestamp($(this))),t=e.format(LocaleHelper.getDateFormat($(this))),t=($(this).text(t),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==t&&"tooltip"===t&&(t=e.format("llll"),$(this).attr("data-original-title",t))})}); +$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let a=0,r=!1,l=!1;return{hideTopbar:()=>e.attr(t,"false"),showTopbar:()=>e.attr(t,"true"),addScrollUpTask:()=>{a+=1,r=r||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}(),LocaleHelper=($(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#main"),r=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),r.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),r.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),i.val(""),e=!1)}}}();function f(){return o.hasClass("loaded")}t.on("click",function(){p.on(),u.on(),i.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),i.on("focus",function(){l.addClass("input-focus")}),i.on("focusout",function(){l.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").on("click",e.toggle),$("#mask").on("click",e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,a=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).on("scroll",()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(a-e)<=o)){if(e>a)ScrollHelper.hideTopbar(),t.is(":focus")&&t.trigger("blur");else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=t.text().trim(),r=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(a);new IntersectionObserver(e=>{var t,o;r?(o=$(window).scrollTop(),t=le,attrTimestamp:()=>t,attrDateFormat:()=>o,getTimestamp:e=>Number(e.attr(t)),getDateFormat:e=>e.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var e=dayjs.unix(LocaleHelper.getTimestamp($(this))),t=e.format(LocaleHelper.getDateFormat($(this))),t=($(this).text(t),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==t&&"tooltip"===t&&(t=e.format("llll"),$(this).attr("data-original-title",t))})}); diff --git a/assets/js/dist/page.min.js b/assets/js/dist/page.min.js index f3d8617..50d5fba 100644 --- a/assets/js/dist/page.min.js +++ b/assets/js/dist/page.min.js @@ -3,4 +3,4 @@ * © 2019 Cotes Chung * MIT Licensed */ -$(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").click(e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).blur(),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>e.attr(t,!1),showTopbar:()=>e.attr(t,!0),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),a.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),a.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),e=!0)},off(){e&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),s.val(""),e=!1)},isVisible(){return e}}}();function h(){return o.hasClass("loaded")}t.click(function(){p.on(),u.on(),s.focus()}),o.click(function(){p.off(),u.off()}),s.focus(function(){l.addClass("input-focus")}),s.focusout(function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?h()?c.removeClass("unloaded"):u.off():(u.on(),h()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").click(e.toggle),$("#mask").click(e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).scroll(()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(r-e)<=o)){if(e>r)ScrollHelper.hideTopbar(),t.is(":focus")&&t.blur();else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let r=t.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(e=>{var t,o;a?(o=$(window).scrollTop(),t=lDate.now())return 1}}function i(e){$(e).attr(t,Date.now()+2e3)}function s(e){$(e).removeAttr(t)}var o=new ClipboardJS(e,{target(e){return e.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(e).tooltip({trigger:"hover",placement:"left"});const r=$(e).children().attr("class");o.on("success",e=>{e.clearSelection();const t=e.trigger;var o;n(t)||(e=t,$(e).children().attr("class","fas fa-check"),e=t,o=$(e).attr(a),$(e).attr(l,o).tooltip("show"),i(t),setTimeout(()=>{var e;e=t,$(e).tooltip("hide").removeAttr(l),e=t,$(e).children().attr("class",r),s(t)},2e3))}),$("#copy-link").click(e=>{let t=$(e.target);if(!n(t)){var e=window.location.href,o=$("");$("body").append(o),o.val(e).select(),document.execCommand("copy"),o.remove();const r=t.attr(l);e=t.attr(a);t.attr(l,e).tooltip("show"),i(t),setTimeout(()=>{t.attr(l,r),s(t)},2e3)}})}),$(function(){const e=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").click(function(a){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let t=RegExp(/^#fnref:/).test(l),o=!t&&RegExp(/^#fn:/).test(l);var n=l.includes(":")?l.replace(/:/g,"\\:"):l;let r=$(n);var n=e.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==r){a.preventDefault(),history.pushState&&history.pushState(null,null,l);a=$(window).scrollTop();let e=r.offset().top-=8;e{if(r.focus(),$(`[${s}=true]`).length&&$(`[${s}=true]`).attr(s,!1),$(":target").length&&$(":target").attr(s,!1),(o||t)&&r.attr(s,!0),r.is(":focus"))return!1;r.attr("tabindex","-1"),r.focus(),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); +$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>e.attr(t,"false"),showTopbar:()=>e.attr(t,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),a.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),a.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),e=!0)},off(){e&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),s.val(""),e=!1)}}}();function f(){return o.hasClass("loaded")}t.on("click",function(){p.on(),u.on(),s.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),s.on("focus",function(){l.addClass("input-focus")}),s.on("focusout",function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").on("click",e.toggle),$("#mask").on("click",e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(r-e)<=o)){if(e>r)ScrollHelper.hideTopbar(),t.is(":focus")&&t.trigger("blur");else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let r=t.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(e=>{var t,o;a?(o=$(window).scrollTop(),t=lDate.now())return 1}}function n(e){$(e).attr(t,Date.now()+2e3)}function i(e){$(e).removeAttr(t)}var o=new ClipboardJS(e,{target(e){return e.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(e).tooltip({trigger:"hover",placement:"left"});const s=$(e).children().attr("class");o.on("success",e=>{e.clearSelection();const t=e.trigger;var o;l(t)||(e=t,$(e).children().attr("class","fas fa-check"),e=t,o=$(e).attr(r),$(e).attr(a,o).tooltip("show"),n(t),setTimeout(()=>{var e;e=t,$(e).tooltip("hide").removeAttr(a),e=t,$(e).children().attr("class",s),i(t)},2e3))}),$("#copy-link").on("click",e=>{let o=$(e.target);l(o)||navigator.clipboard.writeText(window.location.href).then(()=>{const e=o.attr(a);var t=o.attr(r);o.attr(a,t).tooltip("show"),n(o),setTimeout(()=>{o.attr(a,e),i(o)},2e3)})})}),$(function(){const e=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").on("click",function(a){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let t=RegExp(/^#fnref:/).test(l),o=!t&&RegExp(/^#fn:/).test(l);var n=l.includes(":")?l.replace(/:/g,"\\:"):l;let r=$(n);var n=e.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==r){a.preventDefault(),history.pushState&&history.pushState(null,null,l);a=$(window).scrollTop();let e=r.offset().top-=8;e{r.trigger("focus");var e=$(`[${s}=true]`),e=(e.length&&e.attr(s,"false"),$(":target"));if(e.length&&e.attr(s,"false"),(o||t)&&r.attr(s,"true"),r.is(":focus"))return!1;r.attr("tabindex","-1"),r.trigger("focus"),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); diff --git a/assets/js/dist/post.min.js b/assets/js/dist/post.min.js index 05eda48..14f22bc 100644 --- a/assets/js/dist/post.min.js +++ b/assets/js/dist/post.min.js @@ -3,4 +3,4 @@ * © 2019 Cotes Chung * MIT Licensed */ -$(function(){$(window).scroll(()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").click(()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").click(t=>{t=$(t.target);(t.prop("tagName")==="button".toUpperCase()?t:t.parent()).blur(),flipMode()})});const ScrollHelper=function(){const t=$("body"),e="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let a=0,r=!1,l=!1;return{hideTopbar:()=>t.attr(e,!1),showTopbar:()=>t.attr(e,!0),addScrollUpTask:()=>{a+=1,r=r||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}(),LocaleHelper=($(function(){const t=$("#sidebar-trigger"),e=$("#search-trigger"),o=$("#search-cancel"),a=$("#main"),r=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let t=0;return{block(){t=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(t)},getOffset(){return t}}}(),p={on(){t.addClass("unloaded"),r.addClass("unloaded"),e.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),t.removeClass("unloaded"),r.removeClass("unloaded"),e.removeClass("unloaded")}},u=function(){let t=!1;return{on(){t||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),t=!0)},off(){t&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),s.val(""),t=!1)},isVisible(){return t}}}();function h(){return o.hasClass("loaded")}e.click(function(){p.on(),u.on(),s.focus()}),o.click(function(){p.off(),u.off()}),s.focus(function(){l.addClass("input-focus")}),s.focusout(function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?h()?c.removeClass("unloaded"):u.off():(u.on(),h()&&c.addClass("unloaded"))})}),$(function(){var t=function(){const t="sidebar-display";let e=!1;const o=$("body");return{toggle(){!1===e?o.attr(t,""):o.removeAttr(t),e=!e}}}();$("#sidebar-trigger").click(t.toggle),$("#mask").click(t.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),o=ScrollHelper.getTopbarHeight();let t,a=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var t=screen.orientation.type;"landscape-primary"!==t&&"landscape-secondary"!==t||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).scroll(()=>{t=t||!0}),setInterval(()=>{t&&(!function(){var t=$(this).scrollTop();if(!(Math.abs(a-t)<=o)){if(t>a)ScrollHelper.hideTopbar(),e.is(":focus")&&e.blur();else if(t+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=t}}(),t=!1)},250)}),$(function(){var t="div.post>h1:first-of-type",e=$(t);const n=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let a=e.text().trim(),r=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&n.text(a);new IntersectionObserver(t=>{var e,o;r?(o=$(window).scrollTop(),e=lt,attrTimestamp:()=>e,attrDateFormat:()=>o,getTimestamp:t=>Number(t.attr(e)),getDateFormat:t=>t.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var t=dayjs.unix(LocaleHelper.getTimestamp($(this))),e=t.format(LocaleHelper.getDateFormat($(this))),e=($(this).text(e),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==e&&"tooltip"===e&&(e=t.format("llll"),$(this).attr("data-original-title",e))})}),$(function(){var t=".code-header>button";const e="timeout",r="data-title-succeed",l="data-original-title";function n(t){if($(t)[0].hasAttribute(e)){t=$(t).attr(e);if(Number(t)>Date.now())return 1}}function i(t){$(t).attr(e,Date.now()+2e3)}function s(t){$(t).removeAttr(e)}var o=new ClipboardJS(t,{target(t){return t.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(t).tooltip({trigger:"hover",placement:"left"});const a=$(t).children().attr("class");o.on("success",t=>{t.clearSelection();const e=t.trigger;var o;n(e)||(t=e,$(t).children().attr("class","fas fa-check"),t=e,o=$(t).attr(r),$(t).attr(l,o).tooltip("show"),i(e),setTimeout(()=>{var t;t=e,$(t).tooltip("hide").removeAttr(l),t=e,$(t).children().attr("class",a),s(e)},2e3))}),$("#copy-link").click(t=>{let e=$(t.target);if(!n(e)){var t=window.location.href,o=$("");$("body").append(o),o.val(t).select(),document.execCommand("copy"),o.remove();const a=e.attr(l);t=e.attr(r);e.attr(l,t).tooltip("show"),i(e),setTimeout(()=>{e.attr(l,a),s(e)},2e3)}})}),$(function(){const t=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").click(function(r){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let e=RegExp(/^#fnref:/).test(l),o=!e&&RegExp(/^#fn:/).test(l);var n=l.includes(":")?l.replace(/:/g,"\\:"):l;let a=$(n);var n=t.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==a){r.preventDefault(),history.pushState&&history.pushState(null,null,l);r=$(window).scrollTop();let t=a.offset().top-=8;t{if(a.focus(),$(`[${s}=true]`).length&&$(`[${s}=true]`).attr(s,!1),$(":target").length&&$(":target").attr(s,!1),(o||e)&&a.attr(s,!0),a.is(":focus"))return!1;a.attr("tabindex","-1"),a.focus(),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); +$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",t=>{t=$(t.target);(t.prop("tagName")==="button".toUpperCase()?t:t.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const t=$("body"),e="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>t.attr(e,"false"),showTopbar:()=>t.attr(e,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}(),LocaleHelper=($(function(){const t=$("#sidebar-trigger"),e=$("#search-trigger"),o=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let t=0;return{block(){t=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(t)},getOffset(){return t}}}(),p={on(){t.addClass("unloaded"),a.addClass("unloaded"),e.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),t.removeClass("unloaded"),a.removeClass("unloaded"),e.removeClass("unloaded")}},u=function(){let t=!1;return{on(){t||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),t=!0)},off(){t&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),s.val(""),t=!1)}}}();function h(){return o.hasClass("loaded")}e.on("click",function(){p.on(),u.on(),s.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),s.on("focus",function(){l.addClass("input-focus")}),s.on("focusout",function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?h()?c.removeClass("unloaded"):u.off():(u.on(),h()&&c.addClass("unloaded"))})}),$(function(){var t=function(){const t="sidebar-display";let e=!1;const o=$("body");return{toggle(){!1===e?o.attr(t,""):o.removeAttr(t),e=!e}}}();$("#sidebar-trigger").on("click",t.toggle),$("#mask").on("click",t.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),o=ScrollHelper.getTopbarHeight();let t,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var t=screen.orientation.type;"landscape-primary"!==t&&"landscape-secondary"!==t||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{t=t||!0}),setInterval(()=>{t&&(!function(){var t=$(this).scrollTop();if(!(Math.abs(r-t)<=o)){if(t>r)ScrollHelper.hideTopbar(),e.is(":focus")&&e.trigger("blur");else if(t+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=t}}(),t=!1)},250)}),$(function(){var t="div.post>h1:first-of-type",e=$(t);const n=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let r=e.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(t=>{var e,o;a?(o=$(window).scrollTop(),e=lt,attrTimestamp:()=>e,attrDateFormat:()=>o,getTimestamp:t=>Number(t.attr(e)),getDateFormat:t=>t.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var t=dayjs.unix(LocaleHelper.getTimestamp($(this))),e=t.format(LocaleHelper.getDateFormat($(this))),e=($(this).text(e),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==e&&"tooltip"===e&&(e=t.format("llll"),$(this).attr("data-original-title",e))})}),$(function(){var t=".code-header>button";const e="timeout",r="data-title-succeed",a="data-original-title";function l(t){if($(t)[0].hasAttribute(e)){t=$(t).attr(e);if(Number(t)>Date.now())return 1}}function n(t){$(t).attr(e,Date.now()+2e3)}function i(t){$(t).removeAttr(e)}var o=new ClipboardJS(t,{target(t){return t.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(t).tooltip({trigger:"hover",placement:"left"});const s=$(t).children().attr("class");o.on("success",t=>{t.clearSelection();const e=t.trigger;var o;l(e)||(t=e,$(t).children().attr("class","fas fa-check"),t=e,o=$(t).attr(r),$(t).attr(a,o).tooltip("show"),n(e),setTimeout(()=>{var t;t=e,$(t).tooltip("hide").removeAttr(a),t=e,$(t).children().attr("class",s),i(e)},2e3))}),$("#copy-link").on("click",t=>{let o=$(t.target);l(o)||navigator.clipboard.writeText(window.location.href).then(()=>{const t=o.attr(a);var e=o.attr(r);o.attr(a,e).tooltip("show"),n(o),setTimeout(()=>{o.attr(a,t),i(o)},2e3)})})}),$(function(){const t=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").on("click",function(a){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let e=RegExp(/^#fnref:/).test(l),o=!e&&RegExp(/^#fn:/).test(l);var n=l.includes(":")?l.replace(/:/g,"\\:"):l;let r=$(n);var n=t.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==r){a.preventDefault(),history.pushState&&history.pushState(null,null,l);a=$(window).scrollTop();let t=r.offset().top-=8;t{r.trigger("focus");var t=$(`[${s}=true]`),t=(t.length&&t.attr(s,"false"),$(":target"));if(t.length&&t.attr(s,"false"),(o||e)&&r.attr(s,"true"),r.is(":focus"))return!1;r.attr("tabindex","-1"),r.trigger("focus"),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); From 5c6ec9d06b6571e2c0efe6652078442dca8af477 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Wed, 15 Feb 2023 05:03:09 +0800 Subject: [PATCH 07/35] fix: css selector string escaping vulnerability (#888) Resolves #888 --- _javascript/utils/smooth-scroll.js | 2 +- assets/js/dist/page.min.js | 2 +- assets/js/dist/post.min.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_javascript/utils/smooth-scroll.js b/_javascript/utils/smooth-scroll.js index 2c030e1..bd45b67 100644 --- a/_javascript/utils/smooth-scroll.js +++ b/_javascript/utils/smooth-scroll.js @@ -28,7 +28,7 @@ $(function () { const hash = decodeURI(this.hash); let toFootnoteRef = RegExp(/^#fnref:/).test(hash); let toFootnote = toFootnoteRef ? false : RegExp(/^#fn:/).test(hash); - let selector = hash.includes(":") ? hash.replace(/:/g, "\\:") : hash; + let selector = '#' + $.escapeSelector(hash.substring(1)); let $target = $(selector); let isMobileViews = $topbarTitle.is(":visible"); diff --git a/assets/js/dist/page.min.js b/assets/js/dist/page.min.js index 50d5fba..7eae8c8 100644 --- a/assets/js/dist/page.min.js +++ b/assets/js/dist/page.min.js @@ -3,4 +3,4 @@ * © 2019 Cotes Chung * MIT Licensed */ -$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>e.attr(t,"false"),showTopbar:()=>e.attr(t,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),a.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),a.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),e=!0)},off(){e&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),s.val(""),e=!1)}}}();function f(){return o.hasClass("loaded")}t.on("click",function(){p.on(),u.on(),s.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),s.on("focus",function(){l.addClass("input-focus")}),s.on("focusout",function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").on("click",e.toggle),$("#mask").on("click",e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(r-e)<=o)){if(e>r)ScrollHelper.hideTopbar(),t.is(":focus")&&t.trigger("blur");else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let r=t.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(e=>{var t,o;a?(o=$(window).scrollTop(),t=lDate.now())return 1}}function n(e){$(e).attr(t,Date.now()+2e3)}function i(e){$(e).removeAttr(t)}var o=new ClipboardJS(e,{target(e){return e.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(e).tooltip({trigger:"hover",placement:"left"});const s=$(e).children().attr("class");o.on("success",e=>{e.clearSelection();const t=e.trigger;var o;l(t)||(e=t,$(e).children().attr("class","fas fa-check"),e=t,o=$(e).attr(r),$(e).attr(a,o).tooltip("show"),n(t),setTimeout(()=>{var e;e=t,$(e).tooltip("hide").removeAttr(a),e=t,$(e).children().attr("class",s),i(t)},2e3))}),$("#copy-link").on("click",e=>{let o=$(e.target);l(o)||navigator.clipboard.writeText(window.location.href).then(()=>{const e=o.attr(a);var t=o.attr(r);o.attr(a,t).tooltip("show"),n(o),setTimeout(()=>{o.attr(a,e),i(o)},2e3)})})}),$(function(){const e=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").on("click",function(a){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let t=RegExp(/^#fnref:/).test(l),o=!t&&RegExp(/^#fn:/).test(l);var n=l.includes(":")?l.replace(/:/g,"\\:"):l;let r=$(n);var n=e.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==r){a.preventDefault(),history.pushState&&history.pushState(null,null,l);a=$(window).scrollTop();let e=r.offset().top-=8;e{r.trigger("focus");var e=$(`[${s}=true]`),e=(e.length&&e.attr(s,"false"),$(":target"));if(e.length&&e.attr(s,"false"),(o||t)&&r.attr(s,"true"),r.is(":focus"))return!1;r.attr("tabindex","-1"),r.trigger("focus"),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); +$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>e.attr(t,"false"),showTopbar:()=>e.attr(t,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),a.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),a.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),e=!0)},off(){e&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),s.val(""),e=!1)}}}();function f(){return o.hasClass("loaded")}t.on("click",function(){p.on(),u.on(),s.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),s.on("focus",function(){l.addClass("input-focus")}),s.on("focusout",function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").on("click",e.toggle),$("#mask").on("click",e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(r-e)<=o)){if(e>r)ScrollHelper.hideTopbar(),t.is(":focus")&&t.trigger("blur");else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let r=t.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(e=>{var t,o;a?(o=$(window).scrollTop(),t=lDate.now())return 1}}function n(e){$(e).attr(t,Date.now()+2e3)}function i(e){$(e).removeAttr(t)}var o=new ClipboardJS(e,{target(e){return e.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(e).tooltip({trigger:"hover",placement:"left"});const s=$(e).children().attr("class");o.on("success",e=>{e.clearSelection();const t=e.trigger;var o;l(t)||(e=t,$(e).children().attr("class","fas fa-check"),e=t,o=$(e).attr(r),$(e).attr(a,o).tooltip("show"),n(t),setTimeout(()=>{var e;e=t,$(e).tooltip("hide").removeAttr(a),e=t,$(e).children().attr("class",s),i(t)},2e3))}),$("#copy-link").on("click",e=>{let o=$(e.target);l(o)||navigator.clipboard.writeText(window.location.href).then(()=>{const e=o.attr(a);var t=o.attr(r);o.attr(a,t).tooltip("show"),n(o),setTimeout(()=>{o.attr(a,e),i(o)},2e3)})})}),$(function(){const e=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").on("click",function(a){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let t=RegExp(/^#fnref:/).test(l),o=!t&&RegExp(/^#fn:/).test(l);var n="#"+$.escapeSelector(l.substring(1));let r=$(n);var n=e.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==r){a.preventDefault(),history.pushState&&history.pushState(null,null,l);a=$(window).scrollTop();let e=r.offset().top-=8;e{r.trigger("focus");var e=$(`[${s}=true]`),e=(e.length&&e.attr(s,"false"),$(":target"));if(e.length&&e.attr(s,"false"),(o||t)&&r.attr(s,"true"),r.is(":focus"))return!1;r.attr("tabindex","-1"),r.trigger("focus"),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); diff --git a/assets/js/dist/post.min.js b/assets/js/dist/post.min.js index 14f22bc..f6c6ba2 100644 --- a/assets/js/dist/post.min.js +++ b/assets/js/dist/post.min.js @@ -3,4 +3,4 @@ * © 2019 Cotes Chung * MIT Licensed */ -$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",t=>{t=$(t.target);(t.prop("tagName")==="button".toUpperCase()?t:t.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const t=$("body"),e="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>t.attr(e,"false"),showTopbar:()=>t.attr(e,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}(),LocaleHelper=($(function(){const t=$("#sidebar-trigger"),e=$("#search-trigger"),o=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let t=0;return{block(){t=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(t)},getOffset(){return t}}}(),p={on(){t.addClass("unloaded"),a.addClass("unloaded"),e.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),t.removeClass("unloaded"),a.removeClass("unloaded"),e.removeClass("unloaded")}},u=function(){let t=!1;return{on(){t||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),t=!0)},off(){t&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),s.val(""),t=!1)}}}();function h(){return o.hasClass("loaded")}e.on("click",function(){p.on(),u.on(),s.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),s.on("focus",function(){l.addClass("input-focus")}),s.on("focusout",function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?h()?c.removeClass("unloaded"):u.off():(u.on(),h()&&c.addClass("unloaded"))})}),$(function(){var t=function(){const t="sidebar-display";let e=!1;const o=$("body");return{toggle(){!1===e?o.attr(t,""):o.removeAttr(t),e=!e}}}();$("#sidebar-trigger").on("click",t.toggle),$("#mask").on("click",t.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),o=ScrollHelper.getTopbarHeight();let t,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var t=screen.orientation.type;"landscape-primary"!==t&&"landscape-secondary"!==t||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{t=t||!0}),setInterval(()=>{t&&(!function(){var t=$(this).scrollTop();if(!(Math.abs(r-t)<=o)){if(t>r)ScrollHelper.hideTopbar(),e.is(":focus")&&e.trigger("blur");else if(t+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=t}}(),t=!1)},250)}),$(function(){var t="div.post>h1:first-of-type",e=$(t);const n=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let r=e.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(t=>{var e,o;a?(o=$(window).scrollTop(),e=lt,attrTimestamp:()=>e,attrDateFormat:()=>o,getTimestamp:t=>Number(t.attr(e)),getDateFormat:t=>t.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var t=dayjs.unix(LocaleHelper.getTimestamp($(this))),e=t.format(LocaleHelper.getDateFormat($(this))),e=($(this).text(e),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==e&&"tooltip"===e&&(e=t.format("llll"),$(this).attr("data-original-title",e))})}),$(function(){var t=".code-header>button";const e="timeout",r="data-title-succeed",a="data-original-title";function l(t){if($(t)[0].hasAttribute(e)){t=$(t).attr(e);if(Number(t)>Date.now())return 1}}function n(t){$(t).attr(e,Date.now()+2e3)}function i(t){$(t).removeAttr(e)}var o=new ClipboardJS(t,{target(t){return t.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(t).tooltip({trigger:"hover",placement:"left"});const s=$(t).children().attr("class");o.on("success",t=>{t.clearSelection();const e=t.trigger;var o;l(e)||(t=e,$(t).children().attr("class","fas fa-check"),t=e,o=$(t).attr(r),$(t).attr(a,o).tooltip("show"),n(e),setTimeout(()=>{var t;t=e,$(t).tooltip("hide").removeAttr(a),t=e,$(t).children().attr("class",s),i(e)},2e3))}),$("#copy-link").on("click",t=>{let o=$(t.target);l(o)||navigator.clipboard.writeText(window.location.href).then(()=>{const t=o.attr(a);var e=o.attr(r);o.attr(a,e).tooltip("show"),n(o),setTimeout(()=>{o.attr(a,t),i(o)},2e3)})})}),$(function(){const t=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").on("click",function(a){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let e=RegExp(/^#fnref:/).test(l),o=!e&&RegExp(/^#fn:/).test(l);var n=l.includes(":")?l.replace(/:/g,"\\:"):l;let r=$(n);var n=t.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==r){a.preventDefault(),history.pushState&&history.pushState(null,null,l);a=$(window).scrollTop();let t=r.offset().top-=8;t{r.trigger("focus");var t=$(`[${s}=true]`),t=(t.length&&t.attr(s,"false"),$(":target"));if(t.length&&t.attr(s,"false"),(o||e)&&r.attr(s,"true"),r.is(":focus"))return!1;r.attr("tabindex","-1"),r.trigger("focus"),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); +$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",t=>{t=$(t.target);(t.prop("tagName")==="button".toUpperCase()?t:t.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const t=$("body"),e="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>t.attr(e,"false"),showTopbar:()=>t.attr(e,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}(),LocaleHelper=($(function(){const t=$("#sidebar-trigger"),e=$("#search-trigger"),o=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let t=0;return{block(){t=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(t)},getOffset(){return t}}}(),p={on(){t.addClass("unloaded"),a.addClass("unloaded"),e.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),t.removeClass("unloaded"),a.removeClass("unloaded"),e.removeClass("unloaded")}},u=function(){let t=!1;return{on(){t||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),t=!0)},off(){t&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),s.val(""),t=!1)}}}();function h(){return o.hasClass("loaded")}e.on("click",function(){p.on(),u.on(),s.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),s.on("focus",function(){l.addClass("input-focus")}),s.on("focusout",function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?h()?c.removeClass("unloaded"):u.off():(u.on(),h()&&c.addClass("unloaded"))})}),$(function(){var t=function(){const t="sidebar-display";let e=!1;const o=$("body");return{toggle(){!1===e?o.attr(t,""):o.removeAttr(t),e=!e}}}();$("#sidebar-trigger").on("click",t.toggle),$("#mask").on("click",t.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),o=ScrollHelper.getTopbarHeight();let t,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var t=screen.orientation.type;"landscape-primary"!==t&&"landscape-secondary"!==t||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{t=t||!0}),setInterval(()=>{t&&(!function(){var t=$(this).scrollTop();if(!(Math.abs(r-t)<=o)){if(t>r)ScrollHelper.hideTopbar(),e.is(":focus")&&e.trigger("blur");else if(t+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=t}}(),t=!1)},250)}),$(function(){var t="div.post>h1:first-of-type",e=$(t);const n=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let r=e.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(t=>{var e,o;a?(o=$(window).scrollTop(),e=lt,attrTimestamp:()=>e,attrDateFormat:()=>o,getTimestamp:t=>Number(t.attr(e)),getDateFormat:t=>t.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var t=dayjs.unix(LocaleHelper.getTimestamp($(this))),e=t.format(LocaleHelper.getDateFormat($(this))),e=($(this).text(e),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==e&&"tooltip"===e&&(e=t.format("llll"),$(this).attr("data-original-title",e))})}),$(function(){var t=".code-header>button";const e="timeout",r="data-title-succeed",a="data-original-title";function l(t){if($(t)[0].hasAttribute(e)){t=$(t).attr(e);if(Number(t)>Date.now())return 1}}function n(t){$(t).attr(e,Date.now()+2e3)}function i(t){$(t).removeAttr(e)}var o=new ClipboardJS(t,{target(t){return t.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(t).tooltip({trigger:"hover",placement:"left"});const s=$(t).children().attr("class");o.on("success",t=>{t.clearSelection();const e=t.trigger;var o;l(e)||(t=e,$(t).children().attr("class","fas fa-check"),t=e,o=$(t).attr(r),$(t).attr(a,o).tooltip("show"),n(e),setTimeout(()=>{var t;t=e,$(t).tooltip("hide").removeAttr(a),t=e,$(t).children().attr("class",s),i(e)},2e3))}),$("#copy-link").on("click",t=>{let o=$(t.target);l(o)||navigator.clipboard.writeText(window.location.href).then(()=>{const t=o.attr(a);var e=o.attr(r);o.attr(a,e).tooltip("show"),n(o),setTimeout(()=>{o.attr(a,t),i(o)},2e3)})})}),$(function(){const t=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").on("click",function(a){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let e=RegExp(/^#fnref:/).test(l),o=!e&&RegExp(/^#fn:/).test(l);var n="#"+$.escapeSelector(l.substring(1));let r=$(n);var n=t.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==r){a.preventDefault(),history.pushState&&history.pushState(null,null,l);a=$(window).scrollTop();let t=r.offset().top-=8;t{r.trigger("focus");var t=$(`[${s}=true]`),t=(t.length&&t.attr(s,"false"),$(":target"));if(t.length&&t.attr(s,"false"),(o||e)&&r.attr(s,"true"),r.is(":focus"))return!1;r.attr("tabindex","-1"),r.trigger("focus"),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); From d0cf2a8dd59a9510dcfc54b601ad1c7c6ed5ba7c Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Wed, 15 Feb 2023 05:11:47 +0800 Subject: [PATCH 08/35] chore(codeql): improve triggering conditions --- .github/workflows/codeql.yml | 38 ++---------------------------------- 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 25518bb..2937c9d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,24 +1,10 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# name: 'CodeQL' on: push: - branches: [ 'master', 'production' ] - paths: [ '_javascript' ] + paths: [ '**.js' ] pull_request: - # The branches below must be a subset of the branches above - branches: [ 'master' ] - paths: [ '_javascript' ] + paths: [ '**.js' ] schedule: - cron: '0 0 * * 5' @@ -35,9 +21,6 @@ jobs: fail-fast: false matrix: language: [ 'javascript' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Use only 'java' to analyze code written in Java, Kotlin or both - # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: @@ -49,29 +32,12 @@ jobs: uses: github/codeql-action/init@v2 with: languages: '${{ matrix.language }}' - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild uses: github/codeql-action/autobuild@v2 - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 with: From 4490ce41071dee602d52a4ba0c2cd5804d405613 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Thu, 16 Feb 2023 05:02:22 +0800 Subject: [PATCH 09/35] refactor(tools): fix shell check issues --- tools/init | 7 ++++--- tools/release | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/init b/tools/init index 1848f9b..5ea1da0 100755 --- a/tools/init +++ b/tools/init @@ -21,7 +21,7 @@ help() { check_status() { if [[ -n $(git status . -s) ]]; then echo "Error: Commit unstaged files first, and then run this tool again." - exit -1 + exit 1 fi } @@ -33,7 +33,8 @@ check_init() { else if [[ -f .github/workflows/$ACTIONS_WORKFLOW ]]; then # on BSD, the `wc` could contains blank - local _count="$(find .github/workflows/ -type f -name "*.yml" | wc -l)" + local _count + _count=$(find .github/workflows/ -type f -name "*.yml" | wc -l) if [[ ${_count//[[:blank:]]/} == 1 ]]; then _has_inited=true fi @@ -47,7 +48,7 @@ check_init() { } checkout_latest_tag() { - tag=$(git describe --tags $(git rev-list --tags --max-count=1)) + tag=$(git describe --tags "$(git rev-list --tags --max-count=1)") git reset --hard "$tag" } diff --git a/tools/release b/tools/release index b9cdfbc..f6bc6d0 100755 --- a/tools/release +++ b/tools/release @@ -104,7 +104,7 @@ check() { _bump_file() { for i in "${!FILES[@]}"; do - if [[ ${FILES[$i]} == $NODE_CONFIG ]]; then + if [[ ${FILES[$i]} == "$NODE_CONFIG" ]]; then continue fi From f517b339606a1111d8ca297a5545a32156aa1530 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Thu, 16 Feb 2023 23:35:17 +0800 Subject: [PATCH 10/35] docs: update issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 31 ++++++++++++++--------- .github/ISSUE_TEMPLATE/feature_request.md | 11 +++++--- .github/ISSUE_TEMPLATE/help_wanted.md | 26 +++++++++++-------- .github/ISSUE_TEMPLATE/question.md | 15 ++++++++++- 4 files changed, 55 insertions(+), 28 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index e5bd773..c69cfb3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,17 +3,20 @@ name: Bug Report about: Create a report to help us improve --- -We sincerely recommend that you first complete the following checklist: +**NOTE:** Before you start, the following should be completed. -- Read the [tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design. -- No similar [issue](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue)(including closed ones) exists -- Found the bug on the latest code of the `master` branch. +- Read [tutorial][tutorial] to understand the usage and the correct effect of functional design. +- Make sure no [similar issue(including closed ones)][issues] exists. +- Make sure the bug is found in the latest code of the `master` branch. + +[tutorial]: https://cotes2020.github.io/chirpy-demo/categories/tutorial/ +[issues]: https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue ## Describe the bug -### To Reproduce +## To Reproduce Steps to reproduce the behavior: -### Expected behavior +## Expected behavior -### Screenshots +## Logs/Screenshots - + -### Environment +## Environment | Command | Version | |-----------------------------------|---------| @@ -41,21 +44,25 @@ Steps to reproduce the behavior: | `bundle exec jekyll -v` | | | `bundle info jekyll-theme-chirpy` | | + + -### Additional context +## Additional context diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index dc52b35..0b8cb58 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -4,11 +4,14 @@ about: Suggest an idea for this project labels: enhancement --- -We sincerely recommend that you first complete the following checklist: +**NOTE:** Before you start, the following should be completed. -- Read the [tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design. -- No similar [issue](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue)(including closed ones) exists -- This PR is built on top of the latest code in the `master` branch. +- Read [tutorial][tutorial] to understand the usage and the correct effect of functional design. +- Make sure no [similar issue(including closed ones)][issues] exists. +- Make sure the request is based on the latest code in the `master` branch. + +[tutorial]: https://cotes2020.github.io/chirpy-demo/categories/tutorial/ +[issues]: https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue ## Is your feature request related to a problem? Please describe diff --git a/.github/ISSUE_TEMPLATE/help_wanted.md b/.github/ISSUE_TEMPLATE/help_wanted.md index debe1f5..180240e 100644 --- a/.github/ISSUE_TEMPLATE/help_wanted.md +++ b/.github/ISSUE_TEMPLATE/help_wanted.md @@ -1,24 +1,28 @@ --- name: Help Wanted -about: Need help +about: Need help that is not covered in the tutorial labels: 'help wanted' --- -We sincerely recommend that you first complete the following checklist: +**NOTE:** Before you start, the following should be completed. -- Read the [tutorials](https://cotes2020.github.io/chirpy-demo/categories/tutorial/) and know the correct effect of the functional design. -- No similar [issue](https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue)(including closed ones) exists -- Try to find the answer on [Jekyll Forum](https://talk.jekyllrb.com/) and [StackOverflow](https://stackoverflow.com/questions/tagged/jekyll). -- The ask is based on the latest code of the `master` branch. +- Read [tutorial][tutorial] to understand the usage and the correct effect of functional design. +- Make sure no [similar issue(including closed ones)][issues] exists. +- Try to find the answer on [Jekyll Forum][forum] and [StackOverflow][stack_overflow]. + +[tutorial]: https://cotes2020.github.io/chirpy-demo/categories/tutorial/ +[issues]: https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue +[forum]: https://talk.jekyllrb.com/ +[stack_overflow]: https://stackoverflow.com/questions/tagged/jekyll ## Description -## What you have tried +## Operations you have already tried - - If needed, please attach output logs, screenshots, etc. to describe your issue. ---> +## Logs/Screenshots + + diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 42f5747..fb6c1d7 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -1,7 +1,20 @@ --- name: Question -about: Ask whatever you want +about: Issues that differ from other templates labels: question --- +**NOTE:** Before you start, the following should be completed. + +- Read [tutorial][tutorial] to understand the usage and the correct effect of functional design. +- Make sure no [similar issue(including closed ones)][issues] exists. +- Try to find the answer on [Jekyll Forum][forum] and [StackOverflow][stack_overflow]. + +[tutorial]: https://cotes2020.github.io/chirpy-demo/categories/tutorial/ +[issues]: https://github.com/cotes2020/jekyll-theme-chirpy/issues?q=is%3Aissue +[forum]: https://talk.jekyllrb.com/ +[stack_overflow]: https://stackoverflow.com/questions/tagged/jekyll + +## Description + From b1453ccb0c5b269bc867acaaa4f3cc7060df05db Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 18 Feb 2023 10:43:16 +0800 Subject: [PATCH 11/35] chore: delete useless code --- _sass/addon/commons.scss | 5 ----- _sass/layout/post.scss | 9 --------- 2 files changed, 14 deletions(-) diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index e65d336..33d19db 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -419,10 +419,6 @@ i { /* fontawesome icons */ word-spacing: 1px; a { - &:not(:last-child) { - margin-right: 2px; - } - &:not([class]):hover { @extend %link-hover; } @@ -546,7 +542,6 @@ i { /* fontawesome icons */ .img-link { color: transparent; display: inline-flex; - overflow: hidden; } .shimmer { diff --git a/_sass/layout/post.scss b/_sass/layout/post.scss index ac445d7..c79331b 100644 --- a/_sass/layout/post.scss +++ b/_sass/layout/post.scss @@ -26,17 +26,9 @@ color: var(--text-color); } -%preview-margin { - margin: 0; -} - .preview-img { - @include align-center; - @extend %preview-margin; @extend %rounded; - max-width: 100%; - &:not(.no-bg) { img.lazyloaded { background: var(--img-bg); @@ -48,7 +40,6 @@ -o-object-fit: cover; object-fit: cover; - @extend %preview-margin; @extend %rounded; } } From d921b981f7856182d82c95334ec129c9cea8eb7a Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Mon, 20 Feb 2023 05:46:33 +0800 Subject: [PATCH 12/35] docs: update tutorial docs: update tutorial --- README.md | 14 ++++++------- _posts/2019-08-08-write-a-new-post.md | 5 ++++- _posts/2019-08-09-getting-started.md | 30 +++++++++++++-------------- 3 files changed, 26 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 11774ad..427eccc 100644 --- a/README.md +++ b/README.md @@ -39,15 +39,15 @@ ## Quick Start -Before starting, please follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll`, and `Bundler`. In addition, [Git](https://git-scm.com/) is also required to be installed. +Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of the basic environment. [Git](https://git-scm.com/) also needs to be installed. ### Step 1. Creating a New Site -Create a new repository from the [**Chirpy Starter**](https://github.com/cotes2020/chirpy-starter/generate) and name it `.github.io`, where `GH_USERNAME` represents your GitHub username. +Sign in to GitHub and browse to [**Chirpy Starter**](https://github.com/cotes2020/chirpy-starter/), click the button Use this template > Create a new repository, and name the new repository `USERNAME.github.io`, where `USERNAME` represents your GitHub username. ### Step 2. Installing Dependencies -Before running for the first time, go to the root directory of your site, and install dependencies as follows: +Clone it to your local machine, go to its root directory, and run the following command to install the dependencies. ```console $ bundle @@ -55,7 +55,7 @@ $ bundle ### Step 3. Running Local Server -Run the following command in the root directory of the site: +Run the following command in the root directory of your site: ```console $ bundle exec jekyll s @@ -70,11 +70,11 @@ $ docker run -it --rm \ jekyll serve ``` -After a while, navigate to the site at . +After a few seconds, the local service will be published at __. ## Documentation -For more details on usage, please refer to the tutorial on the [demo website](https://cotes2020.github.io/chirpy-demo/) / [wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki). Note that the tutorial is based on the [latest release](https://github.com/cotes2020/jekyll-theme-chirpy/releases/latest), and the features of the default branch are usually ahead of the documentation. +For more details on usage, please refer to the tutorial on the [demo website](https://cotes2020.github.io/chirpy-demo/) or [wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki). Note that the tutorial is based on the [latest release](https://github.com/cotes2020/jekyll-theme-chirpy/releases/latest), and the features of the default branch are usually ahead of the documentation. ## Contributing @@ -90,7 +90,7 @@ Last but not least, thank [JetBrains][jb] for providing the OSS development lice ## Sponsoring -If you like this theme or find it helpful, please consider sponsoring me, because it will encourage and help me better maintain the project, I will be very grateful! +If you like it, please consider sponsoring me. It will help me to maintain this project better and I would be very grateful! [![Ko-fi](https://img.shields.io/badge/-Buy%20Me%20a%20Coffee-ff5f5f?logo=ko-fi&logoColor=white)](https://ko-fi.com/coteschung) [![Wechat Pay](https://img.shields.io/badge/-Tip%20Me%20on%20WeChat-brightgreen?logo=wechat&logoColor=white)][cn-donation] diff --git a/_posts/2019-08-08-write-a-new-post.md b/_posts/2019-08-08-write-a-new-post.md index 2254d1a..4812cee 100644 --- a/_posts/2019-08-08-write-a-new-post.md +++ b/_posts/2019-08-08-write-a-new-post.md @@ -133,13 +133,16 @@ _Image Caption_ ### Size -In order to prevent the page content layout from shifting when the image is loaded, we should set the width and height for each image: +In order to prevent the page content layout from shifting when the image is loaded, we should set the width and height for each image. ```markdown ![Desktop View](/assets/img/sample/mockup.png){: width="700" height="400" } ``` {: .nolineno} +> For an SVG, you have to at least specify its _width_, otherwise it won't be rendered. +{: .prompt-info } + Starting from _Chirpy v5.0.0_, `height` and `width` support abbreviations (`height` → `h`, `width` → `w`). The following example has the same effect as the above: ```markdown diff --git a/_posts/2019-08-09-getting-started.md b/_posts/2019-08-09-getting-started.md index 0677cfe..ffc8682 100644 --- a/_posts/2019-08-09-getting-started.md +++ b/_posts/2019-08-09-getting-started.md @@ -9,7 +9,7 @@ pin: true ## Prerequisites -Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of `Ruby`, `RubyGems`, `Jekyll`, and `Bundler`. In addition, [Git](https://git-scm.com/) is also required to be installed. +Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of the basic environment. [Git](https://git-scm.com/) also needs to be installed. ## Installation @@ -22,11 +22,11 @@ There are two ways to create a new repository for this theme: #### Option 1. Using the Chirpy Starter -Create a new repository from the [**Chirpy Starter**][use-starter] and name it `.github.io`, where `GH_USERNAME` represents your GitHub username. +Sign in to GitHub and browse to [**Chirpy Starter**](https://github.com/cotes2020/chirpy-starter/), click the button Use this template > Create a new repository, and name the new repository `USERNAME.github.io`, where `USERNAME` represents your GitHub username. #### Option 2. Forking on GitHub -[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) on GitHub and rename it to `.github.io`. Please note that the default branch code is in development. If you want the site to be stable, please switch to the [latest tag][latest-tag] and start writing. +[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) on GitHub and rename it to `USERNAME.github.io`. Note that the default branch code is under development. To ensure the stability of your site, please switch to the [latest tag][latest-tag] and start writing. And then execute: @@ -93,31 +93,32 @@ $ docker run -it --rm \ jekyll serve ``` -After a while, the local service will be published at __. +After a few seconds, the local service will be published at __. ## Deployment Before the deployment begins, check out the file `_config.yml`{: .filepath} and make sure the `url` is configured correctly. Furthermore, if you prefer the [**project site**](https://help.github.com/en/github/working-with-github-pages/about-github-pages#types-of-github-pages-sites) and don't use a custom domain, or you want to visit your website with a base URL on a web server other than **GitHub Pages**, remember to change the `baseurl` to your project name that starts with a slash, e.g, `/project-name`. -Now you can choose ONE of the following methods to deploy your Jekyll site. +Now you can choose _ONE_ of the following methods to deploy your Jekyll site. ### Deploy by Using GitHub Actions -Ensure your Jekyll site has the file `.github/workflows/pages-deploy.yml`{: .filepath}. Otherwise, create a new one and fill in the contents of the [sample file][workflow], and the value of the `on.push.branches` should be the same as your repo's default branch name. And then rename your repository to `.github.io` on GitHub. +There are a few things to get ready for. -Furthermore, if you have committed `Gemfile.lock`{: .filepath} to the repository and your local machine is not Linux, go the the root directory of your site and update the platform list: +- If you're on the GitHub Free plan, keep your site repository public. +- If you have committed `Gemfile.lock`{: .filepath} to the repository, and your local machine is not running Linux, go the the root of your site and update the platform list of the lock-file: -```console -$ bundle lock --add-platform x86_64-linux -``` + ```console + $ bundle lock --add-platform x86_64-linux + ``` -Now publish your Jekyll site: +Next, configure the _Pages_ service. 1. Browse to your repository on GitHub. Select the tab _Settings_, then click _Pages_ in the left navigation bar. Then, in the **Source** section (under _Build and deployment_), select [**GitHub Actions**][pages-workflow-src] from the dropdown menu. -2. Push any commit to remote to trigger the GitHub Actions workflow. In the _Actions_ tab of your repository, you should see the workflow _Build and Deploy_ running. Once the build is complete and successful, the site should be deployed automatically. +2. Push any commits to GitHub to trigger the _Actions_ workflow. In the _Actions_ tab of your repository, you should see the workflow _Build and Deploy_ running. Once the build is complete and successful, the site will be deployed automatically. -3. Visit your website at the address indicated by GitHub. +At this point, you can go to the URL indicated by GitHub to access your site. ### Manually Build and Deploy @@ -149,7 +150,7 @@ It depends on how you use the theme: ```diff - gem "jekyll-theme-chirpy", "~> 3.2", ">= 3.2.1" - + gem "jekyll-theme-chirpy", "~> 3.3", ">= 3.3.0" + + gem "jekyll-theme-chirpy", "~> 4.3", ">= 4.3.2" ``` {: .nolineno file="Gemfile" } @@ -165,7 +166,6 @@ It depends on how you use the theme: The merge is likely to conflict with your local modifications. Please be patient and careful to resolve these conflicts. [starter]: https://github.com/cotes2020/chirpy-starter -[use-starter]: https://github.com/cotes2020/chirpy-starter/generate [workflow]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/workflows/pages-deploy.yml.hook [pages-workflow-src]: https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow [latest-tag]: https://github.com/cotes2020/jekyll-theme-chirpy/tags From 712a9b22401ce591cf4c0bb03fbdd1693fee30bb Mon Sep 17 00:00:00 2001 From: Spyros Kokotos <33377581+Greekforce1821@users.noreply.github.com> Date: Wed, 22 Feb 2023 23:17:47 +0200 Subject: [PATCH 13/35] feat(i18n): add Greek Language Support. (#903) --- _data/locales/el-GR.yml | 93 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 _data/locales/el-GR.yml diff --git a/_data/locales/el-GR.yml b/_data/locales/el-GR.yml new file mode 100644 index 0000000..fbc7c2b --- /dev/null +++ b/_data/locales/el-GR.yml @@ -0,0 +1,93 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Δημοσίευση + category: Κατηγορία + tag: Ετικέτα + +# The tabs of sidebar +tabs: + # format: : + home: Home + categories: Κατηγορίες + tags: Ετικέτες + archives: Αρχεία + about: Σχετικά + +# the text displayed in the search bar & search results +search: + hint: αναζήτηση + cancel: Ακύρωση + no_results: Oops! Κανένα αποτέλεσμα δεν βρέθηκε. + +panel: + lastmod: Σχετικά ενημερωμένα + trending_tags: Ετικέτες τάσης + toc: Περιεχόμενα + +copyright: + # Shown at the bottom of the post + license: + template: Η δημοσίευση αυτή βρίσκεται υπο την άδεια :LICENSE_NAME Greekforce1821. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Ορισμένα δικαιώματα reserved. + verbose: >- + Εκτός αλλού ή οπουδήποτε αλλού, τα blog posts σε αυτήν την σελίδα βρίσκονται υπο την άδεια + Creative Commons Attribution 4.0 International (CC BY 4.0) του δημιουργού. + +meta: Αξιοποιώντας την :PLATFORM theme :THEME. + +not_found: + statment: Συγνώμη, έχουμε τοποθετήσει λάθος αυτήν την διεύθυνση URL ή υποδεικνύει κάτι που δεν υπάρχει. + +notification: + update_found: Υπάρχει διαθέσιμη μια νέα έκδοση του περιεχομένου. + update: Ενημέρωση + +# ----- Posts related labels ----- + +post: + written_by: Από + posted: Δημοσιεύθηκε + updated: Ενημερώθηκε + words: λέξεις + pageview_measure: προβολές + read_time: + unit: Λεπτά + prompt: διαβάσματος + relate_posts: Περισσότερα + share: Κοινοποιήστε + button: + next: Νεότερα + previous: Παλαιότερα + copy_code: + succeed: Αντιγράφθηκε! + share_link: + title: Αντιγραφή συνδέσμου + succeed: Η διεύθυνση αντιγράφθηκε με επιτυχία! + # pinned prompt of posts list on homepage + pin_prompt: Pinned + +# Date time format. +# See: , +df: + post: + strftime: '%b %e, %Y' + dayjs: 'll' + archives: + strftime: '%b' + dayjs: 'MMM' + +# categories page +categories: + category_measure: + singular: Κατηγορία + plural: Κατηγορίες + post_measure: + singular: Δημοσίευση + plural: Δημοσιεύσεις \ No newline at end of file From 1e5c025a1ce6880450bd590f951bf631475bc598 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Wed, 1 Mar 2023 00:45:18 +0800 Subject: [PATCH 14/35] chore(vcs): improve git-ignore entries --- .gitignore | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 9735d33..301b844 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,19 @@ -# hidden files -.* -!.git* -!.editorconfig -!.nojekyll -!.husky -!.commitlintrc.json -!.versionrc.json -!.stylelintrc.json - -# bundler cache -_site +# Bundler cache +.bundle vendor Gemfile.lock -# rubygem +# Jekyll cache +.jekyll-cache +_site + +# RubyGems *.gem # npm dependencies node_modules package-lock.json + +# IDE configurations +.idea +.vscode From fe82cea5762bdde6bcefbd3a44af4a6fb74ce01e Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Wed, 1 Mar 2023 00:48:25 +0800 Subject: [PATCH 15/35] chore(tools): fix typo --- tools/init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/init b/tools/init index 5ea1da0..7cf7324 100755 --- a/tools/init +++ b/tools/init @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Init the evrionment for new user. +# Init the environment for new user. set -eu From 09121c1d111afb56af4f6581c4a8a6da29311b99 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Wed, 1 Mar 2023 08:23:08 +0800 Subject: [PATCH 16/35] docs: move the development guide to README (#900) --- .github/CONTRIBUTING.md | 65 +++++++++------------ README.md | 121 +++++++++++++++++++--------------------- 2 files changed, 83 insertions(+), 103 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index ef81bb0..54e7a6f 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,66 +1,55 @@ # How to Contribute -We'd like to thank you for sparing time to improve this project! Here are some guidelines for contributing: +:tada: We really appreciate you taking the time to improve this project! :tada: -To ensure that the blog design is not confused, this project does not accept suggestions for design changes, such as color scheme, fonts, typography, etc. If your request is about an enhancement, it is recommended to first submit a [_Feature Request_](https://github.com/cotes2020/jekyll-theme-chirpy/issues/new?labels=enhancement&template=feature_request.md) issue to discuss whether your idea fits the project. +To ensure that the blog design is not confusing, this project does not accept +suggestions for design changes, such as color scheme, fonts, typography, etc. +If your request is about an enhancement, it is recommended to first submit a +[Feature Request][pr-issue] issue to discuss whether your idea fits the project. -## Basic Process - -Generally, contribute to the project by: +Basically, you can follow these steps to complete the contribution. 1. Fork this project on GitHub and clone it locally. -2. Create a new branch from the default branch and give it a descriptive name (format: `feature/` / `fix/`). -3. After completing the development, submit a new _Pull Request_. Note that the commit message must follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/), otherwise it will fail the PR check. +2. Create a new branch from the default branch and give it a descriptive name + (format: `feature/` or `fix/`). +3. After completing development, create a [Conventional Commit][cc] with git. + (See also: ["Verify the commits"](#verify-the-commits)) +4. Create a [Pull Request][gh-pr]. -## Modifying JavaScript +## Make sure you can pass the CI tests -If your contribution involves JavaScript modification, please read the following sections. - -### Inline Scripts - -If you need to add comments to the inline JavaScript (the code between the HTML tags ``), please use `/* */` instead of two slashes `//`. Because the HTML will be compressed by [jekyll-compress-html](https://github.com/penibelst/jekyll-compress-html) during deployment, but it cannot handle the `//` properly, which will disrupt the structure of the compressed HTML. - -### External Scripts - -If you need to add/change/delete the JavaScript in the directory `_javascript/`, setting up [`Node.js`](https://nodejs.org/) and [`npx`](https://www.npmjs.com/package/npx) is a requirement. And then install the development dependencies: +This project has [CI][ci] turned on. In order for your [PR][gh-pr] to pass the test, +please read the following. +### Check the core functionality + ```console -$ npm i +bash ./tools/test ``` -During JavaScript development, real-time debugging can be performed through the following commands: - -Firstly, start a Jekyll server: +### Check the SASS syntax style ```console -$ bash tools/run +npm test ``` -And then open a new terminal tab and run: +### Verify the commits -```console -# Type 'Ctrl + C' to stop -$ npx gulp dev -``` - -After debugging, run the command `npx gulp` (without any argument) will automatically output the compressed files to the directory `assets/js/dist/`. - -## Verify the commit messages - -If you want to make sure your commits pass the CI check, you can refer to the following steps. +Before you create a git commit, please complete the following setup. Install `commitlint` & `husky`: ```console -$ npm i -g @commitlint/{cli,config-conventional} husky +npm i -g @commitlint/{cli,config-conventional} husky ``` And then enable `husky`: ```console -$ husky install +husky install ``` ---- - -:tada: Your volunteering will make the open-source world more beautiful, thanks again! :tada: +[pr-issue]: https://github.com/cotes2020/jekyll-theme-chirpy/issues/new?labels=enhancement&template=feature_request.md +[gh-pr]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests +[cc]: https://www.conventionalcommits.org/ +[ci]: https://en.wikipedia.org/wiki/Continuous_integration diff --git a/README.md b/README.md index 427eccc..999ea36 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ # Chirpy Jekyll Theme - A minimal, responsive, and powerful Jekyll theme for presenting professional 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)](https://rubygems.org/gems/jekyll-theme-chirpy) [![CI](https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml/badge.svg)](https://github.com/cotes2020/jekyll-theme-chirpy/actions/workflows/ci.yml) @@ -10,97 +10,88 @@ [![GitHub license](https://img.shields.io/github/license/cotes2020/jekyll-theme-chirpy.svg)](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE) [![996.icu](https://img.shields.io/badge/link-996.icu-%23FF4D5B.svg)](https://996.icu) - [**Live Demo →**](https://cotes2020.github.io/chirpy-demo) + [**Live Demo →**][demo] - [![Devices Mockup](https://chirpy-img.netlify.app/commons/devices-mockup.png)](https://cotes2020.github.io/chirpy-demo) + [![Devices Mockup](https://chirpy-img.netlify.app/commons/devices-mockup.png)][demo] ## Features -- Dark/Light Theme Mode -- Localized UI language -- Pinned Posts -- Hierarchical Categories -- Trending Tags -- Table of Contents -- Last Modified Date of Posts -- Syntax Highlighting -- Mathematical Expressions -- Mermaid Diagram & Flowchart -- Dark/Light Mode Images -- Embed Videos -- Disqus/Utterances/Giscus Comments -- Search -- Atom Feeds -- Google Analytics -- Page Views Reporting -- SEO & Performance Optimization +
+ + Click to check out the features + +

-## Quick Start + - Dark/Light Theme Mode + - Localized UI language + - Pinned Posts + - Hierarchical Categories + - Trending Tags + - Table of Contents + - Last Modified Date of Posts + - Syntax Highlighting + - Mathematical Expressions + - Mermaid Diagram & Flowchart + - Dark/Light Mode Images + - Embed Videos + - Disqus/Utterances/Giscus Comments + - Search + - Atom Feeds + - Google Analytics + - Page Views Reporting + - SEO & Performance Optimization -Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installation/) to complete the installation of the basic environment. [Git](https://git-scm.com/) also needs to be installed. - -### Step 1. Creating a New Site - -Sign in to GitHub and browse to [**Chirpy Starter**](https://github.com/cotes2020/chirpy-starter/), click the button Use this template > Create a new repository, and name the new repository `USERNAME.github.io`, where `USERNAME` represents your GitHub username. - -### Step 2. Installing Dependencies - -Clone it to your local machine, go to its root directory, and run the following command to install the dependencies. - -```console -$ bundle -``` - -### Step 3. Running Local Server - -Run the following command in the root directory of your site: - -```console -$ bundle exec jekyll s -``` - -Or run with Docker: - -```console -$ docker run -it --rm \ - --volume="$PWD:/srv/jekyll" \ - -p 4000:4000 jekyll/jekyll \ - jekyll serve -``` - -After a few seconds, the local service will be published at __. +

+
## Documentation -For more details on usage, please refer to the tutorial on the [demo website](https://cotes2020.github.io/chirpy-demo/) or [wiki](https://github.com/cotes2020/jekyll-theme-chirpy/wiki). Note that the tutorial is based on the [latest release](https://github.com/cotes2020/jekyll-theme-chirpy/releases/latest), and the features of the default branch are usually ahead of the documentation. +To explore usage, development, and upgrade guide of the project, please refer to +the [Wiki][wiki]. ## Contributing -Welcome to report bugs, improve code quality or submit a new feature. For more information, see [contributing guidelines](.github/CONTRIBUTING.md). +Welcome to report bugs, help improve the code or submit new features. +For more information, please see the ["Contributing Guidelines"][contribute-guide]. ## Credits -This theme is mainly built with [Jekyll](https://jekyllrb.com/) ecosystem, [Bootstrap](https://getbootstrap.com/), [Font Awesome](https://fontawesome.com/) and some other wonderful tools (their copyright information can be found in the relevant files). The avatar and favicon design come from [Clipart Max](https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/). +This theme is mainly built with [Jekyll][jekyllrb] ecosystem, +[Bootstrap][bootstrap], [Font Awesome][icons] and some other [wonderful tools][lib]. +The avatar and favicon design come from [Clipart Max][image]. -:tada: Thanks to all the volunteers who contributed to this project, their GitHub IDs are on [this list](https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors). Also, I won't forget those guys who submitted the issues or unmerged PR because they reported bugs, shared ideas, or inspired me to write more readable documentation. +Thanks to all the [contributors][contributors]. Also, folks who submitted issues +or unmerged PRs should not be forgotten. Because they reported bugs, shared ideas, +or inspired me to write more readable documentation. -Last but not least, thank [JetBrains][jb] for providing the OSS development license. +Last but not least, thanks to [JetBrains][jetbrains] for providing the +_Open Source Development_ license. ## Sponsoring -If you like it, please consider sponsoring me. It will help me to maintain this project better and I would be very grateful! +If you would like to sponsor this project, the following options are available. [![Ko-fi](https://img.shields.io/badge/-Buy%20Me%20a%20Coffee-ff5f5f?logo=ko-fi&logoColor=white)](https://ko-fi.com/coteschung) -[![Wechat Pay](https://img.shields.io/badge/-Tip%20Me%20on%20WeChat-brightgreen?logo=wechat&logoColor=white)][cn-donation] -[![Alipay](https://img.shields.io/badge/-Tip%20Me%20on%20Alipay-blue?logo=alipay&logoColor=white)][cn-donation] +[![Wechat Pay](https://img.shields.io/badge/-Tip%20Me%20on%20WeChat-brightgreen?logo=wechat&logoColor=white)][donation] +[![Alipay](https://img.shields.io/badge/-Tip%20Me%20on%20Alipay-blue?logo=alipay&logoColor=white)][donation] ## License -This work is published under [MIT](https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE) License. +This work is published under [MIT][mit] License. -[jb]: https://www.jetbrains.com/?from=jekyll-theme-chirpy -[cn-donation]: https://sponsor.cotes.page/ +[jekyllrb]: https://jekyllrb.com/ +[bootstrap]: https://getbootstrap.com/ +[icons]: https://fontawesome.com/ +[image]: https://www.clipartmax.com/middle/m2i8b1m2K9Z5m2K9_ant-clipart-childrens-ant-cute/ +[demo]: https://cotes2020.github.io/chirpy-demo/ +[wiki]: https://github.com/cotes2020/jekyll-theme-chirpy/wiki +[contribute-guide]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/CONTRIBUTING.md +[contributors]: https://github.com/cotes2020/jekyll-theme-chirpy/graphs/contributors +[lib]: https://github.com/cotes2020/chirpy-static-assets +[jetbrains]: https://www.jetbrains.com/?from=jekyll-theme-chirpy +[donation]: https://sponsor.cotes.page/ +[mit]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/LICENSE From 7e6c667e7aa2961b2e4d62c1d6faae8284db03b6 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Thu, 2 Mar 2023 03:50:34 +0800 Subject: [PATCH 17/35] chore: update project description --- _config.yml | 2 +- jekyll-theme-chirpy.gemspec | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_config.yml b/_config.yml index 81090d3..df912c6 100644 --- a/_config.yml +++ b/_config.yml @@ -24,7 +24,7 @@ title: Chirpy # the main title tagline: A text-focused Jekyll theme # it will display as the sub-title description: >- # used by seo meta and the atom feed - A minimal, responsive, and powerful Jekyll theme for presenting professional writing. + A minimal, responsive and feature-rich Jekyll theme for technical writing. # fill in the protocol & hostname for your site, e.g., 'https://username.github.io' url: '' diff --git a/jekyll-theme-chirpy.gemspec b/jekyll-theme-chirpy.gemspec index 6d138f7..9ad026f 100644 --- a/jekyll-theme-chirpy.gemspec +++ b/jekyll-theme-chirpy.gemspec @@ -6,7 +6,7 @@ Gem::Specification.new do |spec| spec.authors = ["Cotes Chung"] spec.email = ["cotes.chung@gmail.com"] - spec.summary = "Chirpy is a minimal, sidebar, responsive web design Jekyll theme that focuses on text presentation." + spec.summary = "A minimal, responsive and feature-rich Jekyll theme for technical writing." spec.homepage = "https://github.com/cotes2020/jekyll-theme-chirpy" spec.license = "MIT" diff --git a/package.json b/package.json index fbd6b10..103f987 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jekyll-theme-chirpy", "version": "5.5.2", - "description": "A minimal, responsive, and powerful Jekyll theme for presenting professional writing.", + "description": "A minimal, responsive and feature-rich Jekyll theme for technical writing.", "repository": { "type": "git", "url": "git+https://github.com/cotes2020/jekyll-theme-chirpy.git" From 4681df715118a37ae1e91b588de0adb67f4e331a Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Thu, 2 Mar 2023 05:16:18 +0800 Subject: [PATCH 18/35] fix: mathematics cannot scroll horizontally (#760) --- _sass/addon/commons.scss | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index 33d19db..d808f35 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -159,11 +159,6 @@ blockquote { @include prompt("danger", "\f071"); } -mjx-container { - overflow-x: auto; - overflow-y: hidden; -} - kbd { font-family: inherit; display: inline-block; @@ -679,6 +674,12 @@ figure .mfp-title { text-align: center; } +/* MathJax */ +mjx-container { + overflow-y: hidden; + min-width: auto !important; +} + /* --- sidebar layout --- */ $sidebar-display: "sidebar-display"; From 968c13ec7de4a8b830a0cc0bf81875e885cdedd4 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 4 Mar 2023 09:52:33 +0800 Subject: [PATCH 19/35] chore(deps): upgrade NPM packages --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 103f987..a9bfc3f 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "gulp-insert": "^0.5.0", "gulp-rename": "^2.0.0", "gulp-uglify": "^3.0.2", - "stylelint": "^14.14.0", - "stylelint-config-standard-scss": "^5.0.0", - "uglify-js": "^3.14.3" + "stylelint": "^15.2.0", + "stylelint-config-standard-scss": "^7.0.1", + "uglify-js": "^3.17.4" } } From 002f02533dbc322807e937d557c0673c06c8a727 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Mon, 6 Mar 2023 08:48:52 +0800 Subject: [PATCH 20/35] chore: update code style config --- .browserslistrc | 5 +++++ .editorconfig | 7 +++++-- .prettierrc | 3 +++ .stylelintrc.json | 7 ++++++- 4 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 .browserslistrc create mode 100644 .prettierrc diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..afe4650 --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,5 @@ +# https://github.com/browserslist/browserslist#browserslistrc + +last 2 versions +> 0.2% +not dead diff --git a/.editorconfig b/.editorconfig index f27e9a9..2b740bf 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,8 +9,11 @@ trim_trailing_whitespace = true end_of_line = lf insert_final_newline = true -[*.js] -indent_size = 4 +[*.{js,css,scss}] +quote_type = single + +[*.{yml,yaml}] +quote_type = double [*.md] trim_trailing_whitespace = false diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..36b3563 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "trailingComma": "none" +} diff --git a/.stylelintrc.json b/.stylelintrc.json index 66c0ffb..09b3c87 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -11,6 +11,11 @@ "alpha-value-notation": "number", "selector-not-notation": "simple", "color-hex-length": "long", - "declaration-block-single-line-max-declarations": 3 + "declaration-block-single-line-max-declarations": 3, + "scss/operator-no-newline-after": null, + "rule-empty-line-before": [ + "always", + { "ignore": ["after-comment", "first-nested", "inside-block"] } + ] } } From b69d3d7eddc3720df012931214dca8611cee3da8 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Mon, 13 Mar 2023 20:20:59 +0800 Subject: [PATCH 21/35] refactor(build): modularize JS code - replace gulp with rollup - remove JS output from repo --- .gitignore | 5 +- _config.yml | 75 +++--- _includes/js-selector.html | 87 +++--- _includes/mode-toggle.html | 65 ++--- _javascript/_copyright | 3 + _javascript/categories.js | 7 + _javascript/commons.js | 5 + _javascript/commons/back-to-top.js | 20 -- _javascript/commons/mode-toggle.js | 13 - _javascript/commons/scroll-helper.js | 38 --- _javascript/commons/search-display.js | 126 --------- _javascript/commons/sidebar.js | 28 -- _javascript/commons/tooltip-loader.js | 6 - _javascript/commons/topbar-switcher.js | 89 ------ _javascript/commons/topbar-title.js | 67 ----- _javascript/copyright | 5 - _javascript/misc.js | 7 + _javascript/modules/components/back-to-top.js | 26 ++ .../modules/components/category-collapse.js | 36 +++ _javascript/modules/components/clipboard.js | 118 ++++++++ .../modules/components/convert-title.js | 68 +++++ _javascript/modules/components/img-extra.js | 27 ++ .../modules/components/locale-datetime.js | 50 ++++ .../modules/components/mode-watcher.js | 21 ++ _javascript/modules/components/pageviews.js | 254 ++++++++++++++++++ .../modules/components/search-display.js | 122 +++++++++ _javascript/modules/components/sidebar.js | 25 ++ .../modules/components/smooth-scroll.js | 109 ++++++++ .../modules/components/tooltip-loader.js | 6 + .../modules/components/topbar-switcher.js | 93 +++++++ .../modules/components/utils/scroll-helper.js | 64 +++++ _javascript/modules/layouts.js | 3 + _javascript/modules/layouts/basic.js | 7 + _javascript/modules/layouts/sidebar.js | 7 + _javascript/modules/layouts/topbar.js | 9 + _javascript/modules/plugins.js | 6 + _javascript/page.js | 9 + _javascript/post.js | 17 ++ _javascript/utils/category-collapse.js | 30 --- _javascript/utils/clipboard.js | 123 --------- _javascript/utils/img-extra.js | 28 -- _javascript/utils/locale-datetime.js | 43 --- _javascript/utils/pageviews.js | 250 ----------------- _javascript/utils/smooth-scroll.js | 98 ------- assets/js/dist/categories.min.js | 6 - assets/js/dist/commons.min.js | 6 - assets/js/dist/home.min.js | 6 - assets/js/dist/misc.min.js | 6 - assets/js/dist/page.min.js | 6 - assets/js/dist/post.min.js | 6 - assets/js/dist/pvreport.min.js | 6 - gulpfile.js/index.js | 10 - gulpfile.js/tasks/js.js | 101 ------- package.json | 24 +- rollup.config.js | 42 +++ 55 files changed, 1267 insertions(+), 1247 deletions(-) create mode 100644 _javascript/_copyright create mode 100644 _javascript/categories.js create mode 100644 _javascript/commons.js delete mode 100644 _javascript/commons/back-to-top.js delete mode 100644 _javascript/commons/mode-toggle.js delete mode 100644 _javascript/commons/scroll-helper.js delete mode 100644 _javascript/commons/search-display.js delete mode 100644 _javascript/commons/sidebar.js delete mode 100644 _javascript/commons/tooltip-loader.js delete mode 100644 _javascript/commons/topbar-switcher.js delete mode 100644 _javascript/commons/topbar-title.js delete mode 100644 _javascript/copyright create mode 100644 _javascript/misc.js create mode 100644 _javascript/modules/components/back-to-top.js create mode 100644 _javascript/modules/components/category-collapse.js create mode 100644 _javascript/modules/components/clipboard.js create mode 100644 _javascript/modules/components/convert-title.js create mode 100644 _javascript/modules/components/img-extra.js create mode 100644 _javascript/modules/components/locale-datetime.js create mode 100644 _javascript/modules/components/mode-watcher.js create mode 100644 _javascript/modules/components/pageviews.js create mode 100644 _javascript/modules/components/search-display.js create mode 100644 _javascript/modules/components/sidebar.js create mode 100644 _javascript/modules/components/smooth-scroll.js create mode 100644 _javascript/modules/components/tooltip-loader.js create mode 100644 _javascript/modules/components/topbar-switcher.js create mode 100644 _javascript/modules/components/utils/scroll-helper.js create mode 100644 _javascript/modules/layouts.js create mode 100644 _javascript/modules/layouts/basic.js create mode 100644 _javascript/modules/layouts/sidebar.js create mode 100644 _javascript/modules/layouts/topbar.js create mode 100644 _javascript/modules/plugins.js create mode 100644 _javascript/page.js create mode 100644 _javascript/post.js delete mode 100644 _javascript/utils/category-collapse.js delete mode 100644 _javascript/utils/clipboard.js delete mode 100644 _javascript/utils/img-extra.js delete mode 100644 _javascript/utils/locale-datetime.js delete mode 100644 _javascript/utils/pageviews.js delete mode 100644 _javascript/utils/smooth-scroll.js delete mode 100644 assets/js/dist/categories.min.js delete mode 100644 assets/js/dist/commons.min.js delete mode 100644 assets/js/dist/home.min.js delete mode 100644 assets/js/dist/misc.min.js delete mode 100644 assets/js/dist/page.min.js delete mode 100644 assets/js/dist/post.min.js delete mode 100644 assets/js/dist/pvreport.min.js delete mode 100644 gulpfile.js/index.js delete mode 100644 gulpfile.js/tasks/js.js create mode 100644 rollup.config.js diff --git a/.gitignore b/.gitignore index 301b844..0124b68 100644 --- a/.gitignore +++ b/.gitignore @@ -10,10 +10,13 @@ _site # RubyGems *.gem -# npm dependencies +# NPM dependencies node_modules package-lock.json # IDE configurations .idea .vscode + +# Misc +assets/js/dist diff --git a/_config.yml b/_config.yml index df912c6..5d1483d 100644 --- a/_config.yml +++ b/_config.yml @@ -5,60 +5,59 @@ theme: jekyll-theme-chirpy # Change the following value to '/PROJECT_NAME' ONLY IF your site type is GitHub Pages Project sites # and doesn't have a custom domain. -baseurl: '' +baseurl: "" # The language of the webpage › http://www.lingoes.net/en/translator/langcode.htm # If it has the same name as one of the files in folder `_data/locales`, the layout language will also be changed, # otherwise, the layout language will use the default value of 'en'. lang: en - # Change to your timezone › http://www.timezoneconverter.com/cgi-bin/findzone/findzone timezone: Asia/Shanghai # jekyll-seo-tag settings › https://github.com/jekyll/jekyll-seo-tag/blob/master/docs/usage.md # ↓ -------------------------- -title: Chirpy # the main title +title: Chirpy # the main title -tagline: A text-focused Jekyll theme # it will display as the sub-title +tagline: A text-focused Jekyll theme # it will display as the sub-title -description: >- # used by seo meta and the atom feed +description: >- # used by seo meta and the atom feed A minimal, responsive and feature-rich Jekyll theme for technical writing. # fill in the protocol & hostname for your site, e.g., 'https://username.github.io' -url: '' +url: "" github: - username: github_username # change to your github username + username: github_username # change to your github username twitter: - username: twitter_username # change to your twitter username + username: twitter_username # change to your twitter username social: # Change to your full name. # It will be displayed as the default author of the posts and the copyright owner in the Footer name: your_full_name - email: example@domain.com # change to your email address + email: example@domain.com # change to your email address links: # The first element serves as the copyright owner's link - - https://twitter.com/username # change to your twitter homepage - - https://github.com/username # change to your github homepage + - https://twitter.com/username # change to your twitter homepage + - https://github.com/username # change to your github homepage # Uncomment below to add more social links # - https://www.facebook.com/username # - https://www.linkedin.com/in/username -google_site_verification: # fill in to your verification string +google_site_verification: # fill in to your verification string # ↑ -------------------------- # The end of `jekyll-seo-tag` settings google_analytics: - id: # fill in your Google Analytics ID + id: # fill in your Google Analytics ID # Google Analytics pageviews report settings pv: - proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine - cache_path: # the local PV cache data, friendly to visitors from GFW region + proxy_endpoint: # fill in the Google Analytics superProxy endpoint of Google App Engine + cache_path: # the local PV cache data, friendly to visitors from GFW region # Prefer color scheme setting. # @@ -71,51 +70,51 @@ google_analytics: # light - Use the light color scheme # dark - Use the dark color scheme # -theme_mode: # [light|dark] +theme_mode: # [light|dark] # The CDN endpoint for images. # Notice that once it is assigned, the CDN url # will be added to all image (site avatar & posts' images) paths starting with '/' # # e.g. 'https://cdn.com' -img_cdn: 'https://chirpy-img.netlify.app' +img_cdn: "https://chirpy-img.netlify.app" # the avatar on sidebar, support local or CORS resources -avatar: '/commons/avatar.jpg' +avatar: "/commons/avatar.jpg" # boolean type, the global switch for ToC in posts. toc: true comments: - active: # The global switch for posts comments, e.g., 'disqus'. Keep it empty means disable + active: # The global switch for posts comments, e.g., 'disqus'. Keep it empty means disable # The active options are as follows: 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: - repo: # / - issue_term: # < url | pathname | title | ...> + repo: # / + issue_term: # < url | pathname | title | ...> # Giscus options › https://giscus.app giscus: - repo: # / + repo: # / repo_id: category: category_id: - mapping: # optional, default to 'pathname' - input_position: # optional, default to 'bottom' - lang: # optional, default to the value of `site.lang` + mapping: # optional, default to 'pathname' + input_position: # optional, default to 'bottom' + lang: # optional, default to the value of `site.lang` reactions_enabled: # optional, default to the value of `1` # Self-hosted static assets, optional › https://github.com/cotes2020/chirpy-static-assets assets: self_host: - enabled: # boolean, keep empty means false + enabled: # boolean, keep empty means false # specify the Jekyll environment, empty means both # only works if `assets.self_host.enabled` is 'true' - env: # [development|production] + env: # [development|production] pwa: - enabled: true # the option for PWA feature + enabled: true # the option for PWA feature paginate: 10 @@ -123,7 +122,7 @@ paginate: 10 kramdown: 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 # default_lang: console span: @@ -139,12 +138,12 @@ collections: defaults: - scope: - path: '' # An empty string here means all files in the project + path: "" # An empty string here means all files in the project type: posts values: layout: post - comments: true # Enable comments in posts. - toc: true # Display TOC column in posts. + comments: true # Enable comments in posts. + toc: true # Display TOC column in posts. # DO NOT modify the following parameter unless you are confident enough # to update the code of all other post links in this project. permalink: /posts/:title/ @@ -153,8 +152,8 @@ defaults: values: comments: false - scope: - path: '' - type: tabs # see `site.collections` + path: "" + type: tabs # see `site.collections` values: layout: page permalink: /:title/ @@ -180,13 +179,13 @@ compress_html: envs: [development] exclude: - - '*.gem' - - '*.gemspec' + - "*.gem" + - "*.gemspec" - tools - README.md - CHANGELOG.md - LICENSE - - gulpfile.js + - rollup.config.js - node_modules - package*.json diff --git a/_includes/js-selector.html b/_includes/js-selector.html index c760968..05ed99e 100644 --- a/_includes/js-selector.html +++ b/_includes/js-selector.html @@ -1,6 +1,4 @@ - + @@ -8,51 +6,50 @@ {% if site.google_analytics.pv.proxy_endpoint or site.google_analytics.pv.cache_path %} - {% endif %} {% endif %} {% if page.layout == 'post' or page.layout == 'page' %} - {% assign _urls = site.data.assets[origin].magnific-popup.js - | append: ',' | append: site.data.assets[origin].lazysizes.js - | append: ',' | append: site.data.assets[origin].clipboard.js + {% assign _urls = site.data.assets[origin]['magnific-popup'].js + | append: ',' + | append: site.data.assets[origin].lazysizes.js + | append: ',' + | append: site.data.assets[origin].clipboard.js %} {% include jsdelivr-combine.html urls=_urls %} {% endif %} {% if page.layout == 'home' - or page.layout == 'post' - or page.layout == 'archives' - or page.layout == 'category' - or page.layout == 'tag' %} - + or page.layout == 'post' + or page.layout == 'archives' + or page.layout == 'category' + or page.layout == 'tag' +%} {% assign locale = site.lang | split: '-' | first %} {% assign _urls = site.data.assets[origin].dayjs.js.common - | append: ',' | append: site.data.assets[origin].dayjs.js.locale - | replace: ':LOCALE', locale - | append: ',' | append: site.data.assets[origin].dayjs.js.relativeTime - | append: ',' | append: site.data.assets[origin].dayjs.js.localizedFormat + | append: ',' + | append: site.data.assets[origin].dayjs.js.locale + | replace: ':LOCALE', locale + | append: ',' + | append: site.data.assets[origin].dayjs.js.relativeTime + | append: ',' + | append: site.data.assets[origin].dayjs.js.localizedFormat %} {% include jsdelivr-combine.html urls=_urls %} - {% endif %} -{% if page.layout == 'home' - or page.layout == 'categories' - or page.layout == 'post' - or page.layout == 'page' %} - {% assign type = page.layout %} -{% elsif page.layout == 'archives' - or page.layout == 'category' - or page.layout == 'tag' %} - {% assign type = "misc" %} -{% else %} - {% assign type = "commons" %} -{% endif %} +{% case page.layout %} + {% when 'categories', 'post', 'page' %} + {% assign type = page.layout %} + {% when 'home', 'archives', 'category', 'tag' %} + {% assign type = 'misc' %} + {% else %} + {% assign type = 'commons' %} +{% endcase %} {% capture script %}/assets/js/dist/{{ type }}.min.js{% endcapture %} @@ -60,23 +57,24 @@ {% if page.math %} - + {% endif %} @@ -95,5 +93,4 @@ {% if site.google_analytics.id != empty and site.google_analytics.id %} {% include google-analytics.html %} {% endif %} - {% endif %} diff --git a/_includes/mode-toggle.html b/_includes/mode-toggle.html index 63b2538..ada0061 100644 --- a/_includes/mode-toggle.html +++ b/_includes/mode-toggle.html @@ -26,13 +26,12 @@ let self = this; /* always follow the system prefers */ - this.sysDarkPrefers.addEventListener("change", () => { + this.sysDarkPrefers.addEventListener('change', () => { if (self.hasMode) { if (self.isDarkMode) { if (!self.isSysDarkPrefer) { self.setDark(); } - } else { if (self.isSysDarkPrefer) { self.setLight(); @@ -43,9 +42,7 @@ } self.notify(); - }); - } /* constructor() */ get sysDarkPrefers() { return window.matchMedia("(prefers-color-scheme: dark)"); } @@ -62,8 +59,7 @@ /* get the current mode on screen */ get modeStatus() { - if (this.isDarkMode - || (!this.hasMode && this.isSysDarkPrefer)) { + if (this.isDarkMode || (!this.hasMode && this.isSysDarkPrefer)) { return ModeToggle.DARK_MODE; } else { return ModeToggle.LIGHT_MODE; @@ -93,37 +89,32 @@ }, "*"); } + flipMode() { + if (this.hasMode) { + if (this.isSysDarkPrefer) { + if (this.isLightMode) { + this.clearMode(); + } else { + this.setLight(); + } + } else { + if (this.isDarkMode) { + this.clearMode(); + } else { + this.setDark(); + } + } + } else { + if (this.isSysDarkPrefer) { + this.setLight(); + } else { + this.setDark(); + } + } + + this.notify(); + } /* flipMode() */ } /* ModeToggle */ - const toggle = new ModeToggle(); - - function flipMode() { - if (toggle.hasMode) { - if (toggle.isSysDarkPrefer) { - if (toggle.isLightMode) { - toggle.clearMode(); - } else { - toggle.setLight(); - } - - } else { - if (toggle.isDarkMode) { - toggle.clearMode(); - } else { - toggle.setDark(); - } - } - - } else { - if (toggle.isSysDarkPrefer) { - toggle.setLight(); - } else { - toggle.setDark(); - } - } - - toggle.notify(); - - } /* flipMode() */ - + const modeToggle = new ModeToggle(); diff --git a/_javascript/_copyright b/_javascript/_copyright new file mode 100644 index 0000000..dedc8ed --- /dev/null +++ b/_javascript/_copyright @@ -0,0 +1,3 @@ +Chirpy v<%= pkg.version %> (<%= pkg.homepage %>) +© 2019 <%= pkg.author %> +<%= pkg.license %> Licensed diff --git a/_javascript/categories.js b/_javascript/categories.js new file mode 100644 index 0000000..15d8251 --- /dev/null +++ b/_javascript/categories.js @@ -0,0 +1,7 @@ +import { basic, initSidebar, initTopbar } from './modules/layouts'; +import { categoryCollapse } from './modules/plugins'; + +basic(); +initSidebar(); +initTopbar(); +categoryCollapse(); diff --git a/_javascript/commons.js b/_javascript/commons.js new file mode 100644 index 0000000..05a9765 --- /dev/null +++ b/_javascript/commons.js @@ -0,0 +1,5 @@ +import { basic, initSidebar, initTopbar } from './modules/layouts'; + +basic(); +initSidebar(); +initTopbar(); diff --git a/_javascript/commons/back-to-top.js b/_javascript/commons/back-to-top.js deleted file mode 100644 index e577e8f..0000000 --- a/_javascript/commons/back-to-top.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Reference: https://bootsnipp.com/snippets/featured/link-to-top-page - */ -$(function() { - $(window).on('scroll',() => { - if ($(this).scrollTop() > 50 && - $("#sidebar-trigger").css("display") === "none") { - $("#back-to-top").fadeIn(); - } else { - $("#back-to-top").fadeOut(); - } - }); - - $("#back-to-top").on('click',() => { - $("body,html").animate({ - scrollTop: 0 - }, 800); - return false; - }); -}); diff --git a/_javascript/commons/mode-toggle.js b/_javascript/commons/mode-toggle.js deleted file mode 100644 index a83bc58..0000000 --- a/_javascript/commons/mode-toggle.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Listener for theme mode toggle - */ -$(function () { - $(".mode-toggle").on('click',(e) => { - const $target = $(e.target); - let $btn = ($target.prop("tagName") === "button".toUpperCase() ? - $target : $target.parent()); - - $btn.trigger('blur'); // remove the clicking outline - flipMode(); - }); -}); diff --git a/_javascript/commons/scroll-helper.js b/_javascript/commons/scroll-helper.js deleted file mode 100644 index 55c1b49..0000000 --- a/_javascript/commons/scroll-helper.js +++ /dev/null @@ -1,38 +0,0 @@ -/** - * A tool for smooth scrolling and topbar switcher - */ -const ScrollHelper = (function () { - const $body = $("body"); - const ATTR_TOPBAR_VISIBLE = "data-topbar-visible"; - const topbarHeight = $("#topbar-wrapper").outerHeight(); - - let scrollUpCount = 0; // the number of times the scroll up was triggered by ToC or anchor - let topbarLocked = false; - let orientationLocked = false; - - return { - hideTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, 'false'), - showTopbar: () => $body.attr(ATTR_TOPBAR_VISIBLE, 'true'), - - // scroll up - - addScrollUpTask: () => { - scrollUpCount += 1; - if (!topbarLocked) { - topbarLocked = true; - } - }, - popScrollUpTask: () => scrollUpCount -= 1, - hasScrollUpTask: () => scrollUpCount > 0, - topbarLocked: () => topbarLocked === true, - unlockTopbar: () => topbarLocked = false, - getTopbarHeight: () => topbarHeight, - - // orientation change - - orientationLocked: () => orientationLocked === true, - lockOrientation: () => orientationLocked = true, - unLockOrientation: () => orientationLocked = false - }; - -}()); diff --git a/_javascript/commons/search-display.js b/_javascript/commons/search-display.js deleted file mode 100644 index 536cfbc..0000000 --- a/_javascript/commons/search-display.js +++ /dev/null @@ -1,126 +0,0 @@ -/** - * This script make #search-result-wrapper switch to unloaded or shown automatically. - */ - -$(function () { - const btnSbTrigger = $("#sidebar-trigger"); - const btnSearchTrigger = $("#search-trigger"); - const btnCancel = $("#search-cancel"); - const main = $("#main"); - const topbarTitle = $("#topbar-title"); - const searchWrapper = $("#search-wrapper"); - const resultWrapper = $("#search-result-wrapper"); - const results = $("#search-results"); - const input = $("#search-input"); - const hints = $("#search-hints"); - - const scrollBlocker = (function () { - let offset = 0; - return { - block() { - offset = window.scrollY; - $("html,body").scrollTop(0); - }, - release() { - $("html,body").scrollTop(offset); - }, - getOffset() { - return offset; - } - }; - }()); - - /*--- Actions in mobile screens (Sidebar hidden) ---*/ - - const mobileSearchBar = (function () { - return { - on() { - btnSbTrigger.addClass("unloaded"); - topbarTitle.addClass("unloaded"); - btnSearchTrigger.addClass("unloaded"); - searchWrapper.addClass("d-flex"); - btnCancel.addClass("loaded"); - }, - off() { - btnCancel.removeClass("loaded"); - searchWrapper.removeClass("d-flex"); - btnSbTrigger.removeClass("unloaded"); - topbarTitle.removeClass("unloaded"); - btnSearchTrigger.removeClass("unloaded"); - } - }; - }()); - - const resultSwitch = (function () { - let visible = false; - - return { - on() { - if (!visible) { - // the block method must be called before $(#main) unloaded. - scrollBlocker.block(); - resultWrapper.removeClass("unloaded"); - main.addClass("unloaded"); - visible = true; - } - }, - off() { - if (visible) { - results.empty(); - if (hints.hasClass("unloaded")) { - hints.removeClass("unloaded"); - } - resultWrapper.addClass("unloaded"); - main.removeClass("unloaded"); - - // now the release method must be called after $(#main) display - scrollBlocker.release(); - - input.val(""); - visible = false; - } - } - }; - - }()); - - function isMobileView() { - return btnCancel.hasClass("loaded"); - } - - btnSearchTrigger.on('click',function () { - mobileSearchBar.on(); - resultSwitch.on(); - input.trigger('focus'); - }); - - btnCancel.on('click',function () { - mobileSearchBar.off(); - resultSwitch.off(); - }); - - input.on('focus',function () { - searchWrapper.addClass("input-focus"); - }); - - input.on('focusout', function () { - searchWrapper.removeClass("input-focus"); - }); - - input.on("input", () => { - if (input.val() === "") { - if (isMobileView()) { - hints.removeClass("unloaded"); - } else { - resultSwitch.off(); - } - - } else { - resultSwitch.on(); - if (isMobileView()) { - hints.addClass("unloaded"); - } - } - }); - -}); diff --git a/_javascript/commons/sidebar.js b/_javascript/commons/sidebar.js deleted file mode 100644 index 66d20df..0000000 --- a/_javascript/commons/sidebar.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Expand or close the sidebar in mobile screens. - */ - -$(function () { - const sidebarUtil = (function () { - const ATTR_DISPLAY = "sidebar-display"; - let isExpanded = false; - const body = $("body"); - - return { - toggle() { - if (isExpanded === false) { - body.attr(ATTR_DISPLAY, ""); - } else { - body.removeAttr(ATTR_DISPLAY); - } - - isExpanded = !isExpanded; - } - }; - - }()); - - $("#sidebar-trigger").on('click', sidebarUtil.toggle); - - $("#mask").on('click', sidebarUtil.toggle); -}); diff --git a/_javascript/commons/tooltip-loader.js b/_javascript/commons/tooltip-loader.js deleted file mode 100644 index 0b2f0b1..0000000 --- a/_javascript/commons/tooltip-loader.js +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Initial Bootstrap Tooltip. - */ -$(function () { - $("[data-toggle=\"tooltip\"]").tooltip(); -}); diff --git a/_javascript/commons/topbar-switcher.js b/_javascript/commons/topbar-switcher.js deleted file mode 100644 index e4c2b97..0000000 --- a/_javascript/commons/topbar-switcher.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Hide Header on scroll down - */ - -$(function () { - const $searchInput = $("#search-input"); - const delta = ScrollHelper.getTopbarHeight(); - - let didScroll; - let lastScrollTop = 0; - - function hasScrolled() { - let st = $(this).scrollTop(); - - /* Make sure they scroll more than delta */ - if (Math.abs(lastScrollTop - st) <= delta) { - return; - } - - if (st > lastScrollTop) { // Scroll Down - ScrollHelper.hideTopbar(); - - if ($searchInput.is(":focus")) { - $searchInput.trigger('blur'); /* remove focus */ - } - - } else { // Scroll up - // has not yet scrolled to the bottom of the screen, that is, there is still space for scrolling - if (st + $(window).height() < $(document).height()) { - - if (ScrollHelper.hasScrollUpTask()) { - return; - } - - if (ScrollHelper.topbarLocked()) { // avoid redundant scroll up event from smooth scrolling - ScrollHelper.unlockTopbar(); - } else { - if (ScrollHelper.orientationLocked()) { // avoid device auto scroll up on orientation change - ScrollHelper.unLockOrientation(); - } else { - ScrollHelper.showTopbar(); - } - } - } - } - - lastScrollTop = st; - - } // hasScrolled() - - function handleLandscape() { - if ($(window).scrollTop() === 0) { - return; - } - ScrollHelper.lockOrientation(); - ScrollHelper.hideTopbar(); - } - - if (screen.orientation) { - screen.orientation.onchange = () => { - const type = screen.orientation.type; - if (type === "landscape-primary" || type === "landscape-secondary") { - handleLandscape(); - } - }; - - } else { - // for the browsers that not support `window.screen.orientation` API - $(window).on("orientationchange", () => { - if ($(window).width() < $(window).height()) { // before rotating, it is still in portrait mode. - handleLandscape(); - } - }); - } - - $(window).on('scroll',() => { - if (didScroll) { - return; - } - didScroll = true; - }); - - setInterval(() => { - if (didScroll) { - hasScrolled(); - didScroll = false; - } - }, 250); -}); diff --git a/_javascript/commons/topbar-title.js b/_javascript/commons/topbar-title.js deleted file mode 100644 index 42e3c2d..0000000 --- a/_javascript/commons/topbar-title.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Top bar title auto change while scrolling up/down in mobile screens. - */ - -$(function () { - const titleSelector = "div.post>h1:first-of-type"; - const $pageTitle = $(titleSelector); - const $topbarTitle = $("#topbar-title"); - - if ($pageTitle.length === 0 /* on Home page */ - || $pageTitle.hasClass("dynamic-title") - || $topbarTitle.is(":hidden")) {/* not in mobile views */ - return; - } - - const defaultTitleText = $topbarTitle.text().trim(); - let pageTitleText = $pageTitle.text().trim(); - let hasScrolled = false; - let lastScrollTop = 0; - - if ($("#page-category").length || $("#page-tag").length) { - /* The title in Category or Tag page will be " <count_of_posts>" */ - if (/\s/.test(pageTitleText)) { - pageTitleText = pageTitleText.replace(/[0-9]/g, "").trim(); - } - } - - // When the page is scrolled down and then refreshed, the topbar title needs to be initialized - if ($pageTitle.offset().top < $(window).scrollTop()) { - $topbarTitle.text(pageTitleText); - } - - let options = { - rootMargin: '-48px 0px 0px 0px', // 48px equals to the topbar height (3rem) - threshold: [0, 1] - }; - - let observer = new IntersectionObserver((entries) => { - if (!hasScrolled) { - hasScrolled = true; - return; - } - - let curScrollTop = $(window).scrollTop(); - let isScrollDown = lastScrollTop < curScrollTop; - lastScrollTop = curScrollTop; - let heading = entries[0]; - - if (isScrollDown) { - if (heading.intersectionRatio === 0) { - $topbarTitle.text(pageTitleText); - } - } else { - if (heading.intersectionRatio === 1) { - $topbarTitle.text(defaultTitleText); - } - } - }, options); - - observer.observe(document.querySelector(titleSelector)); - - /* Click title will scroll to top */ - $topbarTitle.on('click', function () { - $("body,html").animate({scrollTop: 0}, 800); - }); - -}); diff --git a/_javascript/copyright b/_javascript/copyright deleted file mode 100644 index 4775b32..0000000 --- a/_javascript/copyright +++ /dev/null @@ -1,5 +0,0 @@ -/*! - * Chirpy v5.5.2 (https://github.com/cotes2020/jekyll-theme-chirpy/) - * © 2019 Cotes Chung - * MIT Licensed - */ diff --git a/_javascript/misc.js b/_javascript/misc.js new file mode 100644 index 0000000..c7a19d6 --- /dev/null +++ b/_javascript/misc.js @@ -0,0 +1,7 @@ +import { basic, initSidebar, initTopbar } from './modules/layouts'; +import { initLocaleDatetime } from './modules/plugins'; + +basic(); +initSidebar(); +initTopbar(); +initLocaleDatetime(); diff --git a/_javascript/modules/components/back-to-top.js b/_javascript/modules/components/back-to-top.js new file mode 100644 index 0000000..2519a9f --- /dev/null +++ b/_javascript/modules/components/back-to-top.js @@ -0,0 +1,26 @@ +/** + * Reference: https://bootsnipp.com/snippets/featured/link-to-top-page + */ + +export function back2top() { + $(window).on('scroll', () => { + if ( + $(window).scrollTop() > 50 && + $('#sidebar-trigger').css('display') === 'none' + ) { + $('#back-to-top').fadeIn(); + } else { + $('#back-to-top').fadeOut(); + } + }); + + $('#back-to-top').on('click', () => { + $('body,html').animate( + { + scrollTop: 0 + }, + 800 + ); + return false; + }); +} diff --git a/_javascript/modules/components/category-collapse.js b/_javascript/modules/components/category-collapse.js new file mode 100644 index 0000000..d6027a1 --- /dev/null +++ b/_javascript/modules/components/category-collapse.js @@ -0,0 +1,36 @@ +/** + * Tab 'Categories' expand/close effect. + */ +const childPrefix = 'l_'; +const parentPrefix = 'h_'; +const collapse = $('.collapse'); + +export function categoryCollapse() { + /* close up top-category */ + collapse.on('hide.bs.collapse', function () { + /* Bootstrap collapse events. */ const parentId = + 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.on('show.bs.collapse', function () { + const parentId = + parentPrefix + $(this).attr('id').substring(childPrefix.length); + if (parentId) { + $(`#${parentId} .far.fa-folder`).attr( + 'class', + 'far fa-folder-open fa-fw' + ); + $(`#${parentId} i.fas`).removeClass('rotate'); + $(`#${parentId}`).addClass('hide-border-bottom'); + } + }); +} diff --git a/_javascript/modules/components/clipboard.js b/_javascript/modules/components/clipboard.js new file mode 100644 index 0000000..cff2d09 --- /dev/null +++ b/_javascript/modules/components/clipboard.js @@ -0,0 +1,118 @@ +/** + * Clipboard functions + * + * Dependencies: + * - popper.js (https://github.com/popperjs/popper-core) + * - clipboard.js (https://github.com/zenorocha/clipboard.js) + */ + +const btnSelector = '.code-header>button'; +const ICON_SUCCESS = 'fas fa-check'; +const ATTR_TIMEOUT = 'timeout'; +const ATTR_TITLE_SUCCEED = 'data-title-succeed'; +const ATTR_TITLE_ORIGIN = 'data-original-title'; +const TIMEOUT = 2000; // in milliseconds + +function isLocked(node) { + if ($(node)[0].hasAttribute(ATTR_TIMEOUT)) { + let timeout = $(node).attr(ATTR_TIMEOUT); + if (Number(timeout) > Date.now()) { + return true; + } + } + return false; +} + +function lock(node) { + $(node).attr(ATTR_TIMEOUT, Date.now() + TIMEOUT); +} + +function unlock(node) { + $(node).removeAttr(ATTR_TIMEOUT); +} + +function getIcon(btn) { + let iconNode = $(btn).children(); + return iconNode.attr('class'); +} + +const ICON_DEFAULT = getIcon(btnSelector); + +function showTooltip(btn) { + const succeedTitle = $(btn).attr(ATTR_TITLE_SUCCEED); + $(btn).attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show'); +} + +function hideTooltip(btn) { + $(btn).tooltip('hide').removeAttr(ATTR_TITLE_ORIGIN); +} + +function setSuccessIcon(btn) { + let btnNode = $(btn); + let iconNode = btnNode.children(); + iconNode.attr('class', ICON_SUCCESS); +} + +function resumeIcon(btn) { + let btnNode = $(btn); + let iconNode = btnNode.children(); + iconNode.attr('class', ICON_DEFAULT); +} + +export function initClipboard() { + // Initial the clipboard.js object + const clipboard = new ClipboardJS(btnSelector, { + target(trigger) { + let codeBlock = trigger.parentNode.nextElementSibling; + return codeBlock.querySelector('code .rouge-code'); + } + }); + + $(btnSelector).tooltip({ + trigger: 'hover', + 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 --- */ + + $('#copy-link').on('click', (e) => { + let target = $(e.target); + + if (isLocked(target)) { + return; + } + + // Copy URL to clipboard + navigator.clipboard.writeText(window.location.href).then(() => { + const defaultTitle = target.attr(ATTR_TITLE_ORIGIN); + const succeedTitle = target.attr(ATTR_TITLE_SUCCEED); + // Switch tooltip title + target.attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show'); + lock(target); + + setTimeout(() => { + target.attr(ATTR_TITLE_ORIGIN, defaultTitle); + unlock(target); + }, TIMEOUT); + }); + }); +} diff --git a/_javascript/modules/components/convert-title.js b/_javascript/modules/components/convert-title.js new file mode 100644 index 0000000..649f7be --- /dev/null +++ b/_javascript/modules/components/convert-title.js @@ -0,0 +1,68 @@ +/** + * Top bar title auto change while scrolling up/down in mobile screens. + */ +const titleSelector = 'div.post>h1:first-of-type'; +const $pageTitle = $(titleSelector); +const $topbarTitle = $('#topbar-title'); +const defaultTitleText = $topbarTitle.text().trim(); + +export function convertTitle() { + if ( + $pageTitle.length === 0 /* on Home page */ || + $pageTitle.hasClass('dynamic-title') || + $topbarTitle.is(':hidden') + ) { + /* not in mobile views */ + return; + } + + let pageTitleText = $pageTitle.text().trim(); + let hasScrolled = false; + let lastScrollTop = 0; + + if ($('#page-category').length || $('#page-tag').length) { + /* The title in Category or Tag page will be "<title> <count_of_posts>" */ + if (/\s/.test(pageTitleText)) { + pageTitleText = pageTitleText.replace(/[0-9]/g, '').trim(); + } + } + + // When the page is scrolled down and then refreshed, the topbar title needs to be initialized + if ($pageTitle.offset().top < $(window).scrollTop()) { + $topbarTitle.text(pageTitleText); + } + + let options = { + rootMargin: '-48px 0px 0px 0px', // 48px equals to the topbar height (3rem) + threshold: [0, 1] + }; + + let observer = new IntersectionObserver((entries) => { + if (!hasScrolled) { + hasScrolled = true; + return; + } + + let curScrollTop = $(window).scrollTop(); + let isScrollDown = lastScrollTop < curScrollTop; + lastScrollTop = curScrollTop; + let heading = entries[0]; + + if (isScrollDown) { + if (heading.intersectionRatio === 0) { + $topbarTitle.text(pageTitleText); + } + } else { + if (heading.intersectionRatio === 1) { + $topbarTitle.text(defaultTitleText); + } + } + }, options); + + observer.observe(document.querySelector(titleSelector)); + + /* Click title will scroll to top */ + $topbarTitle.on('click', function () { + $('body,html').animate({ scrollTop: 0 }, 800); + }); +} diff --git a/_javascript/modules/components/img-extra.js b/_javascript/modules/components/img-extra.js new file mode 100644 index 0000000..47b8404 --- /dev/null +++ b/_javascript/modules/components/img-extra.js @@ -0,0 +1,27 @@ +/** + * Set up image stuff + */ + +export function imgExtra() { + if ($('#core-wrapper img[data-src]') <= 0) { + return; + } + + /* See: <https://github.com/dimsemenov/Magnific-Popup> */ + $('.popup').magnificPopup({ + type: 'image', + closeOnContentClick: true, + showCloseBtn: false, + zoom: { + enabled: true, + duration: 300, + easing: 'ease-in-out' + } + }); + + /* Stop shimmer when image loaded */ + document.addEventListener('lazyloaded', function (e) { + const $img = $(e.target); + $img.parent().removeClass('shimmer'); + }); +} diff --git a/_javascript/modules/components/locale-datetime.js b/_javascript/modules/components/locale-datetime.js new file mode 100644 index 0000000..7bab64b --- /dev/null +++ b/_javascript/modules/components/locale-datetime.js @@ -0,0 +1,50 @@ +/** + * Update month/day to locale datetime + * + * Requirement: <https://github.com/iamkun/dayjs> + */ + +/* A tool for locale datetime */ +class LocaleHelper { + static get attrTimestamp() { + return 'data-ts'; + } + + static get attrDateFormat() { + return 'data-df'; + } + + static get locale() { + return $('html').attr('lang').substring(0, 2); + } + + static getTimestamp(elem) { + return Number(elem.attr(LocaleHelper.attrTimestamp)); // unix timestamp + } + + static getDateFormat(elem) { + return elem.attr(LocaleHelper.attrDateFormat); + } +} + +export function initLocaleDatetime() { + dayjs.locale(LocaleHelper.locale); + dayjs.extend(window.dayjs_plugin_localizedFormat); + + $(`[${LocaleHelper.attrTimestamp}]`).each(function () { + const date = dayjs.unix(LocaleHelper.getTimestamp($(this))); + const text = date.format(LocaleHelper.getDateFormat($(this))); + $(this).text(text); + $(this).removeAttr(LocaleHelper.attrTimestamp); + $(this).removeAttr(LocaleHelper.attrDateFormat); + + // setup tooltips + const tooltip = $(this).attr('data-toggle'); + if (typeof tooltip === 'undefined' || tooltip !== 'tooltip') { + return; + } + + const tooltipText = date.format('llll'); // see: https://day.js.org/docs/en/display/format#list-of-localized-formats + $(this).attr('data-original-title', tooltipText); + }); +} diff --git a/_javascript/modules/components/mode-watcher.js b/_javascript/modules/components/mode-watcher.js new file mode 100644 index 0000000..7b2298a --- /dev/null +++ b/_javascript/modules/components/mode-watcher.js @@ -0,0 +1,21 @@ +/** + * Add listener for theme mode toggle + */ +const $toggleElem = $('.mode-toggle'); + +export function modeWatcher() { + if ($toggleElem.length === 0) { + return; + } + + $toggleElem.off().on('click', (e) => { + const $target = $(e.target); + let $btn = + $target.prop('tagName') === 'button'.toUpperCase() + ? $target + : $target.parent(); + + modeToggle.flipMode(); // modeToggle: `_includes/mode-toggle.html` + $btn.trigger('blur'); // remove the clicking outline + }); +} diff --git a/_javascript/modules/components/pageviews.js b/_javascript/modules/components/pageviews.js new file mode 100644 index 0000000..99e72ce --- /dev/null +++ b/_javascript/modules/components/pageviews.js @@ -0,0 +1,254 @@ +/** + * Count page views form GA or local cache file. + * + * Dependencies: + * - jQuery + * - countUp.js <https://github.com/inorganik/countUp.js> + */ + +const getInitStatus = (function () { + let hasInit = false; + return () => { + let ret = hasInit; + if (!hasInit) { + hasInit = true; + } + return ret; + }; +})(); + +const PvOpts = (function () { + function getContent(selector) { + return $(selector).attr('content'); + } + + function hasContent(selector) { + let content = getContent(selector); + return typeof content !== 'undefined' && content !== false; + } + + return { + getProxyMeta() { + return getContent('meta[name=pv-proxy-endpoint]'); + }, + getLocalMeta() { + return getContent('meta[name=pv-cache-path]'); + }, + hasProxyMeta() { + return hasContent('meta[name=pv-proxy-endpoint]'); + }, + hasLocalMeta() { + return hasContent('meta[name=pv-cache-path]'); + } + }; +})(); + +const PvStorage = (function () { + const Keys = { + KEY_PV: 'pv', + KEY_PV_SRC: 'pv_src', + KEY_CREATION: 'pv_created_date' + }; + + const Source = { + LOCAL: 'same-origin', + PROXY: 'cors' + }; + + function get(key) { + return localStorage.getItem(key); + } + + function set(key, val) { + localStorage.setItem(key, val); + } + + function saveCache(pv, src) { + set(Keys.KEY_PV, pv); + set(Keys.KEY_PV_SRC, src); + set(Keys.KEY_CREATION, new Date().toJSON()); + } + + return { + keysCount() { + return Object.keys(Keys).length; + }, + hasCache() { + return localStorage.getItem(Keys.KEY_PV) !== null; + }, + getCache() { + return JSON.parse(localStorage.getItem(Keys.KEY_PV)); + }, + saveLocalCache(pv) { + saveCache(pv, Source.LOCAL); + }, + saveProxyCache(pv) { + saveCache(pv, Source.PROXY); + }, + isExpired() { + let date = new Date(get(Keys.KEY_CREATION)); + date.setHours(date.getHours() + 1); // per hour + return Date.now() >= date.getTime(); + }, + isFromLocal() { + return get(Keys.KEY_PV_SRC) === Source.LOCAL; + }, + isFromProxy() { + return get(Keys.KEY_PV_SRC) === Source.PROXY; + }, + newerThan(pv) { + return ( + PvStorage.getCache().totalsForAllResults['ga:pageviews'] > + pv.totalsForAllResults['ga:pageviews'] + ); + }, + inspectKeys() { + if (localStorage.length !== PvStorage.keysCount()) { + localStorage.clear(); + return; + } + + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); + switch (key) { + case Keys.KEY_PV: + case Keys.KEY_PV_SRC: + case Keys.KEY_CREATION: + break; + default: + localStorage.clear(); + return; + } + } + } + }; +})(); /* PvStorage */ + +function countUp(min, max, destId) { + if (min < max) { + let numAnim = new CountUp(destId, min, max); + if (!numAnim.error) { + numAnim.start(); + } else { + console.error(numAnim.error); + } + } +} + +function countPV(path, rows) { + let count = 0; + + if (typeof rows !== 'undefined') { + for (let i = 0; i < rows.length; ++i) { + const gaPath = rows[parseInt(i, 10)][0]; + if (gaPath === path) { + /* path format see: site.permalink */ + count += parseInt(rows[parseInt(i, 10)][1], 10); + break; + } + } + } + + return count; +} + +function tacklePV(rows, path, elem, hasInit) { + let count = countPV(path, rows); + count = count === 0 ? 1 : count; + + if (!hasInit) { + elem.text(new Intl.NumberFormat().format(count)); + } else { + const initCount = parseInt(elem.text().replace(/,/g, ''), 10); + if (count > initCount) { + countUp(initCount, count, elem.attr('id')); + } + } +} + +function displayPageviews(data) { + if (typeof data === 'undefined') { + return; + } + + let hasInit = getInitStatus(); + const rows = data.rows; /* could be undefined */ + + if ($('#post-list').length > 0) { + /* the Home page */ + $('.post-preview').each(function () { + const path = $(this).find('a').attr('href'); + tacklePV(rows, path, $(this).find('.pageviews'), hasInit); + }); + } else if ($('.post').length > 0) { + /* the post */ + const path = window.location.pathname; + tacklePV(rows, path, $('#pv'), hasInit); + } +} + +function fetchProxyPageviews() { + if (PvOpts.hasProxyMeta()) { + $.ajax({ + type: 'GET', + url: PvOpts.getProxyMeta(), + dataType: 'jsonp', + jsonpCallback: 'displayPageviews', + success: (data) => { + PvStorage.saveProxyCache(JSON.stringify(data)); + }, + error: (jqXHR, textStatus, errorThrown) => { + console.log( + 'Failed to load pageviews from proxy server: ' + errorThrown + ); + } + }); + } +} + +function fetchLocalPageviews(hasCache = false) { + return fetch(PvOpts.getLocalMeta()) + .then((response) => response.json()) + .then((data) => { + if (hasCache) { + // The cache from the proxy will sometimes be more recent than the local one + if (PvStorage.isFromProxy() && PvStorage.newerThan(data)) { + return; + } + } + displayPageviews(data); + PvStorage.saveLocalCache(JSON.stringify(data)); + }); +} + +export function initPageviews() { + if ($('.pageviews').length <= 0) { + return; + } + + PvStorage.inspectKeys(); + + if (PvStorage.hasCache()) { + displayPageviews(PvStorage.getCache()); + + if (PvStorage.isExpired()) { + if (PvOpts.hasLocalMeta()) { + fetchLocalPageviews(true).then(fetchProxyPageviews); + } else { + fetchProxyPageviews(); + } + } else { + if (PvStorage.isFromLocal()) { + fetchProxyPageviews(); + } + } + } else { + // no cached + + if (PvOpts.hasLocalMeta()) { + fetchLocalPageviews().then(fetchProxyPageviews); + } else { + fetchProxyPageviews(); + } + } +} diff --git a/_javascript/modules/components/search-display.js b/_javascript/modules/components/search-display.js new file mode 100644 index 0000000..2e38f5e --- /dev/null +++ b/_javascript/modules/components/search-display.js @@ -0,0 +1,122 @@ +/** + * This script make #search-result-wrapper switch to unloaded or shown automatically. + */ +const $btnSbTrigger = $('#sidebar-trigger'); +const $btnSearchTrigger = $('#search-trigger'); +const $btnCancel = $('#search-cancel'); +const $main = $('#main'); +const $topbarTitle = $('#topbar-title'); +const $searchWrapper = $('#search-wrapper'); +const $resultWrapper = $('#search-result-wrapper'); +const $results = $('#search-results'); +const $input = $('#search-input'); +const $hints = $('#search-hints'); +const $viewport = $('html,body'); + +// class names +const C_LOADED = 'loaded'; +const C_UNLOADED = 'unloaded'; +const C_FOCUS = 'input-focus'; +const C_FLEX = 'd-flex'; + +class ScrollBlocker { + static offset = 0; + static resultVisible = false; + + static on() { + ScrollBlocker.offset = window.scrollY; + $viewport.scrollTop(0); + } + + static off() { + $viewport.scrollTop(ScrollBlocker.offset); + } +} + +/*--- Actions in mobile screens (Sidebar hidden) ---*/ +class MobileSearchBar { + static on() { + $btnSbTrigger.addClass(C_UNLOADED); + $topbarTitle.addClass(C_UNLOADED); + $btnSearchTrigger.addClass(C_UNLOADED); + $searchWrapper.addClass(C_FLEX); + $btnCancel.addClass(C_LOADED); + } + + static off() { + $btnCancel.removeClass(C_LOADED); + $searchWrapper.removeClass(C_FLEX); + $btnSbTrigger.removeClass(C_UNLOADED); + $topbarTitle.removeClass(C_UNLOADED); + $btnSearchTrigger.removeClass(C_UNLOADED); + } +} + +class ResultSwitch { + static on() { + if (!ScrollBlocker.resultVisible) { + // the block method must be called before $(#main) unloaded. + ScrollBlocker.on(); + $resultWrapper.removeClass(C_UNLOADED); + $main.addClass(C_UNLOADED); + ScrollBlocker.resultVisible = true; + } + } + + static off() { + if (ScrollBlocker.resultVisible) { + $results.empty(); + if ($hints.hasClass(C_UNLOADED)) { + $hints.removeClass(C_UNLOADED); + } + $resultWrapper.addClass(C_UNLOADED); + $main.removeClass(C_UNLOADED); + + // now the release method must be called after $(#main) display + ScrollBlocker.off(); + + $input.val(''); + ScrollBlocker.resultVisible = false; + } + } +} + +function isMobileView() { + return $btnCancel.hasClass(C_LOADED); +} + +export function displaySearch() { + $btnSearchTrigger.on('click', function () { + MobileSearchBar.on(); + ResultSwitch.on(); + $input.trigger('focus'); + }); + + $btnCancel.on('click', function () { + MobileSearchBar.off(); + ResultSwitch.off(); + }); + + $input.on('focus', function () { + $searchWrapper.addClass(C_FOCUS); + }); + + $input.on('focusout', function () { + $searchWrapper.removeClass(C_FOCUS); + }); + + $input.on('input', () => { + if ($input.val() === '') { + if (isMobileView()) { + $hints.removeClass(C_UNLOADED); + } else { + ResultSwitch.off(); + } + } else { + ResultSwitch.on(); + if (isMobileView()) { + $hints.addClass(C_UNLOADED); + } + } + }); +} diff --git a/_javascript/modules/components/sidebar.js b/_javascript/modules/components/sidebar.js new file mode 100644 index 0000000..9d8567e --- /dev/null +++ b/_javascript/modules/components/sidebar.js @@ -0,0 +1,25 @@ +/** + * Expand or close the sidebar in mobile screens. + */ + +const $body = $('body'); +const ATTR_DISPLAY = 'sidebar-display'; + +class SidebarUtil { + static isExpanded = false; + + static toggle() { + if (SidebarUtil.isExpanded === false) { + $body.attr(ATTR_DISPLAY, ''); + } else { + $body.removeAttr(ATTR_DISPLAY); + } + + SidebarUtil.isExpanded = !SidebarUtil.isExpanded; + } +} + +export function sidebarExpand() { + $('#sidebar-trigger').on('click', SidebarUtil.toggle); + $('#mask').on('click', SidebarUtil.toggle); +} diff --git a/_javascript/modules/components/smooth-scroll.js b/_javascript/modules/components/smooth-scroll.js new file mode 100644 index 0000000..09f75d0 --- /dev/null +++ b/_javascript/modules/components/smooth-scroll.js @@ -0,0 +1,109 @@ +/** + Safari doesn't support CSS `scroll-behavior: smooth`, + so here is a compatible solution for all browser to smooth scrolling + + See: <https://css-tricks.com/snippets/jquery/smooth-scrolling/> + + Warning: It must be called after all `<a>` tags (e.g., the dynamic TOC) are ready. + */ +import ScrollHelper from './utils/scroll-helper'; + +export function smoothScroll() { + const $topbarTitle = $('#topbar-title'); + const REM = 16; // in pixels + const ATTR_SCROLL_FOCUS = 'scroll-focus'; + const SCOPE = "a[href*='#']:not([href='#']):not([href='#0'])"; + + $(SCOPE).on('click', function (event) { + if ( + this.pathname.replace(/^\//, '') !== location.pathname.replace(/^\//, '') + ) { + return; + } + + if (location.hostname !== this.hostname) { + return; + } + + const hash = decodeURI(this.hash); + let toFootnoteRef = RegExp(/^#fnref:/).test(hash); + let toFootnote = toFootnoteRef ? false : RegExp(/^#fn:/).test(hash); + let selector = '#' + $.escapeSelector(hash.substring(1)); + let $target = $(selector); + + let isMobileViews = $topbarTitle.is(':visible'); + let isPortrait = $(window).width() < $(window).height(); + + if (typeof $target === 'undefined') { + return; + } + + event.preventDefault(); + + if (history.pushState) { + /* add hash to URL */ + history.pushState(null, null, hash); + } + + let curOffset = $(window).scrollTop(); + let destOffset = ($target.offset().top -= REM / 2); + + if (destOffset < curOffset) { + // scroll up + ScrollHelper.hideTopbar(); + ScrollHelper.addScrollUpTask(); + + if (isMobileViews && isPortrait) { + destOffset -= ScrollHelper.getTopbarHeight(); + } + } else { + // scroll down + if (isMobileViews && isPortrait) { + destOffset -= ScrollHelper.getTopbarHeight(); + } + } + + $('html').animate( + { + scrollTop: destOffset + }, + 500, + () => { + $target.trigger('focus'); + + /* clean up old scroll mark */ + const $scroll_focus = $(`[${ATTR_SCROLL_FOCUS}=true]`); + if ($scroll_focus.length) { + $scroll_focus.attr(ATTR_SCROLL_FOCUS, 'false'); + } + + /* Clean :target links */ + const $target_links = $(':target'); + if ($target_links.length) { + /* element that visited by the URL with hash */ + $target_links.attr(ATTR_SCROLL_FOCUS, 'false'); + } + + /* set scroll mark to footnotes */ + if (toFootnote || toFootnoteRef) { + $target.attr(ATTR_SCROLL_FOCUS, 'true'); + } + + if ($target.is(':focus')) { + /* Checking if the target was focused */ + return false; + } else { + $target.attr( + 'tabindex', + '-1' + ); /* Adding tabindex for elements not focusable */ + $target.trigger('focus'); /* Set focus again */ + } + + if (ScrollHelper.hasScrollUpTask()) { + ScrollHelper.popScrollUpTask(); + } + } + ); + }); /* click() */ +} diff --git a/_javascript/modules/components/tooltip-loader.js b/_javascript/modules/components/tooltip-loader.js new file mode 100644 index 0000000..809487a --- /dev/null +++ b/_javascript/modules/components/tooltip-loader.js @@ -0,0 +1,6 @@ +/** + * Initial Bootstrap Tooltip. + */ +export function loadTooptip() { + $('[data-toggle="tooltip"]').tooltip(); +} diff --git a/_javascript/modules/components/topbar-switcher.js b/_javascript/modules/components/topbar-switcher.js new file mode 100644 index 0000000..f3eebb7 --- /dev/null +++ b/_javascript/modules/components/topbar-switcher.js @@ -0,0 +1,93 @@ +/** + * Hide Header on scroll down + */ +import ScrollHelper from './utils/scroll-helper'; + +const $searchInput = $('#search-input'); +const delta = ScrollHelper.getTopbarHeight(); + +let didScroll; +let lastScrollTop = 0; + +function hasScrolled() { + let st = $(window).scrollTop(); + + /* Make sure they scroll more than delta */ + if (Math.abs(lastScrollTop - st) <= delta) { + return; + } + + if (st > lastScrollTop) { + /* Scroll down */ + ScrollHelper.hideTopbar(); + + if ($searchInput.is(':focus')) { + $searchInput.trigger('blur'); /* remove focus */ + } + } else { + /* Scroll up */ + + // has not yet scrolled to the bottom of the screen, that is, there is still space for scrolling + if (st + $(window).height() < $(document).height()) { + if (ScrollHelper.hasScrollUpTask()) { + return; + } + + if (ScrollHelper.topbarLocked()) { + // avoid redundant scroll up event from smooth scrolling + ScrollHelper.unlockTopbar(); + } else { + if (ScrollHelper.orientationLocked()) { + // avoid device auto scroll up on orientation change + ScrollHelper.unLockOrientation(); + } else { + ScrollHelper.showTopbar(); + } + } + } + } + + lastScrollTop = st; +} // hasScrolled() + +function handleLandscape() { + if ($(window).scrollTop() === 0) { + return; + } + ScrollHelper.lockOrientation(); + ScrollHelper.hideTopbar(); +} + +export function switchTopbar() { + const orientation = screen.orientation; + if (orientation) { + orientation.onchange = () => { + const type = orientation.type; + if (type === 'landscape-primary' || type === 'landscape-secondary') { + handleLandscape(); + } + }; + } else { + // for the browsers that not support `window.screen.orientation` API + $(window).on('orientationchange', () => { + if ($(window).width() < $(window).height()) { + // before rotating, it is still in portrait mode. + handleLandscape(); + } + }); + } + + $(window).on('scroll', () => { + if (didScroll) { + return; + } + didScroll = true; + }); + + setInterval(() => { + if (didScroll) { + hasScrolled(); + didScroll = false; + } + }, 250); +} diff --git a/_javascript/modules/components/utils/scroll-helper.js b/_javascript/modules/components/utils/scroll-helper.js new file mode 100644 index 0000000..78ad9c8 --- /dev/null +++ b/_javascript/modules/components/utils/scroll-helper.js @@ -0,0 +1,64 @@ +/** + * A tool for smooth scrolling and topbar switcher + */ + +const ATTR_TOPBAR_VISIBLE = 'data-topbar-visible'; +const $body = $('body'); +const $topbarWrapper = $('#topbar-wrapper'); + +export default class ScrollHelper { + static scrollUpCount = 0; // the number of times the scroll up was triggered by ToC or anchor + static topbarIsLocked = false; + static orientationIsLocked = false; + + static hideTopbar() { + $body.attr(ATTR_TOPBAR_VISIBLE, 'false'); + } + + static showTopbar() { + $body.attr(ATTR_TOPBAR_VISIBLE, 'true'); + } + + // scroll up + + static addScrollUpTask() { + ScrollHelper.scrollUpCount += 1; + if (!ScrollHelper.topbarIsLocked) { + ScrollHelper.topbarIsLocked = true; + } + } + + static popScrollUpTask() { + ScrollHelper.scrollUpCount -= 1; + } + + static hasScrollUpTask() { + return ScrollHelper.scrollUpCount > 0; + } + + static topbarLocked() { + return ScrollHelper.topbarIsLocked === true; + } + + static unlockTopbar() { + ScrollHelper.topbarIsLocked = false; + } + + static getTopbarHeight() { + return $topbarWrapper.outerHeight(); + } + + // orientation change + + static orientationLocked() { + return ScrollHelper.orientationIsLocked === true; + } + + static lockOrientation() { + ScrollHelper.orientationIsLocked = true; + } + + static unLockOrientation() { + ScrollHelper.orientationIsLocked = false; + } +} diff --git a/_javascript/modules/layouts.js b/_javascript/modules/layouts.js new file mode 100644 index 0000000..28f7962 --- /dev/null +++ b/_javascript/modules/layouts.js @@ -0,0 +1,3 @@ +export { basic } from './layouts/basic'; +export { initSidebar } from './layouts/sidebar'; +export { initTopbar } from './layouts/topbar'; diff --git a/_javascript/modules/layouts/basic.js b/_javascript/modules/layouts/basic.js new file mode 100644 index 0000000..fb36a8b --- /dev/null +++ b/_javascript/modules/layouts/basic.js @@ -0,0 +1,7 @@ +import { back2top } from '../components/back-to-top'; +import { loadTooptip } from '../components/tooltip-loader'; + +export function basic() { + back2top(); + loadTooptip(); +} diff --git a/_javascript/modules/layouts/sidebar.js b/_javascript/modules/layouts/sidebar.js new file mode 100644 index 0000000..8795693 --- /dev/null +++ b/_javascript/modules/layouts/sidebar.js @@ -0,0 +1,7 @@ +import { modeWatcher } from '../components/mode-watcher'; +import { sidebarExpand } from '../components/sidebar'; + +export function initSidebar() { + modeWatcher(); + sidebarExpand(); +} diff --git a/_javascript/modules/layouts/topbar.js b/_javascript/modules/layouts/topbar.js new file mode 100644 index 0000000..76549bf --- /dev/null +++ b/_javascript/modules/layouts/topbar.js @@ -0,0 +1,9 @@ +import { convertTitle } from '../components/convert-title'; +import { displaySearch } from '../components/search-display'; +import { switchTopbar } from '../components/topbar-switcher'; + +export function initTopbar() { + convertTitle(); + displaySearch(); + switchTopbar(); +} diff --git a/_javascript/modules/plugins.js b/_javascript/modules/plugins.js new file mode 100644 index 0000000..48ada6f --- /dev/null +++ b/_javascript/modules/plugins.js @@ -0,0 +1,6 @@ +export { categoryCollapse } from './components/category-collapse'; +export { initClipboard } from './components/clipboard'; +export { imgExtra } from './components/img-extra'; +export { initLocaleDatetime } from './components/locale-datetime'; +export { initPageviews } from './components/pageviews'; +export { smoothScroll } from './components/smooth-scroll'; diff --git a/_javascript/page.js b/_javascript/page.js new file mode 100644 index 0000000..0d497f0 --- /dev/null +++ b/_javascript/page.js @@ -0,0 +1,9 @@ +import { basic, initSidebar, initTopbar } from './modules/layouts'; +import { imgExtra, initClipboard, smoothScroll } from './modules/plugins'; + +basic(); +initSidebar(); +initTopbar(); +imgExtra(); +initClipboard(); +smoothScroll(); diff --git a/_javascript/post.js b/_javascript/post.js new file mode 100644 index 0000000..2f8cc5c --- /dev/null +++ b/_javascript/post.js @@ -0,0 +1,17 @@ +import { basic, initSidebar, initTopbar } from './modules/layouts'; +import { + imgExtra, + initLocaleDatetime, + initClipboard, + smoothScroll, + initPageviews +} from './modules/plugins'; + +basic(); +initSidebar(); +initTopbar(); +imgExtra(); +initLocaleDatetime(); +initClipboard(); +smoothScroll(); +initPageviews(); diff --git a/_javascript/utils/category-collapse.js b/_javascript/utils/category-collapse.js deleted file mode 100644 index 965bcfd..0000000 --- a/_javascript/utils/category-collapse.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Tab 'Categories' expand/close effect. - */ - -$(function () { - const childPrefix = "l_"; - const parentPrefix = "h_"; - const collapse = $(".collapse"); - - /* close up top-category */ - collapse.on("hide.bs.collapse", function () { /* Bootstrap collapse events. */ - const parentId = 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.on("show.bs.collapse", function () { - const parentId = parentPrefix + $(this).attr("id").substring(childPrefix.length); - if (parentId) { - $(`#${parentId} .far.fa-folder`).attr("class", "far fa-folder-open fa-fw"); - $(`#${parentId} i.fas`).removeClass("rotate"); - $(`#${parentId}`).addClass("hide-border-bottom"); - } - }); - -}); diff --git a/_javascript/utils/clipboard.js b/_javascript/utils/clipboard.js deleted file mode 100644 index 73f33fd..0000000 --- a/_javascript/utils/clipboard.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * Clipboard functions - * - * Dependencies: - * - popper.js (https://github.com/popperjs/popper-core) - * - clipboard.js (https://github.com/zenorocha/clipboard.js) - */ - -$(function () { - const btnSelector = '.code-header>button'; - const ICON_SUCCESS = 'fas fa-check'; - const ATTR_TIMEOUT = 'timeout'; - const ATTR_TITLE_SUCCEED = 'data-title-succeed'; - const ATTR_TITLE_ORIGIN = 'data-original-title'; - const TIMEOUT = 2000; // in milliseconds - - function isLocked(node) { - if ($(node)[0].hasAttribute(ATTR_TIMEOUT)) { - let timeout = $(node).attr(ATTR_TIMEOUT); - if (Number(timeout) > Date.now()) { - return true; - } - } - return false; - } - - function lock(node) { - $(node).attr(ATTR_TIMEOUT, Date.now() + TIMEOUT); - } - - function unlock(node) { - $(node).removeAttr(ATTR_TIMEOUT); - } - - /* --- Copy code block --- */ - - // Initial the clipboard.js object - const clipboard = new ClipboardJS(btnSelector, { - target(trigger) { - let codeBlock = trigger.parentNode.nextElementSibling; - return codeBlock.querySelector('code .rouge-code'); - } - }); - - $(btnSelector).tooltip({ - trigger: 'hover', - placement: 'left' - }); - - function getIcon(btn) { - let iconNode = $(btn).children(); - return iconNode.attr('class'); - } - - const ICON_DEFAULT = getIcon(btnSelector); - - function showTooltip(btn) { - const succeedTitle = $(btn).attr(ATTR_TITLE_SUCCEED); - $(btn).attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show'); - } - - function hideTooltip(btn) { - $(btn).tooltip('hide').removeAttr(ATTR_TITLE_ORIGIN); - } - - function setSuccessIcon(btn) { - let btnNode = $(btn); - let iconNode = btnNode.children(); - iconNode.attr('class', ICON_SUCCESS); - } - - function resumeIcon(btn) { - let btnNode = $(btn); - let iconNode = btnNode.children(); - iconNode.attr('class', ICON_DEFAULT); - } - - 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 --- */ - - $('#copy-link').on('click',(e) => { - let target = $(e.target); - - if (isLocked(target)) { - return; - } - - // Copy URL to clipboard - navigator.clipboard - .writeText(window.location.href) - .then(() => { - const defaultTitle = target.attr(ATTR_TITLE_ORIGIN); - const succeedTitle = target.attr(ATTR_TITLE_SUCCEED); - // Switch tooltip title - target.attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show'); - lock(target); - - setTimeout(() => { - target.attr(ATTR_TITLE_ORIGIN, defaultTitle); - unlock(target); - }, TIMEOUT); - }); - }); -}); diff --git a/_javascript/utils/img-extra.js b/_javascript/utils/img-extra.js deleted file mode 100644 index 90a3f49..0000000 --- a/_javascript/utils/img-extra.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Set up image stuff - */ - -(function() { - if ($('#core-wrapper img[data-src]') <= 0) { - return; - } - - /* See: <https://github.com/dimsemenov/Magnific-Popup> */ - $('.popup').magnificPopup({ - type: 'image', - closeOnContentClick: true, - showCloseBtn: false, - zoom: { - enabled: true, - duration: 300, - easing: 'ease-in-out' - } - }); - - /* Stop shimmer when image loaded */ - document.addEventListener('lazyloaded', function(e) { - const $img = $(e.target); - $img.parent().removeClass('shimmer'); - }); - -})(); diff --git a/_javascript/utils/locale-datetime.js b/_javascript/utils/locale-datetime.js deleted file mode 100644 index bfd3a66..0000000 --- a/_javascript/utils/locale-datetime.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Update month/day to locale datetime - * - * Requirement: <https://github.com/iamkun/dayjs> - */ - -/* A tool for locale datetime */ -const LocaleHelper = (function () { - const locale = $('html').attr('lang').substring(0, 2); - const attrTimestamp = 'data-ts'; - const attrDateFormat = 'data-df'; - - return { - locale: () => locale, - attrTimestamp: () => attrTimestamp, - attrDateFormat: () => attrDateFormat, - getTimestamp: ($elem) => Number($elem.attr(attrTimestamp)), // unix timestamp - getDateFormat: ($elem) => $elem.attr(attrDateFormat) - }; - -}()); - -$(function () { - dayjs.locale(LocaleHelper.locale()); - dayjs.extend(window.dayjs_plugin_localizedFormat); - - $(`[${LocaleHelper.attrTimestamp()}]`).each(function () { - const date = dayjs.unix(LocaleHelper.getTimestamp($(this))); - const text = date.format(LocaleHelper.getDateFormat($(this))); - $(this).text(text); - $(this).removeAttr(LocaleHelper.attrTimestamp()); - $(this).removeAttr(LocaleHelper.attrDateFormat()); - - // setup tooltips - const tooltip = $(this).attr('data-toggle'); - if (typeof tooltip === 'undefined' || tooltip !== 'tooltip') { - return; - } - - const tooltipText = date.format('llll'); // see: https://day.js.org/docs/en/display/format#list-of-localized-formats - $(this).attr('data-original-title', tooltipText); - }); -}); diff --git a/_javascript/utils/pageviews.js b/_javascript/utils/pageviews.js deleted file mode 100644 index 1e875d8..0000000 --- a/_javascript/utils/pageviews.js +++ /dev/null @@ -1,250 +0,0 @@ -/** - * Count page views form GA or local cache file. - * - * Dependencies: - * - jQuery - * - countUp.js <https://github.com/inorganik/countUp.js> - */ - -const getInitStatus = (function () { - let hasInit = false; - return () => { - let ret = hasInit; - if (!hasInit) { - hasInit = true; - } - return ret; - }; -}()); - -const PvOpts = (function () { - function getContent(selector) { - return $(selector).attr("content"); - } - - function hasContent(selector) { - let content = getContent(selector); - return (typeof content !== "undefined" && content !== false); - } - - return { - getProxyMeta() { - return getContent("meta[name=pv-proxy-endpoint]"); - }, - getLocalMeta() { - return getContent("meta[name=pv-cache-path]"); - }, - hasProxyMeta() { - return hasContent("meta[name=pv-proxy-endpoint]"); - }, - hasLocalMeta() { - return hasContent("meta[name=pv-cache-path]"); - } - }; - -}()); - -const PvStorage = (function () { - const Keys = { - KEY_PV: "pv", - KEY_PV_SRC: "pv_src", - KEY_CREATION: "pv_created_date" - }; - - const Source = { - LOCAL: "same-origin", - PROXY: "cors" - }; - - function get(key) { - return localStorage.getItem(key); - } - - function set(key, val) { - localStorage.setItem(key, val); - } - - function saveCache(pv, src) { - set(Keys.KEY_PV, pv); - set(Keys.KEY_PV_SRC, src); - set(Keys.KEY_CREATION, new Date().toJSON()); - } - - return { - keysCount() { - return Object.keys(Keys).length; - }, - hasCache() { - return (localStorage.getItem(Keys.KEY_PV) !== null); - }, - getCache() { - return JSON.parse(localStorage.getItem(Keys.KEY_PV)); - }, - saveLocalCache(pv) { - saveCache(pv, Source.LOCAL); - }, - saveProxyCache(pv) { - saveCache(pv, Source.PROXY); - }, - isExpired() { - let date = new Date(get(Keys.KEY_CREATION)); - date.setHours(date.getHours() + 1); // per hour - return Date.now() >= date.getTime(); - }, - isFromLocal() { - return get(Keys.KEY_PV_SRC) === Source.LOCAL; - }, - isFromProxy() { - return get(Keys.KEY_PV_SRC) === Source.PROXY; - }, - newerThan(pv) { - return PvStorage.getCache().totalsForAllResults["ga:pageviews"] > pv.totalsForAllResults["ga:pageviews"]; - }, - inspectKeys() { - if (localStorage.length !== PvStorage.keysCount()) { - localStorage.clear(); - return; - } - - for (let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i); - switch (key) { - case Keys.KEY_PV: - case Keys.KEY_PV_SRC: - case Keys.KEY_CREATION: - break; - default: - localStorage.clear(); - return; - } - } - } - }; -}()); /* PvStorage */ - -function countUp(min, max, destId) { - if (min < max) { - let numAnim = new CountUp(destId, min, max); - if (!numAnim.error) { - numAnim.start(); - } else { - console.error(numAnim.error); - } - } -} - -function countPV(path, rows) { - let count = 0; - - if (typeof rows !== "undefined") { - for (let i = 0; i < rows.length; ++i) { - const gaPath = rows[parseInt(i, 10)][0]; - if (gaPath === path) { /* path format see: site.permalink */ - count += parseInt(rows[parseInt(i, 10)][1], 10); - break; - } - } - } - - return count; -} - -function tacklePV(rows, path, elem, hasInit) { - let count = countPV(path, rows); - count = (count === 0 ? 1 : count); - - if (!hasInit) { - elem.text(new Intl.NumberFormat().format(count)); - } else { - const initCount = parseInt(elem.text().replace(/,/g, ""), 10); - if (count > initCount) { - countUp(initCount, count, elem.attr("id")); - } - } -} - -function displayPageviews(data) { - if (typeof data === "undefined") { - return; - } - - let hasInit = getInitStatus(); - const rows = data.rows; /* could be undefined */ - - if ($("#post-list").length > 0) { /* the Home page */ - $(".post-preview").each(function () { - const path = $(this).find("a").attr("href"); - tacklePV(rows, path, $(this).find(".pageviews"), hasInit); - }); - - } else if ($(".post").length > 0) { /* the post */ - const path = window.location.pathname; - tacklePV(rows, path, $("#pv"), hasInit); - } -} - -function fetchProxyPageviews() { - if (PvOpts.hasProxyMeta()) { - $.ajax({ - type: "GET", - url: PvOpts.getProxyMeta(), - dataType: "jsonp", - jsonpCallback: "displayPageviews", - success: (data) => { - PvStorage.saveProxyCache(JSON.stringify(data)); - }, - error: (jqXHR, textStatus, errorThrown) => { - console.log("Failed to load pageviews from proxy server: " + errorThrown); - } - }); - } -} - -function fetchLocalPageviews(hasCache = false) { - return fetch(PvOpts.getLocalMeta()) - .then(response => response.json()) - .then(data => { - if (hasCache) { - // The cache from the proxy will sometimes be more recent than the local one - if (PvStorage.isFromProxy() && PvStorage.newerThan(data)) { - return; - } - } - displayPageviews(data); - PvStorage.saveLocalCache(JSON.stringify(data)); - }); -} - -$(function () { - if ($(".pageviews").length <= 0) { - return; - } - - PvStorage.inspectKeys(); - - if (PvStorage.hasCache()) { - displayPageviews(PvStorage.getCache()); - - if (PvStorage.isExpired()) { - if (PvOpts.hasLocalMeta()) { - fetchLocalPageviews(true).then(fetchProxyPageviews); - } else { - fetchProxyPageviews(); - } - - } else { - if (PvStorage.isFromLocal()) { - fetchProxyPageviews(); - } - } - - } else { // no cached - - if (PvOpts.hasLocalMeta()) { - fetchLocalPageviews().then(fetchProxyPageviews); - } else { - fetchProxyPageviews(); - } - } - -}); diff --git a/_javascript/utils/smooth-scroll.js b/_javascript/utils/smooth-scroll.js deleted file mode 100644 index bd45b67..0000000 --- a/_javascript/utils/smooth-scroll.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - Safari doesn't support CSS `scroll-behavior: smooth`, - so here is a compatible solution for all browser to smooth scrolling - - See: <https://css-tricks.com/snippets/jquery/smooth-scrolling/> - - Warning: It must be called after all `<a>` tags (e.g., the dynamic TOC) are ready. - */ - -$(function () { - const $topbarTitle = $("#topbar-title"); - const REM = 16; // in pixels - const ATTR_SCROLL_FOCUS = "scroll-focus"; - - $("a[href*='#']") - .not("[href='#']") - .not("[href='#0']") - .on('click', function (event) { - if (this.pathname.replace(/^\//, "") !== - location.pathname.replace(/^\//, "")) { - return; - } - - if (location.hostname !== this.hostname) { - return; - } - - const hash = decodeURI(this.hash); - let toFootnoteRef = RegExp(/^#fnref:/).test(hash); - let toFootnote = toFootnoteRef ? false : RegExp(/^#fn:/).test(hash); - let selector = '#' + $.escapeSelector(hash.substring(1)); - let $target = $(selector); - - let isMobileViews = $topbarTitle.is(":visible"); - let isPortrait = $(window).width() < $(window).height(); - - if (typeof $target === "undefined") { - return; - } - - event.preventDefault(); - - if (history.pushState) { /* add hash to URL */ - history.pushState(null, null, hash); - } - - let curOffset = $(window).scrollTop(); - let destOffset = $target.offset().top -= REM / 2; - - if (destOffset < curOffset) { // scroll up - ScrollHelper.hideTopbar(); - ScrollHelper.addScrollUpTask(); - - if (isMobileViews && isPortrait) { - destOffset -= ScrollHelper.getTopbarHeight(); - } - - } else { // scroll down - if (isMobileViews && isPortrait) { - destOffset -= ScrollHelper.getTopbarHeight(); - } - } - - $("html").animate({ - scrollTop: destOffset - }, 500, () => { - $target.trigger("focus"); - - /* clean up old scroll mark */ - const $scroll_focus = $(`[${ATTR_SCROLL_FOCUS}=true]`); - if ($scroll_focus.length) { - $scroll_focus.attr(ATTR_SCROLL_FOCUS, "false"); - } - - /* Clean :target links */ - const $target_links = $(":target"); - if ($target_links.length) { /* element that visited by the URL with hash */ - $target_links.attr(ATTR_SCROLL_FOCUS, "false"); - } - - /* set scroll mark to footnotes */ - if (toFootnote || toFootnoteRef) { - $target.attr(ATTR_SCROLL_FOCUS, "true"); - } - - if ($target.is(":focus")) { /* Checking if the target was focused */ - return false; - } else { - $target.attr("tabindex", "-1"); /* Adding tabindex for elements not focusable */ - $target.trigger("focus"); /* Set focus again */ - } - - if (ScrollHelper.hasScrollUpTask()) { - ScrollHelper.popScrollUpTask(); - } - }); - }); /* click() */ -}); diff --git a/assets/js/dist/categories.min.js b/assets/js/dist/categories.min.js deleted file mode 100644 index db5a001..0000000 --- a/assets/js/dist/categories.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Chirpy v5.5.2 (https://github.com/cotes2020/jekyll-theme-chirpy/) - * © 2019 Cotes Chung - * MIT Licensed - */ -$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",o=>{o=$(o.target);(o.prop("tagName")==="button".toUpperCase()?o:o.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const o=$("body"),e="data-topbar-visible",t=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>o.attr(e,"false"),showTopbar:()=>o.attr(e,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0<r,topbarLocked:()=>!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>t,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const o=$("#sidebar-trigger"),e=$("#search-trigger"),t=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let o=0;return{block(){o=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(o)},getOffset(){return o}}}(),p={on(){o.addClass("unloaded"),a.addClass("unloaded"),e.addClass("unloaded"),l.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),l.removeClass("d-flex"),o.removeClass("unloaded"),a.removeClass("unloaded"),e.removeClass("unloaded")}},f=function(){let o=!1;return{on(){o||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),o=!0)},off(){o&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),i.val(""),o=!1)}}}();function u(){return t.hasClass("loaded")}e.on("click",function(){p.on(),f.on(),i.trigger("focus")}),t.on("click",function(){p.off(),f.off()}),i.on("focus",function(){l.addClass("input-focus")}),i.on("focusout",function(){l.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?u()?c.removeClass("unloaded"):f.off():(f.on(),u()&&c.addClass("unloaded"))})}),$(function(){var o=function(){const o="sidebar-display";let e=!1;const t=$("body");return{toggle(){!1===e?t.attr(o,""):t.removeAttr(o),e=!e}}}();$("#sidebar-trigger").on("click",o.toggle),$("#mask").on("click",o.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),t=ScrollHelper.getTopbarHeight();let o,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var o=screen.orientation.type;"landscape-primary"!==o&&"landscape-secondary"!==o||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{o=o||!0}),setInterval(()=>{o&&(!function(){var o=$(this).scrollTop();if(!(Math.abs(r-o)<=t)){if(o>r)ScrollHelper.hideTopbar(),e.is(":focus")&&e.trigger("blur");else if(o+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=o}}(),o=!1)},250)}),$(function(){var o="div.post>h1:first-of-type",e=$(o);const n=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let r=e.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(o=>{var e,t;a?(t=$(window).scrollTop(),e=l<t,l=t,t=o[0],e?0===t.intersectionRatio&&n.text(r):1===t.intersectionRatio&&n.text(s)):a=!0},{rootMargin:"-48px 0px 0px 0px",threshold:[0,1]}).observe(document.querySelector(o)),n.on("click",function(){$("body,html").animate({scrollTop:0},800)})}}),$(function(){var o=$(".collapse");o.on("hide.bs.collapse",function(){var o="h_"+$(this).attr("id").substring("l_".length);o&&($(`#${o} .far.fa-folder-open`).attr("class","far fa-folder fa-fw"),$(`#${o} i.fas`).addClass("rotate"),$("#"+o).removeClass("hide-border-bottom"))}),o.on("show.bs.collapse",function(){var o="h_"+$(this).attr("id").substring("l_".length);o&&($(`#${o} .far.fa-folder`).attr("class","far fa-folder-open fa-fw"),$(`#${o} i.fas`).removeClass("rotate"),$("#"+o).addClass("hide-border-bottom"))})}); diff --git a/assets/js/dist/commons.min.js b/assets/js/dist/commons.min.js deleted file mode 100644 index e3bc18e..0000000 --- a/assets/js/dist/commons.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Chirpy v5.5.2 (https://github.com/cotes2020/jekyll-theme-chirpy/) - * © 2019 Cotes Chung - * MIT Licensed - */ -$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",o=>{o=$(o.target);(o.prop("tagName")==="button".toUpperCase()?o:o.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const o=$("body"),e="data-topbar-visible",t=$("#topbar-wrapper").outerHeight();let r=0,l=!1,n=!1;return{hideTopbar:()=>o.attr(e,"false"),showTopbar:()=>o.attr(e,"true"),addScrollUpTask:()=>{r+=1,l=l||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0<r,topbarLocked:()=>!0===l,unlockTopbar:()=>l=!1,getTopbarHeight:()=>t,orientationLocked:()=>!0===n,lockOrientation:()=>n=!0,unLockOrientation:()=>n=!1}}();$(function(){const o=$("#sidebar-trigger"),e=$("#search-trigger"),t=$("#search-cancel"),r=$("#main"),l=$("#topbar-title"),n=$("#search-wrapper"),a=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let o=0;return{block(){o=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(o)},getOffset(){return o}}}(),p={on(){o.addClass("unloaded"),l.addClass("unloaded"),e.addClass("unloaded"),n.addClass("d-flex"),t.addClass("loaded")},off(){t.removeClass("loaded"),n.removeClass("d-flex"),o.removeClass("unloaded"),l.removeClass("unloaded"),e.removeClass("unloaded")}},u=function(){let o=!1;return{on(){o||(d.block(),a.removeClass("unloaded"),r.addClass("unloaded"),o=!0)},off(){o&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),a.addClass("unloaded"),r.removeClass("unloaded"),d.release(),i.val(""),o=!1)}}}();function f(){return t.hasClass("loaded")}e.on("click",function(){p.on(),u.on(),i.trigger("focus")}),t.on("click",function(){p.off(),u.off()}),i.on("focus",function(){n.addClass("input-focus")}),i.on("focusout",function(){n.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var o=function(){const o="sidebar-display";let e=!1;const t=$("body");return{toggle(){!1===e?t.attr(o,""):t.removeAttr(o),e=!e}}}();$("#sidebar-trigger").on("click",o.toggle),$("#mask").on("click",o.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),t=ScrollHelper.getTopbarHeight();let o,r=0;function l(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var o=screen.orientation.type;"landscape-primary"!==o&&"landscape-secondary"!==o||l()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&l()}),$(window).on("scroll",()=>{o=o||!0}),setInterval(()=>{o&&(!function(){var o=$(this).scrollTop();if(!(Math.abs(r-o)<=t)){if(o>r)ScrollHelper.hideTopbar(),e.is(":focus")&&e.trigger("blur");else if(o+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=o}}(),o=!1)},250)}),$(function(){var o="div.post>h1:first-of-type",e=$(o);const a=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!a.is(":hidden")){const s=a.text().trim();let r=e.text().trim(),l=!1,n=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&a.text(r);new IntersectionObserver(o=>{var e,t;l?(t=$(window).scrollTop(),e=n<t,n=t,t=o[0],e?0===t.intersectionRatio&&a.text(r):1===t.intersectionRatio&&a.text(s)):l=!0},{rootMargin:"-48px 0px 0px 0px",threshold:[0,1]}).observe(document.querySelector(o)),a.on("click",function(){$("body,html").animate({scrollTop:0},800)})}}); diff --git a/assets/js/dist/home.min.js b/assets/js/dist/home.min.js deleted file mode 100644 index 3190dd8..0000000 --- a/assets/js/dist/home.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Chirpy v5.5.2 (https://github.com/cotes2020/jekyll-theme-chirpy/) - * © 2019 Cotes Chung - * MIT Licensed - */ -$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let a=0,r=!1,l=!1;return{hideTopbar:()=>e.attr(t,"false"),showTopbar:()=>e.attr(t,"true"),addScrollUpTask:()=>{a+=1,r=r||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0<a,topbarLocked:()=>!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}(),LocaleHelper=($(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#main"),r=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),r.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),r.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),i.val(""),e=!1)}}}();function f(){return o.hasClass("loaded")}t.on("click",function(){p.on(),u.on(),i.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),i.on("focus",function(){l.addClass("input-focus")}),i.on("focusout",function(){l.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").on("click",e.toggle),$("#mask").on("click",e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,a=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).on("scroll",()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(a-e)<=o)){if(e>a)ScrollHelper.hideTopbar(),t.is(":focus")&&t.trigger("blur");else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=t.text().trim(),r=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(a);new IntersectionObserver(e=>{var t,o;r?(o=$(window).scrollTop(),t=l<o,l=o,o=e[0],t?0===o.intersectionRatio&&n.text(a):1===o.intersectionRatio&&n.text(s)):r=!0},{rootMargin:"-48px 0px 0px 0px",threshold:[0,1]}).observe(document.querySelector(e)),n.on("click",function(){$("body,html").animate({scrollTop:0},800)})}}),function(){const e=$("html").attr("lang").substring(0,2),t="data-ts",o="data-df";return{locale:()=>e,attrTimestamp:()=>t,attrDateFormat:()=>o,getTimestamp:e=>Number(e.attr(t)),getDateFormat:e=>e.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var e=dayjs.unix(LocaleHelper.getTimestamp($(this))),t=e.format(LocaleHelper.getDateFormat($(this))),t=($(this).text(t),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==t&&"tooltip"===t&&(t=e.format("llll"),$(this).attr("data-original-title",t))})}); diff --git a/assets/js/dist/misc.min.js b/assets/js/dist/misc.min.js deleted file mode 100644 index 3190dd8..0000000 --- a/assets/js/dist/misc.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Chirpy v5.5.2 (https://github.com/cotes2020/jekyll-theme-chirpy/) - * © 2019 Cotes Chung - * MIT Licensed - */ -$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let a=0,r=!1,l=!1;return{hideTopbar:()=>e.attr(t,"false"),showTopbar:()=>e.attr(t,"true"),addScrollUpTask:()=>{a+=1,r=r||!0},popScrollUpTask:()=>--a,hasScrollUpTask:()=>0<a,topbarLocked:()=>!0===r,unlockTopbar:()=>r=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}(),LocaleHelper=($(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),a=$("#main"),r=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),s=$("#search-results"),i=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),r.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),r.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),a.addClass("unloaded"),e=!0)},off(){e&&(s.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),a.removeClass("unloaded"),d.release(),i.val(""),e=!1)}}}();function f(){return o.hasClass("loaded")}t.on("click",function(){p.on(),u.on(),i.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),i.on("focus",function(){l.addClass("input-focus")}),i.on("focusout",function(){l.removeClass("input-focus")}),i.on("input",()=>{""===i.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").on("click",e.toggle),$("#mask").on("click",e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,a=0;function r(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||r()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&r()}),$(window).on("scroll",()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(a-e)<=o)){if(e>a)ScrollHelper.hideTopbar(),t.is(":focus")&&t.trigger("blur");else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}a=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const s=n.text().trim();let a=t.text().trim(),r=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(a)&&(a=a.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(a);new IntersectionObserver(e=>{var t,o;r?(o=$(window).scrollTop(),t=l<o,l=o,o=e[0],t?0===o.intersectionRatio&&n.text(a):1===o.intersectionRatio&&n.text(s)):r=!0},{rootMargin:"-48px 0px 0px 0px",threshold:[0,1]}).observe(document.querySelector(e)),n.on("click",function(){$("body,html").animate({scrollTop:0},800)})}}),function(){const e=$("html").attr("lang").substring(0,2),t="data-ts",o="data-df";return{locale:()=>e,attrTimestamp:()=>t,attrDateFormat:()=>o,getTimestamp:e=>Number(e.attr(t)),getDateFormat:e=>e.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var e=dayjs.unix(LocaleHelper.getTimestamp($(this))),t=e.format(LocaleHelper.getDateFormat($(this))),t=($(this).text(t),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==t&&"tooltip"===t&&(t=e.format("llll"),$(this).attr("data-original-title",t))})}); diff --git a/assets/js/dist/page.min.js b/assets/js/dist/page.min.js deleted file mode 100644 index 7eae8c8..0000000 --- a/assets/js/dist/page.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Chirpy v5.5.2 (https://github.com/cotes2020/jekyll-theme-chirpy/) - * © 2019 Cotes Chung - * MIT Licensed - */ -$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",e=>{e=$(e.target);(e.prop("tagName")==="button".toUpperCase()?e:e.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const e=$("body"),t="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>e.attr(t,"false"),showTopbar:()=>e.attr(t,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0<r,topbarLocked:()=>!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}();$(function(){const e=$("#sidebar-trigger"),t=$("#search-trigger"),o=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let e=0;return{block(){e=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(e)},getOffset(){return e}}}(),p={on(){e.addClass("unloaded"),a.addClass("unloaded"),t.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),e.removeClass("unloaded"),a.removeClass("unloaded"),t.removeClass("unloaded")}},u=function(){let e=!1;return{on(){e||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),e=!0)},off(){e&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),s.val(""),e=!1)}}}();function f(){return o.hasClass("loaded")}t.on("click",function(){p.on(),u.on(),s.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),s.on("focus",function(){l.addClass("input-focus")}),s.on("focusout",function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?f()?c.removeClass("unloaded"):u.off():(u.on(),f()&&c.addClass("unloaded"))})}),$(function(){var e=function(){const e="sidebar-display";let t=!1;const o=$("body");return{toggle(){!1===t?o.attr(e,""):o.removeAttr(e),t=!t}}}();$("#sidebar-trigger").on("click",e.toggle),$("#mask").on("click",e.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const t=$("#search-input"),o=ScrollHelper.getTopbarHeight();let e,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var e=screen.orientation.type;"landscape-primary"!==e&&"landscape-secondary"!==e||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{e=e||!0}),setInterval(()=>{e&&(!function(){var e=$(this).scrollTop();if(!(Math.abs(r-e)<=o)){if(e>r)ScrollHelper.hideTopbar(),t.is(":focus")&&t.trigger("blur");else if(e+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=e}}(),e=!1)},250)}),$(function(){var e="div.post>h1:first-of-type",t=$(e);const n=$("#topbar-title");if(0!==t.length&&!t.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let r=t.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),t.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(e=>{var t,o;a?(o=$(window).scrollTop(),t=l<o,l=o,o=e[0],t?0===o.intersectionRatio&&n.text(r):1===o.intersectionRatio&&n.text(i)):a=!0},{rootMargin:"-48px 0px 0px 0px",threshold:[0,1]}).observe(document.querySelector(e)),n.on("click",function(){$("body,html").animate({scrollTop:0},800)})}}),$("#core-wrapper img[data-src]")<=0||($(".popup").magnificPopup({type:"image",closeOnContentClick:!0,showCloseBtn:!1,zoom:{enabled:!0,duration:300,easing:"ease-in-out"}}),document.addEventListener("lazyloaded",function(e){$(e.target).parent().removeClass("shimmer")})),$(function(){var e=".code-header>button";const t="timeout",r="data-title-succeed",a="data-original-title";function l(e){if($(e)[0].hasAttribute(t)){e=$(e).attr(t);if(Number(e)>Date.now())return 1}}function n(e){$(e).attr(t,Date.now()+2e3)}function i(e){$(e).removeAttr(t)}var o=new ClipboardJS(e,{target(e){return e.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(e).tooltip({trigger:"hover",placement:"left"});const s=$(e).children().attr("class");o.on("success",e=>{e.clearSelection();const t=e.trigger;var o;l(t)||(e=t,$(e).children().attr("class","fas fa-check"),e=t,o=$(e).attr(r),$(e).attr(a,o).tooltip("show"),n(t),setTimeout(()=>{var e;e=t,$(e).tooltip("hide").removeAttr(a),e=t,$(e).children().attr("class",s),i(t)},2e3))}),$("#copy-link").on("click",e=>{let o=$(e.target);l(o)||navigator.clipboard.writeText(window.location.href).then(()=>{const e=o.attr(a);var t=o.attr(r);o.attr(a,t).tooltip("show"),n(o),setTimeout(()=>{o.attr(a,e),i(o)},2e3)})})}),$(function(){const e=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").on("click",function(a){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let t=RegExp(/^#fnref:/).test(l),o=!t&&RegExp(/^#fn:/).test(l);var n="#"+$.escapeSelector(l.substring(1));let r=$(n);var n=e.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==r){a.preventDefault(),history.pushState&&history.pushState(null,null,l);a=$(window).scrollTop();let e=r.offset().top-=8;e<a&&(ScrollHelper.hideTopbar(),ScrollHelper.addScrollUpTask()),n&&i&&(e-=ScrollHelper.getTopbarHeight()),$("html").animate({scrollTop:e},500,()=>{r.trigger("focus");var e=$(`[${s}=true]`),e=(e.length&&e.attr(s,"false"),$(":target"));if(e.length&&e.attr(s,"false"),(o||t)&&r.attr(s,"true"),r.is(":focus"))return!1;r.attr("tabindex","-1"),r.trigger("focus"),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); diff --git a/assets/js/dist/post.min.js b/assets/js/dist/post.min.js deleted file mode 100644 index f6c6ba2..0000000 --- a/assets/js/dist/post.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Chirpy v5.5.2 (https://github.com/cotes2020/jekyll-theme-chirpy/) - * © 2019 Cotes Chung - * MIT Licensed - */ -$(function(){$(window).on("scroll",()=>{50<$(this).scrollTop()&&"none"===$("#sidebar-trigger").css("display")?$("#back-to-top").fadeIn():$("#back-to-top").fadeOut()}),$("#back-to-top").on("click",()=>($("body,html").animate({scrollTop:0},800),!1))}),$(function(){$(".mode-toggle").on("click",t=>{t=$(t.target);(t.prop("tagName")==="button".toUpperCase()?t:t.parent()).trigger("blur"),flipMode()})});const ScrollHelper=function(){const t=$("body"),e="data-topbar-visible",o=$("#topbar-wrapper").outerHeight();let r=0,a=!1,l=!1;return{hideTopbar:()=>t.attr(e,"false"),showTopbar:()=>t.attr(e,"true"),addScrollUpTask:()=>{r+=1,a=a||!0},popScrollUpTask:()=>--r,hasScrollUpTask:()=>0<r,topbarLocked:()=>!0===a,unlockTopbar:()=>a=!1,getTopbarHeight:()=>o,orientationLocked:()=>!0===l,lockOrientation:()=>l=!0,unLockOrientation:()=>l=!1}}(),LocaleHelper=($(function(){const t=$("#sidebar-trigger"),e=$("#search-trigger"),o=$("#search-cancel"),r=$("#main"),a=$("#topbar-title"),l=$("#search-wrapper"),n=$("#search-result-wrapper"),i=$("#search-results"),s=$("#search-input"),c=$("#search-hints"),d=function(){let t=0;return{block(){t=window.scrollY,$("html,body").scrollTop(0)},release(){$("html,body").scrollTop(t)},getOffset(){return t}}}(),p={on(){t.addClass("unloaded"),a.addClass("unloaded"),e.addClass("unloaded"),l.addClass("d-flex"),o.addClass("loaded")},off(){o.removeClass("loaded"),l.removeClass("d-flex"),t.removeClass("unloaded"),a.removeClass("unloaded"),e.removeClass("unloaded")}},u=function(){let t=!1;return{on(){t||(d.block(),n.removeClass("unloaded"),r.addClass("unloaded"),t=!0)},off(){t&&(i.empty(),c.hasClass("unloaded")&&c.removeClass("unloaded"),n.addClass("unloaded"),r.removeClass("unloaded"),d.release(),s.val(""),t=!1)}}}();function h(){return o.hasClass("loaded")}e.on("click",function(){p.on(),u.on(),s.trigger("focus")}),o.on("click",function(){p.off(),u.off()}),s.on("focus",function(){l.addClass("input-focus")}),s.on("focusout",function(){l.removeClass("input-focus")}),s.on("input",()=>{""===s.val()?h()?c.removeClass("unloaded"):u.off():(u.on(),h()&&c.addClass("unloaded"))})}),$(function(){var t=function(){const t="sidebar-display";let e=!1;const o=$("body");return{toggle(){!1===e?o.attr(t,""):o.removeAttr(t),e=!e}}}();$("#sidebar-trigger").on("click",t.toggle),$("#mask").on("click",t.toggle)}),$(function(){$('[data-toggle="tooltip"]').tooltip()}),$(function(){const e=$("#search-input"),o=ScrollHelper.getTopbarHeight();let t,r=0;function a(){0!==$(window).scrollTop()&&(ScrollHelper.lockOrientation(),ScrollHelper.hideTopbar())}screen.orientation?screen.orientation.onchange=()=>{var t=screen.orientation.type;"landscape-primary"!==t&&"landscape-secondary"!==t||a()}:$(window).on("orientationchange",()=>{$(window).width()<$(window).height()&&a()}),$(window).on("scroll",()=>{t=t||!0}),setInterval(()=>{t&&(!function(){var t=$(this).scrollTop();if(!(Math.abs(r-t)<=o)){if(t>r)ScrollHelper.hideTopbar(),e.is(":focus")&&e.trigger("blur");else if(t+$(window).height()<$(document).height()){if(ScrollHelper.hasScrollUpTask())return;ScrollHelper.topbarLocked()?ScrollHelper.unlockTopbar():ScrollHelper.orientationLocked()?ScrollHelper.unLockOrientation():ScrollHelper.showTopbar()}r=t}}(),t=!1)},250)}),$(function(){var t="div.post>h1:first-of-type",e=$(t);const n=$("#topbar-title");if(0!==e.length&&!e.hasClass("dynamic-title")&&!n.is(":hidden")){const i=n.text().trim();let r=e.text().trim(),a=!1,l=0;($("#page-category").length||$("#page-tag").length)&&/\s/.test(r)&&(r=r.replace(/[0-9]/g,"").trim()),e.offset().top<$(window).scrollTop()&&n.text(r);new IntersectionObserver(t=>{var e,o;a?(o=$(window).scrollTop(),e=l<o,l=o,o=t[0],e?0===o.intersectionRatio&&n.text(r):1===o.intersectionRatio&&n.text(i)):a=!0},{rootMargin:"-48px 0px 0px 0px",threshold:[0,1]}).observe(document.querySelector(t)),n.on("click",function(){$("body,html").animate({scrollTop:0},800)})}}),$("#core-wrapper img[data-src]")<=0||($(".popup").magnificPopup({type:"image",closeOnContentClick:!0,showCloseBtn:!1,zoom:{enabled:!0,duration:300,easing:"ease-in-out"}}),document.addEventListener("lazyloaded",function(t){$(t.target).parent().removeClass("shimmer")})),function(){const t=$("html").attr("lang").substring(0,2),e="data-ts",o="data-df";return{locale:()=>t,attrTimestamp:()=>e,attrDateFormat:()=>o,getTimestamp:t=>Number(t.attr(e)),getDateFormat:t=>t.attr(o)}}());$(function(){dayjs.locale(LocaleHelper.locale()),dayjs.extend(window.dayjs_plugin_localizedFormat),$(`[${LocaleHelper.attrTimestamp()}]`).each(function(){var t=dayjs.unix(LocaleHelper.getTimestamp($(this))),e=t.format(LocaleHelper.getDateFormat($(this))),e=($(this).text(e),$(this).removeAttr(LocaleHelper.attrTimestamp()),$(this).removeAttr(LocaleHelper.attrDateFormat()),$(this).attr("data-toggle"));void 0!==e&&"tooltip"===e&&(e=t.format("llll"),$(this).attr("data-original-title",e))})}),$(function(){var t=".code-header>button";const e="timeout",r="data-title-succeed",a="data-original-title";function l(t){if($(t)[0].hasAttribute(e)){t=$(t).attr(e);if(Number(t)>Date.now())return 1}}function n(t){$(t).attr(e,Date.now()+2e3)}function i(t){$(t).removeAttr(e)}var o=new ClipboardJS(t,{target(t){return t.parentNode.nextElementSibling.querySelector("code .rouge-code")}});$(t).tooltip({trigger:"hover",placement:"left"});const s=$(t).children().attr("class");o.on("success",t=>{t.clearSelection();const e=t.trigger;var o;l(e)||(t=e,$(t).children().attr("class","fas fa-check"),t=e,o=$(t).attr(r),$(t).attr(a,o).tooltip("show"),n(e),setTimeout(()=>{var t;t=e,$(t).tooltip("hide").removeAttr(a),t=e,$(t).children().attr("class",s),i(e)},2e3))}),$("#copy-link").on("click",t=>{let o=$(t.target);l(o)||navigator.clipboard.writeText(window.location.href).then(()=>{const t=o.attr(a);var e=o.attr(r);o.attr(a,e).tooltip("show"),n(o),setTimeout(()=>{o.attr(a,t),i(o)},2e3)})})}),$(function(){const t=$("#topbar-title"),s="scroll-focus";$("a[href*='#']").not("[href='#']").not("[href='#0']").on("click",function(a){if(this.pathname.replace(/^\//,"")===location.pathname.replace(/^\//,"")&&location.hostname===this.hostname){var l=decodeURI(this.hash);let e=RegExp(/^#fnref:/).test(l),o=!e&&RegExp(/^#fn:/).test(l);var n="#"+$.escapeSelector(l.substring(1));let r=$(n);var n=t.is(":visible"),i=$(window).width()<$(window).height();if(void 0!==r){a.preventDefault(),history.pushState&&history.pushState(null,null,l);a=$(window).scrollTop();let t=r.offset().top-=8;t<a&&(ScrollHelper.hideTopbar(),ScrollHelper.addScrollUpTask()),n&&i&&(t-=ScrollHelper.getTopbarHeight()),$("html").animate({scrollTop:t},500,()=>{r.trigger("focus");var t=$(`[${s}=true]`),t=(t.length&&t.attr(s,"false"),$(":target"));if(t.length&&t.attr(s,"false"),(o||e)&&r.attr(s,"true"),r.is(":focus"))return!1;r.attr("tabindex","-1"),r.trigger("focus"),ScrollHelper.hasScrollUpTask()&&ScrollHelper.popScrollUpTask()})}}})}); diff --git a/assets/js/dist/pvreport.min.js b/assets/js/dist/pvreport.min.js deleted file mode 100644 index 4886fd8..0000000 --- a/assets/js/dist/pvreport.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Chirpy v5.5.2 (https://github.com/cotes2020/jekyll-theme-chirpy/) - * © 2019 Cotes Chung - * MIT Licensed - */ -const getInitStatus=function(){let t=!1;return()=>{var e=t;return t=t||!0,e}}(),PvOpts=function(){function t(e){return $(e).attr("content")}function e(e){e=t(e);return void 0!==e&&!1!==e}return{getProxyMeta(){return t("meta[name=pv-proxy-endpoint]")},getLocalMeta(){return t("meta[name=pv-cache-path]")},hasProxyMeta(){return e("meta[name=pv-proxy-endpoint]")},hasLocalMeta(){return e("meta[name=pv-cache-path]")}}}(),PvStorage=function(){const a={KEY_PV:"pv",KEY_PV_SRC:"pv_src",KEY_CREATION:"pv_created_date"},t={LOCAL:"same-origin",PROXY:"cors"};function r(e){return localStorage.getItem(e)}function o(e,t){localStorage.setItem(e,t)}function n(e,t){o(a.KEY_PV,e),o(a.KEY_PV_SRC,t),o(a.KEY_CREATION,(new Date).toJSON())}return{keysCount(){return Object.keys(a).length},hasCache(){return null!==localStorage.getItem(a.KEY_PV)},getCache(){return JSON.parse(localStorage.getItem(a.KEY_PV))},saveLocalCache(e){n(e,t.LOCAL)},saveProxyCache(e){n(e,t.PROXY)},isExpired(){var e=new Date(r(a.KEY_CREATION));return e.setHours(e.getHours()+1),Date.now()>=e.getTime()},isFromLocal(){return r(a.KEY_PV_SRC)===t.LOCAL},isFromProxy(){return r(a.KEY_PV_SRC)===t.PROXY},newerThan(e){return PvStorage.getCache().totalsForAllResults["ga:pageviews"]>e.totalsForAllResults["ga:pageviews"]},inspectKeys(){if(localStorage.length!==PvStorage.keysCount())localStorage.clear();else for(let e=0;e<localStorage.length;e++)switch(localStorage.key(e)){case a.KEY_PV:case a.KEY_PV_SRC:case a.KEY_CREATION:break;default:return void localStorage.clear()}}}}();function countUp(e,t,a){e<t&&((a=new CountUp(a,e,t)).error?console.error(a.error):a.start())}function countPV(t,a){let r=0;if(void 0!==a)for(let e=0;e<a.length;++e)if(a[parseInt(e,10)][0]===t){r+=parseInt(a[parseInt(e,10)][1],10);break}return r}function tacklePV(e,t,a,r){t=0===(t=countPV(t,e))?1:t;r?(e=parseInt(a.text().replace(/,/g,""),10))<t&&countUp(e,t,a.attr("id")):a.text((new Intl.NumberFormat).format(t))}function displayPageviews(e){if(void 0!==e){let t=getInitStatus();const a=e.rows;0<$("#post-list").length?$(".post-preview").each(function(){var e=$(this).find("a").attr("href");tacklePV(a,e,$(this).find(".pageviews"),t)}):0<$(".post").length&&(e=window.location.pathname,tacklePV(a,e,$("#pv"),t))}}function fetchProxyPageviews(){PvOpts.hasProxyMeta()&&$.ajax({type:"GET",url:PvOpts.getProxyMeta(),dataType:"jsonp",jsonpCallback:"displayPageviews",success:e=>{PvStorage.saveProxyCache(JSON.stringify(e))},error:(e,t,a)=>{console.log("Failed to load pageviews from proxy server: "+a)}})}function fetchLocalPageviews(t=!1){return fetch(PvOpts.getLocalMeta()).then(e=>e.json()).then(e=>{t&&PvStorage.isFromProxy()&&PvStorage.newerThan(e)||(displayPageviews(e),PvStorage.saveLocalCache(JSON.stringify(e)))})}$(function(){$(".pageviews").length<=0||(PvStorage.inspectKeys(),PvStorage.hasCache()?(displayPageviews(PvStorage.getCache()),PvStorage.isExpired()?PvOpts.hasLocalMeta()?fetchLocalPageviews(!0).then(fetchProxyPageviews):fetchProxyPageviews():PvStorage.isFromLocal()&&fetchProxyPageviews()):PvOpts.hasLocalMeta()?fetchLocalPageviews().then(fetchProxyPageviews):fetchProxyPageviews())}); diff --git a/gulpfile.js/index.js b/gulpfile.js/index.js deleted file mode 100644 index 14692fb..0000000 --- a/gulpfile.js/index.js +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env node - -"use strict"; - -const js = require('./tasks/js'); - -exports.default = js.build; - -/* keep-alive develop mode, without uglify */ -exports.dev = js.liveRebuild; diff --git a/gulpfile.js/tasks/js.js b/gulpfile.js/tasks/js.js deleted file mode 100644 index 3db0065..0000000 --- a/gulpfile.js/tasks/js.js +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env node - -"use strict"; - -const { src, dest, watch, series, parallel} = require('gulp'); - -const concat = require('gulp-concat'); -const rename = require("gulp-rename"); -const uglify = require('gulp-uglify'); -const insert = require('gulp-insert'); -const fs = require('fs'); - -const JS_SRC = '_javascript'; -const JS_DEST = `assets/js/dist`; - -function concatJs(files, output) { - return src(files) - .pipe(concat(output)) - .pipe(rename({ extname: '.min.js' })) - .pipe(dest(JS_DEST)); -} - -function minifyJs() { - return src(`${ JS_DEST }/*.js`) - .pipe(insert.prepend(fs.readFileSync(`${ JS_SRC }/copyright`, 'utf8'))) - .pipe(uglify({output: {comments: /^!|@preserve|@license|@cc_on/i}})) - .pipe(insert.append('\n')) - .pipe(dest(JS_DEST)); -} - -const commonsJs = () => { - return concatJs(`${JS_SRC}/commons/*.js`, 'commons'); -}; - -const homeJs = () => { - return concatJs([ - `${JS_SRC}/commons/*.js`, - `${JS_SRC}/utils/locale-datetime.js` - ], - 'home' - ); -}; - -const postJs = () => { - return concatJs([ - `${JS_SRC}/commons/*.js`, - `${JS_SRC}/utils/img-extra.js`, - `${JS_SRC}/utils/locale-datetime.js`, - `${JS_SRC}/utils/clipboard.js`, - // 'smooth-scroll.js' must be called after ToC is ready - `${JS_SRC}/utils/smooth-scroll.js` - ], 'post' - ); -}; - -const categoriesJs = () => { - return concatJs([ - `${JS_SRC}/commons/*.js`, - `${JS_SRC}/utils/category-collapse.js` - ], 'categories' - ); -}; - -const pageJs = () => { - return concatJs([ - `${JS_SRC}/commons/*.js`, - `${JS_SRC}/utils/img-extra.js`, - `${JS_SRC}/utils/clipboard.js`, - `${JS_SRC}/utils/smooth-scroll.js` - ], 'page' - ); -}; - -const miscJs = () => { - return concatJs([ - `${JS_SRC}/commons/*.js`, - `${JS_SRC}/utils/locale-datetime.js` - ], 'misc' - ); -}; - -// GA pageviews report -const pvreportJs = () => { - return concatJs(`${JS_SRC}/utils/pageviews.js`, 'pvreport'); -}; - -const buildJs = parallel( - commonsJs, homeJs, postJs, categoriesJs, pageJs, miscJs, pvreportJs); - -exports.build = series(buildJs, minifyJs); - -exports.liveRebuild = () => { - buildJs(); - - watch([ - `${ JS_SRC }/commons/*.js`, - `${ JS_SRC }/utils/*.js` - ], - buildJs - ); -}; diff --git a/package.json b/package.json index a9bfc3f..e95e75c 100644 --- a/package.json +++ b/package.json @@ -11,19 +11,25 @@ "bugs": { "url": "https://github.com/cotes2020/jekyll-theme-chirpy/issues" }, - "homepage": "https://github.com/cotes2020/jekyll-theme-chirpy#readme", + "homepage": "https://github.com/cotes2020/jekyll-theme-chirpy/", "scripts": { + "prebuild": "npx rimraf assets/js/dist", + "build": "NODE_ENV=production npx rollup -c --bundleConfigAsCjs", + "prewatch": "npx rimraf assets/js/dist", + "watch": "npx rollup -c --bundleConfigAsCjs -w", "test": "npx stylelint _sass/**/*.scss", - "fixlint": "npx stylelint _sass/**/*.scss --fix" + "fixlint": "npm run test -- --fix" }, "devDependencies": { - "gulp": "^4.0.2", - "gulp-concat": "^2.6.1", - "gulp-insert": "^0.5.0", - "gulp-rename": "^2.0.0", - "gulp-uglify": "^3.0.2", + "@babel/core": "^7.21.0", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/preset-env": "^7.20.2", + "@rollup/plugin-babel": "^6.0.3", + "@rollup/plugin-terser": "^0.4.0", + "rimraf": "^4.4.0", + "rollup": "^3.19.1", + "rollup-plugin-license": "^3.0.1", "stylelint": "^15.2.0", - "stylelint-config-standard-scss": "^7.0.1", - "uglify-js": "^3.17.4" + "stylelint-config-standard-scss": "^7.0.1" } } diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..f662358 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,42 @@ +import babel from '@rollup/plugin-babel'; +import terser from '@rollup/plugin-terser'; +import license from 'rollup-plugin-license'; +import path from 'path'; + +const JS_SRC = '_javascript'; +const JS_DIST = 'assets/js/dist'; +const isProd = process.env.NODE_ENV === 'production'; + +function build(filename) { + return { + input: [`${JS_SRC}/${filename}.js`], + output: { + file: `${JS_DIST}/${filename}.min.js`, + format: 'iife', + name: 'Chirpy', + sourcemap: !isProd + }, + plugins: [ + babel({ + babelHelpers: 'bundled', + presets: ['@babel/env'], + plugins: ['@babel/plugin-proposal-class-properties'] + }), + license({ + banner: { + commentStyle: 'ignored', + content: { file: path.join(__dirname, JS_SRC, '_copyright') } + } + }), + isProd && terser() + ] + }; +} + +export default [ + build('commons'), + build('categories'), + build('page'), + build('post'), + build('misc') +]; From 60229ae334bd83448b97f35b26f4bc7ab971efe4 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Tue, 14 Mar 2023 01:25:42 +0800 Subject: [PATCH 22/35] chore(ci,tools): adapt to changes in JS builds --- .github/workflows/ci.yml | 26 ++++++++++------ tools/init | 66 ++++++++++++++++++++++++++++------------ tools/release | 41 ++++++++++++------------- 3 files changed, 83 insertions(+), 50 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fcfc88a..b51c183 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,18 +1,18 @@ -name: 'CI' +name: "CI" on: push: branches-ignore: - - 'production' - - 'docs' + - "production" + - "docs" paths-ignore: - - '.github/**' - - '!.github/workflows/ci.yml' - - '.gitignore' - - 'README.md' - - 'LICENSE' + - ".github/**" + - "!.github/workflows/ci.yml" + - ".gitignore" + - "README.md" + - "LICENSE" pull_request: paths: - - '**' + - "**" jobs: build: @@ -26,7 +26,7 @@ jobs: - name: Checkout uses: actions/checkout@v3 with: - fetch-depth: 0 # for posts's lastmod + fetch-depth: 0 # for posts's lastmod - name: Setup Ruby uses: ruby/setup-ruby@v1 @@ -34,5 +34,11 @@ jobs: ruby-version: ${{ matrix.ruby }} bundler-cache: true + - name: Setup Node + uses: actions/setup-node@v3 + + - name: Build Assets + run: npm i && npm run build + - name: Test Site run: bash tools/test diff --git a/tools/init b/tools/init index 7cf7324..e5178db 100755 --- a/tools/init +++ b/tools/init @@ -4,9 +4,15 @@ set -eu +# CLI Dependencies +CLI=("git" "npm") + ACTIONS_WORKFLOW=pages-deploy.yml -TEMP_SUFFIX="to-delete" # temporary file suffixes that make `sed -i` compatible with BSD and Linux +# temporary file suffixes that make `sed -i` compatible with BSD and Linux +TEMP_SUFFIX="to-delete" + +_no_gh=false help() { echo "Usage:" @@ -18,14 +24,32 @@ help() { echo " -h, --help Print this help information." } -check_status() { +# BSD and GNU compatible sed +_sedi() { + regex=$1 + file=$2 + sed -i.$TEMP_SUFFIX "$regex" "$file" + rm -f "$file".$TEMP_SUFFIX +} + +_check_cli() { + for i in "${!CLI[@]}"; do + cli="${CLI[$i]}" + if ! command -v "$cli" &>/dev/null; then + echo "Command '$cli' not found! Hint: you should install it." + exit 1 + fi + done +} + +_check_status() { if [[ -n $(git status . -s) ]]; then echo "Error: Commit unstaged files first, and then run this tool again." exit 1 fi } -check_init() { +_check_init() { local _has_inited=false if [[ ! -d .github ]]; then # using option `--no-gh` @@ -47,9 +71,10 @@ check_init() { fi } -checkout_latest_tag() { - tag=$(git describe --tags "$(git rev-list --tags --max-count=1)") - git reset --hard "$tag" +check_env() { + _check_cli + _check_status + _check_init } init_files() { @@ -63,25 +88,30 @@ init_files() { mv ./${ACTIONS_WORKFLOW}.hook .github/workflows/${ACTIONS_WORKFLOW} ## Cleanup image settings in site config - sed -i.$TEMP_SUFFIX "s/^img_cdn:.*/img_cdn:/;s/^avatar:.*/avatar:/" _config.yml - rm -f _config.yml.$TEMP_SUFFIX + _sedi "s/^img_cdn:.*/img_cdn:/;s/^avatar:.*/avatar:/" _config.yml fi # remove the other fies rm -rf _posts/* - # save changes - git add -A - git commit -m "chore: initialize the environment" -q + # build assest + npm i && npm run build - echo "[INFO] Initialization successful!" + # track the js output + _sedi "/^assets.*\/dist/d" .gitignore } -check_status +commit() { + git add -A + git commit -m "chore: initialize the environment" -q + echo -e "\n[INFO] Initialization successful!\n" +} -check_init - -_no_gh=false +main() { + check_env + init_files + commit +} while (($#)); do opt="$1" @@ -102,6 +132,4 @@ while (($#)); do esac done -checkout_latest_tag - -init_files +main diff --git a/tools/release b/tools/release index f6bc6d0..8efb264 100755 --- a/tools/release +++ b/tools/release @@ -29,7 +29,6 @@ NODE_CONFIG="package.json" FILES=( "_sass/jekyll-theme-chirpy.scss" - "_javascript/copyright" "$GEM_SPEC" "$NODE_CONFIG" ) @@ -69,17 +68,24 @@ _check_git() { } _check_src() { - if [[ ! -f $1 && ! -d $1 ]]; then - echo -e "Error: Missing file \"$1\"!\n" - exit 1 - fi + for i in "${!FILES[@]}"; do + _src="${FILES[$i]}" + if [[ ! -f $_src && ! -d $_src ]]; then + echo -e "Error: Missing file \"$_src\"!\n" + exit 1 + fi + done + } _check_command() { - if ! command -v "$1" &>/dev/null; then - echo "Command '$1' not found" - exit 1 - fi + for i in "${!TOOLS[@]}"; do + cli="${TOOLS[$i]}" + if ! command -v "$cli" &>/dev/null; then + echo "Command '$cli' not found!" + exit 1 + fi + done } _check_node_packages() { @@ -89,20 +95,13 @@ _check_node_packages() { } check() { + _check_command _check_git - - for i in "${!FILES[@]}"; do - _check_src "${FILES[$i]}" - done - - for i in "${!TOOLS[@]}"; do - _check_command "${TOOLS[$i]}" - done - + _check_src _check_node_packages } -_bump_file() { +_bump_files() { for i in "${!FILES[@]}"; do if [[ ${FILES[$i]} == "$NODE_CONFIG" ]]; then continue @@ -111,7 +110,7 @@ _bump_file() { sed -i "s/v[[:digit:]]\+\.[[:digit:]]\+\.[[:digit:]]\+/v$1/" "${FILES[$i]}" done - npx gulp + npm run build } _bump_gemspec() { @@ -127,7 +126,7 @@ _bump_gemspec() { # # 2. Create a commit to save the changes. bump() { - _bump_file "$1" + _bump_files "$1" _bump_gemspec "$1" if [[ $opt_pre = false && -n $(git status . -s) ]]; then From 474b4ba68192381b9accf6118efd503244d72c4b Mon Sep 17 00:00:00 2001 From: Josh Johanning <joshjohanning@github.com> Date: Wed, 15 Mar 2023 09:31:43 -0500 Subject: [PATCH 23/35] chore: update configure-pages action (#931) --- .github/workflows/pages-deploy.yml.hook | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pages-deploy.yml.hook b/.github/workflows/pages-deploy.yml.hook index 356d42a..a0de59d 100644 --- a/.github/workflows/pages-deploy.yml.hook +++ b/.github/workflows/pages-deploy.yml.hook @@ -37,7 +37,7 @@ jobs: - name: Setup Pages id: pages - uses: actions/configure-pages@v1 + uses: actions/configure-pages@v3 - name: Setup Ruby uses: ruby/setup-ruby@v1 From 02b7bd5095a2affe5b4c5ed7b5b182baaf642ff3 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Thu, 16 Mar 2023 02:56:54 +0800 Subject: [PATCH 24/35] feat: change TOC plugin to `tocbot` (#774) --- _config.yml | 2 +- _data/assets/cross_origin.yml | 6 +-- _data/assets/self_host.yml | 6 +-- _includes/head.html | 2 +- _includes/toc.html | 12 ++--- _javascript/modules/components/toc.js | 11 ++++ _javascript/modules/plugins.js | 1 + _javascript/post.js | 6 ++- _layouts/default.html | 2 +- _sass/colors/dark-typography.scss | 43 ++++++---------- _sass/colors/light-typography.scss | 22 ++++---- _sass/layout/post.scss | 72 ++++++++++++++++++++------- assets/lib | 2 +- 13 files changed, 115 insertions(+), 72 deletions(-) create mode 100644 _javascript/modules/components/toc.js diff --git a/_config.yml b/_config.yml index 5d1483d..25ab1a4 100644 --- a/_config.yml +++ b/_config.yml @@ -82,7 +82,7 @@ img_cdn: "https://chirpy-img.netlify.app" # the avatar on sidebar, support local or CORS resources avatar: "/commons/avatar.jpg" -# boolean type, the global switch for ToC in posts. +# boolean type, the global switch for TOC in posts. toc: true comments: diff --git a/_data/assets/cross_origin.yml b/_data/assets/cross_origin.yml index a3a8dfb..01d558f 100644 --- a/_data/assets/cross_origin.yml +++ b/_data/assets/cross_origin.yml @@ -22,9 +22,9 @@ bootstrap: css: https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css js: https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js -bootstrap-toc: - css: https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.css - js: https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@1.0.1/dist/bootstrap-toc.min.js +toc: + css: https://cdn.jsdelivr.net/npm/tocbot@4.20.1/dist/tocbot.min.css + js: https://cdn.jsdelivr.net/npm/tocbot@4.20.1/dist/tocbot.min.js fontawesome: css: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.2.1/css/all.min.css diff --git a/_data/assets/self_host.yml b/_data/assets/self_host.yml index 817c78e..cba1d81 100644 --- a/_data/assets/self_host.yml +++ b/_data/assets/self_host.yml @@ -11,9 +11,9 @@ bootstrap: css: /assets/lib/bootstrap-4.6.1/bootstrap.min.css js: /assets/lib/bootstrap-4.6.1/bootstrap.bundle.min.js -bootstrap-toc: - css: /assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.css - js: /assets/lib/bootstrap-toc-1.0.1/bootstrap-toc.min.js +toc: + css: /assets/lib/tocbot-4.20.1/tocbot.min.css + js: /assets/lib/tocbot-4.20.1/tocbot.min.js fontawesome: css: /assets/lib/fontawesome-free-6.2.1/css/all.min.css diff --git a/_includes/head.html b/_includes/head.html index e2f6336..7b87825 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -97,7 +97,7 @@ <link rel="stylesheet" href="{{ '/assets/css/style.css' | relative_url }}"> {% if site.toc and page.toc %} - <link rel="stylesheet" href="{{ site.data.assets[origin].bootstrap-toc.css | relative_url }}"> + <link rel="stylesheet" href="{{ site.data.assets[origin].toc.css | relative_url }}"> {% endif %} {% if page.layout == 'page' or page.layout == 'post' %} diff --git a/_includes/toc.html b/_includes/toc.html index 6d88167..0d1967c 100644 --- a/_includes/toc.html +++ b/_includes/toc.html @@ -6,11 +6,11 @@ {% endif %} {% if enable_toc %} -<!-- BS-toc.js will be loaded at medium priority --> -<script src="{{ site.data.assets[origin].bootstrap-toc.js | relative_url }}"></script> + <div id="toc-wrapper" class="pl-0 pr-4 mb-5"> + <div class="panel-heading pl-3 pt-2 mb-2">{{- site.data.locales[site.lang].panel.toc -}}</div> + <nav id="toc"></nav> + </div> -<div id="toc-wrapper" class="pl-0 pr-4 mb-5"> - <div class="panel-heading pl-3 pt-2 mb-2">{{- site.data.locales[site.lang].panel.toc -}}</div> - <nav id="toc" data-toggle="toc"></nav> -</div> + <!-- toc.js will be loaded at medium priority --> + <script src="{{ site.data.assets[origin].toc.js | relative_url }}"></script> {% endif %} diff --git a/_javascript/modules/components/toc.js b/_javascript/modules/components/toc.js new file mode 100644 index 0000000..ba0415d --- /dev/null +++ b/_javascript/modules/components/toc.js @@ -0,0 +1,11 @@ +export function toc() { + // see: https://github.com/tscanlin/tocbot#usage + tocbot.init({ + tocSelector: '#toc', + contentSelector: '.post-content', + ignoreSelector: '[data-toc-skip]', + headingSelector: 'h2, h3', + orderedList: false, + scrollSmooth: false + }); +} diff --git a/_javascript/modules/plugins.js b/_javascript/modules/plugins.js index 48ada6f..8d65435 100644 --- a/_javascript/modules/plugins.js +++ b/_javascript/modules/plugins.js @@ -4,3 +4,4 @@ export { imgExtra } from './components/img-extra'; export { initLocaleDatetime } from './components/locale-datetime'; export { initPageviews } from './components/pageviews'; export { smoothScroll } from './components/smooth-scroll'; +export { toc } from './components/toc'; diff --git a/_javascript/post.js b/_javascript/post.js index 2f8cc5c..4b472bc 100644 --- a/_javascript/post.js +++ b/_javascript/post.js @@ -4,7 +4,8 @@ import { initLocaleDatetime, initClipboard, smoothScroll, - initPageviews + initPageviews, + toc } from './modules/plugins'; basic(); @@ -13,5 +14,6 @@ initTopbar(); imgExtra(); initLocaleDatetime(); initClipboard(); -smoothScroll(); +toc(); +smoothScroll(); // must be called after toc is created initPageviews(); diff --git a/_layouts/default.html b/_layouts/default.html index 6d1b0a5..a98c230 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -18,7 +18,7 @@ layout: compress {% include head.html %} - <body data-spy="scroll" data-target="#toc" data-topbar-visible="true"> + <body data-topbar-visible="true"> {% include sidebar.html %} diff --git a/_sass/colors/dark-typography.scss b/_sass/colors/dark-typography.scss index 761a903..13ad156 100644 --- a/_sass/colors/dark-typography.scss +++ b/_sass/colors/dark-typography.scss @@ -27,13 +27,12 @@ --checkbox-color: rgb(118, 120, 121); --checkbox-checked-color: var(--link-color); --img-bg: radial-gradient(circle, rgb(22, 22, 24) 0%, rgb(32, 32, 32) 100%); - --shimmer-bg: - linear-gradient( - 90deg, - rgba(255, 255, 255, 0) 0%, - rgba(58, 55, 55, 0.4) 50%, - rgba(255, 255, 255, 0) 100% - ); + --shimmer-bg: linear-gradient( + 90deg, + rgba(255, 255, 255, 0) 0%, + rgba(58, 55, 55, 0.4) 50%, + rgba(255, 255, 255, 0) 100% + ); /* Sidebar */ --sidebar-bg: radial-gradient(circle, #242424 0%, #1d1f27 100%); @@ -117,16 +116,6 @@ border-color: var(--main-border-color); } - /* posts' toc, override BS */ - nav[data-toggle="toc"] .nav-link.active, - nav[data-toggle="toc"] .nav-link.active:focus, - nav[data-toggle="toc"] .nav-link.active:hover, - nav[data-toggle="toc"] .nav > li > a:focus, - nav[data-toggle="toc"] .nav > li > a:hover { - color: var(--toc-highlight) !important; - border-left-color: var(--toc-highlight) !important; - } - /* categories */ .categories.card, .list-group-item { @@ -151,20 +140,20 @@ } #archives li:nth-child(odd) { - background-image: - linear-gradient( - to left, - rgb(26, 26, 30), - rgb(39, 39, 45), - rgb(39, 39, 45), - rgb(39, 39, 45), - rgb(26, 26, 30) - ); + background-image: linear-gradient( + to left, + rgb(26, 26, 30), + rgb(39, 39, 45), + rgb(39, 39, 45), + rgb(39, 39, 45), + rgb(26, 26, 30) + ); } color-scheme: dark; - #disqus_thread { /* stylelint-disable-line selector-id-pattern */ + /* stylelint-disable-next-line selector-id-pattern */ + #disqus_thread { color-scheme: none; } } /* dark-scheme */ diff --git a/_sass/colors/light-typography.scss b/_sass/colors/light-typography.scss index 7bfb514..5951609 100644 --- a/_sass/colors/light-typography.scss +++ b/_sass/colors/light-typography.scss @@ -24,14 +24,17 @@ --btn-box-shadow: #eaeaea; --checkbox-color: #c5c5c5; --checkbox-checked-color: #07a8f7; - --img-bg: radial-gradient(circle, rgb(255, 255, 255) 0%, rgb(249, 249, 249) 100%); - --shimmer-bg: - linear-gradient( - 90deg, - rgba(250, 250, 250, 0) 0%, - rgba(232, 230, 230, 1) 50%, - rgba(250, 250, 250, 0) 100% - ); + --img-bg: radial-gradient( + circle, + rgb(255, 255, 255) 0%, + rgb(249, 249, 249) 100% + ); + --shimmer-bg: linear-gradient( + 90deg, + rgba(250, 250, 250, 0) 0%, + rgba(232, 230, 230, 1) 50%, + rgba(250, 250, 250, 0) 100% + ); /* Sidebar */ --sidebar-bg: #eeeeee; @@ -59,6 +62,7 @@ --pin-color: #999fa4; /* Posts */ + --toc-highlight: #563d7c; --btn-share-hover-color: var(--link-color); --card-border-color: #f1f1f1; --card-box-shadow: rgba(234, 234, 234, 0.76); @@ -85,7 +89,7 @@ --prompt-danger-bg: rgb(248, 215, 218, 0.56); --prompt-danger-icon-color: #df3c30; - [class^="prompt-"] { + [class^='prompt-'] { --link-underline-color: rgb(219, 216, 216); } diff --git a/_sass/layout/post.scss b/_sass/layout/post.scss index c79331b..2690cf4 100644 --- a/_sass/layout/post.scss +++ b/_sass/layout/post.scss @@ -17,7 +17,7 @@ } @mixin dot($pl: 0.25rem, $pr: 0.25rem) { - content: "\2022"; + content: '\2022'; padding-left: $pl; padding-right: $pr; } @@ -91,6 +91,7 @@ h1 + .post-meta { vertical-align: middle; -webkit-user-select: none; -moz-user-select: none; + -ms-user-select: none; user-select: none; .share-icons { @@ -115,7 +116,7 @@ h1 + .post-meta { &:hover { text-decoration: none; - >i { + > i { @extend %btn-share-hovor; } } @@ -250,24 +251,58 @@ h1 + .post-meta { transition: top 0.2s ease-in-out; -webkit-animation: fade-up 0.8s; animation: fade-up 0.8s; -} -#toc { - ul.nav.navbar-nav { - margin: 0.5rem 0; - padding: 0; + ul { + list-style: none; + font-size: 0.85rem; + line-height: 1.25; + padding-left: 0; li { - padding-top: 2px; - padding-bottom: 2px; - } - } -} + &:not(:last-child) { + margin: 0.4rem 0; + } -nav[data-toggle="toc"] { - .nav { - .nav > li > a.active { - font-weight: 600 !important; + a { + padding: 0.2rem 0 0.2rem 1.25rem; + } + } + + /* Overwrite TOC plugin style */ + + .toc-link { + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + + &:hover { + color: var(--toc-highlight); + text-decoration: none; + } + + &::before { + display: none; + } + } + + .is-active-link { + color: var(--toc-highlight) !important; + font-weight: 600; + + &::before { + display: inline-block; + width: 1px; + left: -1px; + height: 1.25rem; + background-color: var(--toc-highlight) !important; + } + } + + ul { + a { + padding-left: 2rem; + } } } } @@ -324,7 +359,8 @@ nav[data-toggle="toc"] { margin-bottom: 2rem; } - #disqus_thread { /* stylelint-disable-line selector-id-pattern */ + /* stylelint-disable-next-line selector-id-pattern */ + #disqus_thread { min-height: 8.5rem; } } @@ -337,7 +373,7 @@ nav[data-toggle="toc"] { @include label(inherit, 400, inherit); &::after { - content: ":"; + content: ':'; } } diff --git a/assets/lib b/assets/lib index e372141..ba49daf 160000 --- a/assets/lib +++ b/assets/lib @@ -1 +1 @@ -Subproject commit e372141074f370c6f03b68b5264e7663f2b7477c +Subproject commit ba49daf38b3abd1bfcec2a70b2ecc26ffcc4ce71 From 3c7934abf02b1ef89de7d88b91e234abfc650e52 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Thu, 16 Mar 2023 03:36:52 +0800 Subject: [PATCH 25/35] style: improve code style of SCSS & YAML --- .github/workflows/codeql.yml | 40 ++++----- .github/workflows/style-lint.yml | 10 +-- _data/contact.yml | 11 ++- _sass/addon/commons.scss | 147 ++++++++++++++++++++----------- _sass/addon/module.scss | 4 +- _sass/addon/syntax.scss | 28 +++--- _sass/addon/variables.scss | 12 +-- _sass/colors/dark-syntax.scss | 9 +- _sass/colors/light-syntax.scss | 2 +- _sass/layout/archives.scss | 18 ++-- _sass/layout/categories.scss | 3 +- _sass/layout/category-tag.scss | 14 +-- 12 files changed, 181 insertions(+), 117 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 2937c9d..dda3e8e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,12 +1,12 @@ -name: 'CodeQL' +name: "CodeQL" on: push: - paths: [ '**.js' ] + paths: ["**.js"] pull_request: - paths: [ '**.js' ] + paths: ["**.js"] schedule: - - cron: '0 0 * * 5' + - cron: "0 0 * * 5" jobs: analyze: @@ -20,25 +20,25 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: ["javascript"] # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support steps: - - name: Checkout repository - uses: actions/checkout@v3 + - name: Checkout repository + uses: actions/checkout@v3 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: '${{ matrix.language }}' + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: "${{ matrix.language }}" - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v2 + # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v2 - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: '/language:${{ matrix.language }}' + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/style-lint.yml b/.github/workflows/style-lint.yml index 2f1cdd0..9500ac4 100644 --- a/.github/workflows/style-lint.yml +++ b/.github/workflows/style-lint.yml @@ -1,15 +1,15 @@ -name: 'Style Lint' +name: "Style Lint" on: push: branches-ignore: - - 'production' - - 'docs' + - "production" + - "docs" paths: - - '_sass/**/*.scss' + - "_sass/**/*.scss" pull_request: paths: - - '_sass/**/*.scss' + - "_sass/**/*.scss" jobs: stylelint: diff --git a/_data/contact.yml b/_data/contact.yml index 971969e..76b667a 100644 --- a/_data/contact.yml +++ b/_data/contact.yml @@ -1,19 +1,18 @@ # The contact options. - type: github - icon: 'fab fa-github' + icon: "fab fa-github" - type: twitter - icon: 'fab fa-twitter' + icon: "fab fa-twitter" - type: email - icon: 'fas fa-envelope' - noblank: true # open link in current tab + icon: "fas fa-envelope" + noblank: true # open link in current tab - type: rss - icon: 'fas fa-rss' + icon: "fas fa-rss" noblank: true - # Uncomment and complete the url below to enable more contact options # # - type: mastodon diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index d808f35..0fa399d 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -5,22 +5,22 @@ html { @media (prefers-color-scheme: light) { &:not([data-mode]), - &[data-mode="light"] { + &[data-mode='light'] { @include light-scheme; } - &[data-mode="dark"] { + &[data-mode='dark'] { @include dark-scheme; } } @media (prefers-color-scheme: dark) { &:not([data-mode]), - &[data-mode="dark"] { + &[data-mode='dark'] { @include dark-scheme; } - &[data-mode="light"] { + &[data-mode='light'] { @include light-scheme; } } @@ -32,7 +32,7 @@ body { background: var(--body-bg); color: var(--text-color); -webkit-font-smoothing: antialiased; - font-family: "Source Sans Pro", "Microsoft Yahei", sans-serif; + font-family: 'Source Sans Pro', 'Microsoft Yahei', sans-serif; line-height: 1.75; } @@ -90,7 +90,7 @@ img { animation: fade-in 0.4s ease-in; } - &[data-lqip="true"] { + &[data-lqip='true'] { &.lazyload, &.lazyloading { -webkit-filter: blur(20px); @@ -98,7 +98,7 @@ img { } } - &:not([data-lqip="true"]) { + &:not([data-lqip='true']) { &.lazyload, &.lazyloading { background: var(--img-bg); @@ -115,13 +115,21 @@ img { } @-webkit-keyframes fade-in { - from { opacity: 0; } - to { opacity: 1; } + from { + opacity: 0; + } + to { + opacity: 1; + } } @keyframes fade-in { - from { opacity: 0; } - to { opacity: 1; } + from { + opacity: 0; + } + to { + opacity: 1; + } } } @@ -130,7 +138,7 @@ blockquote { padding-left: 1rem; color: var(--blockquote-text-color); - &[class^="prompt-"] { + &[class^='prompt-'] { border-left: 0; position: relative; padding: 1rem 1rem 1rem 3rem; @@ -153,10 +161,10 @@ blockquote { } } - @include prompt("tip", "\f0eb", "regular"); - @include prompt("info", "\f06a"); - @include prompt("warning", "\f06a"); - @include prompt("danger", "\f071"); + @include prompt('tip', '\f0eb', 'regular'); + @include prompt('info', '\f06a'); + @include prompt('warning', '\f06a'); + @include prompt('danger', '\f071'); } kbd { @@ -208,7 +216,8 @@ footer { } } -i { /* fontawesome icons */ +/* fontawesome icons */ +i { &.far, &.fas { @extend %no-cursor; @@ -266,7 +275,7 @@ i { /* fontawesome icons */ } } - [data-topbar-visible="true"] & > div { + [data-topbar-visible='true'] & > div { top: 6rem; } } @@ -310,7 +319,7 @@ i { /* fontawesome icons */ /* [scroll-focus] added by `smooth-scroll.js` */ &:target:not([scroll-focus]), - &[scroll-focus="true"] > p { + &[scroll-focus='true'] > p { background-color: var(--footnote-target-bg); width: -moz-fit-content; width: -webkit-fit-content; @@ -331,7 +340,7 @@ i { /* fontawesome icons */ /* [scroll-focus] added by `smooth-scroll.js` */ @at-root sup:target:not([scroll-focus]), - sup[scroll-focus=true] > a#{&} { + sup[scroll-focus='true'] > a#{&} { background-color: var(--footnote-target-bg); } } @@ -384,7 +393,7 @@ i { /* fontawesome icons */ } } } /* tbody */ - }/* table */ + } /* table */ } /* --- post --- */ @@ -476,7 +485,8 @@ i { /* fontawesome icons */ list-style-type: none; padding-left: 0; - > i { /* checkbox icon */ + /* checkbox icon */ + > i { width: 2rem; margin-left: -1.25rem; color: var(--checkbox-color); @@ -492,7 +502,7 @@ i { /* fontawesome icons */ } } - input[type="checkbox"] { + input[type='checkbox'] { margin: 0 0.5rem 0.2rem -1.3rem; vertical-align: middle; } @@ -545,7 +555,7 @@ i { /* fontawesome icons */ background: var(--img-bg); &::before { - content: ""; + content: ''; position: absolute; background: var(--shimmer-bg); height: 100%; @@ -555,13 +565,25 @@ i { /* fontawesome icons */ } @-webkit-keyframes shimmer { - 0% { -webkit-transform: translateX(-100%); transform: translateX(-100%); } - 100% { -webkit-transform: translateX(100%); transform: translateX(100%); } + 0% { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + } + 100% { + -webkit-transform: translateX(100%); + transform: translateX(100%); + } } @keyframes shimmer { - 0% { -webkit-transform: translateX(-100%); transform: translateX(-100%); } - 100% { -webkit-transform: translateX(100%); transform: translateX(100%); } + 0% { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); + } + 100% { + -webkit-transform: translateX(100%); + transform: translateX(100%); + } } } @@ -627,7 +649,8 @@ i { /* fontawesome icons */ @include no-text-decoration; } -.tooltip-inner { /* Overrided BS4 Tooltip */ +/* Overrided BS4 Tooltip */ +.tooltip-inner { font-size: 0.7rem; max-width: 220px; text-align: left; @@ -682,7 +705,7 @@ mjx-container { /* --- sidebar layout --- */ -$sidebar-display: "sidebar-display"; +$sidebar-display: 'sidebar-display'; #sidebar { @include pl-pr(0); @@ -702,8 +725,8 @@ $sidebar-display: "sidebar-display"; } /* Hide scrollbar for IE, Edge and Firefox */ - -ms-overflow-style: none; /* IE and Edge */ - scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE and Edge */ + scrollbar-width: none; /* Firefox */ a { @extend %sidebar-links; @@ -768,6 +791,7 @@ $sidebar-display: "sidebar-display"; min-height: 3rem; /* avoid vertical shifting in multi-line words */ -webkit-user-select: none; -moz-user-select: none; + -ms-user-select: none; user-select: none; } @@ -811,10 +835,11 @@ $sidebar-display: "sidebar-display"; width: 100%; } - &::after { /* the cursor */ + /* the cursor */ + &::after { display: table; visibility: hidden; - content: ""; + content: ''; position: relative; right: 1px; width: $cursor-width; @@ -833,7 +858,8 @@ $sidebar-display: "sidebar-display"; @for $i from 1 through $tab-count { $offset: $tab-count - $i; - $top: (-$offset * $tab-height) + (($tab-height - $tab-cursor-height) * 0.5); + $top: (-$offset * $tab-height) + + (($tab-height - $tab-cursor-height) * 0.5); @if $i < $tab-count { > li.active:nth-child(#{$i}), @@ -894,7 +920,7 @@ $sidebar-display: "sidebar-display"; @extend %no-cursor; background-color: var(--sidebar-muted-color); - content: ""; + content: ''; width: 3px; height: 3px; border-radius: 50%; @@ -937,13 +963,14 @@ $sidebar-display: "sidebar-display"; border-bottom: 1px solid rgba(0, 0, 0, 0.07); background-color: var(--topbar-wrapper-bg); - [data-topbar-visible="false"] & { + [data-topbar-visible='false'] & { top: -$topbar-height; /* same as topbar height. */ } } #topbar { - i { /* icons */ + /* icons */ + i { color: #999999; } @@ -959,7 +986,7 @@ $sidebar-display: "sidebar-display"; span { &:not(:last-child) { &::after { - content: "›"; + content: '›'; padding: 0 0.3rem; } } @@ -987,7 +1014,8 @@ $sidebar-display: "sidebar-display"; } } -#search-cancel { /* 'Cancel' link */ +/* 'Cancel' link */ +#search-cancel { color: var(--link-color); margin-left: 1rem; display: none; @@ -1008,9 +1036,21 @@ $sidebar-display: "sidebar-display"; background: center; &.form-control { - &::-moz-placeholder { @include input-placeholder; } - &::-webkit-input-placeholder { @include input-placeholder; } - &::placeholder { @include input-placeholder; } + &::-moz-placeholder { + @include input-placeholder; + } + &::-webkit-input-placeholder { + @include input-placeholder; + } + &:-ms-input-placeholder { + @include input-placeholder; + } + &::-ms-input-placeholder { + @include input-placeholder; + } + &::placeholder { + @include input-placeholder; + } } } } @@ -1032,7 +1072,7 @@ $sidebar-display: "sidebar-display"; margin: 0 1.25rem 1rem 0; &::before { - content: "#"; + content: '#'; color: var(--text-muted-color); padding-right: 0.2rem; } @@ -1064,7 +1104,8 @@ $sidebar-display: "sidebar-display"; margin-bottom: 1rem; } - i { /* icons */ + /* icons */ + i { color: #818182; margin-right: 0.15rem; font-size: 80%; @@ -1262,7 +1303,9 @@ $sidebar-display: "sidebar-display"; } #core-wrapper { - min-height: calc(100vh - #{$topbar-height} - #{$footer-height-mobile}) !important; + min-height: calc( + 100vh - #{$topbar-height} - #{$footer-height-mobile} + ) !important; h1 { margin-top: 2.2rem; @@ -1270,7 +1313,7 @@ $sidebar-display: "sidebar-display"; } .post-content { - > blockquote[class^="prompt-"] { + > blockquote[class^='prompt-'] { @include ml-mr(-1.25rem); border-radius: 0; @@ -1406,7 +1449,7 @@ $sidebar-display: "sidebar-display"; } /* max-width: 849px */ @media all and (max-width: 849px) and (orientation: portrait) { - [data-topbar-visible="false"] #topbar-wrapper { + [data-topbar-visible='false'] #topbar-wrapper { top: 0; } } @@ -1596,7 +1639,9 @@ $sidebar-display: "sidebar-display"; } #search-wrapper { - margin-right: calc(#{$main-content-max-width} * 0.25 - #{$search-max-width}); + margin-right: calc( + #{$main-content-max-width} * 0.25 - #{$search-max-width} + ); } #topbar, @@ -1611,7 +1656,9 @@ $sidebar-display: "sidebar-display"; } #back-to-top { - right: calc((100vw - #{$sidebar-width-large} - #{$main-content-max-width}) / 2 + 2rem); + right: calc( + (100vw - #{$sidebar-width-large} - #{$main-content-max-width}) / 2 + 2rem + ); } #sidebar { diff --git a/_sass/addon/module.scss b/_sass/addon/module.scss index 1fc9ae5..44f21d2 100644 --- a/_sass/addon/module.scss +++ b/_sass/addon/module.scss @@ -7,7 +7,7 @@ %heading { color: var(--heading-color); font-weight: 400; - font-family: Lato, "Microsoft Yahei", sans-serif; + font-family: Lato, 'Microsoft Yahei', sans-serif; } %section { @@ -150,7 +150,7 @@ transform: translateX(-50%); } -@mixin prompt($type, $fa-content, $fa-style: "solid") { +@mixin prompt($type, $fa-content, $fa-style: 'solid') { &.prompt-#{$type} { background-color: var(--prompt-#{$type}-bg); diff --git a/_sass/addon/syntax.scss b/_sass/addon/syntax.scss index 6667380..bc48ab0 100644 --- a/_sass/addon/syntax.scss +++ b/_sass/addon/syntax.scss @@ -2,28 +2,28 @@ * The syntax highlight. */ -@import "colors/light-syntax"; -@import "colors/dark-syntax"; +@import 'colors/light-syntax'; +@import 'colors/dark-syntax'; html { @media (prefers-color-scheme: light) { &:not([data-mode]), - &[data-mode="light"] { + &[data-mode='light'] { @include light-syntax; } - &[data-mode="dark"] { + &[data-mode='dark'] { @include dark-syntax; } } @media (prefers-color-scheme: dark) { &:not([data-mode]), - &[data-mode="dark"] { + &[data-mode='dark'] { @include dark-syntax; } - &[data-mode="light"] { + &[data-mode='light'] { @include light-syntax; } } @@ -68,16 +68,17 @@ html { word-wrap: normal; /* Fixed Safari overflow-x */ /* set the dollar sign to non-selectable */ - >.gp:first-child { + > .gp:first-child { -webkit-user-select: none; -moz-user-select: none; + -ms-user-select: none; user-select: none; } } table { td pre { - overflow: visible; /* Fixed iOS safari overflow-x */ + overflow: visible; /* Fixed iOS safari overflow-x */ word-break: normal; /* Fixed iOS safari linenos code break */ } } @@ -90,12 +91,14 @@ html { -webkit-user-select: none; -moz-user-select: none; -o-user-select: none; + -ms-user-select: none; user-select: none; } } /* .highlight */ code { -webkit-hyphens: none; + -ms-hyphens: none; hyphens: none; &.highlighter-rouge { @@ -147,7 +150,7 @@ td.rouge-code { /* Hide line numbers for default, console, and terminal code snippets */ div { - &[class^="highlighter-rouge"], + &[class^='highlighter-rouge'], &.nolineno, &.language-plaintext.highlighter-rouge, &.language-console.highlighter-rouge, @@ -176,15 +179,14 @@ div { $dot-size: 0.75rem; $dot-margin: 0.5rem; - content: ""; + content: ''; display: inline-block; margin-left: 1rem; width: $dot-size; height: $dot-size; border-radius: 50%; background-color: var(--code-header-muted-color); - box-shadow: - ($dot-size + $dot-margin) 0 0 var(--code-header-muted-color), + box-shadow: ($dot-size + $dot-margin) 0 0 var(--code-header-muted-color), ($dot-size + $dot-margin) * 2 0 0 var(--code-header-muted-color); } @@ -256,7 +258,7 @@ div { @media all and (max-width: 576px) { .post-content { - > div[class^="language-"] { + > div[class^='language-'] { @include ml-mr(-1.25rem); border-radius: 0; diff --git a/_sass/addon/variables.scss b/_sass/addon/variables.scss index 99614a5..1db532e 100644 --- a/_sass/addon/variables.scss +++ b/_sass/addon/variables.scss @@ -4,23 +4,23 @@ /* sidebar */ -$sidebar-width: 260px !default; /* the basic width */ -$sidebar-width-small: 210px !default; /* screen width: >= 850px, <= 1199px (iPad landscape) */ -$sidebar-width-large: 350px !default; /* screen width: >= 1650px */ +$sidebar-width: 260px !default; /* the basic width */ +$sidebar-width-small: 210px !default; /* screen width: >= 850px, <= 1199px (iPad landscape) */ +$sidebar-width-large: 350px !default; /* screen width: >= 1650px */ /* tabs of sidebar */ -$tab-count: 5 !default; /* backward compatible (version <= 4.0.2) */ +$tab-count: 5 !default; /* backward compatible (version <= 4.0.2) */ $tab-height: 3rem !default; $tab-cursor-height: 1.6rem !default; -$cursor-width: 2px !default; /* the cursor width of the selected tab */ +$cursor-width: 2px !default; /* the cursor width of the selected tab */ /* other framework sizes */ $topbar-height: 3rem !default; $search-max-width: 210px !default; $footer-height: 5rem !default; -$footer-height-mobile: 6rem !default; /* screen width: <= 576px */ +$footer-height-mobile: 6rem !default; /* screen width: <= 576px */ $main-content-max-width: 1250px !default; $bottom-min-height: 35rem !default; diff --git a/_sass/colors/dark-syntax.scss b/_sass/colors/dark-syntax.scss index 3912ed3..8c22d24 100644 --- a/_sass/colors/dark-syntax.scss +++ b/_sass/colors/dark-syntax.scss @@ -13,10 +13,13 @@ --clipboard-checked-color: #2bcc2b; --filepath-text-color: #bdbdbd; - pre { color: #bfbfbf; } /* override Bootstrap */ + /* override Bootstrap */ + pre { + color: #bfbfbf; + } - .highlight { - .gp { color: #818c96; } + .highlight .gp { + color: #818c96; } /* syntax highlight colors from https://raw.githubusercontent.com/jwarby/pygments-css/master/monokai.css */ diff --git a/_sass/colors/light-syntax.scss b/_sass/colors/light-syntax.scss index aeac91f..a4dde91 100644 --- a/_sass/colors/light-syntax.scss +++ b/_sass/colors/light-syntax.scss @@ -76,7 +76,7 @@ --code-header-icon-color: #d1d1d1; --clipboard-checked-color: #43c743; - [class^="prompt-"] { + [class^='prompt-'] { --inline-code-bg: #fbfafa; --highlighter-rouge-color: rgb(82, 82, 82); } diff --git a/_sass/layout/archives.scss b/_sass/layout/archives.scss index 70cf379..3a2e86b 100644 --- a/_sass/layout/archives.scss +++ b/_sass/layout/archives.scss @@ -8,7 +8,7 @@ $timeline-width: 4px; %timeline { - content: ""; + content: ''; width: $timeline-width; position: relative; float: left; @@ -37,8 +37,9 @@ top: 24px; } - &::after { /* Year dot */ - content: ""; + /* Year dot */ + &::after { + content: ''; display: inline-block; position: relative; border-radius: 50%; @@ -63,7 +64,14 @@ &:nth-child(odd) { background-color: var(--main-bg, #ffffff); - background-image: linear-gradient(to left, #ffffff, #fbfbfb, #fbfbfb, #fbfbfb, #ffffff); + background-image: linear-gradient( + to left, + #ffffff, + #fbfbfb, + #fbfbfb, + #fbfbfb, + #ffffff + ); } &::before { @@ -109,7 +117,7 @@ &::before { /* the dot before post title */ - content: ""; + content: ''; display: inline-block; position: relative; border-radius: 50%; diff --git a/_sass/layout/categories.scss b/_sass/layout/categories.scss index c818e33..31c8e8e 100644 --- a/_sass/layout/categories.scss +++ b/_sass/layout/categories.scss @@ -54,7 +54,8 @@ } } -@media (hover: hover) { /* only works on desktop */ +/* only works on desktop */ +@media (hover: hover) { .category-trigger:hover { background-color: var(--categories-hover-bg); } diff --git a/_sass/layout/category-tag.scss b/_sass/layout/category-tag.scss index 4488671..3b25db5 100644 --- a/_sass/layout/category-tag.scss +++ b/_sass/layout/category-tag.scss @@ -13,31 +13,35 @@ line-height: 1.5rem; padding: 0.6rem 0; - &::before { /* dot */ + /* dot */ + &::before { background: #999999; width: 5px; height: 5px; border-radius: 50%; display: block; - content: ""; + content: ''; position: relative; top: 0.6rem; margin-right: 0.5rem; } - > a { /* post's title */ + /* post's title */ + > a { @extend %no-bottom-border; font-size: 1.1rem; } + /* post's date */ > span:last-child { white-space: nowrap; - } /* post's date */ + } } } -#page-tag h1 > i { /* tag icon */ +/* tag icon */ +#page-tag h1 > i { font-size: 1.2rem; } From 820ba62e9e939090523a7077d01d01bd78ec84eb Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Fri, 17 Mar 2023 01:17:06 +0800 Subject: [PATCH 26/35] fix: notch status bar doesn't match theme color (#918) Resolves #918 --- _includes/head.html | 35 +++++++++++++++--------------- _sass/addon/commons.scss | 4 +++- _sass/colors/dark-typography.scss | 3 +-- _sass/colors/light-typography.scss | 3 +-- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/_includes/head.html b/_includes/head.html index 7b87825..edec4b1 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -1,13 +1,17 @@ -<!-- - The Head ---> +<!-- The Head --> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <meta name="theme-color" media="(prefers-color-scheme: light)" content="#f7f7f7"> + <meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1b1b1e"> + <meta name="apple-mobile-web-app-capable" content="yes"> + <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> + <meta + name="viewport" + content="width=device-width, user-scalable=no initial-scale=1, shrink-to-fit=no, viewport-fit=cover" + > {% if page.layout == 'home' or page.layout == 'post' %} - {% if site.google_analytics.pv.proxy_endpoint %} <meta name="pv-proxy-endpoint" content="{{ site.google_analytics.pv.proxy_endpoint }}"> {% endif %} @@ -15,7 +19,6 @@ {% if site.google_analytics.pv.cache_path %} <meta name="pv-cache-path" content="{{ site.google_analytics.pv.cache_path | relative_url }}"> {% endif %} - {% endif %} {% capture seo_tags %} @@ -40,40 +43,34 @@ {% endif %} {% assign seo_tags = seo_tags | replace: target, replacement %} - {% endunless %} - {% endif %} {{ seo_tags }} <title> - {%- unless page.layout == "home" -%} - {{ page.title | append: " | "}} - {%- endunless -%} + {%- unless page.layout == 'home' -%} + {{ page.title | append: ' | ' }} + {%- endunless -%} {{ site.title }} {% include favicons.html %} {% if site.resources.ignore_env != jekyll.environment and site.resources.self_hosted %} - {% else %} - {% for cdn in site.data.assets[origin].cdns %} {% endfor %} - {% endif %} - {% if jekyll.environment == 'production' - and site.google_analytics.id != empty and site.google_analytics.id %} + {% if jekyll.environment == 'production' and site.google_analytics.id != empty and site.google_analytics.id %} @@ -82,7 +79,11 @@ {% if site.google_analytics.pv.proxy_endpoint %} {% assign proxy_url = site.google_analytics.pv.proxy_endpoint - | replace: "https://", "" | split: "/" | first | prepend: "https://" %} + | replace: 'https://', '' + | split: '/' + | first + | prepend: 'https://' + %} {% endif %} diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index 0fa399d..9407257 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -29,7 +29,9 @@ html { } body { - background: var(--body-bg); + background: var(--main-bg); + padding: env(safe-area-inset-top) env(safe-area-inset-right) + env(safe-area-inset-bottom) env(safe-area-inset-left); color: var(--text-color); -webkit-font-smoothing: antialiased; font-family: 'Source Sans Pro', 'Microsoft Yahei', sans-serif; diff --git a/_sass/colors/dark-typography.scss b/_sass/colors/dark-typography.scss index 13ad156..8db9c41 100644 --- a/_sass/colors/dark-typography.scss +++ b/_sass/colors/dark-typography.scss @@ -4,9 +4,8 @@ @mixin dark-scheme { /* Framework color */ - --body-bg: var(--main-bg); - --mask-bg: rgb(68, 69, 70); --main-bg: rgb(27, 27, 30); + --mask-bg: rgb(68, 69, 70); --main-border-color: rgb(44, 45, 45); /* Common color */ diff --git a/_sass/colors/light-typography.scss b/_sass/colors/light-typography.scss index 5951609..d2383af 100644 --- a/_sass/colors/light-typography.scss +++ b/_sass/colors/light-typography.scss @@ -4,9 +4,8 @@ @mixin light-scheme { /* Framework color */ - --body-bg: #fafafa; - --mask-bg: #c1c3c5; --main-bg: white; + --mask-bg: #c1c3c5; --main-border-color: #f3f3f3; /* Common color */ From d96b8811a7fcfebbb41b04bb2d00d793de0ba678 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Fri, 17 Mar 2023 05:52:32 +0800 Subject: [PATCH 27/35] refactor: remove version number from self host config --- _data/assets/self_host.yml | 36 ++++++++++++++++++------------------ assets/lib | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/_data/assets/self_host.yml b/_data/assets/self_host.yml index cba1d81..3327e48 100644 --- a/_data/assets/self_host.yml +++ b/_data/assets/self_host.yml @@ -5,47 +5,47 @@ webfonts: /assets/lib/fonts/main.css # Libraries jquery: - js: /assets/lib/jquery-3.6.0/jquery.min.js + js: /assets/lib/jquery/jquery.min.js bootstrap: - css: /assets/lib/bootstrap-4.6.1/bootstrap.min.css - js: /assets/lib/bootstrap-4.6.1/bootstrap.bundle.min.js + css: /assets/lib/bootstrap/bootstrap.min.css + js: /assets/lib/bootstrap/bootstrap.bundle.min.js toc: - css: /assets/lib/tocbot-4.20.1/tocbot.min.css - js: /assets/lib/tocbot-4.20.1/tocbot.min.js + css: /assets/lib/tocbot/tocbot.min.css + js: /assets/lib/tocbot/tocbot.min.js fontawesome: - css: /assets/lib/fontawesome-free-6.2.1/css/all.min.css + css: /assets/lib/fontawesome-free/css/all.min.css search: - js: /assets/lib/simple-jekyll-search-1.10.0/simple-jekyll-search.min.js + js: /assets/lib/simple-jekyll-search/simple-jekyll-search.min.js mermaid: - js: /assets/lib/mermaid-9.1.7/mermaid.min.js + js: /assets/lib/mermaid/mermaid.min.js dayjs: js: - common: /assets/lib/dayjs-1.10.7/dayjs.min.js - locale: /assets/lib/dayjs-1.10.7/locale/en.min.js - relativeTime: /assets/lib/dayjs-1.10.7/plugin/relativeTime.min.js - localizedFormat: /assets/lib/dayjs-1.10.7/plugin/localizedFormat.min.js + common: /assets/lib/dayjs/dayjs.min.js + locale: /assets/lib/dayjs/locale/en.min.js + relativeTime: /assets/lib/dayjs/plugin/relativeTime.min.js + localizedFormat: /assets/lib/dayjs/plugin/localizedFormat.min.js countup: - js: /assets/lib/countup.js-1.9.3/countUp.min.js + js: /assets/lib/countup.js/countUp.min.js magnific-popup: - css: /assets/lib/magnific-popup-1.1.0/magnific-popup.css - js: /assets/lib/magnific-popup-1.1.0/jquery.magnific-popup.min.js + css: /assets/lib/magnific-popup/magnific-popup.css + js: /assets/lib/magnific-popup/jquery.magnific-popup.min.js lazysizes: - js: /assets/lib/lazysizes-5.3.2/lazysizes.min.js + js: /assets/lib/lazysizes/lazysizes.min.js clipboard: - js: /assets/lib/clipboard-2.0.9/clipboard.min.js + js: /assets/lib/clipboard/clipboard.min.js polyfill: js: /assets/lib/polyfill-v3-es6/polyfill.min.js mathjax: - js: /assets/lib/mathjax-3.2.0/tex-chtml.js + js: /assets/lib/mathjax/tex-chtml.js diff --git a/assets/lib b/assets/lib index ba49daf..24ebdb7 160000 --- a/assets/lib +++ b/assets/lib @@ -1 +1 @@ -Subproject commit ba49daf38b3abd1bfcec2a70b2ecc26ffcc4ce71 +Subproject commit 24ebdb708f3f5451df953cb5f9deb3ad4433404a From e8e4901e340dd7e5fc5f656dd3c7bcd6c97b886a Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Fri, 17 Mar 2023 06:37:14 +0800 Subject: [PATCH 28/35] fix: some console snippets will be incompletely copied Sample: ```console echo $PATH ``` --- _sass/addon/syntax.scss | 8 -------- 1 file changed, 8 deletions(-) diff --git a/_sass/addon/syntax.scss b/_sass/addon/syntax.scss index bc48ab0..e3a93bb 100644 --- a/_sass/addon/syntax.scss +++ b/_sass/addon/syntax.scss @@ -66,14 +66,6 @@ html { font-size: $code-font-size; line-height: 1.4rem; word-wrap: normal; /* Fixed Safari overflow-x */ - - /* set the dollar sign to non-selectable */ - > .gp:first-child { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - } } table { From 111b82838dfd5b65b78b242242f7f407ffa3219e Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 18 Mar 2023 00:28:46 +0800 Subject: [PATCH 29/35] style: fix scss lint issue type: declaration-block-no-redundant-longhand-properties --- _sass/addon/commons.scss | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index 9407257..c73e93d 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -1154,10 +1154,7 @@ $sidebar-display: 'sidebar-display'; #mask { display: none; position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; + inset: 0 0 0 0; height: 100%; width: 100%; z-index: 1; From b85f6330dea666350631c4461b742cdb54c5f052 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 18 Mar 2023 00:31:52 +0800 Subject: [PATCH 30/35] feat(ux): turn home page posts into clickable cards (#895) Resolves #895 --- _layouts/home.html | 97 +++++++++++++++--------------- _sass/colors/dark-typography.scss | 3 +- _sass/colors/light-typography.scss | 3 +- _sass/layout/home.scss | 64 ++++++++++++++------ 4 files changed, 96 insertions(+), 71 deletions(-) diff --git a/_layouts/home.html b/_layouts/home.html index 9d9eae3..42b9fe2 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -3,10 +3,10 @@ layout: page # The Home page layout --- -{% assign pinned = site.posts | where: "pin", "true" %} -{% assign default = site.posts | where_exp: "item", "item.pin != true and item.hidden != true" %} +{% assign pinned = site.posts | where: 'pin', 'true' %} +{% assign default = site.posts | where_exp: 'item', 'item.pin != true and item.hidden != true' %} -{% assign posts = "" | split: "" %} +{% assign posts = '' | split: '' %} @@ -29,7 +29,7 @@ layout: page {% assign default_beg = 0 %} {% endif %} -{% assign default_num = paginator.posts | size | minus: pinned_num %} +{% assign default_num = paginator.posts | size | minus: pinned_num %} {% assign default_end = default_beg | plus: default_num | minus: 1 %} {% if default_num > 0 %} @@ -39,55 +39,54 @@ layout: page {% endif %}
+ {% for post in posts %} +
+ +
+

+ {{ post.title }} +

-{% for post in posts %} +
+

+ {% include no-linenos.html content=post.content %} + {{ content | markdownify | strip_html | truncate: 200 | escape }} +

+
-
-

- {{ post.title }} -

+ +
- - - -
- -{% endfor %} - -
+ + {% endfor %} +
+ {% if paginator.total_pages > 0 %} {% include post-paginator.html %} diff --git a/_sass/colors/dark-typography.scss b/_sass/colors/dark-typography.scss index 8db9c41..dc6f543 100644 --- a/_sass/colors/dark-typography.scss +++ b/_sass/colors/dark-typography.scss @@ -68,7 +68,8 @@ --btn-share-color: #6c757d; --btn-share-hover-color: #bfc1ca; --relate-post-date: var(--text-muted-color); - --card-bg: rgb(39, 40, 43); + --card-bg: #212121; + --card-hovor-bg: #3a3a3a; --card-border-color: rgb(53, 53, 60); --card-box-shadow: var(--main-bg); --kbd-wrap-color: #6a6a6a; diff --git a/_sass/colors/light-typography.scss b/_sass/colors/light-typography.scss index d2383af..f04629b 100644 --- a/_sass/colors/light-typography.scss +++ b/_sass/colors/light-typography.scss @@ -63,7 +63,8 @@ /* Posts */ --toc-highlight: #563d7c; --btn-share-hover-color: var(--link-color); - --card-border-color: #f1f1f1; + --card-hovor-bg: #eeeeee; + --card-border-color: #ececec; --card-box-shadow: rgba(234, 234, 234, 0.76); --label-color: #616161; --relate-post-date: rgba(30, 55, 70, 0.4); diff --git a/_sass/layout/home.scss b/_sass/layout/home.scss index fd0f146..cdf1f09 100644 --- a/_sass/layout/home.scss +++ b/_sass/layout/home.scss @@ -53,16 +53,26 @@ } /* .pagination */ #post-list { - margin-top: 1rem; + margin-top: 1.75rem; padding-right: 0.5rem; - .post-preview { - padding-top: 1.5rem; - padding-bottom: 1rem; - border-bottom: 1px solid var(--main-border-color); + a:hover { + text-decoration: none; + } - a:hover { - @extend %link-hover; + .post-preview { + padding: 0.25rem; + border-radius: 0.75rem; + border: 1px solid var(--card-border-color); + background: var(--card-bg); + + &:hover { + background: var(--card-hovor-bg); + box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); + } + + &:not(:last-child) { + margin-bottom: 1.75rem; } h1 { @@ -103,7 +113,6 @@ color: var(--post-list-text-color); > p { - /* Make preview shorter on the homepage */ margin: 0; overflow: hidden; text-overflow: ellipsis; @@ -115,8 +124,19 @@ } /* .post-preview */ } /* #post-list */ +@media (hover: hover) { + .post-preview { + transition: all 0.35s ease-in-out; + } +} + /* Hide SideBar and TOC */ @media all and (max-width: 830px) { + .post-preview { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + .pagination { justify-content: space-evenly; @@ -131,20 +151,24 @@ /* Sidebar is visible */ @media all and (min-width: 831px) { #post-list { - margin-top: 1.5rem; + margin-top: 3rem; - .post-preview .post-meta { - .pin { - background: var(--pin-bg); - border-radius: 5px; - line-height: 1.4rem; - height: 1.3rem; - margin-top: 3px; - padding-left: 1px; - padding-right: 6px; + .post-preview { + padding: 0.5rem; - > span { - display: inline; + .post-meta { + .pin { + background: var(--pin-bg); + border-radius: 5px; + line-height: 1.4rem; + height: 1.3rem; + margin-top: 3px; + padding-left: 1px; + padding-right: 6px; + + > span { + display: inline; + } } } } From 3cd81e71284a835292af5f55ea124b1a9017c00d Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 18 Mar 2023 00:41:23 +0800 Subject: [PATCH 31/35] chore: recover accidentally deleted LQIP style --- _sass/addon/commons.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index c73e93d..e16184f 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -549,6 +549,7 @@ i { .img-link { color: transparent; display: inline-flex; + overflow: hidden; } .shimmer { From 471e8c40188fcbf54fe86061a11d53834f1aa8e4 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 18 Mar 2023 00:49:26 +0800 Subject: [PATCH 32/35] chore(tools): resume git checkout in initialization --- tools/init | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/init b/tools/init index e5178db..af3ce76 100755 --- a/tools/init +++ b/tools/init @@ -77,6 +77,11 @@ check_env() { _check_init } +checkout_latest_tag() { + tag=$(git describe --tags "$(git rev-list --tags --max-count=1)") + git reset --hard "$tag" +} + init_files() { if $_no_gh; then rm -rf .github @@ -109,6 +114,7 @@ commit() { main() { check_env + checkout_latest_tag init_files commit } From 388efb1ae3ee3eefa953b29ef7227951d8fc794f Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 18 Mar 2023 01:33:44 +0800 Subject: [PATCH 33/35] chore(tools): add JS dist to gem release --- tools/release | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tools/release b/tools/release index 8efb264..48bff39 100755 --- a/tools/release +++ b/tools/release @@ -27,6 +27,9 @@ GEM_SPEC="jekyll-theme-chirpy.gemspec" NODE_CONFIG="package.json" +JS_DIST="assets/js/dist" +BACKUP_PATH="$(mktemp -d)" + FILES=( "_sass/jekyll-theme-chirpy.scss" "$GEM_SPEC" @@ -150,7 +153,10 @@ build_gem() { echo -e "Build the gem package for v$_version\n" cleanup_config rm -f ./*.gem + git add "$JS_DIST" -f # add JS dist to gem gem build "$GEM_SPEC" + cp "$JS_DIST"/* "$BACKUP_PATH" + git restore --staged "$JS_DIST" # resume the git status resume_config } @@ -202,6 +208,9 @@ main() { else release "$_version" fi + + # restore the dist files for future development + mkdir -p "$JS_DIST" && cp "$BACKUP_PATH"/* "$JS_DIST" } while (($#)); do From 6e6b6479f52181a6177b19ea5a7fceedd06bb3af Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 18 Mar 2023 02:07:14 +0800 Subject: [PATCH 34/35] docs: migrate upgrade details to the wiki --- README.md | 12 +++----- _posts/2019-08-09-getting-started.md | 46 +++++++--------------------- 2 files changed, 16 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 999ea36..9b36789 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,11 @@
- Click to check out the features + Click to view features

- - Dark/Light Theme Mode + - Dark / Light Theme Mode - Localized UI language - Pinned Posts - Hierarchical Categories @@ -34,9 +34,9 @@ - Syntax Highlighting - Mathematical Expressions - Mermaid Diagram & Flowchart - - Dark/Light Mode Images + - Dark / Light Mode Images - Embed Videos - - Disqus/Utterances/Giscus Comments + - Disqus / Utterances / Giscus Comments - Search - Atom Feeds - Google Analytics @@ -71,7 +71,7 @@ _Open Source Development_ license. ## Sponsoring -If you would like to sponsor this project, the following options are available. +If you'd like to sponsor this project, the following options are available. [![Ko-fi](https://img.shields.io/badge/-Buy%20Me%20a%20Coffee-ff5f5f?logo=ko-fi&logoColor=white)](https://ko-fi.com/coteschung) [![Wechat Pay](https://img.shields.io/badge/-Tip%20Me%20on%20WeChat-brightgreen?logo=wechat&logoColor=white)][donation] @@ -81,8 +81,6 @@ If you would like to sponsor this project, the following options are available. This work is published under [MIT][mit] License. - - [jekyllrb]: https://jekyllrb.com/ [bootstrap]: https://getbootstrap.com/ [icons]: https://fontawesome.com/ diff --git a/_posts/2019-08-09-getting-started.md b/_posts/2019-08-09-getting-started.md index ffc8682..120ab7f 100644 --- a/_posts/2019-08-09-getting-started.md +++ b/_posts/2019-08-09-getting-started.md @@ -18,17 +18,17 @@ Follow the instructions in the [Jekyll Docs](https://jekyllrb.com/docs/installat There are two ways to create a new repository for this theme: - [**Using the Chirpy Starter**](#option-1-using-the-chirpy-starter) - Easy to upgrade, isolates irrelevant project files so you can focus on writing. -- [**Forking on GitHub**](#option-2-forking-on-github) - Convenient for custom development, but difficult to upgrade. Unless you are familiar with Jekyll and are determined to tweak or contribute to this project, this approach is not recommended. +- [**GitHub Fork**](#option-2-github-fork) - Convenient for custom development, but difficult to upgrade. Unless you are familiar with Jekyll and are determined to tweak or contribute to this project, this approach is not recommended. #### Option 1. Using the Chirpy Starter -Sign in to GitHub and browse to [**Chirpy Starter**](https://github.com/cotes2020/chirpy-starter/), click the button Use this template > Create a new repository, and name the new repository `USERNAME.github.io`, where `USERNAME` represents your GitHub username. +Sign in to GitHub and browse to [**Chirpy Starter**][starter], click the button Use this template > Create a new repository, and name the new repository `USERNAME.github.io`, where `USERNAME` represents your GitHub username. -#### Option 2. Forking on GitHub +#### Option 2. GitHub Fork -[Fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork) on GitHub and rename it to `USERNAME.github.io`. Note that the default branch code is under development. To ensure the stability of your site, please switch to the [latest tag][latest-tag] and start writing. +Sign in to GitHub to [fork **Chirpy**](https://github.com/cotes2020/jekyll-theme-chirpy/fork), and then rename it to `USERNAME.github.io` (`USERNAME` means your username). -And then execute: +Next, clone your site to local machine. In order to build JavaScript files later, we need to install [Node.js][nodejs], and then run the tool: ```console $ bash tools/init @@ -39,15 +39,14 @@ $ bash tools/init The above command will: -1. Remove the files in `_posts`{: .filepath} from your repository. - -2. If the option `--no-gh` is provided, the directory `.github`{: .filepath} will be deleted. Otherwise, set up the GitHub Action workflow by removing the extension `.hook`{: .filepath} of `.github/workflows/pages-deploy.yml.hook`{: .filepath}, and then remove the other files and directories in the folder `.github`{: .filepath}. - -3. Create a new commit to save the changes automatically. +1. Check out the code to the [latest tag][latest-tag] (to ensure the stability of your site: as the code for the default branch is under development). +2. Remove non-essential sample files and take care of GitHub-related files. +3. Build JavaScript files and export to `assets/js/dist/`{: .filepath }, then make them tracked by Git. +4. Automatically create a new commit to save the changes above. ### Installing Dependencies -Before running for the first time, go to the root directory of your site, and install dependencies as follows: +Before running local server for the first time, go to the root directory of your site and run: ```console $ bundle @@ -142,30 +141,7 @@ $ docker run -it --rm \ Unless you specified the output path, the generated site files will be placed in folder `_site`{: .filepath} of the project's root directory. Now you should upload those files to the target server. -## Upgrading - -It depends on how you use the theme: - -- If you are using the theme gem (there will be `gem "jekyll-theme-chirpy"` in the `Gemfile`{: .filepath}), editing the `Gemfile`{: .filepath} and update the version number of the theme gem, for example: - - ```diff - - gem "jekyll-theme-chirpy", "~> 3.2", ">= 3.2.1" - + gem "jekyll-theme-chirpy", "~> 4.3", ">= 4.3.2" - ``` - {: .nolineno file="Gemfile" } - - And then execute the following command: - - ```console - $ bundle update jekyll-theme-chirpy - ``` - - As the version upgrades, the critical files (for details, see the [Startup Template][starter]) and configuration options will change. Please refer to the [Upgrade Guide](https://github.com/cotes2020/jekyll-theme-chirpy/wiki/Upgrade-Guide) to keep your repo's files in sync with the latest version of the theme. - -- If you forked from the source project (there will be `gemspec` in the `Gemfile`{: .filepath} of your site), then merge the [latest upstream tags][latest-tag] into your Jekyll site to complete the upgrade. -The merge is likely to conflict with your local modifications. Please be patient and careful to resolve these conflicts. - +[nodejs]: https://nodejs.org/ [starter]: https://github.com/cotes2020/chirpy-starter -[workflow]: https://github.com/cotes2020/jekyll-theme-chirpy/blob/master/.github/workflows/pages-deploy.yml.hook [pages-workflow-src]: https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#publishing-with-a-custom-github-actions-workflow [latest-tag]: https://github.com/cotes2020/jekyll-theme-chirpy/tags From 0d9cec6abcb699fc6317dbc97b5ec8b9b5edb698 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 18 Mar 2023 02:07:58 +0800 Subject: [PATCH 35/35] chore(release): 5.6.0 --- CHANGELOG.md | 17 +++++++++++++++++ _sass/jekyll-theme-chirpy.scss | 2 +- jekyll-theme-chirpy.gemspec | 2 +- package.json | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4864fbc..43f0011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. +## [5.6.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v5.5.2...v5.6.0) (2023-03-17) + + +### Features + +* change TOC plugin to `tocbot` ([#774](https://github.com/cotes2020/jekyll-theme-chirpy/issues/774)) ([02b7bd5](https://github.com/cotes2020/jekyll-theme-chirpy/commit/02b7bd5095a2affe5b4c5ed7b5b182baaf642ff3)) +* **i18n:** add Greek Language Support. ([#903](https://github.com/cotes2020/jekyll-theme-chirpy/issues/903)) ([712a9b2](https://github.com/cotes2020/jekyll-theme-chirpy/commit/712a9b22401ce591cf4c0bb03fbdd1693fee30bb)) +* **ux:** turn home page posts into clickable cards ([#895](https://github.com/cotes2020/jekyll-theme-chirpy/issues/895)) ([b85f633](https://github.com/cotes2020/jekyll-theme-chirpy/commit/b85f6330dea666350631c4461b742cdb54c5f052)) + + +### Bug Fixes + +* css selector string escaping vulnerability ([#888](https://github.com/cotes2020/jekyll-theme-chirpy/issues/888)) ([5c6ec9d](https://github.com/cotes2020/jekyll-theme-chirpy/commit/5c6ec9d06b6571e2c0efe6652078442dca8af477)) +* mathematics cannot scroll horizontally ([#760](https://github.com/cotes2020/jekyll-theme-chirpy/issues/760)) ([4681df7](https://github.com/cotes2020/jekyll-theme-chirpy/commit/4681df715118a37ae1e91b588de0adb67f4e331a)) +* notch status bar doesn't match theme color ([#918](https://github.com/cotes2020/jekyll-theme-chirpy/issues/918)) ([820ba62](https://github.com/cotes2020/jekyll-theme-chirpy/commit/820ba62e9e939090523a7077d01d01bd78ec84eb)) +* some console snippets will be incompletely copied ([e8e4901](https://github.com/cotes2020/jekyll-theme-chirpy/commit/e8e4901e340dd7e5fc5f656dd3c7bcd6c97b886a)) + ## [5.5.2](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v5.5.1...v5.5.2) (2023-01-30) diff --git a/_sass/jekyll-theme-chirpy.scss b/_sass/jekyll-theme-chirpy.scss index 38c43e0..25e1a14 100644 --- a/_sass/jekyll-theme-chirpy.scss +++ b/_sass/jekyll-theme-chirpy.scss @@ -1,7 +1,7 @@ /*! * The styles for Jekyll theme Chirpy * - * Chirpy v5.5.2 (https://github.com/cotes2020/jekyll-theme-chirpy) + * Chirpy v5.6.0 (https://github.com/cotes2020/jekyll-theme-chirpy) * © 2019 Cotes Chung * MIT Licensed */ diff --git a/jekyll-theme-chirpy.gemspec b/jekyll-theme-chirpy.gemspec index 9ad026f..1a98ecf 100644 --- a/jekyll-theme-chirpy.gemspec +++ b/jekyll-theme-chirpy.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |spec| spec.name = "jekyll-theme-chirpy" - spec.version = "5.5.2" + spec.version = "5.6.0" spec.authors = ["Cotes Chung"] spec.email = ["cotes.chung@gmail.com"] diff --git a/package.json b/package.json index e95e75c..6427099 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jekyll-theme-chirpy", - "version": "5.5.2", + "version": "5.6.0", "description": "A minimal, responsive and feature-rich Jekyll theme for technical writing.", "repository": { "type": "git",