Commit Graph
58 Commits
Author SHA1 Message Date
thzxx dd78ff15a9 v0.3.7: 全面代码审计修复 - 20项Bug/安全/稳定性改进 2026-06-15 15:02:38 +08:00
thzxx c0e16f2885 v0.3.7: 修复保存竞争态 + 新增源码编辑模式
Bug修复:
  - BUG-10 修复: 保存文件时 watcher restart 触发虚假 change 事件覆盖编辑器内容
    - ipc-handlers.ts: restart watcher 在 setSelfWriting(true) 保护内执行
    - App.tsx handleReloadModified: 增加 if (tab?.isModified) return 安全守卫

新功能:
  - 新增源码(Source)视图模式,直接用 textarea 编辑原始 Markdown
  - ViewMode 扩展为 editor|preview|source
  - 工具栏增加源码按钮,快捷键 Ctrl+3
  - 内容与 WYSIWYG 编辑器共享 tabStore,切换模式不丢内容

验证: TS 0错误, ESLint 0错误(1个预存警告), 90/90测试通过
2026-06-04 15:17:26 +08:00
thzxx c34a843d5c v0.3.6: 修复文档大纲导航Bug + 新增自动保存功能
Bug修复:
  - 文档大纲点击标题未定位到编辑器内容 (P0)
  - 根因: raw markdown字符偏移 ≠ ProseMirror文档位置
  - 改为通过 view.state.doc.descendants() 遍历节点树,
    按 heading类型名 + level + textContent 三重匹配定位

新增功能:
  - 自动保存 (2秒防抖), 仅对文件标签页生效
  - 状态栏显示 自动/保存中... 指示器

版本同步: package.json / AboutDialog / README 均更新至 v0.3.6
2026-06-04 14:23:27 +08:00
thzxx a84ccb7353 v0.3.5: Bug修复+性能优化+状态栏文档统计
Bug修复:
- BUG-01: Sidebar norm函数正则修复(单反斜杠匹配), Windows路径规范化恢复
- BUG-02: 3处result.content truthy检查改为content !== undefined, 空文件可打开
- BUG-03: TAB_SWITCHED路径校验顺序修复, activeFilePath不在校验前写入

优化:
- OPT-01: Sidebar handleFileClick添加loading状态, 打开文件有视觉反馈

新功能:
- FEAT-01: 状态栏添加行数/单词数/字符数统计
  - useDocStats hook + computeDocStats 纯函数
  - StatusBar右侧显示 行/词/字符 统计信息
  - 12个单元测试覆盖空值/空白/ASCII/UTF-8/Markdown等场景

验证: TS 0错误, ESLint 0错误(1个预存警告), 90/90测试通过
2026-06-04 13:43:10 +08:00
thzxx 899d2b7914 v0.3.4: Bug修复+性能优化+文档大纲功能
🔴 Bug修复 (6):
- Sidebar反斜杠正则修复 (Windows路径规范化)
- FileWatcher文件删除后自动恢复监听
- SearchReplace replaceAll防过期匹配位置
- openFolderDialog null结果守卫
- 保存异常时空路径保护
- Markdown绝对路径图片拼接修复

🟡 性能优化:
- Editor切换标签时内容比较,相同跳过replaceAll

🔵 代码质量:
- 创建共享常量模块 src/shared/constants.ts,消除双副本

🎯 新增功能:
- 文档大纲 (Table of Contents) — 侧边栏标题导航

🔧 换行符统一: CRLF → LF
2026-06-04 13:24:23 +08:00
thzxx efa7f61809 v0.3.3: 代码安全审查与Bug修复
CRITICAL 修复:
- 路径遍历防护绕过:validatePath在normalize()之后检查..,可被绕过读取任意文件
- 编辑器异步创建竞态条件:editor.create()完成后组件已卸载导致内存泄漏
- editor.create() Promise缺少.catch() → 未捕获的Promise拒绝
- handleOpenRecent空文件被跳过:result.content truthy检查阻塞空文件打开

MAJOR 修复:
- DIR_WATCH/TAB_SWITCHED IPC缺少路径校验,可被用于监视任意文件
- AboutDialog内联箭头函数使React.memo完全失效
- ConfirmDialog关闭时焦点恢复逻辑反转
- markdown.ts一刀切屏蔽..导致合法相对路径图片不显示

