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 bb6e8958..3f497372 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 @@ -256,3 +256,9 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据 - Worker D run `reasonix-2026-05-24T23-05-57-257Z-c917f1ef` 有完整 `process-handoff.md/json`、`result.json`、`final.md`,源码零 diff;`task489`、`task488`、`task487`、`task451` 在 3001 均通过。 - Codex 已读取 Hindsight recall 与 handoff/result,并独立复跑主控验收。 - 已验证:`cargo fmt --manifest-path rust/Cargo.toml --all --check`、`git diff --check`、`cargo check --manifest-path rust/spikes/leptos-tiptap-spike/Cargo.toml`、wasm release build、`wasm-bindgen`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 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:3001 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:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task487-local-folder-tree-live-consumer-smoke.js`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js`。 +- 2026-05-25:Batch AE 未派发 Reasonix worker;上一轮刚清理 worker 上限事实源漂移,主控先完成低风险机械切片。 + - CodeGraph / `rg` 结论:`target_element` 被图片 toolbar、block hover、DnD 和编辑区 click 过滤共用;`event_target_matches_selector` 是 toolbar mousedown 的中性 selector hit-test。两者适合迁入中性 DOM event runtime 模块,不属于 `block_dnd` 专属逻辑。 + - Codex 主控新增 `editor_runtime/dom_events.rs`,迁入 `target_element(target)` 与 `event_target_matches_selector(target, selector)`;`lib.rs` 通过 import 继续调用,不改事件 listener、图片 toolbar、block hover、DnD 或 overlay 编排。 + - 修改:`rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_events.rs`、`rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs`、`rust/spikes/leptos-tiptap-spike/src/lib.rs`。 + - 异常记录:本批验证后发现一个未由主控派发的 Reasonix runner / ACP 正在 `/mnt/Data1T/mnote-worktrees/0525-ae-worker-a-5-29-handle-corridor-rects` 运行;主控已终止进程,不读取、不采纳其输出。 + - 已验证:`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`、`MNOTE_WEB_SMOKE_BASE_URL=http://127.0.0.1:3001 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:3001 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:3001 NODE_PATH=/mnt/Data1T/mnote/node_modules node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`。 diff --git a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.js b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.js index a0083847..daf461d3 100644 --- a/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.js +++ b/rust/spikes/leptos-tiptap-spike/generated/island/mnote-leptos-tiptap-spike-island.js @@ -1284,7 +1284,7 @@ function __wbg_get_imports() { return ret; }, __wbindgen_cast_0000000000000006: function(arg0, arg1) { - // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("KeyboardEvent")], shim_idx: 892, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("KeyboardEvent")], shim_idx: 849, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__hd90af689bc3e71bf); return ret; }, 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 cc7c63b6..86ff8c33 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/dom_events.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_events.rs new file mode 100644 index 00000000..82e9b2f3 --- /dev/null +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/dom_events.rs @@ -0,0 +1,23 @@ +//! 编辑器 DOM event target 的窄 helper。 +//! +//! 本模块只做 EventTarget -> Element 归一化和 selector 命中判断, +//! 不处理编辑器状态、overlay 或命令分发。 + +use wasm_bindgen::JsCast; +use web_sys::{Element, EventTarget, Node}; + +pub(crate) fn target_element(target: EventTarget) -> Option { + target.clone().dyn_into::().ok().or_else(|| { + target + .dyn_into::() + .ok() + .and_then(|node| node.parent_element()) + }) +} + +pub(crate) fn event_target_matches_selector(target: Option, selector: &str) -> bool { + target + .and_then(target_element) + .and_then(|element| element.closest(selector).ok().flatten()) + .is_some() +} 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 0ff56a26..c8212ebb 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/mod.rs @@ -6,6 +6,7 @@ pub(crate) mod block_menu_document; pub(crate) mod block_menu_overlay; pub(crate) mod block_menu_legacy_html; pub(crate) mod command_sync; +pub(crate) mod dom_events; pub(crate) mod dom_selection; pub(crate) mod editor_focus; pub(crate) mod history_safe_commands; diff --git a/rust/spikes/leptos-tiptap-spike/src/lib.rs b/rust/spikes/leptos-tiptap-spike/src/lib.rs index b3ba4033..4c959bd3 100644 --- a/rust/spikes/leptos-tiptap-spike/src/lib.rs +++ b/rust/spikes/leptos-tiptap-spike/src/lib.rs @@ -39,6 +39,7 @@ use editor_runtime::block_hover_state::{ use editor_runtime::command_sync::{ read_editor_snapshot, sync_editor_outputs, sync_persisted_editor_command, }; +use editor_runtime::dom_events::{event_target_matches_selector, target_element}; use editor_runtime::dom_selection::{ runtime_block_id_from_index, selection_payload, selection_summary, SelectionPayload, }; @@ -4843,22 +4844,6 @@ fn block_label_for_element(block: &Element) -> String { } } -fn target_element(target: web_sys::EventTarget) -> Option { - target.clone().dyn_into::().ok().or_else(|| { - target - .dyn_into::() - .ok() - .and_then(|node| node.parent_element()) - }) -} - -fn event_target_matches_selector(target: Option, selector: &str) -> bool { - target - .and_then(target_element) - .and_then(|element| element.closest(selector).ok().flatten()) - .is_some() -} - fn current_target_html_element(event: &WheelEvent) -> Option { event.current_target()?.dyn_into::().ok() }