Files
MarkLite/DESIGN.md
T

14 KiB
Raw Blame History

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. 多标签页

    • Ctrl+T 新建空白标签
    • Ctrl+W 关闭当前标签(未保存时确认)
    • Ctrl+Tab / Ctrl+Shift+Tab 切换标签
    • 点击标签切换,hover 显示关闭按钮
    • 同一文件不会重复打开(自动切换到已有标签)
    • 每个标签独立保存:内容、滚动位置、光标位置、修改状态
  2. 文件打开

    • 工具栏 → 打开按钮(支持 .md / .txt / .markdown
    • 拖拽文件到窗口打开(支持多文件同时拖入)
    • 支持 Windows 文件关联(双击 .md 文件打开)
    • 支持命令行参数传入文件路径
  3. 文件保存

    • Ctrl+S 快捷键保存
    • 工具栏 → 保存按钮
    • Ctrl+Shift+S 另存为
  4. 实时预览

    • 左侧编辑器 + 右侧预览(默认分屏模式)
    • 编辑 150ms 防抖后更新预览
    • 基于 DOM 位置映射的滚动同步
  5. 视图模式

    • 编辑+预览(Split View)— Ctrl+1
    • 纯编辑模式 — Ctrl+2
    • 纯预览模式 — Ctrl+3
    • 记忆上次使用的视图模式(localStorage
  6. 文件修改检测

    • 主进程通过 fs.watch 监听当前活动标签的文件
    • 外部修改时显示黄色提示横幅
    • 支持「重新加载」或「忽略」
    • 切换标签时自动切换监听目标
  7. 未保存提醒

    • 关闭窗口时检测所有标签的未保存修改
    • 弹出确认对话框,防止误操作
    • 主进程 5 秒超时兜底,防止渲染进程无响应时窗口卡死
  8. 暗色主题

    • 工具栏右侧月亮/太阳图标切换
    • CSS 变量驱动,一键切换整套配色
    • 主题偏好持久化(localStorage
  9. 搜索替换

    • Ctrl+F 打开搜索栏,Ctrl+H 打开搜索+替换栏
    • 实时高亮所有匹配项,当前匹配用不同颜色标识
    • Enter / Shift+Enter 导航下一个/上一个匹配
    • 区分大小写(Alt+C)、正则表达式(Alt+R)切换
    • 替换当前(Ctrl+Shift+G)、全部替换(Ctrl+Shift+H
    • 自动将选中文本填充到搜索框
    • Esc 关闭搜索栏
  10. 文件树侧边栏

    • 工具栏按钮打开文件夹选择对话框
    • 递归读取目录结构,只显示 .md/.markdown/.txt 文件
    • 自动跳过 node_modules、.git、dist 等无关目录
    • 点击文件夹展开/折叠,点击文件在新标签页打开
    • 已打开的文件自动切换到对应标签
    • fs.watch 监听目录变化,自动刷新树
    • 侧边栏折叠状态持久化(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                                         ─ □ ✕  │
├──────────────────────────────────────────────────────────────────────────┤
│  📁 打开 │ 💾 保存 │ ⬜ 分屏 │ ✏️ 编辑 │ 👁 预览 │              🌙    │
├──────────────────────────────────────────────────────────────────────────┤
│  [file1.md] [file2.md] [未命名]  [+]                                    │
├──────────────────────────────────────────────────────────────────────────┤
│  ⚠️ 文件已被外部程序修改                [重新加载] [忽略]                 │
├──────────┬─────────────────────────┬─────────────────────────────────────┤
│ 资源管理器│                         │                                     │
│ ▼ project │ 🔍 查找...       2/5   │  Title                              │
│   📁 src  │    [替换... ] [替换][全部]│  ───────                            │
│   📄 file1│                         │                                     │
│   📄 file2│  1  # Title             │  Title                              │
│   📁 lib  │  2                     │  ───────                            │
│           │  3  content...         │  content...                         │
│           │  4                     │                                     │
├──────────┴─────────────────────────┴─────────────────────────────────────┤
│  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 } 重新加载当前文件
tab:switched filePath 通知主进程切换活动文件
window:forceClose 强制关闭窗口(跳过未保存检查)
dir:readTree dirPath { success, tree, rootPath } 递归读取目录树
dir:openDialog string | null 打开文件夹选择对话框
dir:watch dirPath 监听目录变化
dir:unwatch 停止监听目录变化

5.2 主进程 → 渲染进程(send)

通道 数据 说明
file:openInTab { filePath, content } 在新标签中打开文件
file:opened { filePath, content } 文件已打开(兼容旧路径)
file:externallyModified filePath 文件被外部修改
menu:save 菜单触发保存
menu:saveAs 菜单触发另存为
menu:viewMode mode 菜单切换视图模式
window:confirmClose 请求确认关闭
window:closing 窗口即将关闭
sidebar:dirChanged 目录结构变化,通知渲染进程刷新树

6. 标签页数据模型

每个标签页在渲染进程中维护独立状态:

{
  id: Number,              // 唯一标识
  filePath: String | null, // 文件路径(未命名标签为 null)
  content: String,         // 编辑器内容
  isModified: Boolean,     // 是否已修改
  scrollTop: Number,       // 编辑器滚动位置
  scrollLeft: Number,
  selectionStart: Number,  // 光标选区
  selectionEnd: Number,
  previewScrollTop: Number // 预览面板滚动位置
}

切换标签时自动保存当前状态、恢复目标状态。

7. 数据持久化

通过 localStorage 存储用户偏好,key 为 marklite-settings

{
  "darkMode": false,
  "viewMode": "split",
  "splitRatio": 50,
  "sidebarCollapsed": false
}
字段 类型 说明
darkMode boolean 暗色主题开关
viewMode string 视图模式:split / editor / preview
splitRatio number 分屏比例(20~80
sidebarCollapsed boolean 侧边栏是否折叠

8. Markdown 渲染支持

支持标准 Markdown 和 GFMGitHub Flavored Markdown):

  • 标题(h1-h6
  • 段落、换行
  • 粗体斜体删除线
  • 有序/无序列表
  • 任务列表(- [x]
  • 代码块(围栏式 + 语法高亮,180+ 语言)
  • 行内代码
  • 链接、图片
  • 表格
  • 引用块
  • 水平线
  • HTML 内联

9. 快捷键

快捷键 功能
Ctrl + T 新建标签页
Ctrl + W 关闭当前标签页
Ctrl + Tab 切换到下一个标签页
Ctrl + Shift + Tab 切换到上一个标签页
Ctrl + O 打开文件
Ctrl + S 保存文件
Ctrl + Shift + S 另存为
Ctrl + 1 编辑 + 预览(分屏)
Ctrl + 2 纯编辑模式
Ctrl + 3 纯预览模式
Ctrl + F 搜索
Ctrl + H 搜索并替换
Enter / Shift+Enter 下一个 / 上一个匹配
Alt + C 切换区分大小写
Alt + R 切换正则表达式
Ctrl + Shift + G 替换当前匹配
Ctrl + Shift + H 全部替换
Esc 关闭搜索栏

10. 构建与发布

使用 electron-builder 打包:

  • 输出格式:NSIS 安装包(.exe
  • 目标平台:Windows x64
  • 应用图标:assets/icon.ico
  • 文件关联:.md / .markdown / .txt
  • 支持自定义安装目录、桌面/开始菜单快捷方式
  • 便携版:npm run build:portable

详见 DEVSETUP.md