From e6b87d28111457cbc2f497866b71d8a2d00e35bc Mon Sep 17 00:00:00 2001 From: Alexander Fuks Date: Tue, 24 Sep 2024 04:21:34 +0400 Subject: [PATCH 01/15] chore: remove `h1` element from site title (#1960) --- _includes/sidebar.html | 4 +--- _sass/addon/commons.scss | 12 +++++------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/_includes/sidebar.html b/_includes/sidebar.html index 4f0bb8cad3d..569585f6f24 100644 --- a/_includes/sidebar.html +++ b/_includes/sidebar.html @@ -11,9 +11,7 @@ {%- endif -%} -

- {{ site.title }} -

+ {{ site.title }}

{{ site.tagline }}

diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index 465cb085905..e2a0e6154b5 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -738,6 +738,9 @@ $btn-mb: 0.5rem; } .site-title { + @extend %clickable-transition; + @extend %sidebar-link-hover; + font-family: inherit; font-weight: 900; font-size: 1.75rem; @@ -745,13 +748,8 @@ $btn-mb: 0.5rem; letter-spacing: 0.25px; margin-top: 1.25rem; margin-bottom: 0.5rem; - - a { - @extend %clickable-transition; - @extend %sidebar-link-hover; - - color: var(--site-title-color); - } + width: fit-content; + color: var(--site-title-color); } .site-subtitle { From 93f616b25d7ed6c4f090c50c8663f8c1f59947f4 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Thu, 26 Sep 2024 22:30:56 +0800 Subject: [PATCH 02/15] fix: pagination error when pinned posts exceed the page size (#1965) --- _layouts/home.html | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/_layouts/home.html b/_layouts/home.html index e44efe8f4cb..451e391cd6d 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -5,38 +5,45 @@ {% include lang.html %} -{% assign pinned = site.posts | where: 'pin', 'true' %} -{% assign default = site.posts | where_exp: 'item', 'item.pin != true and item.hidden != true' %} +{% assign all_pinned = site.posts | where: 'pin', 'true' %} +{% assign all_normal = site.posts | where_exp: 'item', 'item.pin != true and item.hidden != true' %} {% assign posts = '' | split: '' %} - + -{% assign offset = paginator.page | minus: 1 | times: paginator.per_page %} -{% assign pinned_num = pinned.size | minus: offset %} +{% assign visible_start = paginator.page | minus: 1 | times: paginator.per_page %} +{% assign visible_end = visible_start | plus: paginator.per_page %} -{% if pinned_num > 0 %} - {% for i in (offset..pinned.size) limit: pinned_num %} - {% assign posts = posts | push: pinned[i] %} +{% if all_pinned.size > visible_start %} + {% if all_pinned.size > visible_end %} + {% assign pinned_size = paginator.per_page %} + {% else %} + {% assign pinned_size = all_pinned.size | minus: visible_start %} + {% endif %} + + {% for i in (visible_start..all_pinned.size) limit: pinned_size %} + {% assign posts = posts | push: all_pinned[i] %} {% endfor %} {% else %} - {% assign pinned_num = 0 %} + {% assign pinned_size = 0 %} {% endif %} - + -{% assign default_beg = offset | minus: pinned.size %} +{% assign normal_size = paginator.posts | size | minus: pinned_size %} -{% if default_beg < 0 %} - {% assign default_beg = 0 %} -{% endif %} +{% if normal_size > 0 %} + {% if pinned_size > 0 %} + {% assign normal_start = 0 %} + {% else %} + {% assign normal_start = visible_start | minus: all_pinned.size %} + {% endif %} -{% assign default_num = paginator.posts | size | minus: pinned_num %} -{% assign default_end = default_beg | plus: default_num | minus: 1 %} + {% assign normal_end = normal_start | plus: normal_size | minus: 1 %} -{% if default_num > 0 %} - {% for i in (default_beg..default_end) %} - {% assign posts = posts | push: default[i] %} + {% for i in (normal_start..normal_end) %} + {% assign posts = posts | push: all_normal[i] %} {% endfor %} {% endif %} From 740bd84c51cbb929438ea538ddc942f97d1c1431 Mon Sep 17 00:00:00 2001 From: Bence Boros <39780892+borosbence@users.noreply.github.com> Date: Tue, 1 Oct 2024 17:19:39 +0200 Subject: [PATCH 03/15] chore(i18n): update hungarian translation (#1976) --- _data/locales/hu-HU.yml | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/_data/locales/hu-HU.yml b/_data/locales/hu-HU.yml index 53d88e96e52..be3a31b7d63 100644 --- a/_data/locales/hu-HU.yml +++ b/_data/locales/hu-HU.yml @@ -14,24 +14,23 @@ tabs: categories: Kategóriák tags: Címkék archives: Archívum - about: Rólam + about: Bemutatkozás # the text displayed in the search bar & search results search: hint: keresés cancel: Mégse - no_results: Oops! Nincs találat a keresésre. + no_results: Hoppá! Nincs találat a keresésre. panel: lastmod: Legutóbb frissítve trending_tags: Népszerű Címkék toc: Tartalom - links: Blog linkek copyright: # Shown at the bottom of the post license: - template: A bejegyzés :LICENSE_NAME licenccel rendelkezik. + template: A bejegyzést a szerző :LICENSE_NAME licenc alatt engedélyezte. name: CC BY 4.0 link: https://creativecommons.org/licenses/by/4.0/ @@ -42,7 +41,7 @@ copyright: Creative Commons Attribution 4.0 International (CC BY 4.0) licenccel rendelkeznek, hacsak másképp nincs jelezve. -meta: Készítve :PLATFORM motorral :THEME témával +meta: Készítve :THEME témával a :PLATFORM platformra. not_found: statement: Sajnáljuk, az URL-t rosszul helyeztük el, vagy valami nem létezőre mutat. @@ -73,7 +72,21 @@ post: title: Link másolása succeed: Link sikeresen másolva! +# Date time format. +# See: , +df: + post: + strftime: "%Y. %B. %e." + dayjs: "YYYY. MMMM D." + archives: + strftime: "%B" + dayjs: "MMM" + # categories page categories: - category_measure: kategória - post_measure: bejegyzés + category_measure: + singular: kategória + plural: kategória + post_measure: + singular: bejegyzés + plural: bejegyzés From 8a064a5e5a95cd22aa654f7c80da09d107262508 Mon Sep 17 00:00:00 2001 From: Alexander Fuks Date: Fri, 11 Oct 2024 18:32:10 +0400 Subject: [PATCH 04/15] feat: show toc on mobile screens (#1964) --- _includes/toc-status.html | 10 + _includes/toc.html | 9 +- _javascript/modules/components/toc.js | 41 ++-- .../modules/components/toc/toc-desktop.js | 22 ++ .../modules/components/toc/toc-mobile.js | 117 ++++++++++ _javascript/modules/plugins.js | 2 +- _javascript/post.js | 7 +- _layouts/post.html | 28 ++- _sass/addon/commons.scss | 4 +- _sass/addon/module.scss | 7 + _sass/colors/typography-dark.scss | 2 +- _sass/colors/typography-light.scss | 2 +- _sass/layout/post.scss | 209 ++++++++++++++++++ 13 files changed, 430 insertions(+), 30 deletions(-) create mode 100644 _includes/toc-status.html create mode 100644 _javascript/modules/components/toc/toc-desktop.js create mode 100644 _javascript/modules/components/toc/toc-mobile.js diff --git a/_includes/toc-status.html b/_includes/toc-status.html new file mode 100644 index 00000000000..4b71caeefcc --- /dev/null +++ b/_includes/toc-status.html @@ -0,0 +1,10 @@ +{% comment %} + Determine TOC state and return it through variable "enable_toc" +{% endcomment %} + +{% assign enable_toc = false %} +{% if site.toc and page.toc %} + {% if page.content contains ' +

{{- site.data.locales[include.lang].panel.toc -}}

diff --git a/_javascript/modules/components/toc.js b/_javascript/modules/components/toc.js index 56ce26fac50..765336ac2db 100644 --- a/_javascript/modules/components/toc.js +++ b/_javascript/modules/components/toc.js @@ -1,15 +1,30 @@ -export function toc() { - if (document.querySelector('main h2, main h3')) { - // see: https://github.com/tscanlin/tocbot#usage - tocbot.init({ - tocSelector: '#toc', - contentSelector: '.content', - ignoreSelector: '[data-toc-skip]', - headingSelector: 'h2, h3, h4', - orderedList: false, - scrollSmooth: false - }); - - document.getElementById('toc-wrapper').classList.remove('d-none'); +import { TocMobile as mobile } from './toc/toc-mobile'; +import { TocDesktop as desktop } from './toc/toc-desktop'; + +const desktopMode = matchMedia('(min-width: 1200px)'); + +function refresh(e) { + if (e.matches) { + mobile.hidePopup(); + desktop.refresh(); + } else { + mobile.refresh(); } } + +function init() { + if (document.querySelector('main>article[data-toc="true"]') === null) { + return; + } + + // Avoid create multiple instances of Tocbot. Ref: + if (desktopMode.matches) { + desktop.init(); + } else { + mobile.init(); + } + + desktopMode.onchange = refresh; +} + +export { init as initToc }; diff --git a/_javascript/modules/components/toc/toc-desktop.js b/_javascript/modules/components/toc/toc-desktop.js new file mode 100644 index 00000000000..5021a72a082 --- /dev/null +++ b/_javascript/modules/components/toc/toc-desktop.js @@ -0,0 +1,22 @@ +export class TocDesktop { + /* Tocbot options Ref: https://github.com/tscanlin/tocbot#usage */ + static options = { + tocSelector: '#toc', + contentSelector: '.content', + ignoreSelector: '[data-toc-skip]', + headingSelector: 'h2, h3, h4', + orderedList: false, + scrollSmooth: false, + headingsOffset: 16 * 2 // 2rem + }; + + static refresh() { + tocbot.refresh(this.options); + } + + static init() { + if (document.getElementById('toc-wrapper')) { + tocbot.init(this.options); + } + } +} diff --git a/_javascript/modules/components/toc/toc-mobile.js b/_javascript/modules/components/toc/toc-mobile.js new file mode 100644 index 00000000000..48b372df443 --- /dev/null +++ b/_javascript/modules/components/toc/toc-mobile.js @@ -0,0 +1,117 @@ +/** + * TOC button, topbar and popup for mobile devices + */ + +const $tocBar = document.getElementById('toc-bar'); +const $soloTrigger = document.getElementById('toc-solo-trigger'); +const $triggers = document.getElementsByClassName('toc-trigger'); +const $popup = document.getElementById('toc-popup'); +const $btnClose = document.getElementById('toc-popup-close'); + +const SCROLL_LOCK = 'overflow-hidden'; +const CLOSING = 'closing'; + +export class TocMobile { + static invisible = true; + static barHeight = 16 * 3; // 3rem + + static options = { + tocSelector: '#toc-popup-content', + contentSelector: '.content', + ignoreSelector: '[data-toc-skip]', + headingSelector: 'h2, h3, h4', + orderedList: false, + scrollSmooth: false, + collapseDepth: 4, + headingsOffset: this.barHeight + }; + + static initBar() { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + $tocBar.classList.toggle('invisible', entry.isIntersecting); + }); + }, + { rootMargin: `-${this.barHeight}px 0px 0px 0px` } + ); + + observer.observe($soloTrigger); + this.invisible = false; + } + + static listenAnchors() { + const $anchors = document.getElementsByClassName('toc-link'); + [...$anchors].forEach((anchor) => { + anchor.onclick = this.hidePopup; + }); + } + + static refresh() { + if (this.invisible) { + this.initComponents(); + } + tocbot.refresh(this.options); + this.listenAnchors(); + } + + static showPopup() { + TocMobile.lockScroll(true); + $popup.showModal(); + const activeItem = $popup.querySelector('li.is-active-li'); + activeItem.scrollIntoView({ block: 'center' }); + } + + static hidePopup() { + if (!$popup.open) { + return; + } + + $popup.toggleAttribute(CLOSING); + + $popup.addEventListener( + 'animationend', + () => { + $popup.toggleAttribute(CLOSING); + $popup.close(); + }, + { once: true } + ); + + TocMobile.lockScroll(false); + } + + static lockScroll(enable) { + document.documentElement.classList.toggle(SCROLL_LOCK, enable); + document.body.classList.toggle(SCROLL_LOCK, enable); + } + + static clickBackdrop(event) { + const rect = event.target.getBoundingClientRect(); + if ( + event.clientX < rect.left || + event.clientX > rect.right || + event.clientY < rect.top || + event.clientY > rect.bottom + ) { + TocMobile.hidePopup(); + } + } + + static initComponents() { + this.initBar(); + + [...$triggers].forEach((trigger) => { + trigger.onclick = this.showPopup; + }); + + $popup.onclick = this.clickBackdrop; + $btnClose.onclick = $popup.oncancel = this.hidePopup; + } + + static init() { + tocbot.init(this.options); + this.listenAnchors(); + this.initComponents(); + } +} diff --git a/_javascript/modules/plugins.js b/_javascript/modules/plugins.js index fb892e25bf5..cc95c1bc393 100644 --- a/_javascript/modules/plugins.js +++ b/_javascript/modules/plugins.js @@ -3,4 +3,4 @@ export { initClipboard } from './components/clipboard'; export { loadImg } from './components/img-loading'; export { imgPopup } from './components/img-popup'; export { initLocaleDatetime } from './components/locale-datetime'; -export { toc } from './components/toc'; +export { initToc } from './components/toc'; diff --git a/_javascript/post.js b/_javascript/post.js index 9340f05e70d..1c616ecd0a6 100644 --- a/_javascript/post.js +++ b/_javascript/post.js @@ -1,14 +1,15 @@ -import { basic, initSidebar, initTopbar } from './modules/layouts'; +import { basic, initTopbar, initSidebar } from './modules/layouts'; + import { loadImg, imgPopup, initLocaleDatetime, initClipboard, - toc + initToc } from './modules/plugins'; loadImg(); -toc(); +initToc(); imgPopup(); initSidebar(); initLocaleDatetime(); diff --git a/_layouts/post.html b/_layouts/post.html index f17ceea8641..bcc133f8559 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -11,7 +11,9 @@ {% include lang.html %} -
+{% include toc-status.html %} + +

{{ page.title }}

{% if page.description %} @@ -95,6 +97,30 @@

{{ page.title }}

+ {% if enable_toc %} + + + + + +
+
{{- page.title -}}
+ +
+
+
+ {% endif %} +
{{ content }}
diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index e2a0e6154b5..e332f21336a 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -908,9 +908,7 @@ $btn-mb: 0.5rem; } #topbar { - button i { - color: #999999; - } + @extend %btn-color; #breadcrumb { font-size: 1rem; diff --git a/_sass/addon/module.scss b/_sass/addon/module.scss index 42db4e2d991..34ac67b95ea 100644 --- a/_sass/addon/module.scss +++ b/_sass/addon/module.scss @@ -8,6 +8,7 @@ color: var(--heading-color); font-weight: 400; font-family: $font-family-heading; + scroll-margin-top: 3.5rem; } %anchor { @@ -134,6 +135,12 @@ } } +%btn-color { + button i { + color: #999999; + } +} + /* ---------- scss mixin --------- */ @mixin mt-mb($value) { diff --git a/_sass/colors/typography-dark.scss b/_sass/colors/typography-dark.scss index 12427ec494a..664c93653e6 100644 --- a/_sass/colors/typography-dark.scss +++ b/_sass/colors/typography-dark.scss @@ -22,7 +22,6 @@ --btn-border-color: #2e2f31; --btn-backtotop-color: var(--text-color); --btn-backtotop-border-color: #212122; - --btn-box-shadow: var(--main-bg); --card-header-bg: #292929; --checkbox-color: rgb(118, 120, 121); --checkbox-checked-color: var(--link-color); @@ -60,6 +59,7 @@ /* Posts */ --toc-highlight: rgb(116, 178, 243); + --toc-popup-border-color: #373737; --tag-hover: rgb(43, 56, 62); --tb-odd-bg: #252526; /* odd rows of the posts' table */ --tb-even-bg: rgb(31, 31, 34); /* even rows of the posts' table */ diff --git a/_sass/colors/typography-light.scss b/_sass/colors/typography-light.scss index 78000746925..b6fc5618ad5 100644 --- a/_sass/colors/typography-light.scss +++ b/_sass/colors/typography-light.scss @@ -22,7 +22,6 @@ --btn-border-color: #e9ecef; --btn-backtotop-color: #686868; --btn-backtotop-border-color: #f1f1f1; - --btn-box-shadow: #eaeaea; --checkbox-color: #c5c5c5; --checkbox-checked-color: #07a8f7; --img-bg: radial-gradient( @@ -63,6 +62,7 @@ /* Posts */ --toc-highlight: #0550ae; + --toc-popup-border-color: lightgray; --btn-share-color: gray; --btn-share-hover-color: #0d6efd; --card-bg: white; diff --git a/_sass/layout/post.scss b/_sass/layout/post.scss index 815db933198..be727006b62 100644 --- a/_sass/layout/post.scss +++ b/_sass/layout/post.scss @@ -228,6 +228,7 @@ header { } } +/* TOC panel */ #toc-wrapper { border-left: 1px solid rgba(158, 158, 158, 0.17); position: -webkit-sticky; @@ -290,6 +291,201 @@ header { } } +/* --- TOC button, bar and popup in mobile/tablet --- */ + +#toc-bar { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1; + margin: 0 -1rem; + height: $topbar-height; + background: var(--main-bg); + border-bottom: 1px solid var(--main-border-color); + transition: all 0.2s ease-in-out; + + @extend %btn-color; + + .label { + @extend %heading; + + margin-left: 0.25rem; + padding: 0 0.75rem; + color: inherit; + } + + &.invisible { + top: -$topbar-height; + transition: none; + } +} + +#toc-solo-trigger { + color: var(--text-muted-color); + border-color: var(--btn-border-color); + border-radius: $radius-lg; + + .label { + font-size: 1rem; + font-family: $font-family-heading; + } + + &:hover { + box-shadow: none; + background: none; + } +} + +@mixin slide-in { + from { + opacity: 0.7; + transform: translateY(-$topbar-height); + } + + to { + opacity: 1; + transform: translateY(0); + } +} + +@mixin slide-out { + 0% { + transform: translateY(0); + opacity: 1; + } + + 100% { + transform: translateY(-$topbar-height); + opacity: 0; + } +} + +@-webkit-keyframes slide-in { + @include slide-in; +} + +@keyframes slide-in { + @include slide-in; +} + +@-webkit-keyframes slide-out { + @include slide-out; +} + +@keyframes slide-out { + @include slide-out; +} + +#toc-popup { + $slide-in: slide-in 0.3s ease-out; + $slide-out: slide-out 0.3s ease-out; + $curtain-height: 2rem; + + border-color: var(--toc-popup-border-color); + border-width: 1px; + border-radius: $radius-lg; + color: var(--text-color); + background: var(--main-bg); + margin-top: $topbar-height; + min-width: 20rem; + font-size: 1.05rem; + + @media all and (min-width: 576px) { + max-width: 32rem; + } + + &[open] { + -webkit-animation: $slide-in; + animation: $slide-in; + } + + &[closing] { + -webkit-animation: $slide-out; + animation: $slide-out; + } + + @media all and (min-width: 850px) { + left: $sidebar-width; + } + + .header { + @extend %btn-color; + + position: -webkit-sticky; + position: sticky; + top: 0; + background-color: inherit; + border-bottom: 1px solid var(--main-border-color); + + .label { + font-family: $font-family-heading; + } + } + + button:focus-visible { + box-shadow: none; + } + + ul { + list-style-type: none; + padding-left: 0; + + li { + ul, + & + li { + margin-top: 0.25rem; + } + + a { + display: flex; + line-height: 1.5; + padding: 0.375rem 0; + padding-right: 1.125rem; + + &.toc-link::before { + display: none; + } + } + } + } + + @for $i from 2 through 4 { + .node-name--H#{$i} { + padding-left: 1.125rem * ($i - 1); + } + } + + .is-active-link { + color: var(--toc-highlight) !important; + font-weight: 600; + } + + &::-webkit-backdrop { + -webkit-backdrop-filter: blur(5px); + backdrop-filter: blur(5px); + } + + &::backdrop { + -webkit-backdrop-filter: blur(5px); + backdrop-filter: blur(5px); + } + + &::after { + display: flex; + content: ''; + position: relative; + background: linear-gradient(transparent, var(--main-bg) 70%); + height: $curtain-height; + } + + #toc-popup-content { + overflow: auto; + max-height: calc(100vh - 4 * $topbar-height); + font-family: $font-family-heading; + margin-bottom: -$curtain-height; + } +} + /* --- Related Posts --- */ #related-posts { @@ -368,3 +564,16 @@ header { margin-right: -0.5rem; } } + +@media all and (min-width: 1200px) { + h2, + h3, + h4 { + scroll-margin-top: 2rem; + } + + #toc-bar, + #toc-solo-trigger { + display: none !important; + } +} From 03e302cbf68cc502a2b6bef0726186a0b3ef321c Mon Sep 17 00:00:00 2001 From: Alexander Fuks Date: Sun, 13 Oct 2024 21:16:25 +0400 Subject: [PATCH 05/15] chore: close toc-popup gracefully with Esc key (#1990) --- _javascript/modules/components/toc/toc-mobile.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/_javascript/modules/components/toc/toc-mobile.js b/_javascript/modules/components/toc/toc-mobile.js index 48b372df443..8d717dd006e 100644 --- a/_javascript/modules/components/toc/toc-mobile.js +++ b/_javascript/modules/components/toc/toc-mobile.js @@ -62,7 +62,11 @@ export class TocMobile { activeItem.scrollIntoView({ block: 'center' }); } - static hidePopup() { + static hidePopup(event) { + if (event?.type === 'cancel') { + event.preventDefault(); + } + if (!$popup.open) { return; } From 6f461132c00c7f7d557e0b865530bb256c1fe5be Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 19 Oct 2024 21:13:21 +0800 Subject: [PATCH 06/15] refactor: improve toc popup module --- _javascript/modules/components/toc.js | 5 +- .../modules/components/toc/toc-mobile.js | 48 ++++++++++--------- _layouts/post.html | 6 +-- _sass/layout/post.scss | 24 ++++++---- 4 files changed, 49 insertions(+), 34 deletions(-) diff --git a/_javascript/modules/components/toc.js b/_javascript/modules/components/toc.js index 765336ac2db..e9086eedf9a 100644 --- a/_javascript/modules/components/toc.js +++ b/_javascript/modules/components/toc.js @@ -5,7 +5,10 @@ const desktopMode = matchMedia('(min-width: 1200px)'); function refresh(e) { if (e.matches) { - mobile.hidePopup(); + if (mobile.popupOpened) { + mobile.hidePopup(); + } + desktop.refresh(); } else { mobile.refresh(); diff --git a/_javascript/modules/components/toc/toc-mobile.js b/_javascript/modules/components/toc/toc-mobile.js index 8d717dd006e..20e24a73c9f 100644 --- a/_javascript/modules/components/toc/toc-mobile.js +++ b/_javascript/modules/components/toc/toc-mobile.js @@ -12,8 +12,8 @@ const SCROLL_LOCK = 'overflow-hidden'; const CLOSING = 'closing'; export class TocMobile { - static invisible = true; - static barHeight = 16 * 3; // 3rem + static #invisible = true; + static #barHeight = 16 * 3; // 3rem static options = { tocSelector: '#toc-popup-content', @@ -23,7 +23,7 @@ export class TocMobile { orderedList: false, scrollSmooth: false, collapseDepth: 4, - headingsOffset: this.barHeight + headingsOffset: this.#barHeight }; static initBar() { @@ -33,44 +33,40 @@ export class TocMobile { $tocBar.classList.toggle('invisible', entry.isIntersecting); }); }, - { rootMargin: `-${this.barHeight}px 0px 0px 0px` } + { rootMargin: `-${this.#barHeight}px 0px 0px 0px` } ); observer.observe($soloTrigger); - this.invisible = false; + this.#invisible = false; } static listenAnchors() { const $anchors = document.getElementsByClassName('toc-link'); [...$anchors].forEach((anchor) => { - anchor.onclick = this.hidePopup; + anchor.onclick = () => this.hidePopup(); }); } static refresh() { - if (this.invisible) { + if (this.#invisible) { this.initComponents(); } tocbot.refresh(this.options); this.listenAnchors(); } + static get popupOpened() { + return $popup.open; + } + static showPopup() { - TocMobile.lockScroll(true); + this.lockScroll(true); $popup.showModal(); const activeItem = $popup.querySelector('li.is-active-li'); activeItem.scrollIntoView({ block: 'center' }); } - static hidePopup(event) { - if (event?.type === 'cancel') { - event.preventDefault(); - } - - if (!$popup.open) { - return; - } - + static hidePopup() { $popup.toggleAttribute(CLOSING); $popup.addEventListener( @@ -82,7 +78,7 @@ export class TocMobile { { once: true } ); - TocMobile.lockScroll(false); + this.lockScroll(false); } static lockScroll(enable) { @@ -91,6 +87,10 @@ export class TocMobile { } static clickBackdrop(event) { + if ($popup.hasAttribute(CLOSING)) { + return; + } + const rect = event.target.getBoundingClientRect(); if ( event.clientX < rect.left || @@ -98,7 +98,7 @@ export class TocMobile { event.clientY < rect.top || event.clientY > rect.bottom ) { - TocMobile.hidePopup(); + this.hidePopup(); } } @@ -106,11 +106,15 @@ export class TocMobile { this.initBar(); [...$triggers].forEach((trigger) => { - trigger.onclick = this.showPopup; + trigger.onclick = () => this.showPopup(); }); - $popup.onclick = this.clickBackdrop; - $btnClose.onclick = $popup.oncancel = this.hidePopup; + $popup.onclick = (e) => this.clickBackdrop(e); + $btnClose.onclick = () => this.hidePopup(); + $popup.oncancel = (e) => { + e.preventDefault(); + this.hidePopup(); + }; } static init() { diff --git a/_layouts/post.html b/_layouts/post.html index bcc133f8559..6a2deff7be6 100644 --- a/_layouts/post.html +++ b/_layouts/post.html @@ -100,7 +100,7 @@

{{ page.title }}

{% if enable_toc %} @@ -113,8 +113,8 @@

{{ page.title }}

{{- page.title -}}
-
diff --git a/_sass/layout/post.scss b/_sass/layout/post.scss index be727006b62..01021f3f615 100644 --- a/_sass/layout/post.scss +++ b/_sass/layout/post.scss @@ -380,12 +380,13 @@ header { $slide-in: slide-in 0.3s ease-out; $slide-out: slide-out 0.3s ease-out; $curtain-height: 2rem; + $backdrop: blur(5px); border-color: var(--toc-popup-border-color); border-width: 1px; border-radius: $radius-lg; color: var(--text-color); - background: var(--main-bg); + background: var(--card-bg); margin-top: $topbar-height; min-width: 20rem; font-size: 1.05rem; @@ -422,8 +423,15 @@ header { } } - button:focus-visible { - box-shadow: none; + button { + > i { + font-size: 1.25rem; + vertical-align: middle; + } + + &:focus-visible { + box-shadow: none; + } } ul { @@ -461,20 +469,20 @@ header { } &::-webkit-backdrop { - -webkit-backdrop-filter: blur(5px); - backdrop-filter: blur(5px); + -webkit-backdrop-filter: $backdrop; + backdrop-filter: $backdrop; } &::backdrop { - -webkit-backdrop-filter: blur(5px); - backdrop-filter: blur(5px); + -webkit-backdrop-filter: $backdrop; + backdrop-filter: $backdrop; } &::after { display: flex; content: ''; position: relative; - background: linear-gradient(transparent, var(--main-bg) 70%); + background: linear-gradient(transparent, var(--card-bg) 70%); height: $curtain-height; } From c1bd9eb9eece4cf3b7e76d750bcc4108aec63361 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sun, 20 Oct 2024 13:47:54 +0800 Subject: [PATCH 07/15] refactor: reduce duplicate scss --- _sass/addon/commons.scss | 22 ++++++++++------------ _sass/addon/module.scss | 21 ++++++++++++++++++--- _sass/layout/archives.scss | 5 ++--- _sass/layout/category-tag.scss | 4 +--- _sass/layout/home.scss | 5 ++--- _sass/layout/post.scss | 26 ++++++++++++-------------- 6 files changed, 45 insertions(+), 38 deletions(-) diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index e332f21336a..2bf99b85b71 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -251,8 +251,8 @@ i { > p { margin-left: 0.25em; - margin-top: 0; - margin-bottom: 0; + + @include mt-mb(0); } } } @@ -769,8 +769,8 @@ $btn-mb: 0.5rem; li.nav-item { opacity: 0.9; width: 100%; - padding-left: 1.5rem; - padding-right: 1.5rem; + + @include pl-pr(1.5rem); a.nav-link { @include pt-pb(0.6rem); @@ -1043,7 +1043,7 @@ search { a { font-size: 1.4rem; - line-height: 2.5rem; + line-height: 1.5rem; &:hover { @extend %link-hover; @@ -1069,8 +1069,9 @@ search { } > p { - overflow: hidden; - text-overflow: ellipsis; + @extend %text-ellipsis; + + white-space: break-spaces; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; @@ -1086,10 +1087,7 @@ search { color: var(--topbar-text-color); text-align: center; width: 70%; - overflow: hidden; - text-overflow: ellipsis; word-break: keep-all; - white-space: nowrap; } #mask { @@ -1492,8 +1490,8 @@ search { #main-wrapper > .container { max-width: $main-content-max-width; - padding-left: 1.75rem !important; - padding-right: 1.75rem !important; + + @include pl-pr(1.75rem, true); } main.col-12, diff --git a/_sass/addon/module.scss b/_sass/addon/module.scss index 34ac67b95ea..1dfb735fd01 100644 --- a/_sass/addon/module.scss +++ b/_sass/addon/module.scss @@ -112,6 +112,16 @@ -webkit-box-orient: vertical; } +@mixin text-ellipsis { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +%text-ellipsis { + @include text-ellipsis; +} + %text-highlight { color: var(--text-muted-highlight-color); font-weight: 600; @@ -158,9 +168,14 @@ padding-bottom: $val; } -@mixin pl-pr($val) { - padding-left: $val; - padding-right: $val; +@mixin pl-pr($val, $important: false) { + @if $important { + padding-left: $val !important; + padding-right: $val !important; + } @else { + padding-left: $val; + padding-right: $val; + } } @mixin placeholder { diff --git a/_sass/layout/archives.scss b/_sass/layout/archives.scss index 3a2e86b1191..fd1979b8f91 100644 --- a/_sass/layout/archives.scss +++ b/_sass/layout/archives.scss @@ -58,9 +58,8 @@ li { font-size: 1.1rem; line-height: 3rem; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + + @extend %text-ellipsis; &:nth-child(odd) { background-color: var(--main-bg, #ffffff); diff --git a/_sass/layout/category-tag.scss b/_sass/layout/category-tag.scss index 9e43a911ace..fe7d99cec25 100644 --- a/_sass/layout/category-tag.scss +++ b/_sass/layout/category-tag.scss @@ -63,9 +63,7 @@ } > a { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + @include text-ellipsis; } } } diff --git a/_sass/layout/home.scss b/_sass/layout/home.scss index 0d95d7ba6a6..7fff3ba1627 100644 --- a/_sass/layout/home.scss +++ b/_sass/layout/home.scss @@ -74,9 +74,8 @@ > div:first-child { display: block; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + + @extend %text-ellipsis; } } } diff --git a/_sass/layout/post.scss b/_sass/layout/post.scss index 01021f3f615..b66e906c87f 100644 --- a/_sass/layout/post.scss +++ b/_sass/layout/post.scss @@ -1,6 +1,6 @@ -/* - Post-specific style -*/ +/** + * Post-specific styles + */ %btn-post-nav { width: 50%; @@ -97,7 +97,7 @@ header { &:hover { i { - @extend %btn-share-hovor; + @extend %btn-share-hover; } } } @@ -258,9 +258,8 @@ header { .toc-link { display: block; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + + @extend %text-ellipsis; &:hover { color: var(--toc-highlight); @@ -509,10 +508,11 @@ header { } p { + @extend %text-ellipsis; + font-size: 0.9rem; margin-bottom: 0.5rem; - overflow: hidden; - text-overflow: ellipsis; + white-space: break-spaces; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; @@ -534,7 +534,7 @@ header { max-width: 100%; } -%btn-share-hovor { +%btn-share-hover { color: var(--btn-share-hover-color) !important; } @@ -566,10 +566,8 @@ header { /* Hide SideBar and TOC */ @media all and (max-width: 849px) { .post-navigation { - padding-left: 0; - padding-right: 0; - margin-left: -0.5rem; - margin-right: -0.5rem; + @include pl-pr(0); + @include ml-mr(-0.5rem); } } From d4f7f39ece2d8feaca963b8bfba331268b28811e Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Tue, 22 Oct 2024 10:42:07 +0800 Subject: [PATCH 08/15] refactor: simplify sidebar animation --- _javascript/modules/components/sidebar.js | 23 +++++++++-------------- _layouts/default.html | 2 +- _sass/addon/commons.scss | 10 ---------- 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/_javascript/modules/components/sidebar.js b/_javascript/modules/components/sidebar.js index 6b562d84147..aed759ed57d 100644 --- a/_javascript/modules/components/sidebar.js +++ b/_javascript/modules/components/sidebar.js @@ -2,26 +2,21 @@ * Expand or close the sidebar in mobile screens. */ -const ATTR_DISPLAY = 'sidebar-display'; +const $sidebar = document.getElementById('sidebar'); +const $trigger = document.getElementById('sidebar-trigger'); +const $mask = document.getElementById('mask'); class SidebarUtil { - static isExpanded = false; + static #isExpanded = false; static toggle() { - if (SidebarUtil.isExpanded === false) { - document.body.setAttribute(ATTR_DISPLAY, ''); - } else { - document.body.removeAttribute(ATTR_DISPLAY); - } - - SidebarUtil.isExpanded = !SidebarUtil.isExpanded; + this.#isExpanded = !this.#isExpanded; + document.body.toggleAttribute('sidebar-display', this.#isExpanded); + $sidebar.classList.toggle('z-2', this.#isExpanded); + $mask.classList.toggle('d-none', !this.#isExpanded); } } export function sidebarExpand() { - document - .getElementById('sidebar-trigger') - .addEventListener('click', SidebarUtil.toggle); - - document.getElementById('mask').addEventListener('click', SidebarUtil.toggle); + $trigger.onclick = $mask.onclick = () => SidebarUtil.toggle(); } diff --git a/_layouts/default.html b/_layouts/default.html index ea438fe7abb..1590ef62430 100644 --- a/_layouts/default.html +++ b/_layouts/default.html @@ -68,7 +68,7 @@ -
+
{% if site.pwa.enabled %} {% include_cached notification.html lang=lang %} diff --git a/_sass/addon/commons.scss b/_sass/addon/commons.scss index 2bf99b85b71..5e8aceaa262 100644 --- a/_sass/addon/commons.scss +++ b/_sass/addon/commons.scss @@ -688,7 +688,6 @@ $btn-mb: 0.5rem; height: 100%; overflow-y: auto; width: $sidebar-width; - z-index: 99; background: var(--sidebar-bg); border-right: 1px solid var(--sidebar-border-color); @@ -1091,16 +1090,7 @@ search { } #mask { - display: none; - position: fixed; inset: 0 0 0 0; - height: 100%; - width: 100%; - z-index: 1; - - @at-root [#{$sidebar-display}] & { - display: block !important; - } } /* --- basic wrappers --- */ From 74ed06321c1730dc788af3306b80a0f1739510d4 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Fri, 25 Oct 2024 19:48:11 +0800 Subject: [PATCH 09/15] ci: block invalid pull requests (#2010) --- .github/workflows/pr-filter.yml | 22 ++++++++++++++ .github/workflows/scripts/pr-filter.js | 40 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 .github/workflows/pr-filter.yml create mode 100644 .github/workflows/scripts/pr-filter.js diff --git a/.github/workflows/pr-filter.yml b/.github/workflows/pr-filter.yml new file mode 100644 index 00000000000..b6bcd00a3ca --- /dev/null +++ b/.github/workflows/pr-filter.yml @@ -0,0 +1,22 @@ +name: Block Invalid PR + +on: + pull_request_target: + types: [opened, reopened, edited] + +jobs: + check-template: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Check PR Content + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const script = require('.github/workflows/scripts/pr-filter.js'); + await script({ github, context }); diff --git a/.github/workflows/scripts/pr-filter.js b/.github/workflows/scripts/pr-filter.js new file mode 100644 index 00000000000..e7206301ead --- /dev/null +++ b/.github/workflows/scripts/pr-filter.js @@ -0,0 +1,40 @@ +function noTypes(markdown) { + if (/## Type of change/.test(markdown) && /- \[x\]/i.test(markdown)) { + return false; + } + return true; +} + +function noDescription(markdown) { + return ( + /## Description/.test(markdown) === false || + /## Description\s*\n\s*## \w+/.test(markdown) || + /## Description\s*\n\s*$/.test(markdown) + ); +} + +module.exports = async ({ github, context }) => { + const pr = context.payload.pull_request; + + if (pr.labels.length > 0) { + // Skip if the PR is already labeled (typically created by a deps-bot.) + return; + } + + const body = pr.body === null ? '' : pr.body.trim(); + const markdown = body.replace(//g, ''); + + if (body === '' || noTypes(markdown) || noDescription(markdown)) { + await github.rest.pulls.update({ + ...context.repo, + pull_number: pr.number, + state: 'closed' + }); + + await github.rest.issues.createComment({ + ...context.repo, + issue_number: pr.number, + body: "Oops, it seems you've submitted an invalid pull request. No worries, we'll close it for you." + }); + } +}; From c7f967529c294f9622f142470406f2be43ea4d35 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Sat, 26 Oct 2024 16:58:07 +0800 Subject: [PATCH 10/15] ci: skip test for invalid PRs (#2013) --- .github/workflows/ci.yml | 7 +++++- .github/workflows/commitlint.yml | 3 ++- .github/workflows/pr-filter.yml | 17 +++++++++++--- .github/workflows/scripts/pr-filter.js | 31 ++++++++++++-------------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50a158b10a9..f909b7e6bb4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,4 +1,5 @@ name: "CI" + on: push: branches: @@ -11,7 +12,7 @@ on: - "docs/**" - "README.md" - "LICENSE" - pull_request: + workflow_call: jobs: build: @@ -43,3 +44,7 @@ jobs: - name: Test Site run: bash tools/test.sh + + check-commit: + needs: build + uses: ./.github/workflows/commitlint.yml diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index c9c48c33f97..ac8726f3111 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -1,5 +1,6 @@ name: Lint Commit Messages -on: pull_request + +on: workflow_call jobs: commitlint: diff --git a/.github/workflows/pr-filter.yml b/.github/workflows/pr-filter.yml index b6bcd00a3ca..fe393a29ea5 100644 --- a/.github/workflows/pr-filter.yml +++ b/.github/workflows/pr-filter.yml @@ -1,22 +1,33 @@ -name: Block Invalid PR +name: PR Filter on: pull_request_target: - types: [opened, reopened, edited] + types: [opened, reopened] jobs: check-template: runs-on: ubuntu-latest permissions: pull-requests: write + steps: - name: Checkout Code uses: actions/checkout@v4 - name: Check PR Content + id: intercept uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} + result-encoding: string script: | const script = require('.github/workflows/scripts/pr-filter.js'); - await script({ github, context }); + return await script({ github, context }); + + - name: Abort due to invalid PR + if: ${{ steps.intercept.outputs.result != 'true' }} + run: exit 1 + + test: + needs: check-template + uses: ./.github/workflows/ci.yml diff --git a/.github/workflows/scripts/pr-filter.js b/.github/workflows/scripts/pr-filter.js index e7206301ead..f4190ddf1f4 100644 --- a/.github/workflows/scripts/pr-filter.js +++ b/.github/workflows/scripts/pr-filter.js @@ -1,30 +1,25 @@ -function noTypes(markdown) { - if (/## Type of change/.test(markdown) && /- \[x\]/i.test(markdown)) { - return false; - } - return true; +function hasTypes(markdown) { + return /## Type of change/.test(markdown) && /-\s*\[x\]/i.test(markdown); } -function noDescription(markdown) { +function hasDescription(markdown) { return ( - /## Description/.test(markdown) === false || - /## Description\s*\n\s*## \w+/.test(markdown) || - /## Description\s*\n\s*$/.test(markdown) + /## Description/.test(markdown) && + !/## Description\s*\n\s*(##|\s*$)/.test(markdown) ); } module.exports = async ({ github, context }) => { const pr = context.payload.pull_request; - - if (pr.labels.length > 0) { - // Skip if the PR is already labeled (typically created by a deps-bot.) - return; - } - const body = pr.body === null ? '' : pr.body.trim(); const markdown = body.replace(//g, ''); + const action = context.payload.action; + + const isValid = + pr.labels.length > 0 || // PR create by Dependabot would have labels + (markdown !== '' && hasTypes(markdown) && hasDescription(markdown)); - if (body === '' || noTypes(markdown) || noDescription(markdown)) { + if (!isValid) { await github.rest.pulls.update({ ...context.repo, pull_number: pr.number, @@ -34,7 +29,9 @@ module.exports = async ({ github, context }) => { await github.rest.issues.createComment({ ...context.repo, issue_number: pr.number, - body: "Oops, it seems you've submitted an invalid pull request. No worries, we'll close it for you." + body: `Oops, it seems you've ${action} an invalid pull request. No worries, we'll close it for you.` }); } + + return isValid; }; From 4ef3cd8efc90518cc56b4e92306f81aa36feee70 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Tue, 29 Oct 2024 22:56:32 +0800 Subject: [PATCH 11/15] ci: improve workflow triggers (#2017) - Unchain commit-lint and CI - Even if a commit does not meet the CI path filter, it still needs to lint the commit message. - Unchain PR filter and CI - The CI workflow needs to be triggered when the commits in a pull request are modified. - Allow manual publishing - Sometimes `semantic-release` will error out due to commit messages referencing discussions, but this does not affect the final RubyGems/GitHub Release. In such cases, manual triggering of the publish process is needed to complete the remaining publishing steps. --- .github/workflows/cd.yml | 7 +++---- .github/workflows/ci.yml | 25 ++++++++++++++----------- .github/workflows/commitlint.yml | 7 ++++++- .github/workflows/pr-filter.yml | 11 +---------- .github/workflows/publish.yml | 1 + .github/workflows/scripts/pr-filter.js | 10 +++++----- .github/workflows/style-lint.yml | 6 ++++-- 7 files changed, 34 insertions(+), 33 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 4f2da0e3683..c665f755e11 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -2,13 +2,12 @@ name: CD on: push: - branches: - - production - tags-ignore: - - "**" + branches: [production] + tags-ignore: ["**"] jobs: release: + if: ${{ ! startsWith(github.event.head_commit.message, 'chore(release)') }} permissions: contents: write issues: write diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f909b7e6bb4..31b878632b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,18 +1,25 @@ -name: "CI" +name: CI on: push: branches: - - "master" - - "hotfix/**" + - master + - "hotfix/*" paths-ignore: - ".github/**" - "!.github/workflows/ci.yml" - - ".gitignore" + - .gitignore - "docs/**" - - "README.md" - - "LICENSE" - workflow_call: + - README.md + - LICENSE + pull_request: + paths-ignore: + - ".github/**" + - "!.github/workflows/ci.yml" + - .gitignore + - "docs/**" + - README.md + - LICENSE jobs: build: @@ -44,7 +51,3 @@ jobs: - name: Test Site run: bash tools/test.sh - - check-commit: - needs: build - uses: ./.github/workflows/commitlint.yml diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml index ac8726f3111..58f1a3ff3d1 100644 --- a/.github/workflows/commitlint.yml +++ b/.github/workflows/commitlint.yml @@ -1,6 +1,11 @@ name: Lint Commit Messages -on: workflow_call +on: + push: + branches: + - master + - "hotfix/*" + pull_request: jobs: commitlint: diff --git a/.github/workflows/pr-filter.yml b/.github/workflows/pr-filter.yml index fe393a29ea5..42e1d640089 100644 --- a/.github/workflows/pr-filter.yml +++ b/.github/workflows/pr-filter.yml @@ -19,15 +19,6 @@ jobs: uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} - result-encoding: string script: | const script = require('.github/workflows/scripts/pr-filter.js'); - return await script({ github, context }); - - - name: Abort due to invalid PR - if: ${{ steps.intercept.outputs.result != 'true' }} - run: exit 1 - - test: - needs: check-template - uses: ./.github/workflows/ci.yml + await script({ github, context, core }); diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 99114ea3cb6..b0f9713f2ef 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,6 +10,7 @@ on: required: true BUILDER: required: true + workflow_dispatch: jobs: launch: diff --git a/.github/workflows/scripts/pr-filter.js b/.github/workflows/scripts/pr-filter.js index f4190ddf1f4..97242016b22 100644 --- a/.github/workflows/scripts/pr-filter.js +++ b/.github/workflows/scripts/pr-filter.js @@ -1,5 +1,5 @@ function hasTypes(markdown) { - return /## Type of change/.test(markdown) && /-\s*\[x\]/i.test(markdown); + return /## Type of change/.test(markdown) && /-\s\[x\]/i.test(markdown); } function hasDescription(markdown) { @@ -9,9 +9,9 @@ function hasDescription(markdown) { ); } -module.exports = async ({ github, context }) => { +module.exports = async ({ github, context, core }) => { const pr = context.payload.pull_request; - const body = pr.body === null ? '' : pr.body.trim(); + const body = pr.body === null ? '' : pr.body; const markdown = body.replace(//g, ''); const action = context.payload.action; @@ -31,7 +31,7 @@ module.exports = async ({ github, context }) => { issue_number: pr.number, body: `Oops, it seems you've ${action} an invalid pull request. No worries, we'll close it for you.` }); - } - return isValid; + core.setFailed('PR content does not meet template requirements.'); + } }; diff --git a/.github/workflows/style-lint.yml b/.github/workflows/style-lint.yml index f84f3bcc432..5cb38a7a11a 100644 --- a/.github/workflows/style-lint.yml +++ b/.github/workflows/style-lint.yml @@ -1,8 +1,10 @@ -name: "Style Lint" +name: Style Lint on: push: - branches: ["master", "hotfix/**"] + branches: + - master + - "hotfix/*" paths: ["_sass/**/*.scss"] pull_request: paths: ["_sass/**/*.scss"] From 86b13c917f8f9477b10766fb621cbe987c025203 Mon Sep 17 00:00:00 2001 From: Alexander Fuks Date: Fri, 1 Nov 2024 14:39:03 +0400 Subject: [PATCH 12/15] chore: improve feed interoperability (#2024) --- assets/feed.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/feed.xml b/assets/feed.xml index 0ab20e3be6a..d2aad4db1c1 100644 --- a/assets/feed.xml +++ b/assets/feed.xml @@ -34,7 +34,7 @@ permalink: /feed.xml {{ post.date | date_to_xmlschema }} {% endif %} {{ post_absolute_url }} - + {{ post.author | default: site.social.name }} From 42dea8ee2986ee609ca6f2643a03bd29bd5456a3 Mon Sep 17 00:00:00 2001 From: Supreeth Mysore Venkatesh Date: Sun, 3 Nov 2024 17:45:59 +0100 Subject: [PATCH 13/15] build(deps): update `wdm` gem version for compatibility (#2028) --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 66f9337db44..e5415748ad5 100644 --- a/Gemfile +++ b/Gemfile @@ -11,4 +11,4 @@ platforms :mingw, :x64_mingw, :mswin, :jruby do gem "tzinfo-data" end -gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin] +gem "wdm", "~> 0.2.0", :platforms => [:mingw, :x64_mingw, :mswin] From 2f844978aac587a8631c16d6907f24a8af6035a3 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Fri, 8 Nov 2024 22:15:31 +0800 Subject: [PATCH 14/15] chore: change stale label to `inactive` --- .github/workflows/stale.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index bcf425ae604..4f6e91cbf39 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -9,7 +9,7 @@ permissions: pull-requests: write env: - STALE_LABEL: stale + STALE_LABEL: inactive EXEMPT_LABELS: "pending,planning,in progress" MESSAGE: > This conversation has been automatically marked as stale because it has not had recent activity. From d51345e29754ba92a0c2fd6534bbd248ff298331 Mon Sep 17 00:00:00 2001 From: Cotes Chung <11371340+cotes2020@users.noreply.github.com> Date: Fri, 8 Nov 2024 22:35:18 +0800 Subject: [PATCH 15/15] ci: reduce unnecessary pr-filter runs (#2033) - Checking the repository of the PR is more effective than checking the label to identify bot-initiated PRs - This change also allows more flexible PR body definitions for developers with write access to the repository --- .github/workflows/pr-filter.yml | 1 + .github/workflows/scripts/pr-filter.js | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-filter.yml b/.github/workflows/pr-filter.yml index 42e1d640089..8e9a18b736f 100644 --- a/.github/workflows/pr-filter.yml +++ b/.github/workflows/pr-filter.yml @@ -6,6 +6,7 @@ on: jobs: check-template: + if: github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name runs-on: ubuntu-latest permissions: pull-requests: write diff --git a/.github/workflows/scripts/pr-filter.js b/.github/workflows/scripts/pr-filter.js index 97242016b22..03f50dc5ca2 100644 --- a/.github/workflows/scripts/pr-filter.js +++ b/.github/workflows/scripts/pr-filter.js @@ -16,8 +16,7 @@ module.exports = async ({ github, context, core }) => { const action = context.payload.action; const isValid = - pr.labels.length > 0 || // PR create by Dependabot would have labels - (markdown !== '' && hasTypes(markdown) && hasDescription(markdown)); + markdown !== '' && hasTypes(markdown) && hasDescription(markdown); if (!isValid) { await github.rest.pulls.update({