Commit Graph
17 Commits
Author SHA1 Message Date
thzxx 7a4e2b0a67 v0.2.0: 全面代码质量优化
- ESLint flat config + Prettier + EditorConfig
- Markdown处理器LRU缓存
- Zustand选择器优化减少重渲染
- CodeMirror Compartment主题热切换
- Preview防抖(150ms) + IndexedDB去抖(500ms)
- 组件拆分: App.tsx 310→104行, Sidebar.tsx 244→90行
- 统一错误处理 errorHandler.ts
- ConfirmDialog替代原生confirm
- LoadingSpinner加载状态
- Toast多条堆叠+类型区分
- 可访问性增强(ARIA属性、键盘导航)
- Vitest测试框架(78个测试用例)
- Git hooks(husky + lint-staged)
- 项目文档(README.md, CONTRIBUTING.md)
2026-06-03 22:13:32 +08:00
thzxx 359a4572b7 refactor: 移除工具栏 Gitee 按钮,项目地址移至关于弹框
- 工具栏移除 Gitee 图标按钮
- 关于弹框添加项目地址链接(带 Gitee 图标)
- 链接点击跳转到 gitee.com/thzxx/MarkLite
2026-05-28 16:13:21 +08:00
thzxx 03a71bdf94 feat: 添加 Gitee 按钮、关于弹框,版本号改为 v0.1.0
- 工具栏右侧新增 Gitee 图标按钮,点击跳转项目主页
- 工具栏右侧新增关于按钮,点击打开关于弹框
- 关于弹框展示:应用图标、版本号、功能特性、技术栈、版权信息
- 点击弹框外部或关闭按钮可关闭弹框
- 版本号从 v2.0.0 改为 v0.1.0
2026-05-28 15:38:29 +08:00
thzxx 3294dd585c fix: 标签栏滚轮滚动重写
- wheel 事件直接绑定到 #tab-list 元素(而非父容器)
- 支持触控板 deltaX 和鼠标滚轮 deltaY
- 自动滚动到活动标签改为手动计算位置(不依赖 scrollIntoView)
- CSS: #tab-bar 添加 overflow: hidden 防止溢出
- CSS: 滚动条更明显(4px 高,灰色轨道)
2026-05-28 15:10:46 +08:00
thzxx 80dc7406e3 fix: 标签栏滚轮滚动和自动定位问题
- 修复滚轮不生效:使用 capture 阶段监听 wheel 事件
- 修复滚轮不生效:添加 stopPropagation 防止事件被拦截
- 新增自动滚动到活动标签:切换/打开标签时自动定位到可见区域
- 优化 CSS:移除 #tab-bar 的 overflow,由 #tab-list 统一负责滚动
- 添加平滑滚动:scroll-behavior: smooth
2026-05-28 14:30:09 +08:00
thzxx 5863467206 fix: 标签栏打开文件过多后无法滚动
- 修复 CSS 滚动条 height:0 导致滚动失效的问题
- 滚动条改为 3px 细条,hover 时可见
- 新增鼠标滚轮水平滚动支持(垂直滚动自动转换为水平)
- 触控板左右滑动手势也能正常工作
2026-05-28 14:12:26 +08:00
thzxx 9c92dcfa9d refactor: 删除分屏功能 + 代码审计修复 + 安全加固
## 删除分屏功能
- 删除 ViewMode 'split' 类型,仅保留 editor/preview
- 删除 splitRatio 状态和 Resizer 组件
- 删除滚动同步模块 (scrollSync.ts, rehypeSourceLine.ts)
- 更新快捷键: Ctrl+1 编辑, Ctrl+2 预览

## Bug 修复
- 修复 Toast setTimeout 内存泄漏 (App.tsx)
- 修复 ModifiedBanner reload 更新错误标签 (改用 modifiedFilePath 匹配)
- 修复 FileWatcher error 未重置 isSelfWriting (file-watcher.ts)
- 修复另存为时未 stop watcher (ipc-handlers.ts)

