Files

94 lines
13 KiB
Markdown
Raw Permalink 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.
我手动测试,以下bug仍然存在:
1.我的空间:向文件树中的md文件中拖动文件进行上传文件,能正常在主编辑 md 中显示,点击也能正常打开,但是见 /mnt/Data1T/mnote/tmp/image copy
65.png,文件是和主文件夹同级(应该在我的文件夹下级)。
2.上传文件后,弹出文件冲突:/mnt/Data1T/mnote/tmp/image copy 76.png,重新新建页面(冲突信息被带到新页面,
刷新后消失),文件冲突依然存在。冲突信息:/mnt/Data1T/mnote/tmp/image copy 77.png;另外一个例子:/mnt/Data1T/mnote/tmp/image copy 85.png,新建的页面直接向文件树拖入文件就提示冲突。
处理记录(2026-05-24):
- 归类:`05-editor-mainline`,本质是本地 Markdown working copy 冲突合同缺失,不是单个上传入口问题。
- 参考设计:`design/05-editor-mainline/process/5-27-local-markdown-working-copy-conflict-contract-v1.md`
- Sidex/VSCode 对照结论:正文冲突只应属于同一个 Markdown resource;同 root 下的附件、拖入资源、目录级 watcher 事件不能升级成当前 working copy 冲突。
- 根因 1:前端本地文件夹 document event channel 只按 `rootUri` 共享,且 SSE 请求没有携带当前 `documentId`,后端无法按 Markdown 正文路径过滤。
- 根因 2:上传附件/文件树拖入等非 Markdown 资源事件的 `documentId` 为空,前端仍继续设置 `externalChangePending`,导致误报文件冲突。
- 根因 3:冲突面板是手动插入 `.document-pane` 的 DOM,页面切换时没有随 editor view unmount 清理,因此旧页面冲突 UI 会短暂残留到新页面。
- 修复:
- `rust/crates/mnote-web/src/routes/web_shell.rs`document event channel key 从 `rootUri` 收窄为 `rootUri#documentId`,订阅 `/api/local-folder/events` 时携带 `documentId`
- `rust/crates/mnote-web/src/routes/web_shell.rs`:收到空 `documentId` 的资源事件直接忽略,不进入正文冲突链路。
- `rust/crates/mnote-web/src/routes/web_shell.rs``unmountEditorViewBinding` 清理旧 session 冲突面板,避免跨页面残留。
- `rust/crates/mnote-web/src/routes/local_folder_events.rs`:补充 document event filter 测试,确保资源路径不会匹配 Markdown 正文路径。
- `scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`:上传附件和文件树拖入后增加 no-conflict 断言。
- 验证:
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web document_event_filter_rejects_resource_only_changes -- --nocapture` 通过。
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web document_shell_renders_local_markdown_with_same_sidebar_surfaces -- --nocapture` 通过。
- `cargo fmt --manifest-path rust/Cargo.toml --all --check` 通过。
- `node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js` 通过,说明真实冲突路径仍可用。
- `node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js` 中上传附件 no-conflict 与文件树拖入 no-conflict 通过;后续 broken-link 检查 timeout 属于第 2 条以外的资源缺失解析问题,需单独处理。
- Worker 对比:
- Reasonix coding 正确定位空 `documentId` 污染,但漏掉 DOM 生命周期与按 `documentId` 隔离 channel。
- Claude Code coding 额外定位 DOM 生命周期问题,但清理位置偏晚,仍需主控调整到 editor view unmount。
- Claude Code browser 证据更完整,覆盖 no-conflict 与真实冲突;Reasonix browser 只适合作为部分 UI 证据,因为其 result/handoff 状态不一致且误判 SSE 500 为真实冲突阻塞。
3.隐藏本地markdown标题,我去除勾选后,新建页面刷新又恢复默认了,应该维持我的选择的状态。另外应该针对我的空间和其它本地文件夹进行区分,我的空间(包括别人分享给我的我的空间,即所有我的空间)中默认显示本地markdown标题,其它的本地文件夹,默认隐藏markdown标题。
处理记录(2026-05-24):
- 归类:`05-editor-mainline`,本质是本地 Markdown page options 默认值与持久化合同不完整。
- 根因:`resolve_local_markdown_page_aggregate` 在页面没有持久化 `hideTitleHeader` 时无条件设为 `true`,导致所有本地 Markdown 都默认隐藏标题,没有区分托管工作区(我的空间)与普通本地文件夹。用户取消勾选后只对当前页面写入 `.mnote/page-options.json`,新建页面仍因无记录回到错误默认值。
- 修复:
- `rust/crates/mnote-web/src/routes/local_folder_source.rs`:无持久化值时检查当前 root 是否存在托管工作区清单;托管工作区默认 `hide_title_header=false`,普通本地文件夹默认 `true`。已有持久化值继续优先,避免覆盖用户选择。
- `rust/crates/mnote-web/src/routes/local_folder_source.rs`:更新托管工作区标题测试,并新增普通本地文件夹默认隐藏标题测试。
- `scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`:Check 6 调整为托管工作区默认显示标题;先勾选隐藏并验证持久化,再取消勾选显示并验证刷新后仍显示。
- 验证:
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_markdown_page_title_comes_from_file_name_not_body_heading -- --nocapture` 通过。
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_markdown_non_managed_folder_default_hides_title_header -- --nocapture` 通过。
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_folder_documents_save_title_and_options_write_to_disk -- --nocapture` 通过。
- `cargo fmt --manifest-path rust/Cargo.toml --all --check` 通过。
- `node --check scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js` 通过。
- Worker 对比:
- Reasonix coding 在隔离 worktree `mnote-wt-0524c-reasonix-title` 完成可用修复,范围控制在 `local_folder_source.rs``task479`,主控复核后采纳。
- Claude Code coding 本轮 Hindsight 注入成功,但因 `--max-budget-usd 1.20` 超预算退出,只停留在代码探索阶段,未产生 diff;这说明 Claude Code full-mode 对编码任务成本较高,需要更小任务切片或更高预算。
4.CTRL+Z/CTRL+Y对于删除链接不可用,不能恢复删除的链接。(你应该系统看看还有没有其它ctrl+z/CTRL+Y(撤销/恢复)不能用的场景)
处理记录(2026-05-24):
- 归类:`05-editor-mainline`,本质是编辑器命令写入链路绕过 Tiptap/ProseMirror history,不能只按单个链接 UI 修补。
- 根因:本地 Markdown 附件链接被选中后按 `Backspace/Delete` 时,旧逻辑识别本地附件链接并走 `get_html -> delete_top_level_block_html -> editor.set_content(html)``set_content` 是整文替换,不会生成可撤销的用户 transaction,因此 `Ctrl+Z/Ctrl+Y` 无法恢复删除的链接。
- 修复:
- `rust/spikes/leptos-tiptap-spike/src/lib.rs`:删除本地附件链接时不再通过 HTML 整文替换;改为在 keydown 捕获阶段识别 Tiptap 当前非空选区是否位于 `/api/local-folder/files/open` 链接 mark 内,并调用 `editor.delete_selection()`,让删除进入 ProseMirror history。
- `rust/spikes/leptos-tiptap-spike/src/lib.rs`:保留 DOM selection 识别作为鼠标选中文本兜底,但主判断改为读取 Tiptap editor state 的 link attributes,避免内部 selection 与 `window.getSelection()` 不同步。
- `scripts/task488-local-attachment-link-delete-undo-smoke.js`:新增真实浏览器回归,上传本地 Markdown 附件、选中附件链接文本、Delete 删除、`Ctrl+Z` 恢复、`Ctrl+Y` 再删除。脚本显式等待超过 Tiptap history `newGroupDelay`,避免把“上传+删除”合并为同一个撤销事件而误判。
- 验证:
- `cargo fmt --manifest-path rust/Cargo.toml --all --check` 通过。
- `cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml` 通过,只有既有 warning。
- `cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release` 通过,只有既有 warning。
- `wasm-bindgen rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island` 通过。
- `node --check scripts/task488-local-attachment-link-delete-undo-smoke.js` 通过。
- `node scripts/task488-local-attachment-link-delete-undo-smoke.js` 通过。
- Worker 对比:
- Claude Code 三轮任务均因预算超限或无可用 `finalText/process-handoff` 失败,隔离 worktree 没有可采纳 diff;本轮说明 Claude Code 轻量 patch mode 仍需要更窄任务和更稳定预算。
- Reasonix 多轮任务卡住;其中 narrow patch worktree 有 diff,但没有 result/handoff,且包含无关格式和英文注释,未采纳。
- 本轮对比结论:两者都没有直接解决第 4 条;可用价值主要是暴露 worker 失败模式。最终根因、修复和 smoke 由主控完成。
- 系统性后续:
- 当前修复覆盖“选中文本删除本地附件链接”的高频路径。块菜单删除、拖拽重排、折叠标题转换等仍有 `set_content`/HTML 整文替换路径,后续应拆一个 editor command history 设计,把块级删除/重排统一迁移到 Tiptap transaction/command,而不是继续扩散整文替换。
5,md文件上传后刷新前面的黑色方块会变成灰色:/mnt/Data1T/mnote/tmp/image copy 80.png/mnt/Data1T/mnote/tmp/image copy 81.png
处理记录(2026-05-26):
- 归类:`05-editor-mainline`,本质是本地 Markdown 上传附件插入后,Tiptap DOM、document session 保存、刷新后附件增强三者之间的时序合同不完整。
- CodeGraph 定位:拆分后可直接从 `local-upload-runtime.js::insertUploadedAssetIntoEditor``sidebar-attachment-open-runtime.js::enhanceEditorAttachmentLink``document-editor-adapter-runtime.js::handleSessionChange``document-session-runtime.js::persistSession` 定位,不再需要在 `layout.rs` 大型 raw string 中翻找。
- 根因:
- 上传插入成功后,链接只进入当前 Tiptap DOM,没有稳定触发 local-folder document save,刷新后会从旧 Markdown 重建。
- 刷新后 `/api/local-folder/files/open` 本地链接增强存在首屏时序竞态,普通 local open 链接可能暂时只有灰色通用文件 badge。
- 修复:
- `rust/crates/mnote-web/browser/local-upload-runtime.js`:上传插入后派发 Tiptap bridge change,并对 local-folder 上传直接按现有 conversion runtime 转为 `editorBlocks``/api/documents/save`;保存前登记 self-change suppression,避免 watcher 把自写入误报为外部冲突。
- `rust/crates/mnote-web/browser/sidebar-attachment-open-runtime.js`:本地 open 链接也先补 `data-mnote-attachment-link``data-asset-id` 和类型 class,再做存在性刷新;并增加初始附件增强重扫。
- `rust/crates/mnote-web/browser/document-tiptap-conversion-runtime.js`:刷新时从本地 open URL 的 `path` 重新推导附件类型,在 Markdown → Tiptap link mark 边界直接补 `mnote-uploaded-attachment-code` 等类型 classCSS 只消费 class,不再用 `.md` href 颜色选择器兜底。
- `scripts/task491-local-md-attachment-icon-refresh-smoke.js`:新增窄浏览器回归,覆盖上传 md 附件、写入 Markdown、刷新后仍保持黑色 md 附件图标。
- `scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`:第 1 项补充刷新前后 md 附件图标断言,必须恢复 `mnote-uploaded-attachment-code` class,不再接受单纯 `::before` 黑色背景。
- 验证:
- `node scripts/task491-local-md-attachment-icon-refresh-smoke.js` 通过。
- `node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js``editor-upload-to-page-resource-dir` 通过;该宽脚本仍有既有 `broken-link-after-real-file-delete``editor-delete-one-attachment-preserves-adjacent` 失败,非本条阻塞。
6. 当前office文件本地可以打开,我们当前使用sakura frp映射3000端口至:https://www.aichem.dpdns.org 后,发现pdf可以正常打开,但onlyoffice打不开了,报错为:ONLYOFFICE 加载失败{"target":{"frameOrigin":"https://www.aichem.dpdns.org"},"data":{"errorCode":-4,"errorDescription":"下载失败"}}。请检查原因,同时要兼容未来更换域名。
处理记录(2026-05-26):
- 归类:`05-editor-mainline` / OnlyOffice transport,问题是 DocumentServer 下载地址随浏览器公网域名变化。
- 根因:OnlyOffice 页面在非 localhost 访问时把 `proxyOrigin` 设为 `location.origin`,导致 DocumentServer 去拉 `https://www.aichem.dpdns.org/api/onlyoffice/proxy?...`;公网映射域名对 DocumentServer 不一定可达,触发 `errorCode=-4 下载失败`
- 修复:`rust/crates/mnote-web/src/routes/onlyoffice.rs``proxyOrigin``callbackOrigin` 固定使用 `documentUrlBase`,即 `ONLYOFFICE_DOCUMENT_URL_BASE` / 内部可达 base,不再依赖浏览器当前域名;未来换 FRP 域名不影响 DocumentServer 回源。
- 验证:`cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_page_exposes_documentserver_fetch_base_for_local_files -- --test-threads=1` 通过。