From 8f7165cedef8aab58ddbf65e1548261629d63d4e Mon Sep 17 00:00:00 2001 From: nanhaoluo <3075912108@qq.com> Date: Sun, 25 Jan 2026 12:54:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=20Mermaid=20?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=9D=97=E6=A3=80=E6=B5=8B=E5=87=BD=E6=95=B0?= =?UTF-8?q?=20-=20=E5=AE=9E=E7=8E=B0=20detectMermaidBlocks=20=E5=92=8C=20i?= =?UTF-8?q?sRendered=20=E5=87=BD=E6=95=B0=EF=BC=8C=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E4=B8=A4=E7=A7=8D=E6=A0=BC=E5=BC=8F=E7=9A=84=20Mermaid=20?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=9D=97=E5=B9=B6=E8=BF=87=E6=BB=A4=E5=B7=B2?= =?UTF-8?q?=E6=B8=B2=E6=9F=93=E7=9A=84=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .kiro/specs/mermaid-codeblock-magic/tasks.md | 309 +++++++++---------- argontheme.js | 67 ++-- 2 files changed, 191 insertions(+), 185 deletions(-) diff --git a/.kiro/specs/mermaid-codeblock-magic/tasks.md b/.kiro/specs/mermaid-codeblock-magic/tasks.md index c34c3e2..0ecb178 100644 --- a/.kiro/specs/mermaid-codeblock-magic/tasks.md +++ b/.kiro/specs/mermaid-codeblock-magic/tasks.md @@ -1,188 +1,183 @@ -# Mermaid 代码块魔改支持 - 任务列表 +# 实施计划:Mermaid 代码块渲染修复 ## 概述 -实现标准 Markdown 代码块 (` ```mermaid `) 的 Mermaid 图表渲染,通过在代码高亮之前拦截并转换代码块,完全绕过 WordPress 和代码高亮的干扰。 -## 任务列表 +本实施计划旨在修复 Argon WordPress 主题中 Mermaid 图表渲染的关键问题,并增强交互体验。 -### 1. 核心功能实现 +**实施策略:** +- 问题优先:优先修复 PJAX 渲染和语法错误问题 +- 功能完善:添加导出、全屏查看等功能 +- 体验优化:优化交互体验和视觉效果 +- 质量保证:确保代码质量和性能 -- [ ] 1.1 实现 `convertMermaidCodeblocks()` 函数 - - **需求**: 3.1 代码块拦截(核心功能) - - **位置**: `argontheme.js` 第 3942 行之前(`highlightJsRender()` 函数开始处) - - **功能**: - - 使用多个选择器查找 mermaid 代码块 - - 支持 `pre > code.language-mermaid`、`pre > code.mermaid`、`code.language-mermaid`、`pre[data-lang="mermaid"]` 格式 - - 提取纯文本代码(使用 `textContent`) - - 创建 `
` 容器 - - 替换原始代码块元素 - - 添加 `data-processed="true"` 标记防止重复处理 - - **参考**: 设计文档 3.1 节 +## 任务 -- [ ] 1.2 集成到 `highlightJsRender()` 函数 - - **需求**: 3.1 代码块拦截(核心功能) - - **位置**: `argontheme.js` 第 3942 行 - - **修改**: 在函数开始处调用 `convertMermaidCodeblocks()` - - **执行顺序**: 转换 → 代码高亮 → Mermaid 渲染 - - **参考**: 设计文档 3.2 节(集成点 1) +### 阶段 1: 核心问题修复 -### 2. Mermaid 检测适配 +- [ ] 1. 修复 PJAX 页面切换后 Mermaid 不渲染的问题 + - [x] 1.1 实现 Mermaid 代码块检测函数 _需求:3.1-3.5_ + - [~] 1.2 优化 PJAX complete 事件处理 _需求:1.1-1.5_ + - [~] 1.3 添加渲染状态标记,避免重复渲染 _需求:3.5_ + - [~] 1.4 测试 PJAX 跳转后的渲染效果 _需求:1.1-1.5_ -- [ ] 2.1 更新 `detectMermaidBlocks()` 函数 - - **需求**: 3.4 渲染检测 - - **位置**: `argontheme.js` 第 4430 行 - - **修改**: 在 selectors 数组中添加 `'div.mermaid-from-codeblock'` - - **优先级**: 放在 `'div.mermaid-shortcode'` 之后,`'div.mermaid'` 之前 - - **参考**: 设计文档 3.2 节(集成点 2) +- [ ] 2. 修复 Mermaid 语法解析错误 + - [~] 2.1 实现 Mermaid 库加载等待机制 _需求:2.6, 4.1-4.2_ + - [~] 2.2 优化 Mermaid 初始化配置 _需求:2.1-2.4_ + - [~] 2.3 添加语法错误处理和友好提示 _需求:2.5, 7.1-7.4_ + - [~] 2.4 测试各种图表类型(flowchart、erDiagram、stateDiagram) _需求:2.2-2.4_ -- [ ] 2.2 更新 `extractMermaidCode()` 函数 - - **需求**: 3.5 代码提取适配 - - **位置**: `argontheme.js` 第 4650 行 - - **修改**: 添加对 `mermaid-from-codeblock` 类的处理分支 - - **提取方式**: 使用 `element.textContent` 直接获取 - - **参考**: 设计文档 3.2 节(集成点 3) +- [ ] 3. 实现错误处理和降级方案 + - [~] 3.1 创建错误提示组件 _需求:7.1-7.4_ + - [~] 3.2 实现错误日志记录 _需求:14.1-14.6_ + - [~] 3.3 添加原始代码查看功能 _需求:7.2_ + - [~] 3.4 测试各种错误场景 _需求:7.1-7.6_ -### 3. 测试与验证 +### 阶段 2: 交互功能实现 -- [ ] 3.1 创建测试文件 - - **需求**: 6.4 测试用例 - - **文件**: `tests/test-codeblock-magic.html` - - **内容**: - - 标准 Markdown 代码块 (`pre > code.language-mermaid`) - - 多个代码块(测试批量处理) - - 特殊字符代码块(`-->`, `--`, `==` 等) - - 空代码块(测试边界情况) - - 多行代码块(测试换行符保留) - - **参考**: 设计文档 7.4 节 +- [ ] 4. 实现工具栏和基础交互 + - [~] 4.1 创建工具栏组件 _需求:11.1-11.7_ + - [~] 4.2 实现工具栏自动显示/隐藏 _需求:11.1-11.2_ + - [~] 4.3 添加按钮提示(tooltip) _需求:11.4_ + - [~] 4.4 优化工具栏样式(半透明背景) _需求:11.3_ -- [ ] 3.2 功能测试 - - **需求**: 6.1 单元测试、6.2 集成测试 - - **测试项**: - - 代码块正确转换为容器 - - 代码块不被代码高亮处理 - - Mermaid 图表正确渲染 - - 特殊字符不被转换(`-->` 保持不变) - - 换行符正确保留 - - 重复处理防护生效 - - **参考**: 设计文档 7.1 节、7.2 节 +- [ ] 5. 实现缩放功能 + - [~] 5.1 实现鼠标滚轮缩放 _需求:12.1-12.3_ + - [~] 5.2 实现缩放按钮(放大、缩小、重置) _需求:12.4_ + - [~] 5.3 实现双击智能缩放 _需求:12.5_ + - [~] 5.4 优化缩放动画和性能 _需求:12.2-12.3_ -- [ ] 3.3 PJAX 兼容性测试 - - **需求**: 3.6 PJAX 兼容 - - **测试项**: - - 初始页面加载,代码块正确转换和渲染 - - PJAX 切换到新页面,新页面的代码块正确转换和渲染 - - 已转换的代码块不被重复处理 - - 无 JavaScript 错误 - - **参考**: 设计文档 3.3 节 +- [ ] 6. 实现拖拽功能 + - [~] 6.1 实现鼠标拖拽移动 _需求:12.6-12.8_ + - [~] 6.2 优化拖拽视觉反馈 _需求:12.6-12.7_ + - [~] 6.3 智能启用/禁用拖拽 _需求:12.8_ + - [~] 6.4 使用 requestAnimationFrame 优化性能 _需求:8.1-8.5_ -- [ ] 3.4 浏览器兼容性测试 - - **需求**: 6.3 浏览器测试 - - **测试浏览器**: Chrome、Firefox、Safari、Edge(最新版) - - **测试项**: 代码块转换、图表渲染、PJAX 切换、性能表现 - - **参考**: 设计文档 7.3 节 +### 阶段 3: 高级功能实现 -### 4. 文档更新 +- [ ] 7. 实现图表导出功能 + - [~] 7.1 创建导出菜单组件 _需求:5.1-5.3_ + - [~] 7.2 实现 PNG 导出 _需求:5.4_ + - [~] 7.3 实现 SVG 导出 _需求:5.5_ + - [~] 7.4 添加导出错误处理 _需求:5.6, 7.5_ -- [ ] 4.1 更新用户文档 - - **需求**: 7.1 用户文档 - - **文件**: `docs/mermaid-usage-guide.md` - - **内容**: - - 添加代码块魔改方式的说明 - - 提供使用示例(标准 Markdown 语法) - - 说明优缺点(优点:标准语法;缺点:需要主题支持) - - 与其他方式的对比 - - **参考**: 需求文档 7.1 节 +- [ ] 8. 实现全屏查看功能 + - [~] 8.1 集成 Zoomify 图片查看组件 _需求:6.1-6.3_ + - [~] 8.2 实现全屏按钮和事件处理 _需求:6.1-6.2_ + - [~] 8.3 支持键盘快捷键(ESC 退出) _需求:6.4_ + - [~] 8.4 测试全屏模式下的交互功能 _需求:6.3-6.5_ -- [ ] 4.2 更新开发者文档 - - **需求**: 7.2 开发者文档 - - **文件**: `docs/mermaid-developer-guide.md` - - **内容**: - - 说明实现原理(提前拦截、转换容器) - - 提供代码示例(`convertMermaidCodeblocks()` 函数) - - 说明扩展方式(如何添加新的选择器) - - 执行顺序说明 - - **参考**: 需求文档 7.2 节 +- [ ] 9. 实现主题同步功能 + - [~] 9.1 监听主题切换事件 _需求:9.1-9.3_ + - [~] 9.2 实现主题自动切换 _需求:9.1-9.2_ + - [~] 9.3 保持图表状态(缩放、位置) _需求:9.4_ + - [~] 9.4 测试主题切换效果 _需求:9.1-9.5_ -- [ ] 4.3 更新 FAQ 文档 - - **需求**: 7.3 FAQ 文档 - - **文件**: `docs/mermaid-faq.md` - - **内容**: - - 添加常见问题(如何使用标准 Markdown 语法?) - - 提供解决方案(启用代码块魔改功能) - - 说明注意事项(需要主题版本 >= X.X.X) - - 故障排查指南 - - **参考**: 需求文档 7.3 节 +### 阶段 4: 性能和体验优化 -### 5. 性能优化(可选) +- [ ] 10. 优化渲染性能 + - [~] 10.1 实现批量渲染 _需求:8.1_ + - [~] 10.2 实现延迟加载(优先渲染可见图表) _需求:8.2_ + - [~] 10.3 添加加载动画 _需求:8.3, 11.7_ + - [~] 10.4 优化渲染流程,避免阻塞 _需求:8.1-8.4_ -- [ ] 5.1* 添加性能监控 - - **需求**: 4.1 性能要求 - - **功能**: - - 使用 `performance.now()` 记录转换耗时 - - 使用 `console.log()` 输出性能数据(仅调试模式) - - 记录处理的代码块数量 - - **目标**: 单个代码块处理时间 < 10ms - - **参考**: 设计文档 5.3 节 +- [ ] 11. 优化移动端体验 + - [~] 11.1 适配移动端工具栏 _需求:10.1_ + - [~] 11.2 实现触摸手势支持(双指缩放、单指拖拽) _需求:10.2_ + - [~] 11.3 优化触摸事件响应 _需求:10.5_ + - [~] 11.4 测试移动端交互体验 _需求:10.1-10.5_ -- [ ] 5.2* 优化选择器性能 - - **需求**: 4.1 性能要求 - - **优化**: - - 使用更精确的选择器(减少匹配范围) - - 批量处理元素(减少 DOM 查询次数) - - 提前返回(跳过已处理的元素) - - **参考**: 设计文档 5.2 节 +- [ ] 12. 实现生命周期管理 + - [~] 12.1 实现 PJAX 集成(清理和重新渲染) _需求:8.5, 16.1-16.5_ + - [~] 12.2 实现资源清理函数 _需求:16.1-16.5_ + - [~] 12.3 移除事件监听器,避免内存泄漏 _需求:16.2_ + - [~] 12.4 测试内存泄漏情况 _需求:16.1-16.5_ -### 6. 错误处理增强(可选) +### 阶段 5: 代码质量和测试 -- [ ] 6.1* 添加错误日志 - - **需求**: 5.3 错误处理 - - **功能**: - - 使用 try-catch 包裹关键代码 - - 捕获异常后记录日志(`console.error()`) - - 不中断其他代码块的处理 - - **参考**: 设计文档 3.4 节 +- [ ] 13. 代码质量检查 + - [~] 13.1 添加 JSDoc 注释 _需求:13.2_ + - [~] 13.2 遵循项目代码规范(Tab 缩进、单引号等) _需求:13.1_ + - [~] 13.3 使用 let/const 替代 var _需求:13.3_ + - [~] 13.4 优化错误处理和日志记录 _需求:13.4, 14.1-14.6_ + - [~] 13.5 代码审查和重构 _需求:13.1-13.7_ -- [ ] 6.2* 提供降级方案 - - **需求**: 5.3 错误处理 - - **功能**: - - 如果转换失败,保留原始代码块 - - 原始代码块仍可通过降级选择器检测(`pre code.language-mermaid`) - - 确保即使转换失败,仍能渲染 - - **参考**: 设计文档 3.4 节 +- [ ] 14. 兼容性测试 + - [~] 14.1 测试主流浏览器(Chrome、Firefox、Safari、Edge) _需求:15.1-15.5_ + - [~] 14.2 测试移动端浏览器(iOS Safari、Android Chrome) _需求:15.4_ + - [~] 14.3 测试降级方案 _需求:15.1-15.5_ + - [~] 14.4 修复兼容性问题 _需求:15.1-15.5_ -## 任务说明 +- [ ] 15. 功能测试 + - [~] 15.1 测试 PJAX 页面切换 + - [~] 15.2 测试各种图表类型渲染 + - [~] 15.3 测试交互功能(缩放、拖拽、全屏) + - [~] 15.4 测试导出功能(PNG、SVG) + - [~] 15.5 测试错误处理和降级方案 -### 优先级 -- **必须完成**: 1.1 - 2.2(核心功能)、3.1 - 3.3(测试验证)、4.1 - 4.3(文档更新) -- **可选任务**: 5.1 - 5.2(性能优化)、6.1 - 6.2(错误处理增强) +- [ ] 16. 性能测试 + - [~] 16.1 测试渲染性能(多图表页面) + - [~] 16.2 测试内存占用和泄漏 + - [~] 16.3 测试交互性能(缩放、拖拽流畅度) + - [~] 16.4 优化性能瓶颈 -### 执行顺序 -1. 先完成核心功能(1.1 - 1.2) -2. 再完成 Mermaid 检测适配(2.1 - 2.2) -3. 然后进行测试验证(3.1 - 3.4) -4. 最后更新文档(4.1 - 4.3) -5. 可选任务可在主要功能完成后进行 +- [ ] 17. 文档和总结 + - [~] 17.1 更新代码注释 + - [~] 17.2 编写使用文档 + - [~] 17.3 记录已知问题和限制 + - [~] 17.4 总结优化效果 -### 验收标准 -- ✅ 可以使用 ` ```mermaid ` 代码块编写图表 -- ✅ 代码块不会被代码高亮处理 -- ✅ 图表正确渲染 -- ✅ 特殊字符不被转换 -- ✅ 换行符正确保留 -- ✅ PJAX 切换正常工作 -- ✅ 性能无明显影响 -- ✅ 兼容所有主流浏览器 +## 实施优先级 + +**P0 (必须完成 - 核心问题修复):** +- 任务 1: 修复 PJAX 渲染问题 +- 任务 2: 修复语法解析错误 +- 任务 3: 实现错误处理 + +**P1 (重要 - 基础交互):** +- 任务 4: 实现工具栏 +- 任务 5: 实现缩放功能 +- 任务 6: 实现拖拽功能 +- 任务 12: 生命周期管理 + +**P2 (可选 - 高级功能):** +- 任务 7: 图表导出 +- 任务 8: 全屏查看 +- 任务 9: 主题同步 + +**P3 (增强 - 优化和测试):** +- 任务 10: 性能优化 +- 任务 11: 移动端优化 +- 任务 13-17: 质量保证和测试 + +## 预期效果 + +### 问题修复 +- ✅ PJAX 页面切换后 Mermaid 图表正常渲染 +- ✅ 语法解析错误得到修复 +- ✅ 错误提示友好,保留原始代码 + +### 功能增强 +- ✅ 支持图表导出(PNG、SVG) +- ✅ 支持全屏查看(复用图片查看组件) +- ✅ 支持缩放和拖拽 +- ✅ 工具栏自动显示/隐藏 + +### 体验优化 +- ✅ 交互流畅,响应迅速 +- ✅ 移动端体验良好 +- ✅ 主题自动同步 +- ✅ 加载动画和视觉反馈 + +### 代码质量 +- ✅ 代码规范,注释完整 +- ✅ 错误处理完善 +- ✅ 性能优化到位 +- ✅ 无内存泄漏 ## 注意事项 -1. **执行顺序约束**: 必须严格遵守"转换 → 代码高亮 → Mermaid 渲染"的执行顺序 -2. **代码风格**: 使用 Tab 缩进、单引号、严格相等(`===`) -3. **安全性**: 使用 `textContent` 而非 `innerHTML`,防止 XSS -4. **兼容性**: 保持与现有功能的兼容,不影响 Shortcode 和容器语法 -5. **调试**: 添加详细的调试日志,便于追踪问题 - -## 参考文档 - -- **需求文档**: `.kiro/specs/mermaid-codeblock-magic/requirements.md` -- **设计文档**: `.kiro/specs/mermaid-codeblock-magic/design.md` -- **代码规范**: `.kiro/steering/code-style.md` +1. **向后兼容**:保持现有 API 和配置不变 +2. **性能优先**:避免阻塞主线程,使用批量渲染 +3. **错误处理**:所有异步操作都要有错误处理 +4. **内存管理**:确保事件监听器和 DOM 引用被正确清理 +5. **测试充分**:测试各种边缘情况和错误场景 diff --git a/argontheme.js b/argontheme.js index fa486d1..0fc39d8 100644 --- a/argontheme.js +++ b/argontheme.js @@ -4879,42 +4879,53 @@ void 0; /** * 检测所有 Mermaid 代码块 - * @returns {Array} Mermaid 代码块元素数组 + * 需求 3.1-3.5: 扫描页面中的 Mermaid 代码块并过滤已渲染的块 + * @returns {HTMLElement[]} 未渲染的 Mermaid 代码块数组 */ detectMermaidBlocks() { const blocks = []; - // 检测规则(优先级从高到低) - const selectors = [ - 'div.mermaid-shortcode', // Shortcode 格式(推荐) - 'div.mermaid-from-codeblock', // 代码块魔改格式(新增) - 'div.mermaid', // 标准格式 - 'pre code.language-mermaid', // Markdown 格式(降级) - 'pre[data-lang="mermaid"]', // 自定义属性格式 - 'code.mermaid' // 简化格式 - ]; - - selectors.forEach(selector => { - const elements = document.querySelectorAll(selector); - elements.forEach(element => { - // 避免重复添加 - if (!blocks.includes(element)) { - // 检查是否在注释中 - if (!this.isInComment(element)) { - blocks.push(element); - } - } - }); + // 需求 3.1: 扫描所有
 元素