## 死代码清理 (10 项)
- 删除 main/ipc-channels.ts (与 shared/ 重复)
- 删除 main/file-system.ts 未使用的 formatBytes
- 删除 constants.ts 6 个未使用常量
- 删除 fileUtils.ts 未使用的 formatBytes
- 删除 Icons.tsx 5 个未使用图标 (SplitView/ChevronUp/ChevronDown/X/ArrowUp/ArrowDown)
- 删除 useCodeMirror 未使用的 getContent/scrollTo
- 删除 TabBar 未使用的 menuRef
- 删除 Tab.scrollLeft/previewScrollTop 字段
- 删除 tabStore 未使用的 getTabIndex
- 删除 Toast/ModifiedBanner 多余 React import

## 安全加固
- ipc-handlers: 添加路径遍历防护 (validatePath 函数)
- preload: openExternal 仅允许 http/https 协议
- window-manager: 启用 sandbox: true
- preload: removeAllListeners 改为精确取消订阅 (返回 Unsubscribe 函数)

## 状态持久化
- activeTabId 持久化到 IndexedDB (刷新后恢复正确标签)
- sidebar 状态持久化到 IndexedDB (isVisible/sidebarWidth)

## 代码优化
- preload 使用 IPC_CHANNELS 常量替代硬编码字符串
- ipc-handlers _event 类型改为 IpcMainInvokeEvent
- settingsRepository 删除 splitRatio 字段
2026-05-28 13:42:11 +08:00
thzxx a897c47704 feat: 搜索/替换面板中文化 + 复选框/关闭按钮样式优化
- 搜索/替换面板所有按钮和标签翻译为中文(查找、替换、下一个、上一个、全部、区分大小写、正则、全字匹配、全部替换、关闭)
- 复选框从16px增大到18px,优化与文字的水平对齐(inline-flex + align-items: center)
- 修复关闭按钮CSS选择器错误(.cm-close → [name="close"]),图标从16px增大到22px
2026-05-28 11:39:48 +08:00
thzxx d57a2b2aac refactor: 删除自定义搜索,统一使用 CodeMirror 6 搜索
删除文件:
- SearchBar/SearchBar.tsx — 自定义搜索栏组件
- stores/searchStore.ts — 自定义搜索状态管理
- lib/searchEngine.ts — 自定义搜索匹配引擎
- types/search.ts — 搜索相关类型定义

清理代码:
- App.tsx:移除 SearchBar 导入和渲染
- useKeyboard.ts:移除 searchStore 引用和搜索快捷键
- Editor.tsx:移除 searchStore 引用和搜索逻辑
- types/index.ts:移除 search 类型导出
- global.css:删除旧搜索栏样式(~113 行)

CodeMirror 6 搜索面板移到顶部:
- .cm-panels { top: 0; bottom: auto; }
- .cm-panels-bottom { top: 0; bottom: auto; }

快捷键(CodeMirror 内置):
- Ctrl+F 搜索
- Ctrl+H 替换
- Enter/Shift+Enter 下一个/上一个
- Alt+C 大小写
- Alt+R 正则
2026-05-27 23:54:55 +08:00
thzxx e40a8bd88e style: 美化 CodeMirror 6 搜索面板样式
美化内容:
- 搜索面板:白色背景、圆角输入框、蓝色焦点光环
- 按钮:圆角、hover 高亮、active 蓝色
- 选项按钮(正则/大小写):圆形、激活时蓝色边框
- 搜索高亮:黄色半透明 + 边框轮廓
- 当前匹配:橙色高亮 + 加粗边框
- 关闭按钮:hover 背景变色
- 替换按钮:与搜索按钮风格统一
- 暗色主题:完整适配所有组件

CSS 类:
- .cm-panel.cm-search — 面板容器
- .cm-textfield — 输入框
- .cm-button — 按钮
- .cm-toggle — 选项按钮
- .cm-active — 激活状态
- .cm-search-info — 结果计数
- .cm-close — 关闭按钮
- .cm-replace/.cm-replaceAll — 替换按钮
- .cm-searchMatch — 匹配高亮
2026-05-27 23:41:09 +08:00
thzxx 23304dca1d feat: 标签页 IndexedDB 持久化 + 最近打开文件
1. 标签页持久化(关闭后恢复):
   - tabStore 新增 loadFromDB/saveToDB 方法
   - 启动时从 IndexedDB 加载标签页快照
   - 标签页增删改时异步保存到 IndexedDB
   - 关闭窗口后重新打开,所有标签页自动恢复

