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 f39f87ec..a79a1581 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 @@ -267,4 +267,4 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据 - 2026-05-25:Batch AF 未派发 Reasonix worker;基于 Batch AE Worker B 只读审计和 CodeGraph/`rg` 本地复核,主控完成 table overlay 小切片。 - 修改:`editor_runtime/overlays.rs` 新增 `table_overlay_anchor_from_table`、`current_table_overlay_anchor`、`table_row_aux_style`、`table_col_aux_style`;`lib.rs` 删除同名实现并通过 import 继续调用。 - 边界:未迁 table selection signal、row/column click handler、overlay DOM view 或 `table_selection_overlay_style`;本批只外置表格 overlay anchor / aux style 的纯 DOM rect 与 CSS 计算。 - - 验证待补:`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`、`task489`、`task488`、`task479`。 + - 已验证:`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 daf461d3..2ea52871 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: 849, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`. + // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [NamedExternref("KeyboardEvent")], shim_idx: 294, 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 86ff8c33..33976162 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/overlays.rs b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/overlays.rs index a2cbafb3..d1c4cf74 100644 --- a/rust/spikes/leptos-tiptap-spike/src/editor_runtime/overlays.rs +++ b/rust/spikes/leptos-tiptap-spike/src/editor_runtime/overlays.rs @@ -6,6 +6,7 @@ use crate::{ editor_runtime::editor_focus::active_editor_stage, editor_stage_element, }; +use web_sys::{window, Element}; #[derive(Clone, Debug, PartialEq)] pub(crate) struct FloatingToolbarAnchor { @@ -51,6 +52,63 @@ pub(crate) struct TableSelectionOverlayState { pub(crate) index: usize, } +pub(crate) fn table_overlay_anchor_from_table(table: &Element) -> Option { + let stage = editor_stage_element()?; + let table_rect = table.get_bounding_client_rect(); + let stage_rect = stage.get_bounding_client_rect(); + if table_rect.width() <= 0.0 || table_rect.height() <= 0.0 { + return None; + } + + let rows = table.get_elements_by_tag_name("tr").length() as usize; + let cols = table + .query_selector("tr") + .ok() + .flatten() + .map(|row| row.children().length() as usize) + .unwrap_or(0); + if rows == 0 || cols == 0 { + return None; + } + + Some(TableOverlayAnchor { + top: table_rect.top() - stage_rect.top(), + left: table_rect.left() - stage_rect.left(), + width: table_rect.width(), + height: table_rect.height(), + rows, + cols, + }) +} + +pub(crate) fn current_table_overlay_anchor() -> Option { + let table = window() + .and_then(|win| win.document()) + .and_then(|document| { + document + .query_selector(".editor-surface .ProseMirror table") + .ok() + .flatten() + })?; + table_overlay_anchor_from_table(&table) +} + +pub(crate) fn table_row_aux_style(anchor: &TableOverlayAnchor, index: usize) -> String { + let row_height = anchor.height / anchor.rows.max(1) as f64; + format!( + "left:-24px;top:{:.1}px;", + (row_height * index as f64) + (row_height / 2.0) - 9.0 + ) +} + +pub(crate) fn table_col_aux_style(anchor: &TableOverlayAnchor, index: usize) -> String { + let col_width = anchor.width / anchor.cols.max(1) as f64; + format!( + "left:{:.1}px;top:-24px;", + (col_width * index as f64) + (col_width / 2.0) - 9.0 + ) +} + pub(crate) fn floating_toolbar_anchor_from_selection() -> Option { let selection = active_editor_text_selection()?; let range = selection.get_range_at(0).ok()?; diff --git a/rust/spikes/leptos-tiptap-spike/src/lib.rs b/rust/spikes/leptos-tiptap-spike/src/lib.rs index 4c959bd3..283872b6 100644 --- a/rust/spikes/leptos-tiptap-spike/src/lib.rs +++ b/rust/spikes/leptos-tiptap-spike/src/lib.rs @@ -46,9 +46,10 @@ use editor_runtime::dom_selection::{ use editor_runtime::editor_focus::{active_editor_stage, body_has_focus, schedule_editor_focus}; use editor_runtime::overlays::{ close_editor_floating_overlays_if_escape, open_block_menu_overlay, open_image_toolbar_overlay, - open_slash_menu_overlay, sync_overlays_on_selection_change, toolbar_overlay_locked, - try_sync_editor_overlay_state, FloatingToolbarAnchor, ImageToolbarAnchor, TableOverlayAnchor, - TableSelectionKind, TableSelectionOverlayState, + open_slash_menu_overlay, current_table_overlay_anchor, sync_overlays_on_selection_change, + table_col_aux_style, table_overlay_anchor_from_table, table_row_aux_style, + toolbar_overlay_locked, try_sync_editor_overlay_state, FloatingToolbarAnchor, + ImageToolbarAnchor, TableOverlayAnchor, TableSelectionKind, TableSelectionOverlayState, }; use editor_runtime::persistence::{ load_persisted_document, normalize_identity_value, persist_document_state, @@ -4902,63 +4903,6 @@ fn block_state_from_index(index: usize) -> Option { }) } -fn table_overlay_anchor_from_table(table: &Element) -> Option { - let stage = editor_stage_element()?; - let table_rect = table.get_bounding_client_rect(); - let stage_rect = stage.get_bounding_client_rect(); - if table_rect.width() <= 0.0 || table_rect.height() <= 0.0 { - return None; - } - - let rows = table.get_elements_by_tag_name("tr").length() as usize; - let cols = table - .query_selector("tr") - .ok() - .flatten() - .map(|row| row.children().length() as usize) - .unwrap_or(0); - if rows == 0 || cols == 0 { - return None; - } - - Some(TableOverlayAnchor { - top: table_rect.top() - stage_rect.top(), - left: table_rect.left() - stage_rect.left(), - width: table_rect.width(), - height: table_rect.height(), - rows, - cols, - }) -} - -fn current_table_overlay_anchor() -> Option { - let table = window() - .and_then(|win| win.document()) - .and_then(|document| { - document - .query_selector(".editor-surface .ProseMirror table") - .ok() - .flatten() - })?; - table_overlay_anchor_from_table(&table) -} - -fn table_row_aux_style(anchor: &TableOverlayAnchor, index: usize) -> String { - let row_height = anchor.height / anchor.rows.max(1) as f64; - format!( - "left:-24px;top:{:.1}px;", - (row_height * index as f64) + (row_height / 2.0) - 9.0 - ) -} - -fn table_col_aux_style(anchor: &TableOverlayAnchor, index: usize) -> String { - let col_width = anchor.width / anchor.cols.max(1) as f64; - format!( - "left:{:.1}px;top:-24px;", - (col_width * index as f64) + (col_width / 2.0) - 9.0 - ) -} - fn table_selection_overlay_style( anchor: &TableOverlayAnchor, selection: &TableSelectionOverlayState,