(() => { // 单例模式:检查是否已经初始化过 if (window.mermaidInitialized) { return; } window.mermaidInitialized = true; // 记录当前主题状态,避免不必要的重新渲染 let currentTheme = null; let isRendering = false; // 防止并发渲染 let retryCount = 0; const MAX_RETRIES = 3; const RETRY_DELAY = 1000; // 1秒 // 检查主题是否真的发生了变化 function hasThemeChanged() { const isDark = document.documentElement.classList.contains("dark"); const newTheme = isDark ? "dark" : "default"; if (currentTheme !== newTheme) { currentTheme = newTheme; return true; } return false; } // 等待 Mermaid 库加载完成 function waitForMermaid(timeout = 10000) { return new Promise((resolve, reject) => { const startTime = Date.now(); function check() { if (window.mermaid && typeof window.mermaid.initialize === "function") { resolve(window.mermaid); } else if (Date.now() - startTime > timeout) { reject(new Error("Mermaid library failed to load within timeout")); } else { setTimeout(check, 100); } } check(); }); } // 设置 MutationObserver 监听 html 元素的 class 属性变化 function setupMutationObserver() { const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if ( mutation.type === "attributes" && mutation.attributeName === "class" ) { // 检查是否是 dark 类的变化 const target = mutation.target; const wasDark = mutation.oldValue ? mutation.oldValue.includes("dark") : false; const isDark = target.classList.contains("dark"); if (wasDark !== isDark) { if (hasThemeChanged()) { // 延迟渲染,避免主题切换时的闪烁 setTimeout(() => renderMermaidDiagrams(), 150); } } } }); }); // 开始观察 html 元素的 class 属性变化 observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"], attributeOldValue: true, }); } // 设置其他事件监听器 function setupEventListeners() { // 监听页面切换 document.addEventListener("astro:page-load", () => { // 重新初始化主题状态 currentTheme = null; retryCount = 0; // 重置重试计数 if (hasThemeChanged()) { setTimeout(() => renderMermaidDiagrams(), 100); } }); // 监听页面可见性变化,页面重新可见时重新渲染 document.addEventListener("visibilitychange", () => { if (!document.hidden) { setTimeout(() => renderMermaidDiagrams(), 200); } }); } async function initializeMermaid() { try { await waitForMermaid(); // 初始化 Mermaid 配置 window.mermaid.initialize({ startOnLoad: false, theme: "default", themeVariables: { fontFamily: "inherit", fontSize: "16px", }, securityLevel: "loose", // 添加错误处理配置 errorLevel: "warn", logLevel: "error", }); // 渲染所有 Mermaid 图表 await renderMermaidDiagrams(); } catch (error) { console.error("Failed to initialize Mermaid:", error); // 如果初始化失败,尝试重新加载 if (retryCount < MAX_RETRIES) { retryCount++; setTimeout(() => initializeMermaid(), RETRY_DELAY * retryCount); } } } async function renderMermaidDiagrams() { // 防止并发渲染 if (isRendering) { return; } // 检查 Mermaid 是否可用 if (!window.mermaid || typeof window.mermaid.render !== "function") { console.warn("Mermaid not available, skipping render"); return; } isRendering = true; try { const mermaidElements = document.querySelectorAll( ".mermaid[data-mermaid-code]", ); if (mermaidElements.length === 0) { isRendering = false; return; } // 延迟检测主题,确保 DOM 已经更新 await new Promise((resolve) => setTimeout(resolve, 100)); const htmlElement = document.documentElement; const isDark = htmlElement.classList.contains("dark"); const theme = isDark ? "dark" : "default"; // 更新 Mermaid 主题(只需要更新一次) window.mermaid.initialize({ startOnLoad: false, theme: theme, themeVariables: { fontFamily: "inherit", fontSize: "16px", // 强制应用主题变量 primaryColor: isDark ? "#ffffff" : "#000000", primaryTextColor: isDark ? "#ffffff" : "#000000", primaryBorderColor: isDark ? "#ffffff" : "#000000", lineColor: isDark ? "#ffffff" : "#000000", secondaryColor: isDark ? "#333333" : "#f0f0f0", tertiaryColor: isDark ? "#555555" : "#e0e0e0", }, securityLevel: "loose", errorLevel: "warn", logLevel: "error", }); // 批量渲染所有图表,添加重试机制 const renderPromises = Array.from(mermaidElements).map( async (element, index) => { let attempts = 0; const maxAttempts = 3; while (attempts < maxAttempts) { try { const code = element.getAttribute("data-mermaid-code"); if (!code) { break; } // 显示加载状态 element.innerHTML = '
Failed to render diagram after ${maxAttempts} attempts.