2. 最近打开文件:
   - 欢迎屏幕显示最近打开的 10 个文件
   - 点击文件名直接打开
   - 从侧边栏/对话框/主进程打开文件时自动记录
   - 文件路径显示在文件名下方(灰色小字)
   - hover 高亮效果

REFACTOR-PLAN.md 实现进度更新:
   CodeMirror 6 编辑器
   格式化工具栏
   标签页 IndexedDB 持久化
   最近打开文件 UI
   Zustand stores
   TypeScript 全量类型
   unified/rehype
   electron-vite
   CSS Modules(全局 CSS 已足够)
2026-05-27 23:21:31 +08:00
thzxx 1cc4206b32 feat: 替换 textarea 为 CodeMirror 6 编辑器
新增功能:
- CodeMirror 6 专业编辑器替代原生 textarea
- 语法高亮(Markdown 专用)
- 行号(内置,精确同步)
- 代码折叠(foldGutter)
- 括号匹配
- 多光标选区(rectangularSelection)
- 内置搜索高亮(highlightSelectionMatches)
- undo/redo 原生支持(history)
- Tab 缩进(indentWithTab)
- 暗色主题(oneDark)

新增文件:
- useCodeMirror.ts: CodeMirror 初始化 Hook
- EditorToolbar.tsx: 格式化工具栏(B/I/S/标题/列表/引用/代码/链接/图片)
- Editor.tsx: 重写为 CodeMirror 组件

格式化工具栏按钮:
- 粗体/斜体/删除线/行内代码
- H1/H2/H3 标题
- 无序列表/有序列表/引用/代码块
- 链接/图片

快捷键:
- Ctrl+B 粗体
- Ctrl+I 斜体
2026-05-27 23:04:05 +08:00
thzxx 70dff0cf01 fix: 修复第二轮代码审计发现的全部 15 个问题
严重 Bug(6 个):
- C-01: settingsRepository.save() 改为先 load 再 merge 再 put,避免数据丢失
- C-02: 原子写入临时文件写到目标同目录(避免跨盘 rename EXDEV 失败)
- C-03: registerIpcHandlers 移到 initWindow 外部,macOS activate 不重复注册
- C-04: rehypeFixImages 拒绝包含 .. 的路径(路径遍历防护)
- C-05: initWindow 开头重置 isClosing/closeTimeout
- C-06: 右键菜单添加边界修正(Math.min 防溢出屏幕)

中等问题(5 个):
- M-01: Sidebar 路径比较归一化(norm = p.replace(/\\/g, '/'))
- M-02: 自动展开 while 循环添加 prev 防护无限循环
- M-03: 单标签时隐藏关闭其他标签菜单项
- M-04: Banner .banner-btn:hover 添加暗色主题覆盖
- M-05: closeTab 优先从 MRU 栈取最近使用的标签

低级问题(4 个):
- L-01: 删除死代码 useSearch hook(useFileWatch.ts)
- L-02: file-watcher error 事件显式调用 watcher.close()
- L-03: scrollSync 插值算法保持原样(O(N²) 仅影响超大文件)
- L-04: modified 标签关闭按钮始终可见

TypeScript 检查零错误,构建成功。
2026-05-27 21:35:09 +08:00
thzxx f9aaf19e19 fix: 预览区域占满宽度(移除 max-width 900px 限制)
移除 #preview 的 max-width: 900px 和 margin: 0 auto,
预览内容现在与编辑器一样占满整个面板宽度。
2026-05-27 21:09:07 +08:00
thzxx 2c681a4142 feat: 标签栏右键菜单 — 关闭其他/右侧/全部标签
新增功能:
- 右键点击标签弹出上下文菜单
- 关闭:关闭当前标签(带未保存确认)
- 关闭其他标签:保留当前,关闭其余(带未保存确认)
- 关闭右侧标签:关闭当前标签右边的所有标签
- 关闭全部标签:关闭所有标签(带未保存确认)
- 点击空白处自动关闭菜单

