diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml new file mode 100644 index 00000000000..1e1923486dd --- /dev/null +++ b/.github/workflows/lint-js.yml @@ -0,0 +1,30 @@ +name: Lint JS + +on: + push: + paths: + - "_javascript/**/*.js" + - ".github/workflows/scripts/**/*.js" + - "*.js" + pull_request: + paths: + - "_javascript/**/*.js" + - ".github/workflows/scripts/*.js" + - "*.js" + +jobs: + lint-js: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: lts/* + + - name: Install Dependencies + run: npm i + + - name: Lint JS + run: npm run lint:js diff --git a/.github/workflows/lint-scss.yml b/.github/workflows/lint-scss.yml new file mode 100644 index 00000000000..57776dd2c99 --- /dev/null +++ b/.github/workflows/lint-scss.yml @@ -0,0 +1,26 @@ +name: Lint SCSS + +on: + push: + paths: + - "_sass/**/*.scss" + pull_request: + paths: + - "_sass/**/*.scss" + +jobs: + lint-scss: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: lts/* + + - name: Install Dependencies + run: npm i + + - name: Lint SCSS + run: npm run lint:scss diff --git a/.github/workflows/pr-filter.yml b/.github/workflows/pr-filter.yml index 8e9a18b736f..40ba53b1c5d 100644 --- a/.github/workflows/pr-filter.yml +++ b/.github/workflows/pr-filter.yml @@ -21,5 +21,5 @@ jobs: with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | - const script = require('.github/workflows/scripts/pr-filter.js'); - await script({ github, context, core }); + const { default: filter } = await import('${{ github.workspace }}/.github/workflows/scripts/pr-filter.js'); + await filter({ github, context, core }); diff --git a/.github/workflows/scripts/pr-filter.js b/.github/workflows/scripts/pr-filter.js index 03f50dc5ca2..52e8d526a1b 100644 --- a/.github/workflows/scripts/pr-filter.js +++ b/.github/workflows/scripts/pr-filter.js @@ -9,7 +9,7 @@ function hasDescription(markdown) { ); } -module.exports = async ({ github, context, core }) => { +export default async ({ github, context, core }) => { const pr = context.payload.pull_request; const body = pr.body === null ? '' : pr.body; const markdown = body.replace(//g, ''); diff --git a/.stylelintrc.json b/.stylelintrc.json index b890290957c..c0c1b95a587 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -8,8 +8,6 @@ "property-no-vendor-prefix": null, "selector-no-vendor-prefix": null, "value-no-vendor-prefix": null, - "color-function-notation": "legacy", - "alpha-value-notation": "number", "selector-not-notation": "simple", "color-hex-length": "long", "declaration-block-single-line-max-declarations": 3, diff --git a/_data/locales/da-DK.yml b/_data/locales/da-DK.yml new file mode 100644 index 00000000000..4b41fb389ea --- /dev/null +++ b/_data/locales/da-DK.yml @@ -0,0 +1,86 @@ +# The layout text of site + +# ----- Commons label ----- + +layout: + post: Opslag + category: Kategori + tag: Tag + +# The tabs of sidebar +tabs: + # format: : + home: Hjem + categories: Kategorier + tags: Tags + archives: Arkiv + about: Om siden + +# the text displayed in the search bar & search results +search: + hint: søg + cancel: Afbryd + no_results: Ups! Ingen resultater fundet. + +panel: + lastmod: Senest opdateret + trending_tags: Populære tags + toc: Indhold + +copyright: + # Shown at the bottom of the post + license: + template: Dette opslag er licenseret under :LICENSE_NAME af forfatteren. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: Nogle rettigheder forbeholdes. + verbose: >- + Medmindre andet er angivet, er opslag på denne side beskyttet + under Creative Commons Attribution 4.0 International (CC BY 4.0) licensen af forfatteren. + +# meta: Using the :THEME theme for :PLATFORM. + +not_found: + statement: Beklager, vi har malpaceret denne URL, eller den peger på et sted, som ikke findes. + +notification: + update_found: En ny version af indholdet er fundet! + update: Opdater + +# ----- Posts related labels ----- + +post: + written_by: Af + posted: Udgivet + updated: Opdateret + words: ord + pageview_measure: visninger + read_time: + unit: min + prompt: læsetid + relate_posts: Læs videre + share: Del + button: + next: Nyere + previous: Ældre + copy_code: + succeed: Kopieret! + share_link: + title: Kopier link + succeed: Link kopieret! + +# Date time format. +# See: , +df: + post: + strftime: "%Y/%m/%d" + dayjs: "YYYY/MM/DD" + +# categories page +categories: + category_measure: + singular: kategori + plural: kategorier + post_measure: opslag diff --git "a/_data/locales/dv\342\200\221MV.yml" "b/_data/locales/dv\342\200\221MV.yml" new file mode 100644 index 00000000000..680ca1f8b4c --- /dev/null +++ "b/_data/locales/dv\342\200\221MV.yml" @@ -0,0 +1,90 @@ +# The layout text of site in Dhivehi (Maldives) + +# ----- Commons label ----- + +layout: + post: ޕޯސްޓް + category: ނަތީޖާ + tag: ޓެގް + +# The tabs of sidebar +tabs: + # format: : + home: ހުންނަ + categories: ނަތީޖާތައް + tags: ޓެގްތައް + archives: އާރޗިވްސް + about: އިންސާން + +# the text displayed in the search bar & search results +search: + hint: ސާރޗް + cancel: ކެންސަލް + no_results: އޮޕްސް! އެއްވެސް ނުފެނުނީ. + +panel: + lastmod: އާދަމާ އޮޕްޑޭޓްކުރި + trending_tags: މަރާހު ޓެގްތައް + toc: ކޮންޓެންސް + +copyright: + # Shown at the bottom of the post + license: + template: މި ޕޯސްޓް :LICENSE_NAME އިން ލައިސަންސްކުރާ ނުވަތަ މުޤައްރާއަށް. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: އެކީ ބާރަށް ހުށަހަޅާ. + verbose: >- + އަދި އެ ރަނގަޅުގައި ނުލާހެވެސް، މި ސައިޓުގެ ޕޯސްޓްތައް + މުޤައްރާއަށް Creative Commons Attribution 4.0 International (CC BY 4.0) ލައިސަންސްކުރަނީ. + +meta: :PLATFORM އަށް :THEME ތީމް ބަލާލާށެވެ. + +not_found: + statement: ސޯރީ، މި ޔޫ.އާރއެލް މަށެވެއްނެ ނުވަތަ އެކަމެއް ނުވެއެވެ. + +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: ލިންކް ހަދަންކުރެވި! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +categories: + category_measure: + singular: ނަތީޖާ + plural: ނަތީޖާތައް + post_measure: + singular: ޕޯސްޓް + plural: ޕޯސްޓްތައް diff --git a/_data/locales/fa-IR.yaml b/_data/locales/fa-IR.yml similarity index 85% rename from _data/locales/fa-IR.yaml rename to _data/locales/fa-IR.yml index d5c6e0eb6ab..7a33deb1209 100644 --- a/_data/locales/fa-IR.yaml +++ b/_data/locales/fa-IR.yml @@ -37,10 +37,10 @@ copyright: # Displayed in the footer brief: برخی حقوق محفوظ است. verbose: >- - مگر اینکه خلاف آن ذکر شده باشد، پست‌های وبلاگ در این سایت + به‌جز مواردی که خلاف آن ذکر شده باشد، محتوای پست‌های این وبلاگ تحت مجوز Creative Commons Attribution 4.0 International (CC BY 4.0) توسط نویسنده منتشر شده‌اند. -meta: با استفاده از :PLATFORM قالب :THEME +meta: با استفاده از قالب :THEME برای :PLATFORM not_found: statement: متأسفیم، لینک زیر معتبر نیست یا به صفحه‌ای که وجود ندارد اشاره می‌کند. @@ -55,11 +55,11 @@ post: written_by: نوشته شده توسط posted: منتشر شده updated: به‌روزرسانی شده - words: کلمات - pageview_measure: بازدیدها + words: کلمه + pageview_measure: بازدید read_time: - unit: دقیقه - prompt: زمان مطالعه + unit: "دقیقه " + prompt: " زمان مطالعه" relate_posts: بیشتر بخوانید share: اشتراک‌گذاری button: @@ -85,7 +85,7 @@ df: categories: category_measure: singular: دسته‌بندی - plural: دسته‌بندی‌ها + plural: دسته‌بندی‌ post_measure: singular: پست - plural: پست‌ها + plural: پست‌ diff --git a/_data/locales/ku-IQ.yml b/_data/locales/ku-IQ.yml new file mode 100644 index 00000000000..bcc53565f92 --- /dev/null +++ b/_data/locales/ku-IQ.yml @@ -0,0 +1,91 @@ +# The layout text of site in Kurdish (Sorani) + +# ----- Commons label ----- + +layout: + post: بابەت + category: هاوپۆل + tag: تاگ + +# The tabs of sidebar +tabs: + # format: : + home: سەرەکی + categories: هاوپۆلەکان + tags: تاگەکان + archives: ئەرشیف + about: دەربارە + +# the text displayed in the search bar & search results +search: + hint: گەڕان + cancel: هەڵوەشاندنەوە + no_results: ببوورە! هیچ ئەنجامێک نەدۆزرایەوە. + +panel: + lastmod: دوایین نوێکردنەوەکان + trending_tags: تاگە باوەکان + toc: ناوەڕۆک + +copyright: + # Shown at the bottom of the post + license: + template: ئەم بابەتە لەلایەن نووسەرەوە بە مۆڵەتی :LICENSE_NAME بڵاوکراوەتەوە. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: هەندێک مافی پارێزراوە. + verbose: >- + تەنها لەو شوێنانەی کە بە پێچەوانەوە ئاماژەی پێدراوە، بابەتەکانی بڵۆگ لەم سایتەدا + لەژێر مۆڵەتی Creative Commons Attribution 4.0 International (CC BY 4.0) لەلایەن نووسەرەوە مۆڵەتیان پێدراوە. + +meta: بە بەکارهێنانی :PLATFORM لەگەڵ ڕووکاری :THEME + +not_found: + statement: ببوورە، ئەم بەستەرە نادۆزرێتەوە یان ئاماژە بە شتێک دەکات کە بوونی نییە. + +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: بەستەر بە سەرکەوتوویی کۆپی کرا! + +# Date time format. +# See: , +df: + post: + strftime: "%d %b, %Y" + dayjs: "DD MMM, YYYY" + archives: + strftime: "%b" + dayjs: "MMM" + +# categories page +categories: + category_measure: + singular: هاوپۆل + plural: هاوپۆل + post_measure: + singular: بابەت + plural: بابەت diff --git "a/_data/locales/ps\342\200\221AF.yml" "b/_data/locales/ps\342\200\221AF.yml" new file mode 100644 index 00000000000..fca6877238c --- /dev/null +++ "b/_data/locales/ps\342\200\221AF.yml" @@ -0,0 +1,90 @@ +# The layout text of site in Pashto (Afghanistan) + +# ----- Commons label ----- + +layout: + post: لیکنه + category: وېشنيزه + tag: ټګ + +# The tabs of sidebar +tabs: + # format: : + home: کورپاڼه + categories: وېشنيزې + tags: ټګونه + archives: آرشيف + about: په اړه + +# the text displayed in the search bar & search results +search: + hint: لټون + cancel: لغوه + no_results: ها! هېڅ پایله ونه موندل شوه. + +panel: + lastmod: وروستی تازه + trending_tags: مشهور ټګونه + toc: منځپانګه + +copyright: + # Shown at the bottom of the post + license: + template: دا لیکنه د :LICENSE_NAME جواز لاندې د لیکوال له خوا خپره شوې ده. + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: ځینې حقونه خوندي دي. + verbose: >- + تر هغه ځایه چې بل ډول نه وي یاد شوي، د دې سایټ لیکنې + د لیکوال له خوا د کریټېو کامنز د انتساب 4.0 نړیوال (CC BY 4.0) جواز لاندې خپرېږي. + +meta: د :PLATFORM لپاره د :THEME موضوع کاروي. + +not_found: + statement: بښنه غواړو، دغه 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: لینک بریالي کاپي شو! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +categories: + category_measure: + singular: وېشنيزه + plural: وېشنيزې + post_measure: + singular: لیکنه + plural: لیکنې diff --git a/_data/locales/ur-PK.yml b/_data/locales/ur-PK.yml new file mode 100644 index 00000000000..e5184df171c --- /dev/null +++ b/_data/locales/ur-PK.yml @@ -0,0 +1,90 @@ +# The layout text of site in Urdu (Pakistan) + +# ----- Commons label ----- + +layout: + post: تحریر + category: زمرہ + tag: ٹیگ + +# The tabs of sidebar +tabs: + # format: : + home: گھر + categories: زمروں + tags: ٹیگز + archives: محفوظات + about: تعارف + +# the text displayed in the search bar & search results +search: + hint: تلاش + cancel: منسوخ + no_results: اوہ! کوئی نتیجہ نہیں ملا۔ + +panel: + lastmod: حال ہی میں اپ ڈیٹ + trending_tags: مقبول ٹیگز + toc: مواد + +copyright: + # Shown at the bottom of the post + license: + template: یہ تحریر :LICENSE_NAME کے تحت مصنف کی جانب سے لائسنس یافتہ ہے۔ + name: CC BY 4.0 + link: https://creativecommons.org/licenses/by/4.0/ + + # Displayed in the footer + brief: کچھ حقوق محفوظ ہیں۔ + verbose: >- + جب تک کہ دوسری صورت میں ذکر نہ ہو، اس سائٹ کی تحریریں + مصنف کی جانب سے تخلیقی العام انتساب 4.0 بین الاقوامی (CC BY 4.0) لائسنس کے تحت دستیاب ہیں۔ + +meta: :PLATFORM کے لیے :THEME تھیم استعمال کیا جا رہا ہے۔ + +not_found: + statement: معذرت، یہ 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: لنک کامیابی سے کاپی ہو گیا! + +# Date time format. +# See: , +df: + post: + strftime: "%b %e, %Y" + dayjs: "ll" + archives: + strftime: "%b" + dayjs: "MMM" + +categories: + category_measure: + singular: زمرہ + plural: زمروں + post_measure: + singular: تحریر + plural: تحریریں diff --git a/_includes/pageviews/goatcounter.html b/_includes/pageviews/goatcounter.html index 265b22430c8..9cd1281e3bb 100644 --- a/_includes/pageviews/goatcounter.html +++ b/_includes/pageviews/goatcounter.html @@ -10,7 +10,7 @@ fetch(url) .then((response) => response.json()) .then((data) => { - const count = data.count.replace(/\s/g, ''); + const count = data.count.replace(/\D/g, ''); pv.innerText = new Intl.NumberFormat().format(count); }) .catch((error) => { diff --git a/_includes/post-description.html b/_includes/post-description.html index c00e516533e..48bb03b76eb 100644 --- a/_includes/post-description.html +++ b/_includes/post-description.html @@ -2,24 +2,29 @@ Get post description or generate it from the post content. {%- endcomment -%} -{%- assign max_length = include.max_length | default: 200 -%} - {%- capture description -%} -{%- if post.description -%} - {{- post.description -}} -{%- else -%} - {% comment %} - Remove the line number of the code snippet. - {% endcomment %} - {% assign content = post.content %} + {%- if post.description -%} + {{- post.description -}} + {%- else -%} + {% comment %} + Remove the line number of the code snippet. + {% endcomment %} + {%- assign content = post.content -%} - {% if content contains '
' %}
-    {% assign content = content | replace: '
', '' %}
-  {% endif %}
+    {%- if content contains '
' -%}
+      {%- assign content = content | replace: '
', '' -%}
+    {%- endif -%}
 
-  {{- content | markdownify | strip_html | newline_to_br | replace: '
', ' ' | strip_newlines -}} -{%- endif -%} + {{- content | strip_html | newline_to_br | replace: '
', ' ' | strip_newlines -}} + {%- endif -%} {%- endcapture -%} -{{- description | strip | truncate: max_length | escape -}} +{%- if include.json -%} + {%- assign description = description | jsonify -%} +{%- else -%} + {%- assign max_length = include.max_length | default: 200 -%} + {%- assign description = description | strip | truncate: max_length -%} +{%- endif -%} + +{{- description -}} diff --git a/_layouts/home.html b/_layouts/home.html index 451e391cd6d..66a12012f49 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -55,16 +55,15 @@ {% if post.image %} {% assign src = post.image.path | default: post.image %} - {% unless src contains '//' %} - {% assign src = post.media_subpath | append: '/' | append: src | replace: '//', '/' %} - {% endunless %} + {% capture src %}{% include media-url.html src=src subpath=post.media_subpath %}{% endcapture %} {% assign alt = post.image.alt | xml_escape | default: 'Preview Image' %} {% assign lqip = null %} {% if post.image.lqip %} - {% capture lqip %}lqip="{{ post.image.lqip }}"{% endcapture %} + {% capture lqip_url %}{% include media-url.html src=post.image.lqip subpath=post.media_subpath %}{% endcapture %} + {% assign lqip = 'lqip="' | append: lqip_url | append: '"' %} {% endif %}
diff --git a/_sass/base/_base.scss b/_sass/base/_base.scss index 19f153bd657..46e9eb6e83f 100644 --- a/_sass/base/_base.scss +++ b/_sass/base/_base.scss @@ -103,7 +103,7 @@ main { width: 100%; height: 100%; position: absolute; - background-color: var(--card-hovor-bg); + background-color: var(--card-hover-bg); opacity: 0; transition: opacity 0.35s ease-in-out; } @@ -349,7 +349,7 @@ main { } .disabled { - color: rgb(206, 196, 196); + color: rgb(206 196 196); pointer-events: auto; cursor: not-allowed; } diff --git a/_sass/base/_syntax.scss b/_sass/base/_syntax.scss index 69924fc693e..ae03d0dc9c8 100644 --- a/_sass/base/_syntax.scss +++ b/_sass/base/_syntax.scss @@ -66,7 +66,7 @@ code { &.highlighter-rouge { font-size: v.$code-font-size; padding: 3px 5px; - word-break: break-word; + overflow-wrap: break-word; border-radius: v.$radius-sm; background-color: var(--inline-code-bg); } @@ -243,7 +243,7 @@ div { } &:not([timeout]):hover { - background-color: rgba(128, 128, 128, 0.37); + background-color: rgb(128 128 128 / 37%); i { color: white; diff --git a/_sass/base/_typography.scss b/_sass/base/_typography.scss index 4cf39643687..1e7a6ef3eda 100644 --- a/_sass/base/_typography.scss +++ b/_sass/base/_typography.scss @@ -238,7 +238,7 @@ main { border-spacing: 0; thead { - border-bottom: solid 2px rgba(210, 215, 217, 0.75); + border-bottom: solid 2px rgb(210 215 217 / 75%); th { @extend %table-cell; diff --git a/_sass/components/_popups.scss b/_sass/components/_popups.scss index ca3e2fc697d..e94fcde368f 100644 --- a/_sass/components/_popups.scss +++ b/_sass/components/_popups.scss @@ -41,7 +41,7 @@ border-radius: 0.5rem; -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); - background-color: rgba(255, 255, 255, 0.5); + background-color: rgb(255 255 255 / 50%); color: #1b1b1eba; position: fixed; left: 50%; diff --git a/_sass/pages/_home.scss b/_sass/pages/_home.scss index 7a4bbf9b0c8..027cbe6a628 100644 --- a/_sass/pages/_home.scss +++ b/_sass/pages/_home.scss @@ -160,7 +160,7 @@ cursor: not-allowed; .page-link { - color: rgba(108, 117, 125, 0.57); + color: rgb(108 117 125 / 57%); } } } /* .page-item */ diff --git a/_sass/themes/_dark.scss b/_sass/themes/_dark.scss index 8c2f6ea8bd5..aae652213d4 100644 --- a/_sass/themes/_dark.scss +++ b/_sass/themes/_dark.scss @@ -2,33 +2,33 @@ color-scheme: dark; /* Framework color */ - --main-bg: rgb(27, 27, 30); - --mask-bg: rgb(68, 69, 70); - --main-border-color: rgb(44, 45, 45); + --main-bg: rgb(27 27 30); + --mask-bg: rgb(68 69 70); + --main-border-color: rgb(44 45 45); /* Common color */ - --text-color: rgb(175, 176, 177); + --text-color: rgb(175 176 177); --text-muted-color: #868686; --text-muted-highlight-color: #aeaeae; --heading-color: #cccccc; --label-color: #a7a7a7; - --blockquote-border-color: rgb(66, 66, 66); + --blockquote-border-color: rgb(66 66 66); --blockquote-text-color: #868686; - --link-color: rgb(138, 180, 248); - --link-underline-color: rgb(82, 108, 150); + --link-color: rgb(138 180 248); + --link-underline-color: rgb(82 108 150); --button-bg: #1e1e1e; --btn-border-color: #2e2f31; --btn-backtotop-color: var(--text-color); --btn-backtotop-border-color: #212122; --card-header-bg: #292929; - --checkbox-color: rgb(118, 120, 121); + --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%); + --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% + rgb(255 255 255 / 0%) 0%, + rgb(58 55 55 / 40%) 50%, + rgb(255 255 255 / 0%) 100% ); /* Sidebar */ @@ -37,65 +37,65 @@ --sidebar-bg: #1e1e1e; --sidebar-border-color: #292929; --sidebar-muted-color: #868686; - --sidebar-active-color: rgb(255, 255, 255, 0.95); + --sidebar-active-color: rgb(255 255 255 / 95%); --sidebar-hover-bg: #262626; --sidebar-btn-bg: #232328; --sidebar-btn-color: #787878; - --avatar-border-color: rgb(206, 206, 206, 0.9); + --avatar-border-color: rgb(206 206 206 / 90%); /* Topbar */ - --topbar-bg: rgb(27, 27, 30, 0.64); + --topbar-bg: rgb(27 27 30 / 64%); --topbar-text-color: var(--text-color); - --search-border-color: rgb(55, 55, 55); - --search-icon-color: rgb(100, 102, 105); - --input-focus-border-color: rgb(112, 114, 115); + --search-border-color: rgb(55 55 55); + --search-icon-color: rgb(100 102 105); + --input-focus-border-color: rgb(112 114 115); /* Home page */ - --post-list-text-color: rgb(175, 176, 177); + --post-list-text-color: rgb(175 176 177); --btn-patinator-text-color: var(--text-color); --btn-paginator-hover-color: #2e2e2e; /* Posts */ - --toc-highlight: rgb(116, 178, 243); + --toc-highlight: rgb(116 178 243); --toc-popup-border-color: #373737; - --tag-hover: rgb(43, 56, 62); + --tag-hover: rgb(43 56 62); --tb-odd-bg: #252526; /* odd rows of the posts' table */ - --tb-even-bg: rgb(31, 31, 34); /* even rows of the posts' table */ + --tb-even-bg: rgb(31 31 34); /* even rows of the posts' table */ --tb-border-color: var(--tb-odd-bg); - --footnote-target-bg: rgb(63, 81, 181); + --footnote-target-bg: rgb(63 81 181); --btn-share-color: #6c757d; --btn-share-hover-color: #bfc1ca; --card-bg: #1e1e1e; - --card-hovor-bg: #464d51; - --card-shadow: rgb(21, 21, 21, 0.72) 0 6px 18px 0, - rgb(137, 135, 135, 0.24) 0 0 0 1px; + --card-hover-bg: #464d51; + --card-shadow: rgb(21 21 21 / 72%) 0 6px 18px 0, + rgb(137 135 135 / 24%) 0 0 0 1px; --kbd-wrap-color: #6a6a6a; --kbd-text-color: #d3d3d3; --kbd-bg-color: #242424; - --prompt-text-color: rgb(216, 212, 212, 0.75); - --prompt-tip-bg: rgb(22, 60, 36, 0.64); - --prompt-tip-icon-color: rgb(15, 164, 15, 0.81); - --prompt-info-bg: rgb(7, 59, 104, 0.8); + --prompt-text-color: rgb(216 212 212 / 75%); + --prompt-tip-bg: rgb(22 60 36 / 64%); + --prompt-tip-icon-color: rgb(15 164 15 / 81%); + --prompt-info-bg: rgb(7 59 104 / 80%); --prompt-info-icon-color: #0075d1; - --prompt-warning-bg: rgb(90, 69, 3, 0.88); - --prompt-warning-icon-color: rgb(255, 165, 0, 0.8); - --prompt-danger-bg: rgb(86, 28, 8, 0.8); + --prompt-warning-bg: rgb(90 69 3 / 88%); + --prompt-warning-icon-color: rgb(255 165 0 / 80%); + --prompt-danger-bg: rgb(86 28 8 / 80%); --prompt-danger-icon-color: #cd0202; /* Tags */ - --tag-border: rgb(59, 79, 88); - --tag-shadow: rgb(32, 33, 33); - --dash-color: rgb(63, 65, 68); + --tag-border: rgb(59 79 88); + --tag-shadow: rgb(32 33 33); + --dash-color: rgb(63 65 68); --search-tag-bg: #292828; /* Categories */ - --categories-border: rgb(64, 66, 69, 0.5); - --categories-hover-bg: rgb(73, 75, 76); + --categories-border: rgb(64 66 69 / 50%); + --categories-hover-bg: rgb(73 75 76); --categories-icon-hover-color: white; /* Archive */ - --timeline-node-bg: rgb(150, 152, 156); - --timeline-color: rgb(63, 65, 68); + --timeline-node-bg: rgb(150 152 156); + --timeline-color: rgb(63 65 68); --timeline-year-dot-color: var(--timeline-color); /* Code highlight colors */ @@ -103,7 +103,7 @@ --highlight-bg-color: #151515; --highlighter-rouge-color: #c9def1; --highlight-lineno-color: #808080; - --inline-code-bg: rgba(255, 255, 255, 0.05); + --inline-code-bg: rgb(255 255 255 / 5%); --code-color: #b0b0b0; --code-header-text-color: #6a6a6a; --code-header-muted-color: #353535; @@ -141,11 +141,11 @@ #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) + rgb(26 26 30), + rgb(39 39 45), + rgb(39 39 45), + rgb(39 39 45), + rgb(26 26 30) ); } diff --git a/_sass/themes/_light.scss b/_sass/themes/_light.scss index 14c3962b7ae..48d47558a8f 100644 --- a/_sass/themes/_light.scss +++ b/_sass/themes/_light.scss @@ -20,34 +20,30 @@ --btn-backtotop-border-color: #f1f1f1; --checkbox-color: #c5c5c5; --checkbox-checked-color: #07a8f7; - --img-bg: radial-gradient( - circle, - rgb(255, 255, 255) 0%, - rgb(239, 239, 239) 100% - ); + --img-bg: radial-gradient(circle, rgb(255 255 255) 0%, rgb(239 239 239) 100%); --shimmer-bg: linear-gradient( 90deg, - rgba(250, 250, 250, 0) 0%, - rgba(232, 230, 230, 1) 50%, - rgba(250, 250, 250, 0) 100% + rgb(250 250 250 / 0%) 0%, + rgb(232 230 230 / 100%) 50%, + rgb(250 250 250 / 0%) 100% ); /* Sidebar */ - --site-title-color: rgb(113, 113, 113); + --site-title-color: rgb(113 113 113); --site-subtitle-color: #717171; --sidebar-bg: #f6f8fa; --sidebar-border-color: #efefef; --sidebar-muted-color: #545454; --sidebar-active-color: #1d1d1d; - --sidebar-hover-bg: rgb(223, 233, 241, 0.64); + --sidebar-hover-bg: rgb(223 233 241 / 64%); --sidebar-btn-bg: white; --sidebar-btn-color: #8e8e8e; --avatar-border-color: white; /* Topbar */ - --topbar-bg: rgb(255, 255, 255, 0.7); - --topbar-text-color: rgb(78, 78, 78); - --search-border-color: rgb(240, 240, 240); + --topbar-bg: rgb(255 255 255 / 70%); + --topbar-text-color: rgb(78 78 78); + --search-border-color: rgb(240 240 240); --search-icon-color: #c2c6cc; --input-focus-border-color: #b8b8b8; @@ -62,9 +58,9 @@ --btn-share-color: gray; --btn-share-hover-color: #0d6efd; --card-bg: white; - --card-hovor-bg: #e2e2e2; - --card-shadow: rgb(104, 104, 104, 0.05) 0 2px 6px 0, - rgba(211, 209, 209, 0.15) 0 0 0 1px; + --card-hover-bg: #e2e2e2; + --card-shadow: rgb(104 104 104 / 5%) 0 2px 6px 0, + rgb(211 209 209 / 15%) 0 0 0 1px; --footnote-target-bg: lightcyan; --tb-odd-bg: #fbfcfd; --tb-border-color: #eaeaea; @@ -72,29 +68,29 @@ --kbd-wrap-color: #bdbdbd; --kbd-text-color: var(--text-color); --kbd-bg-color: white; - --prompt-text-color: rgb(46, 46, 46, 0.77); - --prompt-tip-bg: rgb(123, 247, 144, 0.2); + --prompt-text-color: rgb(46 46 46 / 77%); + --prompt-tip-bg: rgb(123 247 144 / 20%); --prompt-tip-icon-color: #03b303; --prompt-info-bg: #e1f5fe; --prompt-info-icon-color: #0070cb; - --prompt-warning-bg: rgb(255, 243, 205); + --prompt-warning-bg: rgb(255 243 205); --prompt-warning-icon-color: #ef9c03; - --prompt-danger-bg: rgb(248, 215, 218, 0.56); + --prompt-danger-bg: rgb(248 215 218 / 56%); --prompt-danger-icon-color: #df3c30; /* Tags */ --tag-border: #dee2e6; --tag-shadow: var(--btn-border-color); - --tag-hover: rgb(222, 226, 230); + --tag-hover: rgb(222 226 230); --search-tag-bg: #f8f9fa; /* Categories */ - --categories-border: rgba(0, 0, 0, 0.125); + --categories-border: rgb(0 0 0 / 12.5%); --categories-hover-bg: var(--btn-border-color); --categories-icon-hover-color: darkslategray; /* Archive */ - --timeline-color: rgba(0, 0, 0, 0.075); + --timeline-color: rgb(0 0 0 / 7.5%); --timeline-node-bg: #c2c6cc; --timeline-year-dot-color: #ffffff; @@ -103,7 +99,7 @@ --highlight-bg-color: #f6f8fa; --highlighter-rouge-color: #3f596f; --highlight-lineno-color: #9e9e9e; - --inline-code-bg: rgba(25, 25, 28, 0.05); + --inline-code-bg: rgb(25 25 28 / 5%); --code-color: #3a3a3a; --code-header-text-color: #a3a3a3; --code-header-muted-color: #e5e5e5; @@ -111,7 +107,7 @@ --clipboard-checked-color: #43c743; [class^='prompt-'] { - --link-underline-color: rgb(219, 216, 216); + --link-underline-color: rgb(219 216 216); } .dark { diff --git a/assets/js/data/search.json b/assets/js/data/search.json index 32bcff9b0c5..5003e518ff2 100644 --- a/assets/js/data/search.json +++ b/assets/js/data/search.json @@ -5,16 +5,13 @@ swcache: true [ {% for post in site.posts %} - {%- capture description -%} - {% include post-description.html %} - {%- endcapture -%} { "title": {{ post.title | jsonify }}, "url": {{ post.url | relative_url | jsonify }}, "categories": {{ post.categories | join: ', ' | jsonify }}, "tags": {{ post.tags | join: ', ' | jsonify }}, - "date": "{{ post.date }}", - "content": "{{ description }}" + "date": {{ post.date | jsonify }}, + "content": {% include post-description.html json=true %} }{% unless forloop.last %},{% endunless %} {% endfor %} ] diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 24afe667416..b9a41727907 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [7.3.1](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.3.0...v7.3.1) (2025-07-26) + +### Bug Fixes + +* escape special JSON characters in search results ([#2481](https://github.com/cotes2020/jekyll-theme-chirpy/issues/2481)) ([7615d72](https://github.com/cotes2020/jekyll-theme-chirpy/commit/7615d72e9300a1514ef2fc8ec941ab2974ba7eb4)) + ## [7.3.0](https://github.com/cotes2020/jekyll-theme-chirpy/compare/v7.2.4...v7.3.0) (2025-05-18) ### Features diff --git a/eslint.config.js b/eslint.config.js index c8f6d53d4c4..b8073b6d60f 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,35 @@ -export default [ +import { defineConfig, globalIgnores } from 'eslint/config'; +import js from '@eslint/js'; +import globals from 'globals'; + +export default defineConfig([ + globalIgnores(['assets/*', 'node_modules/*', '_site/*']), + js.configs.recommended, { - files: ['_javascript/**/*.js'] + rules: { + semi: ['error', 'always'], + quotes: ['error', 'single'] + }, + languageOptions: { + globals: { + ...globals.browser, + ...globals.node + } + } + }, + { + files: ['_javascript/**/*.js'], + languageOptions: { + globals: { + ClipboardJS: 'readonly', + GLightbox: 'readonly', + Theme: 'readonly', + dayjs: 'readonly', + mermaid: 'readonly', + tocbot: 'readonly', + importScripts: 'readonly', + swconf: 'readonly' + } + } } -]; +]); diff --git a/jekyll-theme-chirpy.gemspec b/jekyll-theme-chirpy.gemspec index 07d64e4362d..a4d3679b7f9 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 = "7.3.0" + spec.version = "7.3.1" spec.authors = ["Cotes Chung"] spec.email = ["cotes.chung@gmail.com"] diff --git a/package.json b/package.json index 6f2cfb0c448..bb712a6b452 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jekyll-theme-chirpy", - "version": "7.3.0", + "version": "7.3.1", "description": "A minimal, responsive, and feature-rich Jekyll theme for technical writing.", "repository": { "type": "git", @@ -13,14 +13,16 @@ "url": "https://github.com/cotes2020/jekyll-theme-chirpy/issues" }, "homepage": "https://github.com/cotes2020/jekyll-theme-chirpy/", + "type": "module", "scripts": { "build": "concurrently npm:build:*", "build:css": "node purgecss.js", "build:js": "rollup -c --bundleConfigAsCjs --environment BUILD:production", "watch:js": "rollup -c --bundleConfigAsCjs -w", + "lint:js": "eslint", "lint:scss": "stylelint _sass/**/*.scss", "lint:fix:scss": "npm run lint:scss -- --fix", - "test": "npm run lint:scss", + "test": "npm run lint:js && npm run lint:scss", "prepare": "husky" }, "dependencies": { @@ -42,6 +44,8 @@ "@semantic-release/git": "^10.0.1", "concurrently": "^9.1.2", "conventional-changelog-conventionalcommits": "^8.0.0", + "eslint": "^9.27.0", + "globals": "^16.1.0", "husky": "^9.1.7", "purgecss": "^7.0.2", "rollup": "^4.41.0", diff --git a/purgecss.js b/purgecss.js index ad42db297ee..2380f6f770c 100644 --- a/purgecss.js +++ b/purgecss.js @@ -1,5 +1,6 @@ -const fs = require('fs').promises; -const { PurgeCSS } = require('purgecss'); +import { promises as fs } from 'fs'; +import { PurgeCSS } from 'purgecss'; + const DIST_PATH = '_sass/vendors'; const output = `${DIST_PATH}/_bootstrap.scss`; diff --git a/rollup.config.js b/rollup.config.js index d9322f83adc..42e205e01a4 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -11,7 +11,7 @@ const DIST = 'assets/js/dist'; const banner = `/*! * ${pkg.name} v${pkg.version} | © ${pkg.since} ${pkg.author} | ${pkg.license} Licensed | ${pkg.homepage} */`; -const frontmatter = `---\npermalink: /:basename\n---\n`; +const frontmatter = '---\npermalink: /:basename\n---\n'; const isProd = process.env.BUILD === 'production'; let hasWatched = false;