Files
MarkLite/DESIGN.md
T

262 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MarkLite - 设计文档
## 1. 项目概述
MarkLite 是一款轻量级的 Windows 本地 Markdown 阅读器桌面应用程序。基于 Electron 框架构建,提供简洁现代的用户界面,支持 Markdown 文件的打开、编辑和实时预览。支持亮色/暗色主题切换。
## 2. 技术架构
### 2.1 技术栈
| 组件 | 技术选型 | 说明 |
|------|----------|------|
| 桌面框架 | Electron v28 | 跨平台桌面应用框架 |
| 前端 | HTML + CSS + JavaScript | 原生前端技术,无框架依赖 |
| Markdown 解析 | marked.js v12 | 高性能 Markdown 解析库(本地离线) |
| 代码高亮 | highlight.js v11 | 代码块语法高亮(本地离线) |
| 打包 | electron-builder | 生成 Windows NSIS 安装包 |
### 2.2 进程架构
```
┌─────────────────────────────────────────┐
│ Main Process (main.js) │
│ - 窗口管理 │
│ - 文件系统操作 (fs) │
│ - 文件监听 (fs.watch) │
│ - 未保存提醒拦截 │
│ - IPC 通信主端 │
└──────────────┬──────────────────────────┘
│ IPC (contextBridge)
┌──────────────▼──────────────────────────┐
│ Preload Script (preload.js) │
│ - 安全的 API 桥接 │
│ - exposeInMainWorld │
└──────────────┬──────────────────────────┘
┌──────────────▼──────────────────────────┐
│ Renderer Process (renderer/) │
│ - UI 渲染(亮色/暗色主题) │
│ - Markdown 编辑与预览 │
│ - 拖拽文件处理 │
│ - 快捷键处理 │
│ - 用户设置持久化 (localStorage) │
└─────────────────────────────────────────┘
```
### 2.3 安全模型
- `contextIsolation: true` + `nodeIntegration: false`
- 通过 `contextBridge.exposeInMainWorld` 安全暴露 API
- CSP 策略:`default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; img-src 'self' data:`
- 渲染进程无法直接访问 Node.js API
## 3. 功能设计
### 3.1 核心功能
1. **文件打开**
- 工具栏 → 打开按钮(支持 .md / .txt / .markdown
- 拖拽文件到窗口打开
- 支持 Windows 文件关联(双击 .md 文件打开)
- 支持命令行参数传入文件路径
2. **文件保存**
- Ctrl+S 快捷键保存
- 工具栏 → 保存按钮
- Ctrl+Shift+S 另存为
3. **实时预览**
- 左侧编辑器 + 右侧预览(默认分屏模式)
- 编辑 150ms 防抖后更新预览
- 基于 DOM 位置映射的滚动同步
4. **视图模式**
- 编辑+预览(Split View)— Ctrl+1
- 纯编辑模式 — Ctrl+2
- 纯预览模式 — Ctrl+3
- 记忆上次使用的视图模式(localStorage
5. **文件修改检测**
- 主进程通过 `fs.watch` 监听当前打开文件
- 外部修改时显示黄色提示横幅
- 支持「重新加载」或「忽略」
6. **未保存提醒**
- 关闭窗口时检测未保存修改
- 弹出确认对话框,防止误操作
- 主进程 5 秒超时兜底,防止渲染进程无响应时窗口卡死
7. **暗色主题**
- 工具栏右侧月亮/太阳图标切换
- CSS 变量驱动,一键切换整套配色
- 主题偏好持久化(localStorage
### 3.2 UI 设计
#### 色彩方案(亮色)
| 角色 | 色值 |
|------|------|
| 主色调 | `#1a73e8` |
| 背景色 | `#ffffff` |
| 次级背景 | `#f8f9fa` |
| 三级背景 | `#f1f3f4` |
| 文字色 | `#333333` |
| 次级文字 | `#5f6368` |
| 代码块背景 | `#f6f8fa` |
| 边框色 | `#e1e4e8` |
#### 色彩方案(暗色)
| 角色 | 色值 |
|------|------|
| 主色调 | `#8ab4f8` |
| 背景色 | `#1e1e1e` |
| 次级背景 | `#252526` |
| 三级背景 | `#2d2d2d` |
| 文字色 | `#d4d4d4` |
| 次级文字 | `#9e9e9e` |
| 代码块背景 | `#2d2d2d` |
| 边框色 | `#3e3e3e` |
#### 字体
- **UI 字体**: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif
- **编辑器字体**: "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, monospace
- **预览字体**: 同 UI 字体
#### 布局
```
┌──────────────────────────────────────────────────────────┐
│ MarkLite - filename.md ─ □ ✕ │
├──────────────────────────────────────────────────────────┤
│ 📁 打开 │ 💾 保存 │ ⬜ 分屏 │ ✏️ 编辑 │ 👁 预览 │ 🌙 │
├──────────────────────────────────────────────────────────┤
│ ⚠️ 文件已被外部程序修改 [重新加载] [忽略] │
├────────────────────┬─────────────────────────────────────┤
│ │ │
│ 1 # Title │ Title │
│ 2 │ ─────── │
│ 3 content... │ content... │
│ │ │
│ │ │
│ │ │
├────────────────────┴─────────────────────────────────────┤
│ filename.md │ UTF-8 │ Markdown │ 1.2 KB │ 行 3, 列 1 │
└──────────────────────────────────────────────────────────┘
```
## 4. 文件结构
```
MarkLite/
├── package.json # 项目配置与依赖
├── main.js # Electron 主进程
├── preload.js # 预加载脚本(IPC 桥接)
├── renderer/
│ ├── index.html # 主页面结构
│ ├── style.css # UI 样式(含暗色主题)
│ └── renderer.js # 渲染进程逻辑
├── lib/
│ ├── marked.min.js # Markdown 解析库(离线)
│ ├── highlight.min.js # 代码高亮库(离线)
│ └── highlight-github.css # 代码高亮主题
├── assets/
│ └── icon.ico # 应用图标(多尺寸)
├── DESIGN.md # 设计文档(本文件)
├── DEVSETUP.md # 开发环境配置指南
├── README.md # 项目说明
├── LICENSE # MIT 许可证
└── .gitignore # Git 忽略文件
```
## 5. IPC 通信设计
### 5.1 渲染进程 → 主进程(invoke)
| 通道 | 参数 | 返回值 | 说明 |
|------|------|--------|------|
| `dialog:openFile` | 无 | `{ filePath, content }``null` | 打开文件对话框 |
| `file:read` | `filePath` | `{ success, content }` | 读取文件内容 |
| `file:save` | `{ filePath, content }` | `{ success, filePath }` | 保存文件 |
| `file:saveAs` | `{ content }` | `{ success, filePath }` | 另存为 |
| `file:getCurrentPath` | 无 | `string \| null` | 获取当前文件路径 |
| `file:stats` | `filePath` | `{ success, size, mtime }` | 获取文件元信息 |
| `file:reload` | 无 | `{ success, content, filePath }` | 重新加载当前文件 |
| `window:forceClose` | 无 | 无 | 强制关闭窗口(跳过未保存检查) |
### 5.2 主进程 → 渲染进程(send)
| 通道 | 数据 | 说明 |
|------|------|------|
| `file:opened` | `{ filePath, content }` | 文件已打开 |
| `file:externallyModified` | `filePath` | 文件被外部修改 |
| `menu:save` | 无 | 菜单触发保存 |
| `menu:saveAs` | 无 | 菜单触发另存为 |
| `menu:viewMode` | `mode` | 菜单切换视图模式 |
| `window:confirmClose` | 无 | 请求确认关闭 |
| `window:closing` | 无 | 窗口即将关闭 |
## 6. 数据持久化
通过 `localStorage` 存储用户偏好,key 为 `marklite-settings`
```json
{
"darkMode": false,
"viewMode": "split",
"splitRatio": 50
}
```
| 字段 | 类型 | 说明 |
|------|------|------|
| `darkMode` | boolean | 暗色主题开关 |
| `viewMode` | string | 视图模式:`split` / `editor` / `preview` |
| `splitRatio` | number | 分屏比例(20~80 |
## 7. Markdown 渲染支持
支持标准 Markdown 和 GFMGitHub Flavored Markdown):
- 标题(h1-h6
- 段落、换行
- **粗体**、*斜体*、~~删除线~~
- 有序/无序列表
- 任务列表(`- [x]`
- 代码块(围栏式 + 语法高亮,180+ 语言)
- 行内代码
- 链接、图片
- 表格
- 引用块
- 水平线
- HTML 内联
## 8. 快捷键
| 快捷键 | 功能 |
|:-------|:-----|
| `Ctrl + O` | 打开文件 |
| `Ctrl + S` | 保存文件 |
| `Ctrl + Shift + S` | 另存为 |
| `Ctrl + 1` | 编辑 + 预览(分屏) |
| `Ctrl + 2` | 纯编辑模式 |
| `Ctrl + 3` | 纯预览模式 |
| `F12` | 开发者工具 |
| `Ctrl + R` | 重新加载 |
## 9. 构建与发布
使用 `electron-builder` 打包:
- 输出格式:NSIS 安装包(.exe)
- 目标平台:Windows x64
- 应用图标:assets/icon.ico
- 文件关联:`.md` / `.markdown` / `.txt`
- 支持自定义安装目录、桌面/开始菜单快捷方式
- 便携版:`npm run build:portable`
详见 [DEVSETUP.md](DEVSETUP.md)。