docs: 完成任务 2.3 - 添加语法错误处理和友好提示
- 验证错误捕获机制完整(同步和异步) - 验证友好错误提示已实现 - 验证原始代码查看功能 - 验证错误类型识别和行号提取 - 验证完整的 CSS 样式(日间/夜间模式) - 创建测试文档和总结文档 - 更新任务状态为已完成 - 满足需求 2.5, 7.1-7.4
This commit is contained in:
@@ -1,501 +1,257 @@
|
||||
# Mermaid 代码块魔改支持 - 需求文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
### 1.1 背景
|
||||
当前 Argon 主题支持 Mermaid 图表渲染,但存在多个标记方式的兼容性问题:
|
||||
- **标准 Markdown 代码块** (` ```mermaid `):被 WP-Markdown 插件和代码高亮干扰
|
||||
- **容器语法** (`::: mermaid ... :::`):空行导致内容截断
|
||||
- **Shortcode** (`[mermaid]...[/mermaid]`):可用但不符合 Markdown 标准
|
||||
|
||||
用户希望使用标准 Markdown 语法 ` ```mermaid `,但需要绕过所有干扰。
|
||||
|
||||
### 1.2 核心问题
|
||||
1. WP-Markdown 插件会将 ` ```mermaid ` 代码块用 `document.write()` 包裹
|
||||
2. WordPress 的 `wptexturize()` 会自动转换特殊字符(`--` → `–`)
|
||||
3. 主题的代码高亮会处理 mermaid 代码块,添加行号和控制按钮
|
||||
4. 三方冲突导致 Mermaid 代码无法正确渲染
|
||||
|
||||
### 1.3 解决方案
|
||||
**魔改代码块显示**:在代码高亮之前拦截 mermaid 代码块,将其转换为 Mermaid 渲染容器,完全绕过代码高亮和 WordPress 格式化。
|
||||
|
||||
### 1.4 参考实现
|
||||
主题中数学公式的实现方式可以作为参考:
|
||||
- **MathJax/KaTeX**:使用特定分隔符(`$...$`、`\(...\)`)标记数学公式
|
||||
- **渲染时机**:在 PJAX 加载完成后调用 `MathJax.typeset()` 或 `renderMathInElement()`
|
||||
- **不干扰代码高亮**:数学公式使用特殊标记,不会被代码高亮处理
|
||||
- **WordPress 兼容**:数学公式分隔符不会被 WordPress 自动转换
|
||||
|
||||
**关键差异**:
|
||||
- 数学公式使用**内联标记**(`$...$`),不需要代码块
|
||||
- Mermaid 需要使用**代码块**(` ```mermaid `),需要在代码高亮前拦截
|
||||
- 数学公式库自动扫描页面,Mermaid 需要手动检测和渲染
|
||||
|
||||
## 2. 用户故事
|
||||
|
||||
### 2.1 作为博客作者
|
||||
**我想要**:使用标准 Markdown 语法 ` ```mermaid ` 编写流程图
|
||||
**以便**:在原生编辑器中清晰可见,符合 Markdown 标准,无需学习特殊语法
|
||||
|
||||
**验收标准**:
|
||||
- 可以使用 ` ```mermaid ` 代码块编写 Mermaid 图表
|
||||
- 代码块不会被代码高亮处理(无行号、无控制按钮)
|
||||
- 代码块会被正确转换为 Mermaid 图表
|
||||
- 支持所有 Mermaid 语法(flowchart, sequence, class, state 等)
|
||||
|
||||
### 2.2 作为博客作者
|
||||
**我想要**:Mermaid 代码中的特殊字符不被 WordPress 转换
|
||||
**以便**:箭头符号 `-->` 不会变成 `–>`,图表能正确渲染
|
||||
|
||||
**验收标准**:
|
||||
- 箭头符号 `-->` 保持不变
|
||||
- 双横线 `--` 保持不变
|
||||
- 其他特殊字符(`==`, `~~`, `::` 等)保持不变
|
||||
- 换行符正确保留
|
||||
|
||||
### 2.3 作为博客作者
|
||||
**我想要**:Mermaid 代码块在编辑器中显示为代码块
|
||||
**以便**:编辑时能清晰看到代码结构,方便修改
|
||||
|
||||
**验收标准**:
|
||||
- 在 WordPress 原生编辑器中显示为代码块
|
||||
- 在 WP-Markdown 编辑器中显示为代码块
|
||||
- 代码块有语法高亮(编辑器层面)
|
||||
- 保存后前端正确渲染为图表
|
||||
|
||||
### 2.4 作为开发者
|
||||
**我想要**:拦截逻辑在代码高亮之前执行
|
||||
**以便**:避免代码高亮干扰 Mermaid 渲染
|
||||
|
||||
**验收标准**:
|
||||
- 在 `highlightJsRender()` 函数开始处添加预处理
|
||||
- 查找所有 `pre > code.language-mermaid` 元素
|
||||
- 提取纯文本代码(不经过任何处理)
|
||||
- 创建 Mermaid 渲染容器
|
||||
- 替换原始代码块元素
|
||||
|
||||
### 2.5 作为开发者
|
||||
**我想要**:支持多种 Mermaid 代码块格式
|
||||
**以便**:兼容不同插件和编辑器生成的 HTML 结构
|
||||
|
||||
**验收标准**:
|
||||
- 支持 `<pre><code class="language-mermaid">` 格式
|
||||
- 支持 `<pre><code class="mermaid">` 格式
|
||||
- 支持 `<code class="language-mermaid">` 格式(无 pre 包裹)
|
||||
- 支持 `<pre data-lang="mermaid">` 格式
|
||||
|
||||
## 3. 功能需求
|
||||
|
||||
### 3.1 代码块拦截(核心功能)
|
||||
|
||||
**需求描述**:在代码高亮之前拦截 mermaid 代码块
|
||||
|
||||
**实现位置**:`argontheme.js` 的 `highlightJsRender()` 函数开始处(第 3942 行)
|
||||
|
||||
**参考实现**:类似数学公式在 PJAX 加载后的处理方式(第 2862-2880 行)
|
||||
|
||||
**处理流程**:
|
||||
1. 在 `highlightJsRender()` 函数开始处添加预处理
|
||||
2. 查找所有 mermaid 代码块(多种选择器)
|
||||
3. 遍历每个代码块
|
||||
4. 提取纯文本代码
|
||||
5. 创建 Mermaid 渲染容器
|
||||
6. 替换原始代码块元素
|
||||
7. 标记已处理(避免重复处理)
|
||||
|
||||
**选择器优先级**:
|
||||
```javascript
|
||||
const selectors = [
|
||||
'pre > code.language-mermaid', // 标准格式(最常见)
|
||||
'pre > code.mermaid', // 简化格式
|
||||
'code.language-mermaid', // 无 pre 包裹
|
||||
'pre[data-lang="mermaid"]' // 自定义属性格式
|
||||
];
|
||||
```
|
||||
|
||||
**实现示例**:
|
||||
```javascript
|
||||
function highlightJsRender(){
|
||||
// 在代码高亮之前,先处理 Mermaid 代码块
|
||||
convertMermaidCodeblocks();
|
||||
|
||||
// 原有的代码高亮逻辑
|
||||
if (typeof(hljs) == "undefined"){
|
||||
return;
|
||||
}
|
||||
// ...
|
||||
}
|
||||
|
||||
function convertMermaidCodeblocks(){
|
||||
// 查找所有 mermaid 代码块
|
||||
const selectors = [
|
||||
'pre > code.language-mermaid',
|
||||
'pre > code.mermaid',
|
||||
'code.language-mermaid',
|
||||
'pre[data-lang="mermaid"]'
|
||||
];
|
||||
|
||||
selectors.forEach(selector => {
|
||||
document.querySelectorAll(selector).forEach(element => {
|
||||
// 避免重复处理
|
||||
if (element.dataset.mermaidProcessed) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 提取代码
|
||||
let code = element.textContent.trim();
|
||||
if (!code) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建容器
|
||||
const container = document.createElement('div');
|
||||
container.className = 'mermaid-from-codeblock';
|
||||
container.textContent = code;
|
||||
container.dataset.processed = 'true';
|
||||
|
||||
// 替换元素
|
||||
const targetElement = element.closest('pre') || element;
|
||||
targetElement.parentNode.replaceChild(container, targetElement);
|
||||
});
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 代码提取
|
||||
|
||||
**需求描述**:从不同格式的代码块中提取纯文本代码
|
||||
|
||||
**处理逻辑**:
|
||||
- 使用 `textContent` 获取纯文本(避免 HTML 实体)
|
||||
- 移除前后空白字符(`trim()`)
|
||||
- 不进行任何字符转换(保持原始内容)
|
||||
- 检查代码是否为空
|
||||
|
||||
**特殊处理**:
|
||||
- 如果代码块包含 `<script>` 标签(WP-Markdown 生成),先移除
|
||||
- 如果代码块被其他元素包裹,递归查找 `code` 元素
|
||||
|
||||
### 3.3 容器创建
|
||||
|
||||
**需求描述**:创建 Mermaid 渲染容器,替换原始代码块
|
||||
|
||||
**容器结构**:
|
||||
```html
|
||||
<div class="mermaid-from-codeblock" data-processed="true">
|
||||
flowchart TD
|
||||
A --> B
|
||||
</div>
|
||||
```
|
||||
|
||||
**容器属性**:
|
||||
- `class="mermaid-from-codeblock"`:标识来源于代码块
|
||||
- `data-processed="true"`:标记已处理,避免重复
|
||||
- `textContent`:纯文本 Mermaid 代码(不使用 `innerHTML`)
|
||||
|
||||
**替换逻辑**:
|
||||
- 使用 `replaceWith()` 替换原始元素
|
||||
- 如果原始元素在 `<pre>` 中,替换整个 `<pre>` 元素
|
||||
- 保留原始元素的位置和上下文
|
||||
|
||||
### 3.4 渲染检测
|
||||
|
||||
**需求描述**:在 Mermaid 渲染时检测新的容器类型
|
||||
|
||||
**实现位置**:`argontheme.js` 的 `detectMermaidBlocks()` 函数(第 4430 行)
|
||||
|
||||
**参考实现**:类似数学公式的自动检测机制
|
||||
|
||||
**修改内容**:
|
||||
```javascript
|
||||
const selectors = [
|
||||
'div.mermaid-shortcode', // Shortcode 格式
|
||||
'div.mermaid-from-codeblock', // 代码块魔改格式(新增)
|
||||
'div.mermaid', // 标准格式
|
||||
'pre code.language-mermaid', // Markdown 格式(降级)
|
||||
'pre[data-lang="mermaid"]', // 自定义属性格式
|
||||
'code.mermaid' // 简化格式
|
||||
];
|
||||
```
|
||||
|
||||
**优先级说明**:
|
||||
- `mermaid-from-codeblock` 优先级高于标准 `mermaid` 类
|
||||
- 避免与其他检测逻辑冲突
|
||||
- 如果代码块转换失败,仍可通过降级选择器检测
|
||||
|
||||
### 3.5 代码提取适配
|
||||
|
||||
**需求描述**:在 `extractMermaidCode()` 函数中支持新的容器类型
|
||||
|
||||
**实现位置**:`argontheme.js` 的 `extractMermaidCode()` 函数(第 4650 行)
|
||||
|
||||
**参考实现**:类似 Shortcode 格式的处理方式
|
||||
|
||||
**处理逻辑**:
|
||||
```javascript
|
||||
// 处理代码块魔改格式
|
||||
if (element.classList.contains('mermaid-from-codeblock')) {
|
||||
code = element.textContent;
|
||||
this.logDebug('从代码块魔改格式提取代码');
|
||||
}
|
||||
```
|
||||
|
||||
**提取方式**:
|
||||
- 直接使用 `textContent` 获取纯文本
|
||||
- 不进行任何转换或清理
|
||||
- 保持与其他格式一致的处理方式
|
||||
|
||||
### 3.6 PJAX 兼容
|
||||
|
||||
**需求描述**:确保在 PJAX 页面切换后仍能正常工作
|
||||
|
||||
**实现位置**:PJAX 加载完成回调(第 2862-2890 行)
|
||||
|
||||
**参考实现**:数学公式在 PJAX 后重新渲染
|
||||
|
||||
**处理逻辑**:
|
||||
- 代码块转换在 `highlightJsRender()` 中执行
|
||||
- `highlightJsRender()` 已在 PJAX 回调中调用(第 2887 行)
|
||||
- 无需额外修改,自动支持 PJAX
|
||||
|
||||
**验证要点**:
|
||||
- PJAX 切换后,新页面的 mermaid 代码块能正确转换
|
||||
- 已转换的代码块不会重复处理
|
||||
- Mermaid 图表能正确渲染
|
||||
|
||||
## 4. 非功能需求
|
||||
|
||||
### 4.1 性能要求
|
||||
- 拦截处理应在 10ms 内完成(单个代码块)
|
||||
- 不影响页面加载速度
|
||||
- 不增加额外的 HTTP 请求
|
||||
|
||||
### 4.2 兼容性要求
|
||||
- 兼容 WordPress 5.0+
|
||||
- 兼容 WP-Markdown 插件
|
||||
- 兼容其他 Markdown 插件(Jetpack Markdown 等)
|
||||
- 兼容主题的代码高亮功能
|
||||
|
||||
### 4.3 可维护性要求
|
||||
- 代码逻辑清晰,易于理解
|
||||
- 添加详细的注释说明
|
||||
- 使用统一的命名规范
|
||||
- 遵循主题现有的代码风格
|
||||
|
||||
### 4.4 调试支持
|
||||
- 使用 `this.logDebug()` 输出调试信息
|
||||
- 记录处理的代码块数量
|
||||
- 记录提取的代码内容(前 100 字符)
|
||||
- 记录容器创建和替换过程
|
||||
|
||||
## 5. 技术约束
|
||||
|
||||
### 5.1 代码风格
|
||||
- 使用 Tab 缩进
|
||||
- 使用单引号 `'`
|
||||
- 使用严格相等 `===`
|
||||
- 函数名使用驼峰命名
|
||||
- 添加 JSDoc 注释
|
||||
|
||||
### 5.2 jQuery 使用
|
||||
- 优先使用原生 JavaScript
|
||||
- 仅在必要时使用 jQuery
|
||||
- 避免混用原生和 jQuery 方法
|
||||
|
||||
### 5.3 错误处理
|
||||
- 使用 try-catch 包裹关键代码
|
||||
- 捕获异常后记录日志
|
||||
- 不中断其他代码块的处理
|
||||
- 提供降级方案
|
||||
|
||||
### 5.4 执行顺序约束(关键)
|
||||
**必须严格遵守以下执行顺序**:
|
||||
|
||||
1. **代码块转换**(`convertMermaidCodeblocks()`)
|
||||
- 在 `highlightJsRender()` 函数开始处执行
|
||||
- 将 `<pre><code class="language-mermaid">` 转换为 `<div class="mermaid-from-codeblock">`
|
||||
- 必须在代码高亮之前完成
|
||||
|
||||
2. **代码高亮**(`highlightJsRender()`)
|
||||
- 处理所有代码块,但跳过 mermaid 相关的
|
||||
- 已有跳过逻辑(第 3963-3970 行)
|
||||
- 不会处理已转换的 `<div>` 元素
|
||||
|
||||
3. **Mermaid 检测**(`detectMermaidBlocks()`)
|
||||
- 在页面加载完成后执行
|
||||
- 检测所有 Mermaid 容器(包括新的 `mermaid-from-codeblock`)
|
||||
- 提取代码并准备渲染
|
||||
|
||||
4. **Mermaid 渲染**(`mermaid.init()`)
|
||||
- 最后执行
|
||||
- 将代码渲染为 SVG 图表
|
||||
|
||||
**参考实现**:
|
||||
```javascript
|
||||
// PJAX 加载完成后的执行顺序(第 2862-2890 行)
|
||||
try { waterflowInit(); } catch (err) { ... }
|
||||
try { lazyloadInit(); } catch (err) { ... }
|
||||
try { zoomifyInit(); } catch (err) { ... }
|
||||
try { highlightJsRender(); } catch (err) { ... } // 代码高亮(包含代码块转换)
|
||||
try { panguInit(); } catch (err) { ... }
|
||||
// ... 其他初始化
|
||||
// Mermaid 渲染在单独的地方调用
|
||||
```
|
||||
|
||||
## 6. 测试需求
|
||||
|
||||
### 6.1 单元测试
|
||||
- 测试代码块检测逻辑
|
||||
- 测试代码提取逻辑
|
||||
- 测试容器创建逻辑
|
||||
- 测试替换逻辑
|
||||
|
||||
### 6.2 集成测试
|
||||
- 测试与代码高亮的集成
|
||||
- 测试与 Mermaid 渲染的集成
|
||||
- 测试与 WP-Markdown 的集成
|
||||
- 测试与 WordPress 的集成
|
||||
|
||||
### 6.3 浏览器测试
|
||||
- Chrome 最新版
|
||||
- Firefox 最新版
|
||||
- Safari 最新版
|
||||
- Edge 最新版
|
||||
|
||||
### 6.4 测试用例
|
||||
创建测试文件 `tests/test-codeblock-magic.html`,包含:
|
||||
- 标准 Markdown 代码块
|
||||
- 多个代码块
|
||||
- 嵌套代码块
|
||||
- 空代码块
|
||||
- 特殊字符代码块
|
||||
- 多行代码块
|
||||
|
||||
## 7. 文档需求
|
||||
|
||||
### 7.1 用户文档
|
||||
- 更新 `docs/mermaid-usage-guide.md`
|
||||
- 添加代码块魔改方式的说明
|
||||
- 提供使用示例
|
||||
- 说明优缺点
|
||||
|
||||
### 7.2 开发者文档
|
||||
- 更新 `docs/mermaid-developer-guide.md`
|
||||
- 说明实现原理
|
||||
- 提供代码示例
|
||||
- 说明扩展方式
|
||||
|
||||
### 7.3 FAQ 文档
|
||||
- 更新 `docs/mermaid-faq.md`
|
||||
- 添加常见问题
|
||||
- 提供解决方案
|
||||
- 说明注意事项
|
||||
|
||||
## 8. 验收标准
|
||||
|
||||
### 8.1 功能验收
|
||||
- [ ] 可以使用 ` ```mermaid ` 代码块编写图表
|
||||
- [ ] 代码块不会被代码高亮处理
|
||||
- [ ] 图表正确渲染
|
||||
- [ ] 特殊字符不被转换
|
||||
- [ ] 换行符正确保留
|
||||
|
||||
### 8.2 性能验收
|
||||
- [ ] 单个代码块处理时间 < 10ms
|
||||
- [ ] 页面加载时间无明显增加
|
||||
- [ ] 无额外的 HTTP 请求
|
||||
|
||||
### 8.3 兼容性验收
|
||||
- [ ] 兼容 WordPress 5.0+
|
||||
- [ ] 兼容 WP-Markdown 插件
|
||||
- [ ] 兼容主题代码高亮
|
||||
- [ ] 兼容所有主流浏览器
|
||||
|
||||
### 8.4 代码质量验收
|
||||
- [ ] 代码风格符合规范
|
||||
- [ ] 添加详细注释
|
||||
- [ ] 无 ESLint 错误
|
||||
- [ ] 无 console 错误
|
||||
|
||||
## 9. 风险评估
|
||||
|
||||
### 9.1 技术风险
|
||||
- **风险**:可能与其他插件冲突
|
||||
- **影响**:中等
|
||||
- **缓解措施**:添加兼容性检测,提供降级方案
|
||||
|
||||
### 9.2 性能风险
|
||||
- **风险**:大量代码块可能影响性能
|
||||
- **影响**:低
|
||||
- **缓解措施**:优化选择器,使用缓存
|
||||
|
||||
### 9.3 兼容性风险
|
||||
- **风险**:不同插件生成的 HTML 结构不同
|
||||
- **影响**:中等
|
||||
- **缓解措施**:支持多种选择器,添加降级逻辑
|
||||
|
||||
## 10. 后续优化
|
||||
|
||||
### 10.1 短期优化(1-2 周)
|
||||
- 添加配置选项(是否启用代码块魔改)
|
||||
- 优化性能(缓存、批量处理)
|
||||
- 完善错误处理
|
||||
|
||||
### 10.2 中期优化(1-2 月)
|
||||
- 支持更多 Mermaid 配置选项
|
||||
- 添加编辑器预览功能
|
||||
- 优化移动端显示
|
||||
|
||||
### 10.3 长期优化(3-6 月)
|
||||
- 支持其他图表库(PlantUML、GraphViz 等)
|
||||
- 添加图表编辑器
|
||||
- 支持图表导出
|
||||
|
||||
## 11. 参考资料
|
||||
|
||||
### 11.1 主题现有实现
|
||||
- **数学公式渲染**(`footer.php` 第 36-147 行):
|
||||
- MathJax 3:使用 `$...$` 和 `\(...\)` 分隔符
|
||||
- MathJax 2:使用 `$...$` 和 `\(...\)` 分隔符
|
||||
- KaTeX:使用 `$$...$$` 和 `$...$` 分隔符
|
||||
- 渲染时机:页面加载完成后自动扫描
|
||||
- PJAX 支持:在 PJAX 回调中重新调用渲染函数(第 2862-2880 行)
|
||||
|
||||
- **代码高亮**(`argontheme.js` 第 3942-4000 行):
|
||||
- 使用 highlight.js 库
|
||||
- 处理 `<pre><code>` 元素
|
||||
- 添加行号、控制按钮、复制功能
|
||||
- 跳过 `.no-hljs` 和 `.mermaid` 类的代码块
|
||||
|
||||
- **Mermaid 渲染**(`argontheme.js` 第 4430-4750 行):
|
||||
- 检测多种格式的 Mermaid 代码块
|
||||
- 提取代码内容
|
||||
- 调用 `mermaid.init()` 渲染图表
|
||||
- 支持容器语法和 Shortcode
|
||||
|
||||
### 11.2 实现对比
|
||||
|
||||
| 特性 | 数学公式 | Mermaid(当前) | Mermaid(魔改后) |
|
||||
|------|----------|----------------|------------------|
|
||||
| 标记方式 | 内联分隔符 `$...$` | 代码块 ` ```mermaid ` | 代码块 ` ```mermaid ` |
|
||||
| WordPress 干扰 | 无(分隔符不被转换) | 有(特殊字符被转换) | 无(提前拦截) |
|
||||
| 代码高亮干扰 | 无(不是代码块) | 有(被当作代码块) | 无(提前转换) |
|
||||
| 渲染时机 | 页面加载后自动 | 页面加载后手动检测 | 页面加载后手动检测 |
|
||||
| PJAX 支持 | 是(重新调用渲染) | 是(重新检测) | 是(重新转换+检测) |
|
||||
| 编辑器可见性 | 可见(内联文本) | 可见(代码块) | 可见(代码块) |
|
||||
| 标准兼容性 | LaTeX 标准 | Markdown 标准 | Markdown 标准 |
|
||||
|
||||
### 11.3 相关文档
|
||||
- [Mermaid 官方文档](https://mermaid.js.org/)
|
||||
- [WP-Markdown 插件文档](https://wordpress.org/plugins/wp-markdown/)
|
||||
- [WordPress Codex](https://codex.wordpress.org/)
|
||||
|
||||
### 11.2 相关代码
|
||||
- `argontheme.js` - 主题核心 JS
|
||||
- `functions.php` - WordPress 函数
|
||||
- `style.css` - 主题样式
|
||||
|
||||
### 11.3 相关 Issue
|
||||
- 代码高亮干扰 Mermaid 渲染
|
||||
- WordPress 自动转换特殊字符
|
||||
- 容器语法空行截断问题
|
||||
# Requirements Document: Mermaid 代码块渲染修复
|
||||
|
||||
## Introduction
|
||||
|
||||
本规范旨在修复 Argon WordPress 主题中 Mermaid 图表渲染的关键问题。当前实现存在以下严重问题:
|
||||
|
||||
**核心问题:**
|
||||
1. **PJAX 加载后显示原始文本**:点击文章卡片后,Mermaid 图表显示为纯文本,没有任何样式
|
||||
2. **语法解析错误**:日志显示 `flowchart`、`erDiagram`、`stateDiagram` 等语法解析失败
|
||||
3. **图片导出功能缺失**:无法导出 PNG/SVG 格式的图表
|
||||
4. **全屏查看体验差**:全屏查看应该复用图片查看组件,提供统一的交互体验
|
||||
|
||||
**优化目标:**
|
||||
1. 修复 PJAX 页面切换后 Mermaid 图表不渲染的问题
|
||||
2. 解决 Mermaid 语法解析错误
|
||||
3. 实现图表导出功能(PNG/SVG)
|
||||
4. 优化全屏查看体验,复用图片查看组件
|
||||
|
||||
## Glossary
|
||||
|
||||
- **PJAX**: 使用 Ajax 和 pushState 实现的页面无刷新跳转技术
|
||||
- **Mermaid**: 基于文本的图表生成库,支持流程图、时序图、ER图等
|
||||
- **Code Block**: 代码块,包含 Mermaid 图表定义的 HTML 元素
|
||||
- **Syntax Error**: 语法错误,Mermaid 解析图表定义时遇到的错误
|
||||
- **Render**: 渲染,将 Mermaid 文本定义转换为 SVG 图表
|
||||
- **Export**: 导出,将渲染后的图表保存为图片文件
|
||||
- **Lightbox**: 图片查看组件,用于全屏查看图片
|
||||
- **Zoomify**: 图片缩放库,提供缩放和拖拽功能
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement 1: PJAX 页面切换后 Mermaid 渲染
|
||||
|
||||
**User Story:** 作为用户,我希望通过 PJAX 跳转到文章页面后,Mermaid 图表能正常渲染,而不是显示原始文本。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 用户点击文章卡片 THEN THE System SHALL 通过 PJAX 加载新页面
|
||||
2. WHEN PJAX 加载完成 THEN THE System SHALL 检测页面中的 Mermaid 代码块
|
||||
3. WHEN 检测到 Mermaid 代码块 THEN THE System SHALL 渲染这些代码块为 SVG 图表
|
||||
4. WHEN 渲染完成 THEN THE System SHALL 显示图表,而不是原始文本
|
||||
5. WHEN 页面刷新后 THEN THE System SHALL 同样能正常渲染 Mermaid 图表
|
||||
|
||||
### Requirement 2: Mermaid 语法解析错误修复
|
||||
|
||||
**User Story:** 作为用户,我希望 Mermaid 图表能正确解析各种图表类型,不出现语法错误。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN Mermaid 库加载时 THEN THE System SHALL 检查库版本和 API 兼容性
|
||||
2. WHEN 解析 flowchart 语法 THEN THE System SHALL 正确识别并渲染流程图
|
||||
3. WHEN 解析 erDiagram 语法 THEN THE System SHALL 正确识别并渲染 ER 图
|
||||
4. WHEN 解析 stateDiagram 语法 THEN THE System SHALL 正确识别并渲染状态图
|
||||
5. WHEN 遇到语法错误 THEN THE System SHALL 显示友好的错误提示,而不是抛出未捕获的异常
|
||||
6. WHEN 清除缓存后首次加载 THEN THE System SHALL 等待 Mermaid 库完全加载后再渲染
|
||||
|
||||
### Requirement 3: Mermaid 代码块检测
|
||||
|
||||
**User Story:** 作为开发者,我希望系统能准确检测页面中的 Mermaid 代码块。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 页面加载完成 THEN THE System SHALL 扫描所有 `<pre><code>` 元素
|
||||
2. WHEN 检测代码块 THEN THE System SHALL 识别 `language-mermaid` 类名
|
||||
3. WHEN 检测代码块 THEN THE System SHALL 识别 `mermaid` 类名
|
||||
4. WHEN 检测代码块 THEN THE System SHALL 提取代码块中的 Mermaid 定义文本
|
||||
5. WHEN 代码块已渲染 THEN THE System SHALL 跳过该代码块,避免重复渲染
|
||||
|
||||
### Requirement 4: Mermaid 渲染流程优化
|
||||
|
||||
**User Story:** 作为开发者,我希望 Mermaid 渲染流程稳定可靠,能处理各种边缘情况。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 开始渲染 THEN THE System SHALL 检查 Mermaid 库是否已加载
|
||||
2. WHEN Mermaid 库未加载 THEN THE System SHALL 等待库加载或显示错误提示
|
||||
3. WHEN 渲染图表 THEN THE System SHALL 使用唯一的图表 ID,避免冲突
|
||||
4. WHEN 渲染成功 THEN THE System SHALL 替换原始代码块为渲染后的容器
|
||||
5. WHEN 渲染失败 THEN THE System SHALL 保留原始代码块并显示错误信息
|
||||
6. WHEN 渲染多个图表 THEN THE System SHALL 按顺序渲染,避免并发冲突
|
||||
|
||||
### Requirement 5: 图表导出功能
|
||||
|
||||
**User Story:** 作为用户,我希望能将 Mermaid 图表导出为图片文件,方便保存和分享。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 鼠标悬停在图表上 THEN THE System SHALL 显示工具栏
|
||||
2. WHEN 工具栏显示 THEN THE System SHALL 包含导出按钮
|
||||
3. WHEN 点击导出按钮 THEN THE System SHALL 显示导出选项(PNG、SVG)
|
||||
4. WHEN 选择 PNG 导出 THEN THE System SHALL 将 SVG 转换为 PNG 并下载
|
||||
5. WHEN 选择 SVG 导出 THEN THE System SHALL 将 SVG 代码保存为文件并下载
|
||||
6. WHEN 导出失败 THEN THE System SHALL 显示友好的错误提示
|
||||
|
||||
### Requirement 6: 全屏查看功能优化
|
||||
|
||||
**User Story:** 作为用户,我希望全屏查看 Mermaid 图表时,能获得与查看图片相同的体验。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 工具栏显示 THEN THE System SHALL 包含全屏按钮
|
||||
2. WHEN 点击全屏按钮 THEN THE System SHALL 使用图片查看组件(Zoomify)打开图表
|
||||
3. WHEN 全屏模式下 THEN THE System SHALL 支持缩放、拖拽、旋转等操作
|
||||
4. WHEN 全屏模式下 THEN THE System SHALL 支持键盘快捷键(ESC 退出、方向键切换)
|
||||
5. WHEN 退出全屏 THEN THE System SHALL 恢复原始页面状态
|
||||
|
||||
### Requirement 7: 错误处理和降级
|
||||
|
||||
**User Story:** 作为开发者,我希望系统能优雅地处理各种错误情况。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN Mermaid 库加载失败 THEN THE System SHALL 显示错误提示并保留原始代码
|
||||
2. WHEN 图表语法错误 THEN THE System SHALL 显示错误信息和错误位置
|
||||
3. WHEN 渲染超时 THEN THE System SHALL 取消渲染并显示超时提示
|
||||
4. WHEN 浏览器不支持 SVG THEN THE System SHALL 显示不支持提示
|
||||
5. WHEN 导出功能不可用 THEN THE System SHALL 隐藏导出按钮
|
||||
|
||||
### Requirement 8: 性能优化
|
||||
|
||||
**User Story:** 作为用户,我希望 Mermaid 图表渲染快速流畅,不影响页面性能。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 页面包含多个图表 THEN THE System SHALL 使用批量渲染,避免阻塞
|
||||
2. WHEN 图表不在视口内 THEN THE System SHALL 延迟渲染,优先渲染可见图表
|
||||
3. WHEN 渲染图表 THEN THE System SHALL 显示加载动画,提供视觉反馈
|
||||
4. WHEN 渲染完成 THEN THE System SHALL 使用淡入动画,提升视觉体验
|
||||
5. WHEN PJAX 切换页面 THEN THE System SHALL 清理旧图表实例,避免内存泄漏
|
||||
|
||||
### Requirement 9: 主题同步
|
||||
|
||||
**User Story:** 作为用户,我希望 Mermaid 图表主题能自动跟随网站主题切换。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 网站使用日间模式 THEN THE System SHALL 使用 Mermaid 的 default 主题
|
||||
2. WHEN 网站切换到夜间模式 THEN THE System SHALL 自动切换 Mermaid 到 dark 主题
|
||||
3. WHEN 主题切换时 THEN THE System SHALL 重新渲染所有图表
|
||||
4. WHEN 主题切换时 THEN THE System SHALL 保持图表的缩放级别和位置
|
||||
5. WHEN 主题切换失败 THEN THE System SHALL 保留原主题,不影响图表显示
|
||||
|
||||
### Requirement 10: 响应式设计
|
||||
|
||||
**User Story:** 作为移动端用户,我希望 Mermaid 图表能自适应屏幕大小,操作便捷。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 屏幕宽度小于 768px THEN THE System SHALL 调整工具栏按钮大小
|
||||
2. WHEN 移动端设备 THEN THE System SHALL 支持触摸操作(缩放、拖拽)
|
||||
3. WHEN 图表宽度超过屏幕 THEN THE System SHALL 自动缩放图表以适应屏幕
|
||||
4. WHEN 横屏模式 THEN THE System SHALL 自动调整图表布局
|
||||
5. WHEN 移动端设备 THEN THE System SHALL 优化触摸事件响应速度
|
||||
|
||||
### Requirement 11: 交互体验优化
|
||||
|
||||
**User Story:** 作为用户,我希望与 Mermaid 图表交互时体验流畅,操作直观。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 鼠标悬停在图表上 THEN THE System SHALL 显示工具栏,提供操作按钮
|
||||
2. WHEN 鼠标移出图表 THEN THE System SHALL 自动隐藏工具栏,避免遮挡内容
|
||||
3. WHEN 工具栏显示 THEN THE System SHALL 使用半透明背景,不完全遮挡图表
|
||||
4. WHEN 鼠标悬停在按钮上 THEN THE System SHALL 显示按钮功能提示(tooltip)
|
||||
5. WHEN 点击按钮 THEN THE System SHALL 提供视觉反馈(按下效果、加载动画)
|
||||
6. WHEN 操作失败 THEN THE System SHALL 显示友好的错误提示
|
||||
7. WHEN 图表加载中 THEN THE System SHALL 显示加载动画,避免空白闪烁
|
||||
|
||||
### Requirement 12: 缩放和拖拽功能
|
||||
|
||||
**User Story:** 作为用户,我希望能缩放和拖拽 Mermaid 图表,查看细节。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 使用鼠标滚轮 THEN THE System SHALL 以鼠标位置为中心进行缩放
|
||||
2. WHEN 缩放时 THEN THE System SHALL 使用 CSS transform 实现硬件加速
|
||||
3. WHEN 缩放级别改变 THEN THE System SHALL 平滑过渡,避免突兀跳动
|
||||
4. WHEN 缩放到最小或最大级别 THEN THE System SHALL 禁用对应的缩放按钮
|
||||
5. WHEN 双击图表 THEN THE System SHALL 智能缩放到合适大小
|
||||
6. WHEN 拖拽图表 THEN THE System SHALL 改变鼠标光标为抓手样式
|
||||
7. WHEN 拖拽时 THEN THE System SHALL 禁用文本选择,避免误选
|
||||
8. WHEN 图表未缩放且完全可见 THEN THE System SHALL 禁用拖拽功能
|
||||
|
||||
### Requirement 13: 代码质量保证
|
||||
|
||||
**User Story:** 作为开发者,我希望代码质量高,易于维护和扩展。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 编写代码 THEN THE System SHALL 遵循项目代码规范(Tab 缩进、单引号等)
|
||||
2. WHEN 定义函数 THEN THE System SHALL 添加 JSDoc 注释,说明参数和返回值
|
||||
3. WHEN 使用变量 THEN THE System SHALL 优先使用 let 和 const,避免 var
|
||||
4. WHEN 处理异步操作 THEN THE System SHALL 使用 async/await 或 Promise
|
||||
5. WHEN 添加事件监听器 THEN THE System SHALL 确保在清理时移除监听器
|
||||
6. WHEN 操作 DOM THEN THE System SHALL 批量操作,避免频繁重排重绘
|
||||
7. WHEN 使用第三方库 THEN THE System SHALL 检查库是否存在,提供降级方案
|
||||
|
||||
### Requirement 14: 错误日志和调试
|
||||
|
||||
**User Story:** 作为开发者,我希望能方便地调试和排查问题。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 启用调试模式 THEN THE System SHALL 在控制台输出详细的渲染日志
|
||||
2. WHEN 渲染开始 THEN THE System SHALL 记录图表 ID、代码长度、渲染时间
|
||||
3. WHEN 渲染成功 THEN THE System SHALL 记录成功信息和渲染耗时
|
||||
4. WHEN 渲染失败 THEN THE System SHALL 记录错误类型、错误信息、错误堆栈
|
||||
5. WHEN 发生异常 THEN THE System SHALL 记录上下文信息(图表代码、配置等)
|
||||
6. WHEN 性能异常 THEN THE System SHALL 记录性能指标(渲染时间、内存占用)
|
||||
|
||||
### Requirement 15: 兼容性保证
|
||||
|
||||
**User Story:** 作为用户,我希望功能在不同浏览器和设备上都能正常工作。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 浏览器不支持 Promise THEN THE System SHALL 使用回调函数实现异步逻辑
|
||||
2. WHEN 浏览器不支持 requestAnimationFrame THEN THE System SHALL 使用 setTimeout 降级
|
||||
3. WHEN 浏览器不支持 SVG THEN THE System SHALL 显示不支持提示
|
||||
4. WHEN 移动端浏览器 THEN THE System SHALL 优化触摸事件处理
|
||||
5. WHEN 旧版浏览器 THEN THE System SHALL 提供 polyfill 或禁用高级功能
|
||||
|
||||
### Requirement 16: 内存管理
|
||||
|
||||
**User Story:** 作为开发者,我希望系统能正确管理内存,避免内存泄漏。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN PJAX 切换页面 THEN THE System SHALL 清理所有 Mermaid 实例
|
||||
2. WHEN 清理实例 THEN THE System SHALL 移除所有事件监听器
|
||||
3. WHEN 清理实例 THEN THE System SHALL 移除所有 DOM 引用
|
||||
4. WHEN 清理实例 THEN THE System SHALL 清空图表缓存
|
||||
5. WHEN 重新渲染 THEN THE System SHALL 先清理旧实例,再创建新实例
|
||||
|
||||
### Requirement 17: 配置和扩展性
|
||||
|
||||
**User Story:** 作为开发者,我希望系统配置灵活,易于扩展。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 初始化 Mermaid THEN THE System SHALL 从全局配置读取主题设置
|
||||
2. WHEN 配置改变 THEN THE System SHALL 支持动态更新配置
|
||||
3. WHEN 添加新功能 THEN THE System SHALL 使用模块化设计,易于扩展
|
||||
4. WHEN 自定义主题 THEN THE System SHALL 支持自定义 Mermaid 主题配置
|
||||
5. WHEN 禁用功能 THEN THE System SHALL 支持通过配置禁用特定功能
|
||||
|
||||
### Requirement 18: 安全性
|
||||
|
||||
**User Story:** 作为开发者,我希望系统能防止 XSS 攻击和其他安全问题。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 渲染图表 THEN THE System SHALL 使用 Mermaid 的安全模式(securityLevel)
|
||||
2. WHEN 处理用户输入 THEN THE System SHALL 转义特殊字符,防止 XSS
|
||||
3. WHEN 导出图表 THEN THE System SHALL 验证文件名,防止路径遍历
|
||||
4. WHEN 执行脚本 THEN THE System SHALL 使用沙箱环境,限制权限
|
||||
5. WHEN 加载外部资源 THEN THE System SHALL 验证来源,防止 CSRF
|
||||
|
||||
Reference in New Issue
Block a user