# 4-40 文件树 mindmap 连续切换闪烁与文件名过长

## 状态

- 状态：done
- 分类：04-tree-domain
- 发现时间：2026-05-15
- 关联：`4-38`、`4-39`

## 现象

1. 连续点击 File Tree 中的思维导图资源和其它页面时，文件树仍有闪烁感。
2. 思维导图资源文件名暴露技术 ID，例如 `mindmap-mindmap_1778854767490.json`，既长又重复。

## 根因

1. File Tree 中普通页面点击已经走 `__mnoteDocumentPaneRuntime.openPrimaryDocument()`，可以在当前页面内切换主 pane。
2. mindmap 资源点击仍通过 `window.location.assign('/mindmap/...')` 进入对象壳，导致页面壳和 sidebar 重新构建；连续切换时视觉上表现为闪烁。
3. mindmap 文件名由 Convex sidebar dataset 的 `mindmap-${mindmap_id}.json` 派生，若 `mindmap_id` 本身已经以 `mindmap_` 开头，就会显示成 `mindmap-mindmap_...json`。
4. 由于线上 Convex function 可能仍返回旧文件名，mnote-web 初始渲染和 live projection 也需要做展示层兜底规范化。

## 修复

- mindmap 文件树点击改为优先调用 `openPrimaryMindmap()`，在当前 primary pane 内挂载 mindmap 对象，并用 History API 更新 URL。
- primary pane 在文档和 mindmap 之间切换时显式卸载对应 runtime，避免残留视图。
- File Tree mindmap 行展示名统一兜底为短名：`思维导图-xxxx.json`。
- Convex sidebar 源和 Next fallback sidebar 源也同步改为短名口径。
- 新增真实浏览器 smoke：`scripts/task445-filetree-mindmap-switch-no-flicker-smoke.js`。

## 验收标准

- 连续点击 File Tree mindmap 资源 -> 其它页面 -> 同一 mindmap 资源时，`#sidebar-file-tree-root` DOM 根节点保持稳定，不被整页重建。
- URL 可正常切换到 `/mindmap/<documentId>/<mindmapId>` 与 `/documents/<documentId>`。
- mindmap 资源行选中时只选中 `asset:<mindmapId>`，不会闪回父页面行。
- mindmap 文件名不再显示 `mindmap-mindmap_...json`，长度受控。
- 新建页面的 `.md` 文件树标题口径不回退。

## 验证

真实浏览器 smoke：

```bash
MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task445-filetree-mindmap-switch-no-flicker-smoke.js
MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task443-filetree-mindmap-click-active-row-smoke.js
MNOTE_UI_BASE_URL=http://127.0.0.1:3428 node scripts/task444-filetree-create-mindmap-title-cache-smoke.js
```

Rust / 前端定向验证：

```bash
cargo test --manifest-path rust/Cargo.toml -p mnote-web document_shell_returns_page_aggregate_snapshot -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web sidebar_tree_runtime_handles_navigation_drag_and_filetree_actions -- --nocapture
cargo test --manifest-path rust/Cargo.toml -p mnote-web tree_shell_filetree_renderer_outputs_initial_nested_html_contract -- --nocapture
cd wolai-frontend && pnpm test src/lib/sidebar-data.test.ts -- --runInBand
```

`task445` 关键结果：

- `before.mindmapTitle = "思维导图-7712.json"`
- `afterMindmap.fileRootStable = true`
- `afterPage.fileRootStable = true`
- `afterMindmapAgain.fileRootStable = true`
- `failures = []`

备注：`cargo test --manifest-path rust/Cargo.toml -p mnote-web -- --nocapture` 中仍有一个既有 CSS 体积阈值守卫失败：`MNOTE_CSS.len() < 70000`；本轮未修改 CSS。
