bugfix1001.2

星引擎Party已发行!
欢迎来到Star Engine 星引擎 WIKI
点击成为魔法少女!

全站通知:

Widget:Mathjax

来自星引擎WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索
   <script>
       (() => {
           console.log('[MathJax] 开始监控 MathJax 状态');
           // 1. 仅配置日志相关的部分
           window.MathJax = {
               startup: {
                   pageReady: () => {
                       console.log('[MathJax] 页面准备就绪,开始初始化');
                       return MathJax.startup.defaultPageReady();
                   }
               }
               ,
               options: {
                   renderActions: {
                       addMenu: [],
                       checkLoading: [],
                       typeset: []
                   }
               }
           }
               ;
           // 2. 监听 MathJax 全局事件
           const originalOnLoad = window.onload;
           window.onload = function () {
               console.log('[MathJax] 窗口加载完成');
               if (originalOnLoad) originalOnLoad.apply(this, arguments);
           }
               ;
           // 3. 检查是否已存在 MathJax
           if (window.MathJax && window.MathJax.version) {
               console.log('[MathJax] MathJax 已预先加载,版本:', window.MathJax.version);
           } else {
               console.log('[MathJax] 等待 MathJax 加载');
           }
           // 4. 设置 MutationObserver 监控 MathJax 脚本加载
           const observer = new MutationObserver((mutations) => {
               mutations.forEach((mutation) => {
                   mutation.addedNodes.forEach((node) => {
                       if (node.tagName === 'SCRIPT' && node.src && node.src.includes('mathjax')) {
                           console.log('[MathJax] 检测到 MathJax 脚本标签:', node.src);
                           // 监听脚本加载事件
                           node.addEventListener('load', () => {
                               console.log('[MathJax] MathJax 脚本加载成功');
                               if (window.MathJax && window.MathJax.startup) {
                                   console.log('[MathJax] MathJax 实例创建成功');
                               }
                           });
                           node.addEventListener('error', () => {
                               console.error('[MathJax] MathJax 脚本加载失败');
                               main();
                           });
                       }
                   });
               });
           });
           // 开始监控 document.head
           observer.observe(document.head, {
               childList: true
           });
           console.log('[MathJax] 监控器已启动');
       })();
       const main = () => {
           // 轮询配置
           const POLL_INTERVAL = 500;
           const MAX_POLL_TIMES = 5;
           let currentPollTimes = 0;
           let isRendering = false;
           // 新增:标记“首次渲染是否完成”,避免初始监听触发重复渲染
           let isFirstRenderDone = false;
           /**
            * 核心判断逻辑:区分「未渲染公式」和「已渲染公式」
            */
           function checkMathJaxStatus() {
               const rawMathElements = document.querySelectorAll('[math]:not(.mathjax-rendered), .mw-math-element:not(.mathjax-rendered)');
               const hasLatexText = Array.from(document.querySelectorAll('#mw-content-text *')).filter(node => !node.classList.contains('MathJax') && !node.classList.contains('mjx-chtml')).some(node => node.textContent && (node.textContent.includes('\\(') || node.textContent.includes('\\)') || node.textContent.includes('$$') || node.textContent.includes('\\[') || node.textContent.includes('\\]')));
               return rawMathElements.length > 0 || hasLatexText;
           }
           /**
            * 等待模块从loading/loaded变为ready
            */
           function waitForModuleReady() {
               return new Promise((resolve) => {
                   const pollModule = () => {
                       const moduleState = mw.loader.getState('ext.SimpleMathJax');
                       if (moduleState === 'ready') {
                           resolve(true);
                           return;
                       }
                       if (currentPollTimes >= MAX_POLL_TIMES) {
                           console.warn('ext.SimpleMathJax 模块等待超时');
                           resolve(false);
                           return;
                       }
                       currentPollTimes++;
                       setTimeout(pollModule, POLL_INTERVAL);
                   }
                       ;
                   pollModule();
               });
           }
           /**
            * 执行MathJax重新初始化(含防重复、渲染后标记)
            */
           async function reInitMathJax() {
               // 强化防重复:进入函数立即上锁,杜绝并发
               if (isRendering) return;
               isRendering = true;
               try {
                   // 第一步:检查是否有未渲染公式(无则直接退出)
                   const hasUnrenderedMath = checkMathJaxStatus();
                   if (!hasUnrenderedMath) {
                       isRendering = false;
                       return;
                   }
                   const moduleState = mw.loader.getState('ext.SimpleMathJax');
                   console.log(`ext.SimpleMathJax 当前状态:${moduleState}`);
                   if (moduleState === 'registered' || moduleState === null) {
                       await mw.loader.load('ext.SimpleMathJax');
                   } else if (moduleState === 'loading' || moduleState === 'loaded') {
                       const isReady = await waitForModuleReady();
                       if (!isReady) {
                           isRendering = false;
                           return;
                       }
                   }
                   // 第二步:触发渲染
                   const contentContainer = document.getElementById('mw-content-text') || document.body;
                   mw.hook('wikipage.categories').fire(contentContainer);
                   if (window.MathJax && typeof MathJax.typeset === 'function') {
                       MathJax.typeset([contentContainer]);
                   }
                   // 第三步:标记已渲染(提前到渲染后立即执行)
                   document.querySelectorAll('[math], .mw-math-element').forEach(node => {
                       node.classList.add('mathjax-rendered');
                   });
                   // 标记首次渲染完成
                   isFirstRenderDone = true;
                   console.log('MathJax 渲染完成');
               } catch (err) {
                   console.error('SimpleMathJax 加载/渲染失败:', err);
               } finally {
                   isRendering = false;
                   currentPollTimes = 0;
               }
           }
           function init() {
               // 首次执行:主动触发一次渲染
               reInitMathJax();
               // 优化监听逻辑:过滤初始触发 + 仅监听“新增含公式的内容”
               const observer = new MutationObserver((mutations) => {
                   // 跳过首次渲染完成前的初始触发
                   if (!isFirstRenderDone) return;
                   // 严格过滤:仅当新增节点包含公式相关内容时,才触发渲染
                   let needRender = false;
                   mutations.forEach(mutation => {
                       // 1. 新增节点:检查是否包含未渲染的公式节点
                       if (mutation.addedNodes.length > 0) {
                           Array.from(mutation.addedNodes).forEach(node => {
                               if (node.nodeType === 1) {
                                   // 元素节点
                                   const hasMathNode = node.querySelector('[math], .mw-math-element, .latex');
                                   const hasLatexText = node.textContent && (node.textContent.includes('\\(') || node.textContent.includes('$$'));
                                   if (hasMathNode || hasLatexText) {
                                       needRender = true;
                                   }
                               }
                           });
                       }
                       // 2. 文本变化:仅当文本包含LaTeX语法时触发
                       if (mutation.type === 'characterData' && mutation.target.textContent) {
                           const text = mutation.target.textContent;
                           if (text.includes('\\(') || text.includes('$$') || text.includes('\\[')) {
                               needRender = true;
                           }
                       }
                   });
                   // 仅当确实需要渲染时,才执行
                   if (needRender) {
                       reInitMathJax();
                   }
               });
               // 监听内容区域变化
               observer.observe(document.getElementById('mw-content-text') || document.body, {
                   childList: true,
                   subtree: true,
                   characterData: true
               });
           }
           // DOM就绪后启动
           if (document.readyState === 'complete' || document.readyState === 'interactive') {
               init();
           } else {
               document.addEventListener('DOMContentLoaded', init);
           }
       };
   </script>