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 06e9f4b9..79c5a1b2 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 @@ -103,4 +103,14 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据 - 已验证:`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`node scripts/task489-block-menu-delete-undo-smoke.js`、`node scripts/task488-local-attachment-link-delete-undo-smoke.js`。 - 未完成:`sync_editor_overlay_state` / `try_sync_editor_overlay_state`、`HoveredBlockState` shared type、block menu signal 仍未拆出。 - 2026-05-25:Batch E 计划继续采用独立 worktree 候选 patch:Worker A 负责把 `HoveredBlockState`、`BlockMenuLayout`、`DropPlacement`、`DropIndicatorState` 迁入 `editor_runtime/block_hover_state.rs`,只做共享类型边界,不迁 DOM 查询、signal 编排或 block menu 行为。 +- 2026-05-25:Codex 独立复核并移植 Batch E Worker A 候选 diff:新增 `editor_runtime/block_hover_state.rs`,迁出 `HoveredBlockState`、`BlockMenuLayout`、`DropPlacement`、`DropIndicatorState`、`PendingDragState`;`lib.rs` 仍保留 DOM 查询、布局计算、signal 编排和 block menu 行为。 + - Reasonix 协作证据:runner `reasonix-2026-05-24T18-25-26-836Z-aa546442` / `reasonix-2026-05-24T18-26-04-414Z-9476214d` 均仅产出 `prompt.md` / `memory-recall.json` / `reasonix-transcript.jsonl`,无 `final.md`、`result.json`、`process-handoff.md/json`;因此不作为完整 handoff 采纳。Codex 已查 Hindsight recall、核对 worktree diff,并拒绝移植 worktree 中未跟踪 `reference-code` symlink。 + - 候选 worktree:`/mnt/Data1T/mnote-worktrees/0525-e-worker-a-5-29-block-hover-state`。 + - 修改:`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_hover_state.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_legacy_html.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`。 + - 已验证:`git diff --check`、`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`node scripts/task489-block-menu-delete-undo-smoke.js`、`node scripts/task488-local-attachment-link-delete-undo-smoke.js`。 + - 未完成:`sync_editor_overlay_state` / `try_sync_editor_overlay_state`、block menu signal 编排、HTML 整文替换 legacy 路径仍未拆出。 - 2026-05-25:Batch E 派发异常并终止:Worker A 任务被重复启动为两个 runner / ACP 进程(`reasonix-2026-05-24T18-25-26-836Z-aa546442`、`reasonix-2026-05-24T18-26-04-414Z-9476214d`),同一 worktree `/mnt/Data1T/mnote-worktrees/0525-e-worker-a-5-29-block-hover-state` 出现并发写入风险;Codex 已终止相关 Reasonix 进程,未读取到 `final.md`、`result.json`、`process-handoff.md/json`,该 diff 只保留为后续人工审计素材,不采纳。 +- 2026-05-25:Codex 独立复核并推进 block hover state 类型边界拆分:新增 `editor_runtime/block_hover_state.rs`,迁出 `HoveredBlockState`、`BlockMenuLayout`、`DropPlacement`、`DropIndicatorState`、`PendingDragState`;`lib.rs` 仍保留 DOM 查询、signal 编排、block menu 行为和拖拽逻辑。 + - 修改:`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_hover_state.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_legacy_html.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`、generated island wasm。 + - 已验证:`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`。 + - 未完成:`sync_editor_overlay_state` / `try_sync_editor_overlay_state`、block menu signal 和拖拽重排行为仍在 `lib.rs`,后续应继续按更窄 helper 拆分。 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 b7db5820..f10bed20 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/block_hover_state.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_hover_state.rs new file mode 100644 index 00000000..2532504d --- /dev/null +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_hover_state.rs @@ -0,0 +1,47 @@ +//! Block hover / block menu / drop indicator 共享状态类型定义。 +//! +//! 本模块只承接共享状态类型,不承接 Leptos signal、DOM listener、host bridge +//! 或 editor command。类型字段使用 `pub(crate)` 以支持跨模块访问,保持结构 +//! 和语义同构。 + +/// Hovered block 的共享状态:索引、类型标签、位置和高度。 +#[derive(Clone, Debug, PartialEq)] +pub(crate) struct HoveredBlockState { + pub(crate) index: usize, + pub(crate) label: String, + pub(crate) top: f64, + pub(crate) height: f64, +} + +/// Block menu 弹出面板的布局参数:最大高度、展开方向、位置。 +#[derive(Clone, Debug, PartialEq)] +pub(crate) struct BlockMenuLayout { + pub(crate) max_height: f64, + pub(crate) open_upward: bool, + pub(crate) top: f64, + pub(crate) left: f64, +} + +/// 拖拽放置方向:目标块之前或之后。 +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) enum DropPlacement { + Before, + After, +} + +/// 拖拽指示器的显示状态:目标索引、位置和放置方向。 +#[derive(Clone, Debug, PartialEq)] +pub(crate) struct DropIndicatorState { + pub(crate) index: usize, + pub(crate) top: f64, + pub(crate) placement: DropPlacement, +} + +/// 拖拽待确认状态:记录开始拖拽时的索引、锚点和起始坐标。 +#[derive(Clone, Debug, PartialEq)] +pub(crate) struct PendingDragState { + pub(crate) index: usize, + pub(crate) anchor: HoveredBlockState, + pub(crate) start_x: i32, + pub(crate) start_y: i32, +} diff --git a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs index 555ba051..02efd978 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_document.rs @@ -2,7 +2,7 @@ use serde_json::{json, Value}; -use crate::DropPlacement; +use crate::editor_runtime::block_hover_state::DropPlacement; fn document_content_mut(document: &mut Value) -> Result<&mut Vec, String> { document diff --git a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_legacy_html.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_legacy_html.rs index 89c1f151..a8a71706 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_legacy_html.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/block_menu_legacy_html.rs @@ -15,7 +15,7 @@ use wasm_bindgen::JsCast; use web_sys::{window, Element}; -use crate::DropPlacement; +use crate::editor_runtime::block_hover_state::DropPlacement; /// 复制第 `index` 个顶层 HTML 块并插入其后。 /// diff --git a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs index 61a1c9f7..0819f726 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs @@ -1,5 +1,6 @@ pub(crate) mod attachment_links; pub(crate) mod attachment_upload; +pub(crate) mod block_hover_state; pub(crate) mod block_menu_document; pub(crate) mod block_menu_legacy_html; pub(crate) mod command_sync; diff --git a/rust/spikes/leptos-tiptap-spike/src/lib.rs b/rust/spikes/leptos-tiptap-spike/src/lib.rs index cf519d5b..52c506d1 100644 --- a/rust/spikes/leptos-tiptap-spike/src/lib.rs +++ b/rust/spikes/leptos-tiptap-spike/src/lib.rs @@ -24,6 +24,9 @@ use editor_runtime::attachment_upload::dispatch_editor_upload_request; use editor_runtime::block_menu_legacy_html::{ duplicate_top_level_block_html, reorder_top_level_block_html, }; +use editor_runtime::block_hover_state::{ + BlockMenuLayout, DropIndicatorState, DropPlacement, HoveredBlockState, PendingDragState, +}; use editor_runtime::command_sync::{ read_editor_snapshot, sync_editor_outputs, sync_persisted_editor_command, }; @@ -4783,14 +4786,6 @@ fn build_command_listener(mount_id: u32) -> Closure { })) } -#[derive(Clone, Debug, PartialEq)] -struct HoveredBlockState { - index: usize, - label: String, - top: f64, - height: f64, -} - #[derive(Clone, Debug, PartialEq)] struct ImageToolbarAnchor { top: f64, @@ -4829,35 +4824,6 @@ struct TableSelectionOverlayState { index: usize, } -#[derive(Clone, Debug, PartialEq)] -struct BlockMenuLayout { - max_height: f64, - open_upward: bool, - top: f64, - left: f64, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) enum DropPlacement { - Before, - After, -} - -#[derive(Clone, Debug, PartialEq)] -struct DropIndicatorState { - index: usize, - top: f64, - placement: DropPlacement, -} - -#[derive(Clone, Debug, PartialEq)] -struct PendingDragState { - index: usize, - anchor: HoveredBlockState, - start_x: i32, - start_y: i32, -} - fn default_title() -> String { "Leptos Tiptap 主编辑器 P0".to_string() }