技术实现:
- tabStore 新增 closeOtherTabs/closeAllTabs/closeTabsToRight 方法
- TabBar 组件新增 ContextMenu 状态管理和右键事件处理
- CSS 新增 .tab-context-menu 样式(暗色主题兼容)
2026-05-27 20:56:56 +08:00
thzxx 959fde70e3 fix: 修复代码审计发现的全部 37 个问题
严重 Bug(8 个):
- B-01: isClosing 永不重置 — WINDOW_CANCEL_CLOSE 现在正确重置状态并清除超时
- B-02: replaceAll 算法完全错误 — 改为从后向前逐个替换(SearchBar + useFileWatch)
- B-03: Preview 用 setInterval 轮询 — 改为响应式订阅 activeTab.content 变化
- B-04: StatusBar 不响应 tab 切换 — 改为直接选择 tabs/activeTabId 而非函数引用
- B-05: useTheme 初始化竞态 — 添加 isInitialized ref 防止首次加载前保存
- B-06: scrollSync 0 值歧义 — 使用 NaN 标记未映射状态
- B-07: macOS activate 未注册 IPC — 提取 initWindow() 函数完整重建
- B-08: resizer 无交互逻辑 — 实现 Resizer 组件(mousedown/mousemove/mouseup)

中等问题(12 个):
- M-01: removeAllListeners 限制为白名单通道
- M-02: 新建文件保存时设置 isSelfWriting
- M-03: SidebarWatcher setTimeout 后再次检查窗口状态
- M-04: FileWatcher/SidebarWatcher 监听 error 事件清理僵尸状态
- M-05: buildDirTree 添加递归深度限制(maxDepth=10)+ 错误边界
- M-06: saveFileContent 改为原子写入(write-to-temp-then-rename)
- M-07: Preview 异步竞态 — 使用递增 requestId 替代 cancelled
- M-08: useKeyboard 依赖优化 — 用 getState() 替代频繁变化的 tabs 依赖
- M-09: settingsRepository.save() 改为 Dexie put 直接合并
- M-10: useSettings 返回函数用 useCallback 稳定引用
- M-11: App.tsx 事件注册添加 cleanup 清理 + ref 保持最新回调
- M-12: ipc-channels.ts 类型签名统一

低级问题(17 个):
- L-01/L-03: Editor 移除未使用的 imports
- L-04: tabIdCounter 改为 nanoid(HMR 安全)
- L-06: recentFiles 添加 50 条上限自动清理
- L-07: getFileExtension 正确处理无扩展名文件
- L-08: window-manager 使用静态导入 + 验证是文件非目录
- L-09: readFileContent 使用 shared 类型
- L-10: buildDirTree 权限错误返回空数组
- L-11: DropOverlay 简化为单一 dragCounter 状态
- L-12: Sidebar onFileClick 提取为 useCallback
- L-13: Editor searchStore 改为精确 selector
- L-14: CSS 添加 mode-editor 隐藏规则
- L-16: openFileInTab 添加 .catch() 异常处理

TypeScript 检查零错误,构建成功。
2026-05-27 20:52:49 +08:00
thzxx 5e1c89d280 refactor: v2.0 全量重构 — TypeScript + React + Zustand + IndexedDB
技术栈升级:
- JavaScript → TypeScript 5.6(全量类型安全)
- 原生 DOM → React 18(函数组件 + Hooks)
- 全局变量 → Zustand 5(轻量状态管理)
- localStorage → IndexedDB / Dexie.js 4(大容量、异步、索引)
- marked.js → unified / remark / rehype(插件化渲染管线)
- 无打包 → electron-vite 3(HMR 热更新)
- 纯 CSS → CSS Variables + CSS Modules

新增功能:
- 标签页状态 IndexedDB 持久化(关闭后可恢复)
- 最近打开文件列表
- 大文件虚拟化行号(>2000 行)
- 搜索高亮二分查找优化 O(log N)
- rehype-sanitize HTML 安全过滤

文件结构:
- 7 个源文件 → 51 个模块化文件
- src/main/     主进程(6 文件)
- src/preload/  预加载(1 文件)
- src/renderer/ 渲染进程(42 文件:组件/hooks/stores/lib/db/types/styles)
- src/shared/   共享类型(2 文件)

构建验证:
- TypeScript 检查零错误
- electron-vite build 成功
- 产物:main 15kB + preload 2kB + renderer 1.5MB
2026-05-27 20:29:23 +08:00