+			// 需求 3.2: 识别 language-mermaid 类名
+			document.querySelectorAll('pre code.language-mermaid').forEach(code => {
+				// 需求 3.5: 过滤已渲染的代码块
+				if (!this.isRendered(code)) {
+					blocks.push(code);
+				}
 			});
-
-			// 检测 Markdown 容器语法的 Mermaid 代码块
-			// 格式: ::: mermaid ... :::
-			this.detectContainerBlocks(blocks);
-
-			this.logDebug(`检测到 ${blocks.length} 个 Mermaid 代码块`);
+			
+			// 需求 3.3: 识别 mermaid 类名
+			document.querySelectorAll('pre code.mermaid').forEach(code => {
+				// 需求 3.5: 过滤已渲染的代码块
+				if (!this.isRendered(code)) {
+					blocks.push(code);
+				}
+			});
+			
+			this.logDebug(`检测到 ${blocks.length} 个未渲染的 Mermaid 代码块`);
 			return blocks;
 		},
 
+		/**
+		 * 检查代码块是否已渲染
+		 * 需求 3.5: 避免重复渲染已渲染的代码块
+		 * @param {HTMLElement} element - 代码块元素
+		 * @returns {boolean} 是否已渲染
+		 */
+		isRendered(element) {
+			// 检查元素是否有渲染标记
+			if (element.hasAttribute('data-mermaid-rendered')) {
+				return true;
+			}
+			
+			// 检查元素是否在 mermaid-container 容器中
+			if (element.closest('.mermaid-container') !== null) {
+				return true;
+			}
+			
+			return false;
+		},
+
 		/**
 		 * 检查元素是否在 HTML 注释中
 		 * @param {HTMLElement} element - 要检查的元素