refactor: extract table overlay helpers
This commit is contained in:
@@ -267,4 +267,4 @@ UI / 浏览器可见项必须有真实浏览器截图或结构化 smoke 证据
|
|||||||
- 2026-05-25:Batch AF 未派发 Reasonix worker;基于 Batch AE Worker B 只读审计和 CodeGraph/`rg` 本地复核,主控完成 table overlay 小切片。
|
- 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 继续调用。
|
- 修改:`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 计算。
|
- 边界:未迁 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`。
|
||||||
|
|||||||
+1
-1
@@ -1284,7 +1284,7 @@ function __wbg_get_imports() {
|
|||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
__wbindgen_cast_0000000000000006: function(arg0, arg1) {
|
__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);
|
const ret = makeMutClosure(arg0, arg1, wasm_bindgen__convert__closures_____invoke__hd90af689bc3e71bf);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
|
|||||||
BIN
Binary file not shown.
@@ -6,6 +6,7 @@ use crate::{
|
|||||||
editor_runtime::editor_focus::active_editor_stage,
|
editor_runtime::editor_focus::active_editor_stage,
|
||||||
editor_stage_element,
|
editor_stage_element,
|
||||||
};
|
};
|
||||||
|
use web_sys::{window, Element};
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub(crate) struct FloatingToolbarAnchor {
|
pub(crate) struct FloatingToolbarAnchor {
|
||||||
@@ -51,6 +52,63 @@ pub(crate) struct TableSelectionOverlayState {
|
|||||||
pub(crate) index: usize,
|
pub(crate) index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn table_overlay_anchor_from_table(table: &Element) -> Option<TableOverlayAnchor> {
|
||||||
|
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<TableOverlayAnchor> {
|
||||||
|
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<FloatingToolbarAnchor> {
|
pub(crate) fn floating_toolbar_anchor_from_selection() -> Option<FloatingToolbarAnchor> {
|
||||||
let selection = active_editor_text_selection()?;
|
let selection = active_editor_text_selection()?;
|
||||||
let range = selection.get_range_at(0).ok()?;
|
let range = selection.get_range_at(0).ok()?;
|
||||||
|
|||||||
@@ -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::editor_focus::{active_editor_stage, body_has_focus, schedule_editor_focus};
|
||||||
use editor_runtime::overlays::{
|
use editor_runtime::overlays::{
|
||||||
close_editor_floating_overlays_if_escape, open_block_menu_overlay, open_image_toolbar_overlay,
|
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,
|
open_slash_menu_overlay, current_table_overlay_anchor, sync_overlays_on_selection_change,
|
||||||
try_sync_editor_overlay_state, FloatingToolbarAnchor, ImageToolbarAnchor, TableOverlayAnchor,
|
table_col_aux_style, table_overlay_anchor_from_table, table_row_aux_style,
|
||||||
TableSelectionKind, TableSelectionOverlayState,
|
toolbar_overlay_locked, try_sync_editor_overlay_state, FloatingToolbarAnchor,
|
||||||
|
ImageToolbarAnchor, TableOverlayAnchor, TableSelectionKind, TableSelectionOverlayState,
|
||||||
};
|
};
|
||||||
use editor_runtime::persistence::{
|
use editor_runtime::persistence::{
|
||||||
load_persisted_document, normalize_identity_value, persist_document_state,
|
load_persisted_document, normalize_identity_value, persist_document_state,
|
||||||
@@ -4902,63 +4903,6 @@ fn block_state_from_index(index: usize) -> Option<HoveredBlockState> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn table_overlay_anchor_from_table(table: &Element) -> Option<TableOverlayAnchor> {
|
|
||||||
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<TableOverlayAnchor> {
|
|
||||||
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(
|
fn table_selection_overlay_style(
|
||||||
anchor: &TableOverlayAnchor,
|
anchor: &TableOverlayAnchor,
|
||||||
selection: &TableSelectionOverlayState,
|
selection: &TableSelectionOverlayState,
|
||||||
|
|||||||
Reference in New Issue
Block a user