fix(frontend): 修复 aardio 注释着色、代码行距与折叠 hydration

注释不再被运算符拆开;去掉 grid 行 min-height;挂载后再折叠以避免 SSR/CSR 不一致。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-16 06:25:25 +08:00
parent 8d5e00a112
commit 2dd9cb82b3
4 changed files with 90 additions and 25 deletions

View File

@@ -1,5 +1,6 @@
import { createHighlighterCore, type HighlighterCore } from "shiki/core";
import { createOnigurumaEngine } from "shiki/engine/oniguruma";
import type { LanguageRegistration } from "shiki";
import { aardioGrammar } from "./aardioGrammar";
/** 站点 Markdown 代码高亮:显式白名单(非全量) */
@@ -108,9 +109,36 @@ export async function siteCodeToHtml(code: string, langRaw?: string | null): Pro
}
/**
* 供 rehype-pretty-code 的 getHighlighter:
* 忽略其默认 langs:['plaintext'],始终返回站点白名单单例。
* rehype-pretty-code 会对每个 fence 调用 loadLanguage(langId: string)。
* HighlighterCore 不能把裸 string 当 grammar(会 TypeError 并可能搞坏注册表),
* 这里包装:已装载的语言直接跳过。
*/
export async function getPrettyCodeHighlighter(): Promise<HighlighterCore> {
return getSiteHighlighter();
const core = await getSiteHighlighter();
const loadLanguage = async (
...langs: (string | LanguageRegistration | Promise<LanguageRegistration>)[]
) => {
const pending: (LanguageRegistration | Promise<LanguageRegistration>)[] = [];
const loaded = new Set(core.getLoadedLanguages());
for (const lang of langs.flat()) {
if (typeof lang === "string") {
const id = resolveShikiLang(lang);
if (loaded.has(lang) || loaded.has(id) || id === "plaintext") continue;
continue;
}
pending.push(lang);
}
if (pending.length > 0) {
await core.loadLanguage(...pending);
}
};
return new Proxy(core, {
get(target, prop, receiver) {
if (prop === "loadLanguage") return loadLanguage;
const value = Reflect.get(target, prop, receiver);
return typeof value === "function" ? value.bind(target) : value;
},
}) as HighlighterCore;
}