Compare commits

..

No commits in common. "d51345e29754ba92a0c2fd6534bbd248ff298331" and "03e302cbf68cc502a2b6bef0726186a0b3ef321c" have entirely different histories.

21 changed files with 113 additions and 197 deletions

View file

@ -2,12 +2,13 @@ name: CD
on: on:
push: push:
branches: [production] branches:
tags-ignore: ["**"] - production
tags-ignore:
- "**"
jobs: jobs:
release: release:
if: ${{ ! startsWith(github.event.head_commit.message, 'chore(release)') }}
permissions: permissions:
contents: write contents: write
issues: write issues: write

View file

@ -1,25 +1,17 @@
name: CI name: "CI"
on: on:
push: push:
branches: branches:
- master - "master"
- "hotfix/*" - "hotfix/**"
paths-ignore: paths-ignore:
- ".github/**" - ".github/**"
- "!.github/workflows/ci.yml" - "!.github/workflows/ci.yml"
- .gitignore - ".gitignore"
- "docs/**" - "docs/**"
- README.md - "README.md"
- LICENSE - "LICENSE"
pull_request: pull_request:
paths-ignore:
- ".github/**"
- "!.github/workflows/ci.yml"
- .gitignore
- "docs/**"
- README.md
- LICENSE
jobs: jobs:
build: build:

View file

@ -1,11 +1,5 @@
name: Lint Commit Messages name: Lint Commit Messages
on: pull_request
on:
push:
branches:
- master
- "hotfix/*"
pull_request:
jobs: jobs:
commitlint: commitlint:

View file

@ -1,25 +0,0 @@
name: PR Filter
on:
pull_request_target:
types: [opened, reopened]
jobs:
check-template:
if: github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Check PR Content
id: intercept
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const script = require('.github/workflows/scripts/pr-filter.js');
await script({ github, context, core });

View file

@ -10,7 +10,6 @@ on:
required: true required: true
BUILDER: BUILDER:
required: true required: true
workflow_dispatch:
jobs: jobs:
launch: launch:

View file

@ -1,36 +0,0 @@
function hasTypes(markdown) {
return /## Type of change/.test(markdown) && /-\s\[x\]/i.test(markdown);
}
function hasDescription(markdown) {
return (
/## Description/.test(markdown) &&
!/## Description\s*\n\s*(##|\s*$)/.test(markdown)
);
}
module.exports = async ({ github, context, core }) => {
const pr = context.payload.pull_request;
const body = pr.body === null ? '' : pr.body;
const markdown = body.replace(/<!--[\s\S]*?-->/g, '');
const action = context.payload.action;
const isValid =
markdown !== '' && hasTypes(markdown) && hasDescription(markdown);
if (!isValid) {
await github.rest.pulls.update({
...context.repo,
pull_number: pr.number,
state: 'closed'
});
await github.rest.issues.createComment({
...context.repo,
issue_number: pr.number,
body: `Oops, it seems you've ${action} an invalid pull request. No worries, we'll close it for you.`
});
core.setFailed('PR content does not meet template requirements.');
}
};

View file

@ -9,7 +9,7 @@ permissions:
pull-requests: write pull-requests: write
env: env:
STALE_LABEL: inactive STALE_LABEL: stale
EXEMPT_LABELS: "pending,planning,in progress" EXEMPT_LABELS: "pending,planning,in progress"
MESSAGE: > MESSAGE: >
This conversation has been automatically marked as stale because it has not had recent activity. This conversation has been automatically marked as stale because it has not had recent activity.

View file

@ -1,10 +1,8 @@
name: Style Lint name: "Style Lint"
on: on:
push: push:
branches: branches: ["master", "hotfix/**"]
- master
- "hotfix/*"
paths: ["_sass/**/*.scss"] paths: ["_sass/**/*.scss"]
pull_request: pull_request:
paths: ["_sass/**/*.scss"] paths: ["_sass/**/*.scss"]

View file

