diff --git a/design/03-rust-web/process/3-21-final-sidebar-runtime-extraction-v1.md b/design/03-rust-web/process/3-21-final-sidebar-runtime-extraction-v1.md index ef8b6516..e92c0e11 100644 --- a/design/03-rust-web/process/3-21-final-sidebar-runtime-extraction-v1.md +++ b/design/03-rust-web/process/3-21-final-sidebar-runtime-extraction-v1.md @@ -188,11 +188,11 @@ codegraph sync . | browser/ 模块 | 11 个 JS 文件,总计 ~11,000 行 | | editor_runtime/ 模块 | 19 个 Rust 模块(另有 mod.rs) | | 浏览器 smoke | task479/488/489/451 全部 PASS | -| 测试 | editor 13/13, web sidebar 10/10, web full 531/549 | +| 测试 | editor 13/13;web full 最近一次 529/549(20 failed,非本轮 editor runtime / sidebar 外置改动面) | | CodeGraph | 350+ 文件索引完成 | ### 未完成(记录为后续任务) | 项 | 说明 | |----|------| -| Batch C 全量验证 | 尚未运行 `cargo test -p mnote-web --lib` / `cargo test -p mnote-leptos-tiptap-spike` / task451 全套;本轮已完成 spike check/build、wasm-bindgen、task479/task488/task489、临时 slash/table Playwright 回归与直接编辑器交互回归 | +| Batch C 全量验证 | `cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml -- --test-threads=1` 已 13/13 通过,task451 已补跑通过;但 `cargo test --manifest-path rust/Cargo.toml -p mnote-web --lib -- --test-threads=1` 最近一次仍 20 failed(watcher OS limit、legacy proxy、access policy dialog、Hermes block tools 403、local search index、resource trash 503、web_shell 旧断言等),所以本文件保持 `process` 而不是归档到 `done`。 | diff --git a/design/05-editor-mainline/process/5-29-editor-runtime-followup-checklist-v1.md b/design/05-editor-mainline/process/5-29-editor-runtime-followup-checklist-v1.md index cbed1a2c..94e339c8 100644 --- a/design/05-editor-mainline/process/5-29-editor-runtime-followup-checklist-v1.md +++ b/design/05-editor-mainline/process/5-29-editor-runtime-followup-checklist-v1.md @@ -406,9 +406,9 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据 | 文件 | 原大小 | 现大小 | 变化 | |------|--------|--------|------| -| `lib.rs` | 9,873 行 | 8,181 行 | **-17%** | -| `editor_runtime/mindmap_node_view.rs` | — | 909 行 | 新建 | -| `editor_runtime/bridge_events.rs` | — | 149 行 | 新建 | +| `lib.rs` | 9,873 行 | 8,189 行 | **-17%** | +| `editor_runtime/mindmap_node_view.rs` | — | 906 行 | 新建 | +| `editor_runtime/bridge_events.rs` | — | 154 行 | 新建 | | `editor_runtime/slash_actions.rs` | — | 237 行 | 新建 | | `editor_runtime/table_commands.rs` | — | 180 行 | 新建 | | `editor_runtime/bridge_dispatch.rs` | — | 86 行 | 新建 | @@ -459,3 +459,8 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据 - 新增 `table_commands.rs`,迁出 table toolbar / option action、命令执行和 checked 状态计算。 - 新增 `bridge_dispatch.rs`,迁出 `HostCommandKind` 及 host command payload 解析;真实 command 执行 match 仍留在 `lib.rs`。 - 已验证:`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml command -- --test-threads=1`、wasm release build、`wasm-bindgen`、task489、task488、task479、临时 slash 插入简单表格 + 表格行 aux 命令 Playwright 回归。 +- 2026-05-25:Codex 完成本轮 warning / dead-code 清理。 + - 删除无调用方的 `command_sync::apply_document_update`、`dom_selection::selection_has_rich_marks`,移除 `lib.rs` 中未用 import / 变量。 + - 将 `should_auto_close_toolbar_overlays` 接回两个实际 auto-close 判断点,避免 helper 外置后仍有重复手写判定。 + - 对必须持有生命周期但 Rust 编译器无法直接观察用途的 mount handle、host envelope 反序列化字段加局部 `#[allow(dead_code)]`,不扩大到模块级。 + - 已验证:`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml` 无 warning,`cargo test --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml -- --test-threads=1` 13/13 通过。 diff --git a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm index 233a5689..73c5e1b4 100644 Binary files a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm and b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island_bg.wasm differ diff --git a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/bridge_events.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/bridge_events.rs index b18f8ac7..782a3135 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/bridge_events.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/bridge_events.rs @@ -110,6 +110,7 @@ pub(crate) struct HeightPayload { #[derive(Clone, Debug, Deserialize)] #[serde(rename_all = "camelCase")] +#[allow(dead_code)] pub(crate) struct HostCommandEnvelope { pub(crate) protocol: Option, pub(crate) runtime: Option, @@ -131,6 +132,7 @@ pub(crate) struct RuntimePageOptions { #[derive(Clone, Debug, Deserialize)] #[serde(rename_all = "camelCase")] +#[allow(dead_code)] pub(crate) struct HostCommandPayload { pub(crate) command: Option, pub(crate) document_id: Option, diff --git a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/command_sync.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/command_sync.rs index 904870b4..03d8d362 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/command_sync.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/command_sync.rs @@ -1,6 +1,6 @@ use crate::editor_runtime::persistence::{persist_document_state, PersistedDocumentIdentity}; use leptos::prelude::{GetUntracked, ReadSignal, Set, Update, WriteSignal}; -use leptos_tiptap::{TiptapContent, TiptapEditorHandle}; +use leptos_tiptap::TiptapEditorHandle; use serde_json::{json, Value}; pub(crate) fn read_editor_snapshot(editor: TiptapEditorHandle) -> (String, Value, String) { @@ -31,45 +31,6 @@ pub(crate) fn sync_editor_outputs( json_value } -pub(crate) fn apply_document_update( - editor: TiptapEditorHandle, - persisted_identity: &PersistedDocumentIdentity, - next_document: Value, - set_dirty_count: WriteSignal, - set_html_output: WriteSignal, - set_document_json: WriteSignal, - set_json_output: WriteSignal, - title: ReadSignal, - set_command_feedback: WriteSignal, - success_message: impl Into, -) { - let success_message = success_message.into(); - let next_payload = next_document - .get("content") - .and_then(Value::as_array) - .cloned() - .map(Value::Array) - .unwrap_or_else(|| next_document.clone()); - match editor.set_content(TiptapContent::json(next_payload)) { - Ok(()) => { - persist_current_editor_snapshot( - editor, - persisted_identity, - set_dirty_count, - set_html_output, - set_document_json, - set_json_output, - title, - set_command_feedback, - success_message, - ); - } - Err(err) => { - set_command_feedback.set(format!("更新文档失败:{err}")); - } - } -} - pub(crate) fn sync_persisted_editor_command( editor: TiptapEditorHandle, persisted_identity: &PersistedDocumentIdentity, diff --git a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs index ae75eee1..a7f8e320 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs @@ -128,16 +128,6 @@ pub(crate) fn selection_summary(selection: &TiptapSelectionState) -> String { format!("当前块:{block} | 行内样式:{mark_text}") } -pub(crate) fn selection_has_rich_marks(selection: &TiptapSelectionState) -> bool { - selection.bold - || selection.italic - || selection.underline - || selection.strike - || selection.highlight - || selection.text_style - || selection.link -} - pub(crate) fn block_id_from_element(block: &Element) -> Option { block .get_attribute("data-block-id") diff --git a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mindmap_node_view.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mindmap_node_view.rs index 537aac6a..29658791 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mindmap_node_view.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mindmap_node_view.rs @@ -32,6 +32,8 @@ pub(crate) const MINDMAP_SHELL_MINIMAP_EVENT: &str = "mnote:mindmap-shell:minima pub(crate) const MINDMAP_SHELL_ZOOM_EVENT: &str = "mnote:mindmap-shell:zoom"; pub(crate) const MINDMAP_SHELL_TOOLBAR_OVERFLOW_EVENT: &str = "mnote:mindmap-shell:toolbar-overflow"; pub(crate) struct MountedMindmapShell { + // 保留 Leptos mount handle,避免 mindmap shell 被提前释放。 + #[allow(dead_code)] mount_handle: Box, } #[derive(Clone, Deserialize, Serialize)] diff --git a/rust/spikes/leptos-tiptap-spike/src/lib.rs b/rust/spikes/leptos-tiptap-spike/src/lib.rs index d5a1ba22..c3bfed07 100644 --- a/rust/spikes/leptos-tiptap-spike/src/lib.rs +++ b/rust/spikes/leptos-tiptap-spike/src/lib.rs @@ -5,9 +5,8 @@ use leptos_dom::helpers::window_event_listener; use leptos_tiptap::{ TiptapCodeBlockAttributes, TiptapColorAttributes, TiptapContent, TiptapEditor, TiptapEditorHandle, TiptapExtension, TiptapHeadingLevel, TiptapHighlightAttributes, - TiptapImageResource, TiptapInsertContentOptions, TiptapLinkResource, TiptapMarkName, - TiptapNodeName, TiptapRange, TiptapSchemaTarget, TiptapSelectionState, TiptapTextAlign, - TiptapTocNodeAttrs, + TiptapInsertContentOptions, TiptapLinkResource, TiptapMarkName, TiptapNodeName, TiptapRange, + TiptapSchemaTarget, TiptapSelectionState, TiptapTextAlign, TiptapTocNodeAttrs, }; use send_wrapper::SendWrapper; use serde::{Deserialize, Serialize}; @@ -62,9 +61,9 @@ use editor_runtime::overlays::{ close_editor_floating_overlays_if_escape, current_table_overlay_anchor, image_element_from_target, image_toolbar_anchor_from_image, open_block_menu_overlay, open_image_toolbar_overlay, open_slash_menu_overlay, selection_bounding_rect, - sync_overlays_on_selection_change, table_col_aux_style, table_overlay_anchor_from_table, - table_row_aux_style, table_selection_overlay_style, toolbar_overlay_locked, - try_sync_editor_overlay_state, FloatingToolbarAnchor, ImageToolbarAnchor, + should_auto_close_toolbar_overlays, sync_overlays_on_selection_change, table_col_aux_style, + table_overlay_anchor_from_table, table_row_aux_style, table_selection_overlay_style, + toolbar_overlay_locked, try_sync_editor_overlay_state, FloatingToolbarAnchor, ImageToolbarAnchor, TableOverlayAnchor, TableSelectionKind, TableSelectionOverlayState, }; use editor_runtime::persistence::{ @@ -2792,6 +2791,7 @@ const FOLDED_HEADING_ACTIONS: [FoldedHeadingAction; 4] = [ #[derive(Clone, Debug, Deserialize)] #[serde(rename_all = "camelCase")] +#[allow(dead_code)] struct LegacyHostEnvelope { protocol: Option, runtime: Option, @@ -2977,6 +2977,7 @@ struct RuntimeMountContext { } #[derive(Clone, Debug)] +#[allow(dead_code)] struct RuntimeMountOptions { options: MountOptions, mode: RuntimeDeliveryMode, @@ -2989,6 +2990,8 @@ struct MountedRuntimeListener { struct MountedRuntime { listeners: Vec, + // 保留 Leptos mount handle,避免挂载内容被提前释放。 + #[allow(dead_code)] mount_handle: Box, } @@ -5053,7 +5056,6 @@ fn App(mount_options: MountOptions) -> impl IntoView { // ── Block-delta listener(Phase B:AI 写入增量通道) ── let delta_editor = editor; let delta_set_document_json = set_document_json; - let delta_json_output = json_output; let delta_set_json_output = set_json_output; let delta_set_dirty_count = set_dirty_count; let delta_set_html_output = set_html_output; @@ -5134,15 +5136,15 @@ fn App(mount_options: MountOptions) -> impl IntoView { let set_color_menu_open = set_color_menu_open; let set_more_menu_open = set_more_menu_open; Effect::new(move |_| { - let toolbar_locked = toolbar_overlay_locked( + if should_auto_close_toolbar_overlays( + editor_focused.get(), + text_selection_active.get(), turn_into_open.get_untracked(), color_menu_open.get_untracked(), more_menu_open.get_untracked(), - ); - if ((!editor_focused.get() || !text_selection_active.get()) && !toolbar_locked) - || slash_open.get() - || block_menu_open.get() - { + slash_open.get(), + block_menu_open.get(), + ) { set_turn_into_open.set(false); set_color_menu_open.set(false); set_more_menu_open.set(false); @@ -6489,9 +6491,15 @@ fn App(mount_options: MountOptions) -> impl IntoView { floating_toolbar_anchor.get() }; if let Some(anchor) = toolbar_anchor { - if ((!editor_focused.get() || !text_selection_active.get()) && !toolbar_locked) - || slash_open.get() - || block_menu_open.get() + if should_auto_close_toolbar_overlays( + editor_focused.get(), + text_selection_active.get(), + turn_into_open.get(), + color_menu_open.get(), + more_menu_open.get(), + slash_open.get(), + block_menu_open.get(), + ) || dragging_block_index.get().is_some() { return ().into_any();