feat: 实现 Mermaid 库加载失败的降级处理机制
- 添加多 CDN 备选方案(jsdelivr、unpkg、本地镜像) - 实现递归加载逻辑,主 CDN 失败时自动尝试备用 CDN - 添加 onerror 事件处理,捕获库加载失败 - 所有 CDN 失败时显示友好的错误提示 - 在错误提示中保留原始代码供用户查看 - 添加详细的控制台日志输出 - 创建 PHP 和 HTML 测试文件验证功能 - 暴露 MermaidRenderer 到全局作用域供降级处理使用 Requirements: 1.4, 2.3, 7.1, 7.2, 7.3, 7.4, 7.5
This commit is contained in:
977
.kiro/specs/mermaid-support/design.md
Normal file
977
.kiro/specs/mermaid-support/design.md
Normal file
@@ -0,0 +1,977 @@
|
||||
# Design Document: Mermaid 图表支持
|
||||
|
||||
## Overview
|
||||
|
||||
本设计文档描述了在 Argon WordPress 主题中集成 Mermaid 图表支持的技术方案。由于 WP-Markdown 编辑器的特殊渲染方式(将 Mermaid 代码块保存为单行,缺少真正的换行符),直接集成 Mermaid 存在技术障碍。
|
||||
|
||||
本设计采用**插件兼容方案**,通过支持主流 Mermaid WordPress 插件(如 WP Githuber MD、Markdown Block 等)来实现功能,同时提供主题级别的样式优化、夜间模式适配和性能优化。
|
||||
|
||||
### 核心设计原则
|
||||
|
||||
1. **插件优先**:依赖成熟的 Mermaid 插件处理代码解析和渲染
|
||||
2. **主题增强**:提供样式优化、主题适配和性能优化
|
||||
3. **灵活配置**:支持 CDN/本地加载、多种主题、调试模式
|
||||
4. **优雅降级**:加载失败时提供备用方案和友好提示
|
||||
5. **性能优先**:按需加载、异步加载、缓存优化
|
||||
|
||||
## Architecture
|
||||
|
||||
### 系统架构图
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ WordPress 前端页面 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
├─ 包含 Mermaid 代码块?
|
||||
│
|
||||
┌─────────┴─────────┐
|
||||
│ │
|
||||
是 否
|
||||
│ │
|
||||
▼ ▼
|
||||
┌──────────────────┐ ┌──────────┐
|
||||
│ 加载 Mermaid 库 │ │ 不加载 │
|
||||
└──────────────────┘ └──────────┘
|
||||
│
|
||||
├─ CDN 模式 / 本地模式
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ Mermaid.js 库 │
|
||||
└──────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ 代码块检测器 │
|
||||
│ - class="mermaid"│
|
||||
│ - language="mermaid"│
|
||||
│ - data-lang="mermaid"│
|
||||
└──────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ 渲染引擎 │
|
||||
│ - 初始化配置 │
|
||||
│ - 主题适配 │
|
||||
│ - 错误处理 │
|
||||
└──────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ 样式增强器 │
|
||||
│ - 容器样式 │
|
||||
│ - 响应式适配 │
|
||||
│ - 夜间模式 │
|
||||
└──────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────┐
|
||||
│ 渲染后的 SVG │
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
### 组件交互流程
|
||||
|
||||
```
|
||||
用户访问页面
|
||||
│
|
||||
▼
|
||||
WordPress 渲染页面
|
||||
│
|
||||
▼
|
||||
主题检测页面内容
|
||||
│
|
||||
├─ 是否包含 Mermaid 代码块?
|
||||
│
|
||||
▼ (是)
|
||||
加载 Mermaid 库 (CDN/本地)
|
||||
│
|
||||
▼
|
||||
DOMContentLoaded 事件触发
|
||||
│
|
||||
▼
|
||||
初始化 Mermaid 配置
|
||||
│
|
||||
├─ 设置主题 (日间/夜间)
|
||||
├─ 设置安全级别
|
||||
└─ 设置错误处理
|
||||
│
|
||||
▼
|
||||
检测所有 Mermaid 代码块
|
||||
│
|
||||
▼
|
||||
批量渲染图表
|
||||
│
|
||||
├─ 成功 → 应用样式增强
|
||||
└─ 失败 → 显示错误提示
|
||||
│
|
||||
▼
|
||||
监听主题切换事件
|
||||
│
|
||||
▼
|
||||
重新渲染图表 (如需要)
|
||||
```
|
||||
|
||||
|
||||
## Components and Interfaces
|
||||
|
||||
### 1. 配置管理组件 (Configuration Manager)
|
||||
|
||||
**职责**:管理 Mermaid 相关的所有配置选项
|
||||
|
||||
**接口**:
|
||||
```php
|
||||
// 获取配置选项
|
||||
function argon_get_mermaid_option($option_name, $default = null)
|
||||
|
||||
// 保存配置选项
|
||||
function argon_update_mermaid_option($option_name, $value)
|
||||
|
||||
// 验证 CDN 地址格式
|
||||
function argon_validate_mermaid_cdn_url($url)
|
||||
|
||||
// 获取当前主题模式对应的 Mermaid 主题
|
||||
function argon_get_mermaid_theme()
|
||||
```
|
||||
|
||||
**配置选项**:
|
||||
- `argon_enable_mermaid`: 启用/禁用 Mermaid 支持 (true/false)
|
||||
- `argon_mermaid_cdn_source`: CDN 来源 (jsdelivr/unpkg/custom/local)
|
||||
- `argon_mermaid_cdn_custom_url`: 自定义 CDN 地址
|
||||
- `argon_mermaid_theme`: 图表主题 (default/dark/forest/neutral/auto)
|
||||
- `argon_mermaid_use_local`: 使用本地镜像 (true/false)
|
||||
- `argon_mermaid_debug_mode`: 调试模式 (true/false)
|
||||
|
||||
### 2. 库加载器 (Library Loader)
|
||||
|
||||
**职责**:负责检测页面内容并按需加载 Mermaid 库
|
||||
|
||||
**接口**:
|
||||
```php
|
||||
// 检测页面是否包含 Mermaid 代码块
|
||||
function argon_has_mermaid_content($content)
|
||||
|
||||
// 加载 Mermaid 库
|
||||
function argon_enqueue_mermaid_scripts()
|
||||
|
||||
// 获取 Mermaid 库 URL
|
||||
function argon_get_mermaid_library_url()
|
||||
```
|
||||
|
||||
**实现逻辑**:
|
||||
1. 在 `wp_enqueue_scripts` 钩子中检查当前页面内容
|
||||
2. 使用正则表达式检测 Mermaid 代码块标记
|
||||
3. 如果检测到,根据配置加载对应的库文件
|
||||
4. 添加 async 或 defer 属性实现异步加载
|
||||
|
||||
**CDN 地址映射**:
|
||||
```php
|
||||
$cdn_urls = [
|
||||
'jsdelivr' => 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js',
|
||||
'unpkg' => 'https://unpkg.com/mermaid@10/dist/mermaid.min.js',
|
||||
'local' => get_template_directory_uri() . '/assets/vendor/mermaid/mermaid.min.js'
|
||||
];
|
||||
```
|
||||
|
||||
### 3. 渲染引擎初始化器 (Render Engine Initializer)
|
||||
|
||||
**职责**:初始化 Mermaid 配置并启动渲染
|
||||
|
||||
**接口**:
|
||||
```javascript
|
||||
// 初始化 Mermaid 配置
|
||||
function initMermaidConfig()
|
||||
|
||||
// 获取当前主题对应的 Mermaid 主题
|
||||
function getMermaidTheme()
|
||||
|
||||
// 渲染所有 Mermaid 图表
|
||||
function renderAllMermaidCharts()
|
||||
|
||||
// 重新渲染图表(主题切换时)
|
||||
function reRenderMermaidCharts()
|
||||
```
|
||||
|
||||
**Mermaid 配置对象**:
|
||||
```javascript
|
||||
{
|
||||
startOnLoad: false, // 手动控制渲染时机
|
||||
theme: 'default', // 根据页面主题动态设置
|
||||
securityLevel: 'loose', // 允许 HTML 标签
|
||||
logLevel: 'error', // 生产环境使用 error,调试模式使用 debug
|
||||
flowchart: {
|
||||
useMaxWidth: true,
|
||||
htmlLabels: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 代码块检测器 (Code Block Detector)
|
||||
|
||||
**职责**:识别页面中的 Mermaid 代码块
|
||||
|
||||
**接口**:
|
||||
```javascript
|
||||
// 检测所有 Mermaid 代码块
|
||||
function detectMermaidBlocks()
|
||||
|
||||
// 检查元素是否为 Mermaid 代码块
|
||||
function isMermaidBlock(element)
|
||||
|
||||
// 提取代码块内容
|
||||
function extractMermaidCode(element)
|
||||
```
|
||||
|
||||
**检测规则**(优先级从高到低):
|
||||
1. `<div class="mermaid">` - 标准格式
|
||||
2. `<pre><code class="language-mermaid">` - Markdown 格式
|
||||
3. `<pre data-lang="mermaid">` - 自定义属性格式
|
||||
4. `<code class="mermaid">` - 简化格式
|
||||
|
||||
**特殊处理**:
|
||||
- 忽略 HTML 注释中的代码块
|
||||
- 处理 WP-Markdown 生成的 `<script>document.write()</script>` 格式
|
||||
- 解码转义字符(`\n`, `\"`, `\'`)
|
||||
|
||||
### 5. 样式增强器 (Style Enhancer)
|
||||
|
||||
**职责**:为渲染后的图表添加主题样式
|
||||
|
||||
**接口**:
|
||||
```javascript
|
||||
// 应用容器样式
|
||||
function applyMermaidContainerStyles(container)
|
||||
|
||||
// 应用响应式样式
|
||||
function applyResponsiveStyles(container)
|
||||
|
||||
// 应用夜间模式样式
|
||||
function applyDarkModeStyles(container, isDarkMode)
|
||||
```
|
||||
|
||||
**CSS 样式类**:
|
||||
```css
|
||||
.mermaid-container {
|
||||
background: var(--card-background);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 20px 0;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
overflow-x: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.mermaid-container svg {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
html.darkmode .mermaid-container {
|
||||
background: var(--card-background-dark);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 错误处理器 (Error Handler)
|
||||
|
||||
**职责**:处理渲染错误并显示友好提示
|
||||
|
||||
**接口**:
|
||||
```javascript
|
||||
// 处理渲染错误
|
||||
function handleMermaidError(error, element)
|
||||
|
||||
// 显示错误提示
|
||||
function showErrorMessage(element, errorInfo)
|
||||
|
||||
// 记录调试信息
|
||||
function logDebugInfo(message, data)
|
||||
```
|
||||
|
||||
**错误提示格式**:
|
||||
```html
|
||||
<div class="mermaid-error">
|
||||
<div class="error-icon">⚠️</div>
|
||||
<div class="error-title">Mermaid 图表渲染失败</div>
|
||||
<div class="error-message">错误类型: 语法错误</div>
|
||||
<div class="error-details">行号: 3</div>
|
||||
<details>
|
||||
<summary>查看原始代码</summary>
|
||||
<pre><code>...</code></pre>
|
||||
</details>
|
||||
</div>
|
||||
```
|
||||
|
||||
### 7. 主题切换监听器 (Theme Switch Listener)
|
||||
|
||||
**职责**:监听主题模式切换并重新渲染图表
|
||||
|
||||
**接口**:
|
||||
```javascript
|
||||
// 监听主题切换事件
|
||||
function listenThemeSwitch()
|
||||
|
||||
// 主题切换回调
|
||||
function onThemeSwitched(isDarkMode)
|
||||
|
||||
// 批量重新渲染
|
||||
function batchReRender(elements)
|
||||
```
|
||||
|
||||
**实现方式**:
|
||||
- 监听 Argon 主题的 `argon:theme-switched` 自定义事件
|
||||
- 监听 `html` 元素的 `darkmode` class 变化(MutationObserver)
|
||||
- 使用防抖避免频繁重新渲染
|
||||
|
||||
### 8. 插件兼容层 (Plugin Compatibility Layer)
|
||||
|
||||
**职责**:检测并兼容主流 Mermaid 插件
|
||||
|
||||
**接口**:
|
||||
```php
|
||||
// 检测已安装的 Mermaid 插件
|
||||
function argon_detect_mermaid_plugins()
|
||||
|
||||
// 检查是否已加载 Mermaid 库
|
||||
function argon_is_mermaid_loaded()
|
||||
|
||||
// 避免重复加载
|
||||
function argon_prevent_duplicate_loading()
|
||||
```
|
||||
|
||||
**支持的插件**:
|
||||
1. **WP Githuber MD** - 检测 `wp-githuber-md` 插件
|
||||
2. **Markdown Block** - 检测 Gutenberg Mermaid 块
|
||||
3. **Code Syntax Block** - 检测代码高亮插件的 Mermaid 支持
|
||||
|
||||
**兼容策略**:
|
||||
- 如果插件已加载 Mermaid 库,主题不再重复加载
|
||||
- 主题只提供样式增强和主题适配
|
||||
- 通过 `window.mermaid` 对象检测库是否已加载
|
||||
|
||||
|
||||
## Data Models
|
||||
|
||||
### 1. Mermaid 配置对象
|
||||
|
||||
```javascript
|
||||
interface MermaidConfig {
|
||||
enabled: boolean; // 是否启用
|
||||
cdnSource: string; // CDN 来源: 'jsdelivr' | 'unpkg' | 'custom' | 'local'
|
||||
customCdnUrl: string; // 自定义 CDN 地址
|
||||
theme: string; // 图表主题: 'default' | 'dark' | 'forest' | 'neutral' | 'auto'
|
||||
useLocal: boolean; // 是否使用本地镜像
|
||||
debugMode: boolean; // 调试模式
|
||||
autoThemeSwitch: boolean; // 自动切换主题
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 代码块元素对象
|
||||
|
||||
```javascript
|
||||
interface MermaidBlock {
|
||||
element: HTMLElement; // DOM 元素
|
||||
code: string; // Mermaid 代码
|
||||
type: string; // 代码块类型: 'div' | 'pre-code' | 'custom'
|
||||
rendered: boolean; // 是否已渲染
|
||||
error: Error | null; // 渲染错误
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 渲染结果对象
|
||||
|
||||
```javascript
|
||||
interface RenderResult {
|
||||
success: boolean; // 是否成功
|
||||
svg: string; // 渲染后的 SVG
|
||||
error: {
|
||||
type: string; // 错误类型
|
||||
message: string; // 错误信息
|
||||
line: number; // 错误行号
|
||||
} | null;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 插件检测结果
|
||||
|
||||
```php
|
||||
interface PluginDetectionResult {
|
||||
'wp-githuber-md': boolean; // WP Githuber MD
|
||||
'markdown-block': boolean; // Markdown Block
|
||||
'code-syntax-block': boolean; // Code Syntax Block
|
||||
'mermaid-loaded': boolean; // Mermaid 库是否已加载
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 错误信息对象
|
||||
|
||||
```javascript
|
||||
interface ErrorInfo {
|
||||
type: string; // 错误类型: 'syntax' | 'render' | 'load'
|
||||
message: string; // 错误信息
|
||||
line: number | null; // 错误行号
|
||||
code: string; // 原始代码
|
||||
timestamp: number; // 时间戳
|
||||
}
|
||||
```
|
||||
|
||||
## Correctness Properties
|
||||
|
||||
*属性是一种特征或行为,应该在系统的所有有效执行中保持为真——本质上是关于系统应该做什么的正式陈述。属性作为人类可读规范和机器可验证正确性保证之间的桥梁。*
|
||||
|
||||
### Property 1: 按需加载库
|
||||
|
||||
*对于任意* WordPress 页面,当且仅当页面内容包含 Mermaid 代码块时,主题应该加载 Mermaid JavaScript 库。
|
||||
|
||||
**Validates: Requirements 1.1, 1.5, 8.1**
|
||||
|
||||
### Property 2: CDN 地址正确性
|
||||
|
||||
*对于任意* CDN 配置选项(jsdelivr、unpkg、custom、local),生成的脚本 URL 应该与配置选项对应的 CDN 地址匹配。
|
||||
|
||||
**Validates: Requirements 1.2, 1.3**
|
||||
|
||||
### Property 3: 代码块识别完整性
|
||||
|
||||
*对于任意* 包含 Mermaid 标记的 HTML 元素(class="mermaid"、language="mermaid"、data-lang="mermaid"),检测器应该能够识别并提取其中的 Mermaid 代码。
|
||||
|
||||
**Validates: Requirements 10.1, 10.2, 10.3**
|
||||
|
||||
### Property 4: 渲染成功后替换内容
|
||||
|
||||
*对于任意* 成功渲染的 Mermaid 图表,原始代码块文本应该被移除,并替换为渲染后的 SVG 图表。
|
||||
|
||||
**Validates: Requirements 2.4**
|
||||
|
||||
### Property 5: 错误时保留原始代码
|
||||
|
||||
*对于任意* 渲染失败的 Mermaid 代码块,系统应该显示错误提示信息,并保留原始代码块以便用户修正。
|
||||
|
||||
**Validates: Requirements 7.1, 7.4**
|
||||
|
||||
### Property 6: 主题模式自动切换
|
||||
|
||||
*对于任意* 页面主题模式切换(日间↔夜间),当配置为自动切换时,所有 Mermaid 图表应该重新渲染并使用对应的图表主题(浅色↔深色)。
|
||||
|
||||
**Validates: Requirements 4.1, 4.2, 4.3**
|
||||
|
||||
### Property 7: 自定义主题优先级
|
||||
|
||||
*对于任意* 图表,当管理员设置了自定义图表主题时,应该使用自定义主题而不是根据页面主题自动切换。
|
||||
|
||||
**Validates: Requirements 4.5**
|
||||
|
||||
### Property 8: 响应式容器宽度
|
||||
|
||||
*对于任意* 渲染后的 Mermaid 图表容器,其最大宽度应该设置为 100%,并且当图表宽度超过容器时应该启用横向滚动。
|
||||
|
||||
**Validates: Requirements 3.1, 3.3**
|
||||
|
||||
### Property 9: 移动端自适应
|
||||
|
||||
*对于任意* 屏幕宽度小于 768px 的设备,Mermaid 图表应该自动调整大小以适应屏幕宽度,不应该出现横向溢出。
|
||||
|
||||
**Validates: Requirements 3.2**
|
||||
|
||||
### Property 10: 夜间模式样式适配
|
||||
|
||||
*对于任意* Mermaid 图表容器,在夜间模式下应该应用深色背景和边框样式,与页面整体风格保持一致。
|
||||
|
||||
**Validates: Requirements 6.5**
|
||||
|
||||
### Property 11: 卡片内边距
|
||||
|
||||
*对于任意* 在卡片中显示的 Mermaid 图表,容器应该添加适当的内边距(padding),确保图表与卡片边缘有足够的间距。
|
||||
|
||||
**Validates: Requirements 6.3**
|
||||
|
||||
### Property 12: CDN 地址验证
|
||||
|
||||
*对于任意* 用户输入的自定义 CDN 地址,保存前应该验证其格式是否为有效的 URL,并且以 `.js` 结尾。
|
||||
|
||||
**Validates: Requirements 5.5**
|
||||
|
||||
### Property 13: 避免重复加载
|
||||
|
||||
*对于任意* 页面,当检测到已有 Mermaid 插件加载了 Mermaid 库时,主题不应该重复加载该库。
|
||||
|
||||
**Validates: Requirements 9.4**
|
||||
|
||||
### Property 14: 错误信息完整性
|
||||
|
||||
*对于任意* Mermaid 解析错误,错误提示信息应该包含错误类型和详细的错误描述,帮助用户定位问题。
|
||||
|
||||
**Validates: Requirements 7.3**
|
||||
|
||||
### Property 15: 批量渲染性能
|
||||
|
||||
*对于任意* 包含多个 Mermaid 图表的页面,所有图表应该在一次 DOM 遍历中批量收集,然后批量渲染,而不是逐个渲染。
|
||||
|
||||
**Validates: Requirements 8.4**
|
||||
|
||||
### Property 16: 渲染缓存
|
||||
|
||||
*对于任意* 已成功渲染的 Mermaid 图表,在页面生命周期内不应该重复渲染,除非主题模式发生切换。
|
||||
|
||||
**Validates: Requirements 8.3**
|
||||
|
||||
### Property 17: 代码块优先级
|
||||
|
||||
*对于任意* 同时包含多个 Mermaid 标记的元素(如同时有 class="mermaid" 和 data-lang="mermaid"),应该优先使用 class 属性进行识别。
|
||||
|
||||
**Validates: Requirements 10.4**
|
||||
|
||||
### Property 18: 忽略注释代码块
|
||||
|
||||
*对于任意* 被 HTML 注释包裹的 Mermaid 代码块,检测器应该忽略它们,不进行渲染。
|
||||
|
||||
**Validates: Requirements 10.5**
|
||||
|
||||
## Error Handling
|
||||
|
||||
### 1. 库加载失败
|
||||
|
||||
**场景**:CDN 不可用或网络问题导致 Mermaid 库加载失败
|
||||
|
||||
**处理策略**:
|
||||
1. 监听脚本 `onerror` 事件
|
||||
2. 在控制台输出详细错误信息
|
||||
3. 尝试降级到备用 CDN(jsdelivr → unpkg → local)
|
||||
4. 如果所有 CDN 都失败,显示全局提示信息
|
||||
|
||||
**实现**:
|
||||
```javascript
|
||||
function loadMermaidWithFallback(urls, index = 0) {
|
||||
if (index >= urls.length) {
|
||||
console.error('[Argon Mermaid] 所有 CDN 加载失败');
|
||||
showGlobalError('Mermaid 库加载失败,请检查网络连接');
|
||||
return;
|
||||
}
|
||||
|
||||
const script = document.createElement('script');
|
||||
script.src = urls[index];
|
||||
script.async = true;
|
||||
|
||||
script.onerror = () => {
|
||||
console.warn(`[Argon Mermaid] CDN ${urls[index]} 加载失败,尝试备用 CDN`);
|
||||
loadMermaidWithFallback(urls, index + 1);
|
||||
};
|
||||
|
||||
script.onload = () => {
|
||||
console.log(`[Argon Mermaid] 成功从 ${urls[index]} 加载库`);
|
||||
initMermaid();
|
||||
};
|
||||
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 代码解析错误
|
||||
|
||||
**场景**:Mermaid 代码语法错误导致解析失败
|
||||
|
||||
**处理策略**:
|
||||
1. 捕获 Mermaid 渲染异常
|
||||
2. 提取错误类型和行号信息
|
||||
3. 在原代码块位置显示友好的错误提示
|
||||
4. 保留原始代码供用户查看和修正
|
||||
5. 在调试模式下输出详细堆栈信息
|
||||
|
||||
**错误提示 UI**:
|
||||
```html
|
||||
<div class="mermaid-error-container">
|
||||
<div class="error-header">
|
||||
<span class="error-icon">⚠️</span>
|
||||
<span class="error-title">图表渲染失败</span>
|
||||
</div>
|
||||
<div class="error-body">
|
||||
<p class="error-type">错误类型: 语法错误</p>
|
||||
<p class="error-message">Expecting 'NEWLINE', 'SPACE', got 'GRAPH'</p>
|
||||
<p class="error-line">位置: 第 3 行</p>
|
||||
</div>
|
||||
<details class="error-code">
|
||||
<summary>查看原始代码</summary>
|
||||
<pre><code class="language-mermaid">...</code></pre>
|
||||
</details>
|
||||
</div>
|
||||
```
|
||||
|
||||
### 3. 配置验证错误
|
||||
|
||||
**场景**:管理员输入无效的配置选项
|
||||
|
||||
**处理策略**:
|
||||
1. 在保存前验证所有配置项
|
||||
2. CDN URL 格式验证(必须是有效 URL 且以 .js 结尾)
|
||||
3. 主题名称验证(必须是预定义的主题之一)
|
||||
4. 显示具体的验证错误信息
|
||||
5. 阻止保存无效配置
|
||||
|
||||
**验证函数**:
|
||||
```php
|
||||
function argon_validate_mermaid_settings($settings) {
|
||||
$errors = [];
|
||||
|
||||
// 验证 CDN URL
|
||||
if ($settings['cdn_source'] === 'custom') {
|
||||
$url = $settings['custom_cdn_url'];
|
||||
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
||||
$errors[] = 'CDN 地址格式无效';
|
||||
} elseif (!preg_match('/\.js$/', $url)) {
|
||||
$errors[] = 'CDN 地址必须以 .js 结尾';
|
||||
}
|
||||
}
|
||||
|
||||
// 验证主题名称
|
||||
$valid_themes = ['default', 'dark', 'forest', 'neutral', 'auto'];
|
||||
if (!in_array($settings['theme'], $valid_themes)) {
|
||||
$errors[] = '无效的图表主题';
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 插件冲突
|
||||
|
||||
**场景**:多个插件同时加载 Mermaid 库导致冲突
|
||||
|
||||
**处理策略**:
|
||||
1. 在加载前检测 `window.mermaid` 是否已存在
|
||||
2. 如果已存在,跳过库加载,只应用样式增强
|
||||
3. 记录检测结果到控制台
|
||||
4. 在设置页显示插件兼容性状态
|
||||
|
||||
**检测逻辑**:
|
||||
```javascript
|
||||
function checkMermaidLoaded() {
|
||||
if (typeof window.mermaid !== 'undefined') {
|
||||
console.log('[Argon Mermaid] 检测到 Mermaid 库已由其他插件加载');
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 主题切换异常
|
||||
|
||||
**场景**:主题切换时重新渲染失败
|
||||
|
||||
**处理策略**:
|
||||
1. 使用 try-catch 包裹重新渲染逻辑
|
||||
2. 如果重新渲染失败,保留原有图表
|
||||
3. 在控制台输出警告信息
|
||||
4. 不影响页面其他功能
|
||||
|
||||
**实现**:
|
||||
```javascript
|
||||
function reRenderOnThemeSwitch() {
|
||||
const charts = document.querySelectorAll('.mermaid-rendered');
|
||||
|
||||
charts.forEach(chart => {
|
||||
try {
|
||||
const code = chart.dataset.mermaidCode;
|
||||
const newTheme = getMermaidTheme();
|
||||
|
||||
mermaid.initialize({ theme: newTheme });
|
||||
mermaid.render('mermaid-' + Date.now(), code, (svg) => {
|
||||
chart.innerHTML = svg;
|
||||
});
|
||||
} catch (error) {
|
||||
console.warn('[Argon Mermaid] 重新渲染失败,保留原图表', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### 测试方法概述
|
||||
|
||||
本功能采用**双重测试策略**:
|
||||
- **单元测试**:验证具体示例、边缘情况和错误条件
|
||||
- **属性测试**:验证跨所有输入的通用属性
|
||||
|
||||
两者互补且都是全面覆盖所需的:
|
||||
- 单元测试捕获具体的 bug
|
||||
- 属性测试验证一般正确性
|
||||
|
||||
### 单元测试策略
|
||||
|
||||
单元测试应专注于:
|
||||
- **具体示例**:演示正确行为的特定案例
|
||||
- **集成点**:组件之间的交互
|
||||
- **边缘情况和错误条件**:特殊场景处理
|
||||
|
||||
**测试框架**:使用 PHPUnit(PHP 部分)和 Jest(JavaScript 部分)
|
||||
|
||||
**PHP 单元测试示例**:
|
||||
```php
|
||||
// 测试 CDN URL 验证
|
||||
public function test_validate_cdn_url_with_valid_url() {
|
||||
$url = 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js';
|
||||
$this->assertTrue(argon_validate_mermaid_cdn_url($url));
|
||||
}
|
||||
|
||||
public function test_validate_cdn_url_with_invalid_url() {
|
||||
$url = 'not-a-valid-url';
|
||||
$this->assertFalse(argon_validate_mermaid_cdn_url($url));
|
||||
}
|
||||
|
||||
// 测试代码块检测
|
||||
public function test_has_mermaid_content_with_div_class() {
|
||||
$content = '<div class="mermaid">flowchart TD</div>';
|
||||
$this->assertTrue(argon_has_mermaid_content($content));
|
||||
}
|
||||
|
||||
public function test_has_mermaid_content_without_mermaid() {
|
||||
$content = '<p>Regular paragraph</p>';
|
||||
$this->assertFalse(argon_has_mermaid_content($content));
|
||||
}
|
||||
```
|
||||
|
||||
**JavaScript 单元测试示例**:
|
||||
```javascript
|
||||
// 测试主题获取
|
||||
test('getMermaidTheme returns dark theme in dark mode', () => {
|
||||
document.documentElement.classList.add('darkmode');
|
||||
expect(getMermaidTheme()).toBe('dark');
|
||||
});
|
||||
|
||||
test('getMermaidTheme returns default theme in light mode', () => {
|
||||
document.documentElement.classList.remove('darkmode');
|
||||
expect(getMermaidTheme()).toBe('default');
|
||||
});
|
||||
|
||||
// 测试代码块检测
|
||||
test('isMermaidBlock detects div with mermaid class', () => {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'mermaid';
|
||||
expect(isMermaidBlock(div)).toBe(true);
|
||||
});
|
||||
|
||||
test('isMermaidBlock ignores regular div', () => {
|
||||
const div = document.createElement('div');
|
||||
expect(isMermaidBlock(div)).toBe(false);
|
||||
});
|
||||
```
|
||||
|
||||
### 属性测试策略
|
||||
|
||||
**测试框架**:使用 fast-check(JavaScript)进行属性测试
|
||||
|
||||
**配置要求**:
|
||||
- 每个属性测试最少运行 100 次迭代
|
||||
- 每个测试必须引用设计文档中的属性
|
||||
- 标签格式:`Feature: mermaid-support, Property {number}: {property_text}`
|
||||
|
||||
**属性测试示例**:
|
||||
|
||||
```javascript
|
||||
// Feature: mermaid-support, Property 1: 按需加载库
|
||||
// 对于任意 WordPress 页面,当且仅当页面内容包含 Mermaid 代码块时,主题应该加载 Mermaid JavaScript 库
|
||||
fc.assert(
|
||||
fc.property(
|
||||
fc.string(), // 生成随机页面内容
|
||||
fc.boolean(), // 是否包含 Mermaid 代码块
|
||||
(content, hasMermaid) => {
|
||||
const pageContent = hasMermaid
|
||||
? content + '<div class="mermaid">flowchart TD</div>'
|
||||
: content;
|
||||
|
||||
const shouldLoad = argon_has_mermaid_content(pageContent);
|
||||
expect(shouldLoad).toBe(hasMermaid);
|
||||
}
|
||||
),
|
||||
{ numRuns: 100 }
|
||||
);
|
||||
|
||||
// Feature: mermaid-support, Property 2: CDN 地址正确性
|
||||
// 对于任意 CDN 配置选项,生成的脚本 URL 应该与配置选项对应的 CDN 地址匹配
|
||||
fc.assert(
|
||||
fc.property(
|
||||
fc.constantFrom('jsdelivr', 'unpkg', 'local'),
|
||||
(cdnSource) => {
|
||||
const expectedUrls = {
|
||||
'jsdelivr': 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js',
|
||||
'unpkg': 'https://unpkg.com/mermaid@10/dist/mermaid.min.js',
|
||||
'local': '/wp-content/themes/argon/assets/vendor/mermaid/mermaid.min.js'
|
||||
};
|
||||
|
||||
const actualUrl = argon_get_mermaid_library_url(cdnSource);
|
||||
expect(actualUrl).toContain(expectedUrls[cdnSource]);
|
||||
}
|
||||
),
|
||||
{ numRuns: 100 }
|
||||
);
|
||||
|
||||
// Feature: mermaid-support, Property 3: 代码块识别完整性
|
||||
// 对于任意包含 Mermaid 标记的 HTML 元素,检测器应该能够识别并提取其中的 Mermaid 代码
|
||||
fc.assert(
|
||||
fc.property(
|
||||
fc.constantFrom('class', 'language', 'data-lang'),
|
||||
fc.string({ minLength: 10 }),
|
||||
(markType, code) => {
|
||||
let element;
|
||||
switch (markType) {
|
||||
case 'class':
|
||||
element = document.createElement('div');
|
||||
element.className = 'mermaid';
|
||||
element.textContent = code;
|
||||
break;
|
||||
case 'language':
|
||||
element = document.createElement('pre');
|
||||
const codeEl = document.createElement('code');
|
||||
codeEl.className = 'language-mermaid';
|
||||
codeEl.textContent = code;
|
||||
element.appendChild(codeEl);
|
||||
break;
|
||||
case 'data-lang':
|
||||
element = document.createElement('pre');
|
||||
element.setAttribute('data-lang', 'mermaid');
|
||||
element.textContent = code;
|
||||
break;
|
||||
}
|
||||
|
||||
expect(isMermaidBlock(element)).toBe(true);
|
||||
expect(extractMermaidCode(element)).toBe(code);
|
||||
}
|
||||
),
|
||||
{ numRuns: 100 }
|
||||
);
|
||||
|
||||
// Feature: mermaid-support, Property 6: 主题模式自动切换
|
||||
// 对于任意页面主题模式切换,当配置为自动切换时,所有 Mermaid 图表应该重新渲染并使用对应的图表主题
|
||||
fc.assert(
|
||||
fc.property(
|
||||
fc.boolean(), // 初始主题模式
|
||||
fc.integer({ min: 1, max: 10 }), // 图表数量
|
||||
(initialDarkMode, chartCount) => {
|
||||
// 设置初始主题
|
||||
if (initialDarkMode) {
|
||||
document.documentElement.classList.add('darkmode');
|
||||
} else {
|
||||
document.documentElement.classList.remove('darkmode');
|
||||
}
|
||||
|
||||
// 创建多个图表
|
||||
const charts = [];
|
||||
for (let i = 0; i < chartCount; i++) {
|
||||
const chart = document.createElement('div');
|
||||
chart.className = 'mermaid-rendered';
|
||||
chart.dataset.mermaidCode = 'flowchart TD\nA-->B';
|
||||
document.body.appendChild(chart);
|
||||
charts.push(chart);
|
||||
}
|
||||
|
||||
// 切换主题
|
||||
const newDarkMode = !initialDarkMode;
|
||||
if (newDarkMode) {
|
||||
document.documentElement.classList.add('darkmode');
|
||||
} else {
|
||||
document.documentElement.classList.remove('darkmode');
|
||||
}
|
||||
|
||||
// 触发重新渲染
|
||||
reRenderOnThemeSwitch();
|
||||
|
||||
// 验证所有图表都使用了新主题
|
||||
const expectedTheme = newDarkMode ? 'dark' : 'default';
|
||||
charts.forEach(chart => {
|
||||
expect(chart.dataset.currentTheme).toBe(expectedTheme);
|
||||
});
|
||||
|
||||
// 清理
|
||||
charts.forEach(chart => chart.remove());
|
||||
}
|
||||
),
|
||||
{ numRuns: 100 }
|
||||
);
|
||||
|
||||
// Feature: mermaid-support, Property 12: CDN 地址验证
|
||||
// 对于任意用户输入的自定义 CDN 地址,保存前应该验证其格式是否为有效的 URL,并且以 .js 结尾
|
||||
fc.assert(
|
||||
fc.property(
|
||||
fc.webUrl(), // 生成随机 URL
|
||||
fc.constantFrom('.js', '.css', '.json', ''), // 不同的文件扩展名
|
||||
(baseUrl, extension) => {
|
||||
const url = baseUrl + extension;
|
||||
const isValid = argon_validate_mermaid_cdn_url(url);
|
||||
|
||||
// 只有以 .js 结尾的有效 URL 才应该通过验证
|
||||
const shouldBeValid = extension === '.js';
|
||||
expect(isValid).toBe(shouldBeValid);
|
||||
}
|
||||
),
|
||||
{ numRuns: 100 }
|
||||
);
|
||||
|
||||
// Feature: mermaid-support, Property 15: 批量渲染性能
|
||||
// 对于任意包含多个 Mermaid 图表的页面,所有图表应该在一次 DOM 遍历中批量收集,然后批量渲染
|
||||
fc.assert(
|
||||
fc.property(
|
||||
fc.integer({ min: 1, max: 20 }), // 图表数量
|
||||
(chartCount) => {
|
||||
// 创建多个图表
|
||||
for (let i = 0; i < chartCount; i++) {
|
||||
const div = document.createElement('div');
|
||||
div.className = 'mermaid';
|
||||
div.textContent = `flowchart TD\nA${i}-->B${i}`;
|
||||
document.body.appendChild(div);
|
||||
}
|
||||
|
||||
// 记录 DOM 查询次数
|
||||
let queryCount = 0;
|
||||
const originalQuerySelectorAll = document.querySelectorAll;
|
||||
document.querySelectorAll = function(...args) {
|
||||
queryCount++;
|
||||
return originalQuerySelectorAll.apply(this, args);
|
||||
};
|
||||
|
||||
// 执行批量渲染
|
||||
renderAllMermaidCharts();
|
||||
|
||||
// 恢复原始方法
|
||||
document.querySelectorAll = originalQuerySelectorAll;
|
||||
|
||||
// 验证只进行了一次 DOM 查询
|
||||
expect(queryCount).toBe(1);
|
||||
|
||||
// 清理
|
||||
document.querySelectorAll('.mermaid').forEach(el => el.remove());
|
||||
}
|
||||
),
|
||||
{ numRuns: 100 }
|
||||
);
|
||||
```
|
||||
|
||||
### 集成测试
|
||||
|
||||
**测试场景**:
|
||||
1. **完整渲染流程**:从页面加载到图表显示的完整流程
|
||||
2. **插件兼容性**:与 WP Githuber MD、Markdown Block 等插件的集成
|
||||
3. **主题切换**:日间/夜间模式切换时的图表重新渲染
|
||||
4. **错误恢复**:CDN 加载失败时的降级处理
|
||||
|
||||
**测试工具**:使用 Playwright 或 Puppeteer 进行端到端测试
|
||||
|
||||
### 手动测试清单
|
||||
|
||||
由于某些需求难以自动化测试,需要进行手动验证:
|
||||
|
||||
- [ ] 图表颜色与页面背景色有足够的对比度(Requirements 4.4)
|
||||
- [ ] 图表容器样式与主题整体风格一致(Requirements 6.2)
|
||||
- [ ] 所有 Mermaid 官方图表类型都能正确渲染(Requirements 2.2)
|
||||
- [ ] 移动端显示效果良好(Requirements 3.2)
|
||||
- [ ] 错误提示信息友好易懂(Requirements 7.1)
|
||||
- [ ] 设置页预览功能正常工作(Requirements 5.6)
|
||||
|
||||
### 测试覆盖率目标
|
||||
|
||||
- **PHP 代码覆盖率**:≥ 80%
|
||||
- **JavaScript 代码覆盖率**:≥ 85%
|
||||
- **属性测试覆盖**:所有 18 个正确性属性
|
||||
- **单元测试覆盖**:所有核心函数和边缘情况
|
||||
|
||||
143
.kiro/specs/mermaid-support/requirements.md
Normal file
143
.kiro/specs/mermaid-support/requirements.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Requirements Document
|
||||
|
||||
## Introduction
|
||||
|
||||
本文档定义了在 Argon WordPress 主题中实现 Mermaid 图表支持功能的需求。Mermaid 是一个基于 JavaScript 的图表和流程图生成工具,允许用户通过文本描述创建各种类型的可视化图表。
|
||||
|
||||
由于 WP-Markdown 编辑器的特殊渲染方式(将整个 Mermaid 代码块保存为单行,没有真正的换行符),直接集成 Mermaid 存在技术障碍。本需求文档采用插件集成方案,通过支持 Mermaid 的 WordPress 插件来实现功能。
|
||||
|
||||
## Glossary
|
||||
|
||||
- **Mermaid**: 基于 JavaScript 的图表生成库,支持流程图、时序图、类图等多种图表类型
|
||||
- **WP-Markdown**: WordPress Markdown 编辑器,用于在 WordPress 中编辑 Markdown 格式的内容
|
||||
- **Theme**: Argon WordPress 主题系统
|
||||
- **Admin**: WordPress 后台管理员
|
||||
- **CDN**: 内容分发网络,用于加载外部 JavaScript 库
|
||||
- **Render_Engine**: Mermaid 图表渲染引擎
|
||||
- **Code_Block**: Markdown 代码块,用于包含 Mermaid 图表定义
|
||||
- **Theme_Mode**: 主题模式,包括日间模式和夜间模式
|
||||
- **Settings_Page**: Argon 主题设置页面
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement 1: Mermaid 库加载
|
||||
|
||||
**User Story:** 作为开发者,我希望主题能够正确加载 Mermaid 库,以便在文章中渲染图表。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN Admin 在设置页启用 Mermaid 支持 THEN THE Theme SHALL 在前端页面加载 Mermaid JavaScript 库
|
||||
2. WHERE CDN 模式被选择 WHEN 页面加载时 THEN THE Theme SHALL 从指定的 CDN 地址加载 Mermaid 库
|
||||
3. WHERE 本地镜像模式被选择 WHEN 页面加载时 THEN THE Theme SHALL 从主题目录加载本地 Mermaid 库文件
|
||||
4. WHEN Mermaid 库加载失败 THEN THE Theme SHALL 在控制台输出错误信息并降级到备用 CDN
|
||||
5. THE Theme SHALL 仅在包含 Mermaid 代码块的页面加载 Mermaid 库
|
||||
|
||||
### Requirement 2: 图表渲染
|
||||
|
||||
**User Story:** 作为内容创作者,我希望在文章中使用 Mermaid 语法创建图表,并在前端正确显示。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 文章包含 Mermaid 代码块 THEN THE Render_Engine SHALL 将代码块渲染为可视化图表
|
||||
2. THE Render_Engine SHALL 支持所有 Mermaid 官方图表类型(流程图、时序图、类图、状态图、甘特图、饼图、Git 图等)
|
||||
3. WHEN Mermaid 代码语法错误 THEN THE Render_Engine SHALL 显示友好的错误提示信息
|
||||
4. WHEN 图表渲染成功 THEN THE Theme SHALL 移除原始代码块文本并显示渲染后的 SVG 图表
|
||||
5. THE Render_Engine SHALL 在 DOM 加载完成后初始化并渲染所有图表
|
||||
|
||||
### Requirement 3: 响应式设计
|
||||
|
||||
**User Story:** 作为用户,我希望图表能够在不同设备上正确显示,以便在移动端也能查看。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 图表宽度超过容器宽度 THEN THE Theme SHALL 启用横向滚动功能
|
||||
2. WHEN 用户在移动设备上查看 THEN THE Theme SHALL 自动调整图表大小以适应屏幕宽度
|
||||
3. THE Theme SHALL 为图表容器设置最大宽度为 100%
|
||||
4. WHEN 图表高度超过视口高度 THEN THE Theme SHALL 保持图表完整性不进行裁剪
|
||||
5. THE Theme SHALL 在图表容器上应用响应式 CSS 样式
|
||||
|
||||
### Requirement 4: 主题模式适配
|
||||
|
||||
**User Story:** 作为用户,我希望图表能够适配夜间模式,以便在不同主题下都有良好的视觉效果。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN 用户切换到夜间模式 THEN THE Theme SHALL 自动切换 Mermaid 图表主题为深色主题
|
||||
2. WHEN 用户切换到日间模式 THEN THE Theme SHALL 自动切换 Mermaid 图表主题为浅色主题
|
||||
3. THE Theme SHALL 在主题切换时重新渲染所有 Mermaid 图表
|
||||
4. THE Theme SHALL 确保图表颜色与页面背景色有足够的对比度
|
||||
5. WHERE Admin 设置了自定义图表主题 THEN THE Theme SHALL 使用自定义主题而不是自动切换
|
||||
|
||||
### Requirement 5: 后台设置
|
||||
|
||||
**User Story:** 作为管理员,我希望能够在后台配置 Mermaid 功能,以便根据需求调整行为。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Settings_Page SHALL 提供启用或禁用 Mermaid 支持的开关选项
|
||||
2. THE Settings_Page SHALL 提供 CDN 地址选择选项(jsDelivr、unpkg、自定义)
|
||||
3. THE Settings_Page SHALL 提供图表主题选择选项(default、dark、forest、neutral)
|
||||
4. THE Settings_Page SHALL 提供本地镜像开关选项
|
||||
5. WHEN Admin 保存设置 THEN THE Theme SHALL 验证 CDN 地址格式的有效性
|
||||
6. THE Settings_Page SHALL 提供 Mermaid 配置预览功能
|
||||
|
||||
### Requirement 6: 样式优化
|
||||
|
||||
**User Story:** 作为内容创作者,我希望图表有美观的样式,以便提升文章的视觉质量。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Theme SHALL 为图表容器添加背景色、圆角和阴影样式
|
||||
2. THE Theme SHALL 确保图表容器样式与主题整体风格一致
|
||||
3. WHEN 图表在卡片中显示 THEN THE Theme SHALL 添加适当的内边距
|
||||
4. THE Theme SHALL 为图表添加淡入动画效果
|
||||
5. THE Theme SHALL 在夜间模式下调整图表容器的背景色和边框色
|
||||
|
||||
### Requirement 7: 错误处理
|
||||
|
||||
**User Story:** 作为开发者,我希望系统能够优雅地处理错误,以便快速定位和解决问题。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN Mermaid 代码解析失败 THEN THE Theme SHALL 在图表位置显示错误提示信息
|
||||
2. WHEN Mermaid 库加载失败 THEN THE Theme SHALL 在控制台输出详细的错误日志
|
||||
3. THE Theme SHALL 在错误提示中包含错误类型和行号信息
|
||||
4. WHEN 发生错误 THEN THE Theme SHALL 保留原始代码块以便用户修正
|
||||
5. THE Theme SHALL 提供调试模式选项以输出详细的渲染过程信息
|
||||
|
||||
### Requirement 8: 性能优化
|
||||
|
||||
**User Story:** 作为用户,我希望图表加载不影响页面性能,以便获得流畅的浏览体验。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Theme SHALL 仅在包含 Mermaid 代码块的页面加载 Mermaid 库
|
||||
2. THE Theme SHALL 使用异步方式加载 Mermaid 库
|
||||
3. THE Theme SHALL 缓存已渲染的图表以避免重复渲染
|
||||
4. WHEN 页面包含多个图表 THEN THE Theme SHALL 批量渲染以提高性能
|
||||
5. THE Theme SHALL 使用 CDN 加速 Mermaid 库的加载速度
|
||||
|
||||
### Requirement 9: 插件兼容性
|
||||
|
||||
**User Story:** 作为管理员,我希望 Mermaid 功能能够与常用的 WordPress 插件兼容,以便灵活选择编辑器。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Theme SHALL 支持通过 WP Githuber MD 插件创建的 Mermaid 图表
|
||||
2. THE Theme SHALL 支持通过 Markdown Block 插件创建的 Mermaid 图表
|
||||
3. THE Theme SHALL 支持通过 Code Syntax Block 插件创建的 Mermaid 图表
|
||||
4. WHEN 检测到多个 Mermaid 插件 THEN THE Theme SHALL 避免重复加载 Mermaid 库
|
||||
5. THE Theme SHALL 提供插件兼容性检测功能
|
||||
|
||||
### Requirement 10: 代码块识别
|
||||
|
||||
**User Story:** 作为开发者,我希望系统能够准确识别 Mermaid 代码块,以便正确渲染图表。
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Theme SHALL 识别 class 属性为 "mermaid" 的 div 元素作为 Mermaid 代码块
|
||||
2. THE Theme SHALL 识别 language 属性为 "mermaid" 的 pre 或 code 元素作为 Mermaid 代码块
|
||||
3. THE Theme SHALL 识别 data-lang 属性为 "mermaid" 的元素作为 Mermaid 代码块
|
||||
4. WHEN 代码块同时包含多个识别标记 THEN THE Theme SHALL 优先使用 class 属性
|
||||
5. THE Theme SHALL 忽略被注释掉的 Mermaid 代码块
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
- **Validates: Requirements 8.4**
|
||||
- _Requirements: 8.4_
|
||||
|
||||
- [~] 5. 实现错误处理机制
|
||||
- [x] 5. 实现错误处理机制
|
||||
- 添加库加载失败的降级处理(多个 CDN 备选)
|
||||
- 实现代码解析错误的捕获和显示
|
||||
- 创建错误提示 UI 组件
|
||||
|
||||
Reference in New Issue
Block a user