xfy 70edc5e46c feat(frontend): mermaid 流程图懒加载渲染
mermaid 无官方 SSR 支持,采用客户端 IntersectionObserver 懒加载:服务端
markdown.rs 只产出普通 <pre><code class="language-mermaid"> 代码块,
前端在块进视口时动态 import 独立 bundle(~1MB)渲染成 SVG。

新增 libs/mermaid-renderer/:mermaid 11.16 IIFE bundle,输出 public/mermaid/
yggdrasil-core/mermaid.ts:扫描 language-mermaid 块,视口可见时动态 import
  /mermaid/mermaid.js(单例缓存),mermaid.initialize 适配 light/dark 主题,
  securityLevel=strict;渲染失败加 .mermaid-error class 保留源码;幂等守卫
post-content.ts:initCopyButtons 跳过 language-mermaid 块(图无需 copy)
post_content.rs:use_effect 调 __initMermaid('.post-content', theme),
  读 use_resolved_theme() 传主题并建立订阅

新增 6 个 mermaid 单测(扫描/主题/幂等/非mermaid/未命中/错误回退)。
550 Rust + 28 前端测试全过,双 target 编译通过。
2026-07-16 14:22:43 +08:00

26 lines
948 B
TypeScript

import { initAnchorClick } from './anchor-click';
import { scrollToHash } from './hash-scroll';
import { initMermaid } from './mermaid';
import { initPostContent } from './post-content';
import { applyResolvedTheme, startThemeTransition } from './theme-transition';
import type { ThemeName } from '@yggdrasil/shared';
import './style.css';
declare global {
interface Window {
__initPostContent: (selector: string) => void;
__initMermaid: (selector: string, theme: ThemeName) => void;
__initAnchorClick: () => void;
__scrollToHash: () => void;
__startThemeTransition: (x: number, y: number) => void;
__applyResolvedTheme: (isDark: boolean) => void;
}
}
window.__initPostContent = initPostContent;
window.__initMermaid = initMermaid;
window.__initAnchorClick = initAnchorClick;
window.__scrollToHash = scrollToHash;
window.__startThemeTransition = startThemeTransition;
window.__applyResolvedTheme = applyResolvedTheme;