@ -11,4 +11,4 @@ platforms :mingw, :x64_mingw, :mswin, :jruby do
gem "tzinfo-data" gem "tzinfo-data"
end end
gem "wdm", "~> 0.2.0", :platforms => [:mingw, :x64_mingw, :mswin] gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]

View file

@ -2,21 +2,26 @@
* Expand or close the sidebar in mobile screens. * Expand or close the sidebar in mobile screens.
*/ */
const $sidebar = document.getElementById('sidebar'); const ATTR_DISPLAY = 'sidebar-display';
const $trigger = document.getElementById('sidebar-trigger');
const $mask = document.getElementById('mask');
class SidebarUtil { class SidebarUtil {
static #isExpanded = false; static isExpanded = false;
static toggle() { static toggle() {
this.#isExpanded = !this.#isExpanded; if (SidebarUtil.isExpanded === false) {
document.body.toggleAttribute('sidebar-display', this.#isExpanded); document.body.setAttribute(ATTR_DISPLAY, '');
$sidebar.classList.toggle('z-2', this.#isExpanded); } else {
$mask.classList.toggle('d-none', !this.#isExpanded); document.body.removeAttribute(ATTR_DISPLAY);
}
SidebarUtil.isExpanded = !SidebarUtil.isExpanded;
} }
} }
export function sidebarExpand() { export function sidebarExpand() {
$trigger.onclick = $mask.onclick = () => SidebarUtil.toggle(); document
.getElementById('sidebar-trigger')
.addEventListener('click', SidebarUtil.toggle);
document.getElementById('mask').addEventListener('click', SidebarUtil.toggle);
} }

View file

@ -5,10 +5,7 @@ const desktopMode = matchMedia('(min-width: 1200px)');
function refresh(e) { function refresh(e) {
if (e.matches) { if (e.matches) {
if (mobile.popupOpened) { mobile.hidePopup();
mobile.hidePopup();
}
desktop.refresh(); desktop.refresh();
} else { } else {
mobile.refresh(); mobile.refresh();

View file

@ -12,8 +12,8 @@ const SCROLL_LOCK = 'overflow-hidden';
const CLOSING = 'closing'; const CLOSING = 'closing';
export class TocMobile { export class TocMobile {
static #invisible = true; static invisible = true;
static #barHeight = 16 * 3; // 3rem static barHeight = 16 * 3; // 3rem
static options = { static options = {
tocSelector: '#toc-popup-content', tocSelector: '#toc-popup-content',
@ -23,7 +23,7 @@ export class TocMobile {
orderedList: false, orderedList: false,
scrollSmooth: false, scrollSmooth: false,
collapseDepth: 4, collapseDepth: 4,
headingsOffset: this.#barHeight headingsOffset: this.barHeight
}; };
static initBar() { static initBar() {
@ -33,40 +33,44 @@ export class TocMobile {
$tocBar.classList.toggle('invisible', entry.isIntersecting); $tocBar.classList.toggle('invisible', entry.isIntersecting);
}); });
}, },
{ rootMargin: `-${this.#barHeight}px 0px 0px 0px` } { rootMargin: `-${this.barHeight}px 0px 0px 0px` }
); );
observer.observe($soloTrigger); observer.observe($soloTrigger);
this.#invisible = false; this.invisible = false;
} }
static listenAnchors() { static listenAnchors() {
const $anchors = document.getElementsByClassName('toc-link'); const $anchors = document.getElementsByClassName('toc-link');
[...$anchors].forEach((anchor) => { [...$anchors].forEach((anchor) => {
anchor.onclick = () => this.hidePopup(); anchor.onclick = this.hidePopup;
}); });
} }
static refresh() { static refresh() {
if (this.#invisible) { if (this.invisible) {
this.initComponents(); this.initComponents();
} }
tocbot.refresh(this.options); tocbot.refresh(this.options);
this.listenAnchors(); this.listenAnchors();
} }
static get popupOpened() {
return $popup.open;
}
static showPopup() { static showPopup() {
this.lockScroll(true); TocMobile.lockScroll(true);
$popup.showModal(); $popup.showModal();
const activeItem = $popup.querySelector('li.is-active-li'); const activeItem = $popup.querySelector('li.is-active-li');
activeItem.scrollIntoView({ block: 'center' }); activeItem.scrollIntoView({ block: 'center' });
} }
static hidePopup() { static hidePopup(event) {
if (event?.type === 'cancel') {
event.preventDefault();
}
if (!$popup.open) {
return;
}
$popup.toggleAttribute(CLOSING); $popup.toggleAttribute(CLOSING);
$popup.addEventListener( $popup.addEventListener(
@ -78,7 +82,7 @@ export class TocMobile {
{ once: true } { once: true }
); );
this.lockScroll(false); TocMobile.lockScroll(false);
} }
static lockScroll(enable) { static lockScroll(enable) {
@ -87,10 +91,6 @@ export class TocMobile {
} }
static clickBackdrop(event) { static clickBackdrop(event) {
if ($popup.hasAttribute(CLOSING)) {
return;
}
const rect = event.target.getBoundingClientRect(); const rect = event.target.getBoundingClientRect();
if ( if (
event.clientX < rect.left || event.clientX < rect.left ||
@ -98,7 +98,7 @@ export class TocMobile {
event.clientY < rect.top || event.clientY < rect.top ||
event.clientY > rect.bottom event.clientY > rect.bottom
) { ) {
this.hidePopup(); TocMobile.hidePopup();
} }
} }
@ -106,15 +106,11 @@ export class TocMobile {
this.initBar(); this.initBar();
[...$triggers].forEach((trigger) => { [...$triggers].forEach((trigger) => {
trigger.onclick = () => this.showPopup(); trigger.onclick = this.showPopup;
}); });
$popup.onclick = (e) => this.clickBackdrop(e); $popup.onclick = this.clickBackdrop;
$btnClose.onclick = () => this.hidePopup(); $btnClose.onclick = $popup.oncancel = this.hidePopup;
$popup.oncancel = (e) => {
e.preventDefault();
this.hidePopup();
};
} }
static init() { static init() {

View file

@ -68,7 +68,7 @@ layout: compress
</aside> </aside>
</div> </div>
<div id="mask" class="d-none position-fixed w-100 h-100 z-1"></div> <div id="mask"></div>
{% if site.pwa.enabled %} {% if site.pwa.enabled %}
{% include_cached notification.html lang=lang %} {% include_cached notification.html lang=lang %}

View file

@ -100,7 +100,7 @@ tail_includes:
{% if enable_toc %} {% if enable_toc %}
<div id="toc-bar" class="d-flex align-items-center justify-content-between invisible"> <div id="toc-bar" class="d-flex align-items-center justify-content-between invisible">
<span class="label text-truncate">{{ page.title }}</span> <span class="label text-truncate">{{ page.title }}</span>
<button type="button" class="toc-trigger btn me-1"> <button type="button" class="toc-trigger btn btn-link me-1">
<i class="fa-solid fa-list-ul fa-fw"></i> <i class="fa-solid fa-list-ul fa-fw"></i>
</button> </button>
</div> </div>
@ -113,8 +113,8 @@ tail_includes:
<dialog id="toc-popup" class="p-0"> <dialog id="toc-popup" class="p-0">
<div class="header d-flex flex-row align-items-center justify-content-between"> <div class="header d-flex flex-row align-items-center justify-content-between">
<div class="label text-truncate py-2 ms-4">{{- page.title -}}</div> <div class="label text-truncate py-2 ms-4">{{- page.title -}}</div>
<button id="toc-popup-close" type="button" class="btn mx-1 my-1 opacity-75"> <button id="toc-popup-close" type="button" class="btn btn-link">
<i class="fas fa-close"></i> <i class="fas fa-close fa-fw"></i>
</button> </button>
</div> </div>
<div id="toc-popup-content" class="px-4 py-3 pb-4"></div> <div id="toc-popup-content" class="px-4 py-3 pb-4"></div>

View file

@ -251,8 +251,8 @@ i {
> p { > p {
margin-left: 0.25em; margin-left: 0.25em;
margin-top: 0;
@include mt-mb(0); margin-bottom: 0;
} }
} }
} }
@ -688,6 +688,7 @@ $btn-mb: 0.5rem;
height: 100%; height: 100%;
overflow-y: auto; overflow-y: auto;
width: $sidebar-width; width: $sidebar-width;
z-index: 99;
background: var(--sidebar-bg); background: var(--sidebar-bg);
border-right: 1px solid var(--sidebar-border-color); border-right: 1px solid var(--sidebar-border-color);
@ -768,8 +769,8 @@ $btn-mb: 0.5rem;
li.nav-item { li.nav-item {
opacity: 0.9; opacity: 0.9;
width: 100%; width: 100%;
padding-left: 1.5rem;
@include pl-pr(1.5rem); padding-right: 1.5rem;
a.nav-link { a.nav-link {
@include pt-pb(0.6rem); @include pt-pb(0.6rem);
@ -1042,7 +1043,7 @@ search {
a { a {
font-size: 1.4rem; font-size: 1.4rem;
line-height: 1.5rem; line-height: 2.5rem;
&:hover { &:hover {
@extend %link-hover; @extend %link-hover;
@ -1068,9 +1069,8 @@ search {
} }
> p { > p {
@extend %text-ellipsis; overflow: hidden;
text-overflow: ellipsis;
white-space: break-spaces;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
@ -1086,11 +1086,23 @@ search {
color: var(--topbar-text-color); color: var(--topbar-text-color);
text-align: center; text-align: center;
width: 70%; width: 70%;
overflow: hidden;
text-overflow: ellipsis;
word-break: keep-all; word-break: keep-all;
white-space: nowrap;
} }
#mask { #mask {
display: none;
position: fixed;
inset: 0 0 0 0; inset: 0 0 0 0;
height: 100%;
width: 100%;
z-index: 1;
@at-root [#{$sidebar-display}] & {
display: block !important;
}
} }
/* --- basic wrappers --- */ /* --- basic wrappers --- */
@ -1480,8 +1492,8 @@ search {
#main-wrapper > .container { #main-wrapper > .container {
max-width: $main-content-max-width; max-width: $main-content-max-width;
padding-left: 1.75rem !important;
@include pl-pr(1.75rem, true); padding-right: 1.75rem !important;
} }
main.col-12, main.col-12,

View file

@ -112,16 +112,6 @@
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
@mixin text-ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
%text-ellipsis {
@include text-ellipsis;
}
%text-highlight { %text-highlight {
color: var(--text-muted-highlight-color); color: var(--text-muted-highlight-color);
font-weight: 600; font-weight: 600;
@ -168,14 +158,9 @@
padding-bottom: $val; padding-bottom: $val;
} }
@mixin pl-pr($val, $important: false) { @mixin pl-pr($val) {
@if $important { padding-left: $val;
padding-left: $val !important; padding-right: $val;
padding-right: $val !important;
} @else {
padding-left: $val;
padding-right: $val;
}
} }
@mixin placeholder { @mixin placeholder {

View file

@ -58,8 +58,9 @@
li { li {
font-size: 1.1rem; font-size: 1.1rem;
line-height: 3rem; line-height: 3rem;
white-space: nowrap;
@extend %text-ellipsis; overflow: hidden;
text-overflow: ellipsis;
&:nth-child(odd) { &:nth-child(odd) {
background-color: var(--main-bg, #ffffff); background-color: var(--main-bg, #ffffff);

View file

@ -63,7 +63,9 @@
} }
> a { > a {
@include text-ellipsis; white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
} }
} }

View file

@ -74,8 +74,9 @@
> div:first-child { > div:first-child {
display: block; display: block;
white-space: nowrap;
@extend %text-ellipsis; overflow: hidden;
text-overflow: ellipsis;
} }
} }
} }

View file

@ -1,6 +1,6 @@
/** /*
* Post-specific styles Post-specific style
*/ */
%btn-post-nav { %btn-post-nav {
width: 50%; width: 50%;
@ -97,7 +97,7 @@ header {
&:hover { &:hover {
i { i {
@extend %btn-share-hover; @extend %btn-share-hovor;
} }
} }
} }
@ -258,8 +258,9 @@ header {
.toc-link { .toc-link {
display: block; display: block;
white-space: nowrap;
@extend %text-ellipsis; overflow: hidden;
text-overflow: ellipsis;
&:hover { &:hover {
color: var(--toc-highlight); color: var(--toc-highlight);
@ -379,13 +380,12 @@ header {
$slide-in: slide-in 0.3s ease-out; $slide-in: slide-in 0.3s ease-out;
$slide-out: slide-out 0.3s ease-out; $slide-out: slide-out 0.3s ease-out;
$curtain-height: 2rem; $curtain-height: 2rem;
$backdrop: blur(5px);
border-color: var(--toc-popup-border-color); border-color: var(--toc-popup-border-color);
border-width: 1px; border-width: 1px;
border-radius: $radius-lg; border-radius: $radius-lg;
color: var(--text-color); color: var(--text-color);
background: var(--card-bg); background: var(--main-bg);
margin-top: $topbar-height; margin-top: $topbar-height;
min-width: 20rem; min-width: 20rem;
font-size: 1.05rem; font-size: 1.05rem;
@ -422,15 +422,8 @@ header {
} }
} }
button { button:focus-visible {
> i { box-shadow: none;
font-size: 1.25rem;
vertical-align: middle;
}
&:focus-visible {
box-shadow: none;
}
} }
ul { ul {
@ -468,20 +461,20 @@ header {
} }
&::-webkit-backdrop { &::-webkit-backdrop {
-webkit-backdrop-filter: $backdrop; -webkit-backdrop-filter: blur(5px);
backdrop-filter: $backdrop; backdrop-filter: blur(5px);
} }
&::backdrop { &::backdrop {
-webkit-backdrop-filter: $backdrop; -webkit-backdrop-filter: blur(5px);
backdrop-filter: $backdrop; backdrop-filter: blur(5px);
} }
&::after { &::after {
display: flex; display: flex;
content: ''; content: '';
position: relative; position: relative;
background: linear-gradient(transparent, var(--card-bg) 70%); background: linear-gradient(transparent, var(--main-bg) 70%);
height: $curtain-height; height: $curtain-height;
} }
@ -508,11 +501,10 @@ header {
} }
p { p {
@extend %text-ellipsis;
font-size: 0.9rem; font-size: 0.9rem;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
white-space: break-spaces; overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box; display: -webkit-box;
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
@ -534,7 +526,7 @@ header {
max-width: 100%; max-width: 100%;
} }
%btn-share-hover { %btn-share-hovor {
color: var(--btn-share-hover-color) !important; color: var(--btn-share-hover-color) !important;
} }
@ -566,8 +558,10 @@ header {
/* Hide SideBar and TOC */ /* Hide SideBar and TOC */
@media all and (max-width: 849px) { @media all and (max-width: 849px) {
.post-navigation { .post-navigation {
@include pl-pr(0); padding-left: 0;
@include ml-mr(-0.5rem); padding-right: 0;
margin-left: -0.5rem;
margin-right: -0.5rem;
} }
} }

View file

@ -34,7 +34,7 @@ permalink: /feed.xml
<updated>{{ post.date | date_to_xmlschema }}</updated> <updated>{{ post.date | date_to_xmlschema }}</updated>
{% endif %} {% endif %}
<id>{{ post_absolute_url }}</id> <id>{{ post_absolute_url }}</id>
<content type="text/html" src="{{ post_absolute_url }}" /> <content src="{{ post_absolute_url }}" />
<author> <author>
<name>{{ post.author | default: site.social.name }}</name> <name>{{ post.author | default: site.social.name }}</name>
</author> </author>