/** * 数学公式渲染系统 - 全局配置 * 适用于 Laravel + Livewire + Filament */ (function() { 'use strict'; // 全局配置 window.MathRenderConfig = { attempts: 0, maxAttempts: 50, delay: 100, selector: '.math-text', autoInit: true }; // 渲染单个数学元素 window.renderMathElement = function(element) { if (!element) return; // 避免重复渲染 if (element.dataset.rendered === 'true') { return; } // 确保 KaTeX 已加载 if (typeof window.katex === 'undefined') { if (window.MathRenderConfig.attempts < window.MathRenderConfig.maxAttempts) { window.MathRenderConfig.attempts++; setTimeout(() => { window.renderMathElement(element); }, window.MathRenderConfig.delay); } return; } try { const content = element.dataset.mathContent || element.textContent; if (!content) return; let html = content; // 渲染 $$...$$ 块级公式 html = html.replace(/\$\$([\s\S]*?)\$\$/g, (match, formula) => { try { return window.katex.renderToString(formula.trim(), { throwOnError: false, displayMode: true }); } catch (e) { console.warn('[KaTeX] Render error for block formula:', e); return match; } }); // 渲染 \[...\] 块级公式 html = html.replace(/\\\[([\s\S]*?)\\\]/g, (match, formula) => { try { return window.katex.renderToString(formula.trim(), { throwOnError: false, displayMode: true }); } catch (e) { console.warn('[KaTeX] Render error for block formula:', e); return match; } }); // 渲染 $...$ 行内公式 html = html.replace(/\$(.*?)\$/g, (match, formula) => { try { return window.katex.renderToString(formula, { throwOnError: false, displayMode: false }); } catch (e) { console.warn('[KaTeX] Render error for inline formula:', e); return match; } }); // 渲染 \(...\) 行内公式 html = html.replace(/\\\((.*?)\\\)/g, (match, formula) => { try { return window.katex.renderToString(formula, { throwOnError: false, displayMode: false }); } catch (e) { console.warn('[KaTeX] Render error for inline formula:', e); return match; } }); element.innerHTML = html; element.dataset.rendered = 'true'; } catch (error) { console.error('[KaTeX] Render error:', error); } }; // 渲染所有数学元素 window.renderAllMath = function() { document.querySelectorAll(window.MathRenderConfig.selector).forEach(window.renderMathElement); window.MathRenderConfig.attempts = 0; }; // 手动触发渲染 window.triggerMathRender = function() { window.renderAllMath(); }; // DOM 加载完成初始化 function init() { if (!window.MathRenderConfig.autoInit) { return; } // 加载 KaTeX(如果尚未加载) if (typeof window.katex === 'undefined') { const script = document.createElement('script'); script.src = '/js/katex.min.js'; script.defer = true; script.onload = () => { console.log('[KaTeX] Loaded successfully'); window.renderAllMath(); }; script.onerror = () => { console.error('[KaTeX] Failed to load'); }; document.head.appendChild(script); } else { window.renderAllMath(); } } // 事件监听器 document.addEventListener('DOMContentLoaded', init); // Livewire 事件 document.addEventListener('livewire:initialized', () => { console.log('[MathRender] Livewire initialized'); window.renderAllMath(); }); document.addEventListener('livewire:navigated', () => { console.log('[MathRender] Livewire navigated'); setTimeout(window.renderAllMath, 100); }); document.addEventListener('livewire:updated', () => { console.log('[MathRender] Livewire updated'); setTimeout(window.renderAllMath, 100); }); // Alpine.js 事件 document.addEventListener('alpine:init', () => { console.log('[MathRender] Alpine initialized'); window.renderAllMath(); }); // 自定义事件 document.addEventListener('math:render', window.renderAllMath); document.addEventListener('math:render:force', () => { document.querySelectorAll(window.MathRenderConfig.selector).forEach(el => { delete el.dataset.rendered; }); window.renderAllMath(); }); // 表单验证后渲染 document.addEventListener('filament:form:validated', window.renderAllMath); // 全局暴露 window.MathRender = { render: window.renderMathElement, renderAll: window.renderAllMath, trigger: window.triggerMathRender, config: window.MathRenderConfig }; console.log('[MathRender] System initialized'); })();