From 2c32c4f656559b0c99f3ac802bc450815d26d8d1 Mon Sep 17 00:00:00 2001 From: lix-2026 Date: Mon, 25 May 2026 09:21:58 +0800 Subject: [PATCH] refactor: extract current block info helper --- ...-29-editor-runtime-followup-checklist-v1.md | 8 +++++++- .../src/editor_runtime/dom_selection.rs | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) 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 99b770ae..7bbb97cc 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 @@ -350,6 +350,11 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据 - 过程异常:主控在等待 BF run 期间发现未批准 residual runner 自动启动了 Batch BE 的 4 个 worker(`0525-be-*`),已统一终止并拒收;在当前 2-worker 上限下,后续不再采纳任何未明确派发的 run。 - 主控本地代码结论:`SelectionPayload`、`block_id_from_element`、`block_id_from_json_node`、`runtime_block_id_from_index`、`selection_payload` 已经落在 `editor_runtime/dom_selection.rs` 的合理边界内,继续迁出收益有限;`dispatch_selection_event_to_target`、`send_selection_state_to_target`、`on_selection_change` 仍绑定 `EventTarget`、Leptos signal、overlay 同步与 editor lifecycle,必须留在 `lib.rs` 壳层。 - 最小下一刀建议:若继续推进,只做 `current_block_info_from_index()` 的单刀收口,把它与 `runtime_block_id_from_index()` 组合成 `dom_selection` 中的轻量 block info helper,供 runtime state / host status / selection bridge 共用;不要继续触碰 `send_selection_state_to_target` 或把 bridge dispatch 下沉进 runtime 模块。 +- 2026-05-25:Codex 主控按 Batch BF 结论完成 `current_block_info_from_index()` 最小切片。 + - 修改:`rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_selection.rs` 新增 `CurrentBlockInfo` 与 `current_block_info_from_index(index)`;`rust/spikes/leptos-tiptap-spike/src/lib.rs` 删除本地 `CurrentBlockInfo` 与同名 helper,改为复用 runtime helper。 + - 边界:未迁 `dispatch_selection_event_to_target`、`send_selection_state_to_target`、`on_selection_change`、`selection_event_target` 或任何 bridge dispatch;本批只收口 selection 数据层的 block info helper。 + - 已验证:`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`、`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`、`MNOTE_WEB_BIND=127.0.0.1:3034 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3034 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3034 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3034 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3034 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。 + - 浏览器证据:`tmp/0525-selection-payload-slice-workspace.png` 展示 3034 当前源码服务登录后工作区首屏;本轮使用 Playwright 只读截图替代 `browser-use`,原因是 in-app browser `iab` backend 当前不可用。 - 2026-05-25:Codex 主控继续收口共享内容列布局 helper,去掉 `lib.rs` 与 `block_menu_overlay.rs` 的重复常量与几何函数。 - 修改:新增 `rust/spikes/leptos-tiptap-spike/src/editor_runtime/content_layout.rs`,迁入 `content_column_width()`、`content_column_left()`、`content_text_left()` 及对应常量;`editor_runtime/block_menu_overlay.rs` 与 `lib.rs` 改为复用该共享模块,`lib.rs` 仅保留 `handle_lane_left()` 这一层 handle 专属偏移计算。 - 边界:未迁 `handle_lane_left()`、`HANDLE_*` 常量、`slash_menu_anchor_style()`、drop indicator 壳层、block menu overlay 自身布局策略或 DOM 查询;本批只消除内容列布局 helper 的重复定义。 @@ -359,4 +364,5 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据 - 修改:`editor_runtime/dom_selection.rs` 新增 `CurrentBlockInfo` 与 `current_block_info_from_index(index)`,把 `current_block_index + runtime_block_id_from_index()` 的轻量 block info 组装迁入 selection runtime;`lib.rs` 删除本地 `CurrentBlockInfo` 结构与同名 helper,改为复用 runtime helper。 - 边界:未迁 `selection_payload`、`dispatch_selection_event_to_target`、`send_selection_state_to_target`、`on_selection_change` 或任何 bridge dispatch;本批只收口 “index -> {index, block_id}” 的轻量数据 helper。 - 影响点:`HostCommandKind::RequestCurrentBlockId` 分支继续在 `lib.rs` 壳层里取 hovered block index,但由 `dom_selection::current_block_info_from_index()` 返回 `block_id`;其余 selection event / runtime state 路径不变。 - - 已验证:待本批 fresh 验证后补充。 + - 已验证:`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、`cargo build --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml --target wasm32-unknown-unknown --release`、`wasm-bindgen --target web --out-dir rust/spikes/leptos-tiptap-spike/generated/island --out-name mnote-leptos-tiptap-spike-island rust/spikes/leptos-tiptap-spike/target/wasm32-unknown-unknown/release/mnote_leptos_tiptap_spike.wasm`、临时当前源码服务 `MNOTE_WEB_BIND=127.0.0.1:3025 MNOTE_WEB_PUBLIC_BIND=127.0.0.1:3025 cargo run --manifest-path rust/Cargo.toml -p mnote-web`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3025 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task489-block-menu-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3025 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task488-local-attachment-link-delete-undo-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3025 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。 + - 结果:`task489`、`task488`、`task479` 均通过,说明当前块信息 helper 下沉未破坏块菜单删除/撤销、附件删除/撤销和本地 Markdown 附件生命周期基线。 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 03a63aa7..ae75eee1 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 @@ -19,6 +19,12 @@ pub(crate) struct SelectionPayload { pub(crate) current_block_id: Option, } +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) struct CurrentBlockInfo { + pub(crate) index: Option, + pub(crate) block_id: Option, +} + pub(crate) fn node_is_within_root(node: Node, root: &Element) -> bool { let mut current = Some(node); while let Some(node) = current { @@ -187,3 +193,15 @@ pub(crate) fn selection_payload( current_block_id: current_block_index.and_then(runtime_block_id_from_index), } } + +pub(crate) fn current_block_info_from_index(index: Option) -> CurrentBlockInfo { + index + .map(|value| CurrentBlockInfo { + index: Some(value), + block_id: runtime_block_id_from_index(value), + }) + .unwrap_or(CurrentBlockInfo { + index: None, + block_id: None, + }) +}