安全加固:
- 移除未被使用的path.normalize导入
- 所有文件操作IPC使用validatePath统一校验
- 编辑器初始化添加cancelled标志防止卸载后设置实例

验证: TypeScript零错误, ESLint零错误零警告, 78/78测试通过
2026-06-04 13:02:19 +08:00
thzxx 8bcd8a2b2b fix(search): CSS选择器从mark改为通用类名
ProseMirror Decoration.inline渲染的是<span>而非<mark>,
导致mark.search-match-highlight选择器无法匹配,高亮不可见
2026-06-04 11:30:34 +08:00
thzxx ef697c5bcf fix(search): 修复搜索/替换功能三个严重Bug
根因: 直接操作ProseMirror控制的DOM导致内容复制、高亮失效、导航无效

修复方案: 改用ProseMirror Decoration API (Decoration.inline)
- useMilkdown: 新增searchPlugin + getView()暴露EditorView
- SearchReplace: 完全重写,DOM操作→ProseMirror原生事务
- Editor: 传递getView替代editorContainer

Bug详情:
1. parent.children[0]只含Element不含Text → 内容被复制/乱序
2. <mark>不在ProseMirror schema中 → 被reconciliation剥离
3. mark已被移除 → ref指向分离节点 → 导航无效

验证: TypeScript零错误, 78/78测试通过, build成功
2026-06-04 11:08:07 +08:00
thzxx b34cbb5de3 v0.3.1: 添加编辑器搜索/替换功能,修复ESLint和lint-staged错误
- 新增 SearchReplace 组件:Ctrl+F 搜索、Ctrl+H 替换、实时高亮、大小写切换、导航、全部替换
- 修复 tabStore.test.ts 未使用变量的 ESLint 错误
- 修复 lint-staged tsc 命令不兼容 Milkdown .d.ts 的问题
- 版本号 0.3.0 → 0.3.1 (package.json + AboutDialog)
- tsc 零错误、78/78 测试通过、构建成功
2026-06-04 10:22:15 +08:00
thzxx b1803c6467 feat: replace CodeMirror 6 with Milkdown 7.21 editor
- Remove 7 @codemirror/* packages, add 7 @milkdown/* packages
- Rewrite useCodeMirror -> useMilkdown hook (ProseMirror-based)
- Rewrite Editor.tsx with Milkdown lifecycle management
- Update EditorToolbar to use Milkdown callCommand API
- Replace CodeMirror CSS styles with Milkdown/ProseMirror styles
- Support: CommonMark + GFM, dark mode, toolbar formatting
- Bump version 0.2.0 -> 0.3.0
2026-06-04 09:39:10 +08:00
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 3cecb0f9eb v0.1.1: 多Agent代码质量审查+优化
- fix: useCodeMirror onChange闭包过期导致编辑器内容丢失同步(P0)
- feat: 全部组件添加displayName(React DevTools调试支持)
- feat: 全部组件添加ARIA属性(WCAG无障碍支持)
- fix: App异步操作添加try-catch错误边界
- fix: tabStore空catch块添加错误日志
- fix: sidebarStore Set→string[](Zustand可序列化)
- fix: useDragDrop readFile错误处理+空文件修复
- fix: useSettings/useTheme load()添加错误处理
- fix: useTheme toggleDarkMode引用优化
- chore: 版本号升级至0.1.1
2026-06-03 21:02:56 +08:00
thzxx 2716a7d320 release: v1.3.0 版本发布,更新文档与更新日志 2026-05-21 13:44:32 +08:00
thzxx e071a26db6 refactor: renderer.js拆分为6个模块(core/tabs/editor/search/sidebar/markdown) 2026-05-21 13:34:49 +08:00
thzxx b185771c41 opt: 8项优化——搜索高亮精度/滚动同步/行号同步/本地图片/拖拽提示/MRU标签/侧边栏调宽/toast组件 2026-05-21 13:30:11 +08:00
thzxx d178f5b3f6 feat: 侧边栏文件夹目录树添加标题头 2026-05-21 13:16:06 +08:00
thzxx 16fa87e7dd chore: 删除重复的formatFileSize函数,统一用formatBytes 2026-05-21 13:05:21 +08:00
thzxx 04c904dc20 fix: 侧边栏始终可见,不因无文件而隐藏
侧边栏包含「打开文件夹」入口,隐藏会导致用户无法打开文件夹
2026-05-21 12:59:53 +08:00
thzxx 2d899cca7e fix: 侧边栏高亮逻辑清理与边界情况修复
- 移除 loadTabState 中冗余的 updateSidebarHighlight 调用(switchToTab/closeTab 已覆盖)
- 无文件夹+无标签时自动隐藏侧边栏(之前会空显示)
- handleSave/handleSaveAs 后刷新侧边栏(文件路径变化时同步更新)
2026-05-21 12:59:02 +08:00
thzxx eff04606bd fix: 侧边栏高亮跟随标签切换同步更新,支持显示独立打开的文件
- 添加 updateSidebarHighlight() 函数,标签切换时只更新高亮状态而非重建整棵树
- 给树节点添加 data-path 属性用于精确定位高亮
- 新增「已打开的文件」区域,显示不在当前文件夹内的独立文件
- 独立文件支持点击切换、修改状态标识、活跃高亮
- 无文件夹打开时自动显示独立文件列表,全部关闭后隐藏侧边栏
2026-05-21 12:56:50 +08:00
thzxx 65383defd1 fix: 标签栏移入右侧内容区,左侧纯侧边栏 2026-05-21 12:06:14 +08:00
thzxx d25c2ec30d fix: banner移入content-wrapper,标签栏下方直接是两栏布局 2026-05-21 12:04:54 +08:00
thzxx dbbd0f4abb fix: 欢欢迎页移入main-content,侧边栏启动即可见 2026-05-21 12:03:02 +08:00
thzxx 9ac07d376b fix: 修复侧边栏布局——sidebar与main-content并排显示 2026-05-21 11:59:56 +08:00
thzxx f6f1c4f717 fix: 侧边栏watcher泄漏、目录刷新防抖、清理过时注释 2026-05-21 11:43:42 +08:00
thzxx 5d64e4401f fix: 修复渲染进程5个bug(path未定义、editorWrapper未定义、死代码清理) 2026-05-21 11:41:23 +08:00
thzxx 2010f9dff5 docs: 同步 v1.2.0 文档(搜索替换 + 文件树) 2026-05-21 11:39:07 +08:00
thzxx 543af93802 feat: v1.2.0 搜索替换 + 文件树侧边栏 2026-05-21 11:37:02 +08:00
thzxx 320980030e fix: 代码块预览显示undefined - renderer.code参数应为位置参数而非对象解构 2026-05-18 16:16:04 +08:00
thzxx a85c3604c6 fix: 渲染成功后清除错误红色样式残留 2026-05-18 16:01:18 +08:00
thzxx 69e2ee0713 fix: 清理死代码、错误渲染防XSS、blob URL释放时机修复 2026-05-18 15:57:02 +08:00
thzxx addf8e4dd1 fix: save写入失败时恢复文件监听、窗口销毁安全检查、暗色主题跟随系统偏好 2026-05-18 15:50:05 +08:00
thzxx 65451b938c fix: 防御性检查补全
- openFileInTab 增加 isDestroyed() 前置检查
- open-file handler 增加 isDestroyed() 检查
- window:forceClose 增加 isDestroyed() 检查
- close handler 使用 isClosing 防止重入
- cancelClose 重置 isClosing 允许再次关闭
2026-05-18 15:24:01 +08:00
thzxx 5428beb6db fix: 单实例锁,双击md文件在已有窗口打开
- 添加 requestSingleInstanceLock() 防止重复启动
- second-instance 事件中提取文件路径,转发给已有窗口
- 复用 getFilePathFromArgs() 解析命令行参数
2026-05-18 15:10:28 +08:00
thzxx 07989db28e feat: 限制只能打开 md/txt 文件,新建文件仅保存为 md
- 打开对话框移除「所有文件」选项
- 保存对话框移除 .txt 选项
- 拖拽打开增加扩展名过滤
- 浏览器降级路径同步过滤
2026-05-18 14:16:34 +08:00
thzxx 9f0b4550d1 fix: 启动时不自动创建空标签页,直接显示欢迎页 2026-05-18 14:01:43 +08:00
thzxx 5b1caf046c fix: shell.openExternal 添加协议白名单校验
仅允许 http/https 协议,阻止 javascript: 等潜在恶意链接。
2026-05-18 13:58:38 +08:00
thzxx aac6a0b073 fix: 预览选择复制、关闭超时、链接跳转、监听器泄漏
1. 预览区无法选择复制 — #preview 添加 user-select: text
2. IPC 监听器重复注册 — 注册前先 removeAllListeners 防止堆叠
3. 关闭确认取消后 5s 超时仍强制关闭 — 新增 cancelClose IPC 清除超时
4. 预览区链接点击离开应用 — 拦截点击,通过 shell.openExternal 打开
5. 预览区链接光标样式 — .markdown-body a 添加 cursor: pointer
2026-05-18 13:55:02 +08:00
thzxx 394c88e52f fix: 预览区无法选择复制内容
body 全局 user-select: none 导致预览面板继承了不可选择属性,
给 #preview 添加 user-select: text 和 cursor: text 修复。
2026-05-18 13:51:04 +08:00
thzxx b18a2b7e12 版本号升至 1.1.0 2026-05-18 13:37:10 +08:00
thzxx fe478edfde 更新 README.md 和 DESIGN.md:多标签页、暗色主题、文件监听等 v1.1.0 功能 2026-05-18 13:35:23 +08:00
thzxx 5ff89edd2b 清理:移除未使用的 openFiles IPC、优化 setModified 避免每次按键重建标签 DOM 2026-05-18 13:31:14 +08:00
thzxx 78f787a2db 新增多标签页支持:Ctrl+T 新建、Ctrl+W 关闭、Ctrl+Tab 切换、拖拽多文件打开 2026-05-18 13:28:45 +08:00
thzxx 0d82d4ff5e 更新 DESIGN.md:反映暗色主题、文件监听、未保存提醒、IPC 完整通道、localStorage 持久化等实际架构 2026-05-18 13:20:41 +08:00
thzxx ffb925c690 修复:移除 startWatching 中残留的 isModifiedExternally 引用(运行时 ReferenceError) 2026-05-18 13:12:59 +08:00
thzxx b613384030 修复:close超时保护、移除冗余变量、优化文件大小计算、去重formatBytes 2026-05-18 13:11:35 +08:00
thzxx cb29c67f94 全面优化:暗色主题、文件监听、未保存提醒、滚动同步、分屏记忆、文件大小显示、删除死代码 2026-05-18 13:09:31 +08:00
thzxx dbbf1efc78 DEVSETUP.md: 移除硬编码路径,通用化 2026-05-18 13:02:39 +08:00
thzxx 2d41bfd1d7 添加开发环境配置指南 DEVSETUP.md 2026-05-18 12:59:16 +08:00
thzxx 76e03c721c 移除 README 副标题中的 emoji 2026-05-18 12:52:26 +08:00
thzxx bfae531f07 Revert: 移除 README 标题中的 emoji 2026-05-18 12:50:14 +08:00
thzxx 14619fcf7d README 标题添加 🪶 emoji 2026-05-18 12:49:11 +08:00
thzxx 1d76a81ffa 移除原生菜单栏 2026-05-18 12:41:16 +08:00
thzxx 95eec61054 docs: redesign README with detailed Chinese docs and icon 2026-05-18 10:54:46 +08:00
thzxx c573266670 fix: resolve did-finish-load race condition, remove unused import
- Move did-finish-load listener before loadFile() to prevent missing the event
- Remove unused nativeImage import
2026-05-18 10:51:38 +08:00
thzxx 9891feab68 chore: add MIT license 2026-05-18 10:48:40 +08:00
thzxx 76e1699ee7 fix: resolve critical issues found in code review
- Fix marked.js v12 code highlighting (removed deprecated highlight option, use custom renderer.code)
- Fix open-file race condition (handle file association before window ready)
- Fix Tab key undo history (use execCommand/setRangeText instead of direct value assignment)
- Fix drag-drop file path tracking (use IPC readFile instead of FileReader)
- Fix CSP security (remove unsafe-inline from script-src)
- Improve scroll sync (line-based instead of percentage-based)
- Deduplicate file open dialog logic
- Fix .gitignore duplicate entry
2026-05-18 10:46:22 +08:00
thzxx fda3e5987d Initial commit: MarkLite Markdown Reader 2026-05-18 10:40:11 +08:00