feat: initial support for add clickable title.

This commit is contained in:
Yufan Sheng 2024-09-26 17:07:00 +08:00
parent 6269540bc8
commit d2d42e7c1d
Signed by: syhily
GPG Key ID: 9D18A22A7DCD5A9B
7 changed files with 121 additions and 21 deletions

View File

@ -81,6 +81,7 @@
"luoli", "luoli",
"luxon", "luxon",
"mboker", "mboker",
"microflash",
"minagi", "minagi",
"miui", "miui",
"mmwebid", "mmwebid",

View File

@ -2,7 +2,9 @@ import mdx from '@astrojs/mdx';
import zeabur from '@zeabur/astro-adapter/serverless'; import zeabur from '@zeabur/astro-adapter/serverless';
import { uploader } from 'astro-uploader'; import { uploader } from 'astro-uploader';
import { defineConfig, envField } from 'astro/config'; import { defineConfig, envField } from 'astro/config';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import rehypeExternalLinks from 'rehype-external-links'; import rehypeExternalLinks from 'rehype-external-links';
import rehypeSlug from 'rehype-slug';
import options from './options'; import options from './options';
import { astroImage } from './plugins/images'; import { astroImage } from './plugins/images';
@ -38,7 +40,11 @@ export default defineConfig({
integrations: [ integrations: [
mdx({ mdx({
remarkPlugins: [astroImage], remarkPlugins: [astroImage],
rehypePlugins: [[rehypeExternalLinks, { rel: 'nofollow', target: '_blank' }]], rehypePlugins: [
[rehypeExternalLinks, { rel: 'nofollow', target: '_blank' }],
rehypeSlug,
[rehypeAutolinkHeadings, { behavior: 'append', properties: {} }],
],
}), }),
uploader({ uploader({
paths: ['images', 'og', 'cats'], paths: ['images', 'og', 'cats'],

67
package-lock.json generated
View File

@ -39,7 +39,9 @@
"prettier-plugin-astro": "^0.14.1", "prettier-plugin-astro": "^0.14.1",
"prettier-plugin-astro-organize-imports": "^0.4.9", "prettier-plugin-astro-organize-imports": "^0.4.9",
"prettier-plugin-organize-imports": "^4.1.0", "prettier-plugin-organize-imports": "^4.1.0",
"rehype-autolink-headings": "^7.1.0",
"rehype-external-links": "^3.0.0", "rehype-external-links": "^3.0.0",
"rehype-slug": "^6.0.0",
"resize-sensor": "^0.0.6", "resize-sensor": "^0.0.6",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"sharp": "^0.33.5", "sharp": "^0.33.5",
@ -4663,6 +4665,20 @@
"url": "https://opencollective.com/unified" "url": "https://opencollective.com/unified"
} }
}, },
"node_modules/hast-util-heading-rank": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/hast-util-heading-rank/-/hast-util-heading-rank-3.0.0.tgz",
"integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-is-element": { "node_modules/hast-util-is-element": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz",
@ -4826,6 +4842,20 @@
"url": "https://opencollective.com/unified" "url": "https://opencollective.com/unified"
} }
}, },
"node_modules/hast-util-to-string": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.0.tgz",
"integrity": "sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/hast-util-to-text": { "node_modules/hast-util-to-text": {
"version": "4.0.2", "version": "4.0.2",
"resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz",
@ -7556,6 +7586,25 @@
"url": "https://opencollective.com/unified" "url": "https://opencollective.com/unified"
} }
}, },
"node_modules/rehype-autolink-headings": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/rehype-autolink-headings/-/rehype-autolink-headings-7.1.0.tgz",
"integrity": "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0",
"@ungap/structured-clone": "^1.0.0",
"hast-util-heading-rank": "^3.0.0",
"hast-util-is-element": "^3.0.0",
"unified": "^11.0.0",
"unist-util-visit": "^5.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/rehype-external-links": { "node_modules/rehype-external-links": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/rehype-external-links/-/rehype-external-links-3.0.0.tgz", "resolved": "https://registry.npmjs.org/rehype-external-links/-/rehype-external-links-3.0.0.tgz",
@ -7605,6 +7654,24 @@
"url": "https://opencollective.com/unified" "url": "https://opencollective.com/unified"
} }
}, },
"node_modules/rehype-slug": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/rehype-slug/-/rehype-slug-6.0.0.tgz",
"integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/hast": "^3.0.0",
"github-slugger": "^2.0.0",
"hast-util-heading-rank": "^3.0.0",
"hast-util-to-string": "^3.0.0",
"unist-util-visit": "^5.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
}
},
"node_modules/rehype-stringify": { "node_modules/rehype-stringify": {
"version": "10.0.0", "version": "10.0.0",
"resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.0.tgz", "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.0.tgz",

View File

@ -72,7 +72,9 @@
"prettier-plugin-astro": "^0.14.1", "prettier-plugin-astro": "^0.14.1",
"prettier-plugin-astro-organize-imports": "^0.4.9", "prettier-plugin-astro-organize-imports": "^0.4.9",
"prettier-plugin-organize-imports": "^4.1.0", "prettier-plugin-organize-imports": "^4.1.0",
"rehype-autolink-headings": "^7.1.0",
"rehype-external-links": "^3.0.0", "rehype-external-links": "^3.0.0",
"rehype-slug": "^6.0.0",
"resize-sensor": "^0.0.6", "resize-sensor": "^0.0.6",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"sharp": "^0.33.5", "sharp": "^0.33.5",

View File

@ -242,14 +242,14 @@ if (typeof comments !== 'undefined' && comments !== null) {
} }
const scrollIntoView = (elem) => { const scrollIntoView = (elem) => {
let top = 0; if (elem === undefined || elem === null) {
return;
}
const rect = elem.getBoundingClientRect(); const rect = elem.getBoundingClientRect();
const elemTop = rect.top + window.scrollY; const elemTop = rect.top + window.scrollY;
top = elemTop - (window.innerHeight / 2 - rect.height / 2);
const scrollOptions = { const scrollOptions = {
top, top: elemTop,
left: 0, left: 0,
behavior: 'smooth', behavior: 'smooth',
}; };
@ -258,7 +258,7 @@ const scrollIntoView = (elem) => {
}; };
// Highlighting the selected comment. // Highlighting the selected comment.
const focusComment = () => { const focusContent = () => {
if (location.hash.startsWith('#atk-comment-')) { if (location.hash.startsWith('#atk-comment-')) {
for (const li of document.querySelectorAll('.comment-body')) { for (const li of document.querySelectorAll('.comment-body')) {
li.classList.remove('active'); li.classList.remove('active');
@ -269,10 +269,25 @@ const focusComment = () => {
scrollIntoView(li); scrollIntoView(li);
li.querySelector('.comment-body').classList.add('active'); li.querySelector('.comment-body').classList.add('active');
} }
} else {
// Try to find the ID on heading
if (location.hash.startsWith('#')) {
scrollIntoView(document.getElementById(decodeURIComponent(location.hash).substring(1)));
}
} }
}; };
window.addEventListener('hashchange', focusComment);
window.addEventListener('load', focusComment); window.addEventListener('load', focusContent);
// TOC Support
for (const anchor of document.querySelectorAll('a[href^="#"]')) {
anchor.addEventListener('click', (e) => {
e.preventDefault();
const href = anchor.getAttribute('href');
location.hash = `${href}`;
scrollIntoView(document.querySelector(anchor.getAttribute('href')));
});
}
// Add like button for updating likes. // Add like button for updating likes.
const likeButton = document.querySelector('button.post-like'); const likeButton = document.querySelector('button.post-like');

View File

@ -2427,6 +2427,26 @@ a:hover .overlay {
margin: 2rem 0 2rem; margin: 2rem 0 2rem;
} }
.post-content h1 a,
.post-content h2 a,
.post-content h3 a,
.post-content h4 a,
.post-content h5 a,
.post-content h6 a {
margin-left: 0.8rem;
text-decoration: none;
color: var(--color-muted);
}
.post-content h1 a:hover,
.post-content h2 a:hover,
.post-content h3 a:hover,
.post-content h4 a:hover,
.post-content h5 a:hover,
.post-content h6 a:hover {
color: var(--color-primary);
}
.post-content h2 { .post-content h2 {
position: relative; position: relative;
padding: 0 0 0 1.5rem; padding: 0 0 0 1.5rem;
@ -2511,12 +2531,6 @@ a:hover .overlay {
.post-content dd > a, .post-content dd > a,
.post-content td a, .post-content td a,
.post-content th a, .post-content th a,
.post-content h1 a,
.post-content h2 a,
.post-content h3 a,
.post-content h4 a,
.post-content h5 a,
.post-content h6 a,
.post-content em a, .post-content em a,
.post-content strong a { .post-content strong a {
-webkit-box-shadow: 0 -1px 0 0 var(--color-primary) inset; -webkit-box-shadow: 0 -1px 0 0 var(--color-primary) inset;
@ -2531,12 +2545,6 @@ a:hover .overlay {
.post-content dd > a:hover, .post-content dd > a:hover,
.post-content td a:hover, .post-content td a:hover,
.post-content th a:hover, .post-content th a:hover,
.post-content h1 a:hover,
.post-content h2 a:hover,
.post-content h3 a:hover,
.post-content h4 a:hover,
.post-content h5 a:hover,
.post-content h6 a:hover,
.post-content em a:hover, .post-content em a:hover,
.post-content strong a:hover { .post-content strong a:hover {
opacity: 1; opacity: 1;

View File

@ -6,7 +6,8 @@
url('iconfont.ttf?t=1629473213677') format('truetype'); url('iconfont.ttf?t=1629473213677') format('truetype');
} }
.iconfont { .iconfont,
.icon {
font-family: 'iconfont' !important; font-family: 'iconfont' !important;
font-style: normal; font-style: normal;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;