refactor: extract block state helper

This commit is contained in:
lix-2026
2026-05-25 08:12:51 +08:00
parent 10a93ac827
commit b37568bda8
5 changed files with 120 additions and 77 deletions
@@ -3,7 +3,12 @@
//! 本模块只承接拖拽命中所需的窄 helper,不处理 Leptos signal
//! 也不分发 editor command;调用方负责保留编辑器状态编排。
use crate::editor_runtime::block_hover_state::{DropIndicatorState, DropPlacement};
use crate::{
editor_runtime::block_hover_state::{
block_label_for_element, DropIndicatorState, DropPlacement, HoveredBlockState,
},
editor_root_element, editor_stage_element,
};
use web_sys::{window, Element, EventTarget};
pub(crate) struct HandleCorridorGeometry {
@@ -124,6 +129,78 @@ pub(crate) fn drop_indicator_from_block_rects(
)
}
pub(crate) fn block_state_from_index(index: usize) -> Option<HoveredBlockState> {
let root = editor_root_element()?;
let stage = editor_stage_element()?;
let block = root.children().item(index as u32)?;
let block_rect = block.get_bounding_client_rect();
let stage_rect = stage.get_bounding_client_rect();
let block_height = if block_rect.height() > 0.0 {
block_rect.height()
} else {
28.0
};
Some(HoveredBlockState {
index,
label: block_label_for_element(&block),
top: block_rect.top() - stage_rect.top(),
height: block_height,
})
}
pub(crate) fn pointer_in_handle_corridor(
client_x: i32,
client_y: i32,
block: &HoveredBlockState,
handle_selector: &str,
handle_left_fallback: f64,
handle_width: f64,
) -> bool {
let Some(stage) = editor_stage_element() else {
return false;
};
let Some(root) = editor_root_element() else {
return false;
};
let Some(block_element) = root.children().item(block.index as u32) else {
return false;
};
let stage_rect = stage.get_bounding_client_rect();
let block_rect = block_element.get_bounding_client_rect();
let handle_rect = window()
.and_then(|win| win.document())
.and_then(|document| document.query_selector(handle_selector).ok().flatten())
.map(|handle| handle.get_bounding_client_rect());
let block_left = block_rect.left() - stage_rect.left();
let block_top = block_rect.top() - stage_rect.top();
let block_bottom = block_rect.bottom() - stage_rect.top();
let handle_left = handle_rect
.as_ref()
.map(|rect| rect.left() - stage_rect.left())
.unwrap_or(handle_left_fallback);
let handle_right = handle_rect
.as_ref()
.map(|rect| rect.right() - stage_rect.left())
.unwrap_or_else(|| handle_left + handle_width);
pointer_in_handle_corridor_geometry(
client_x,
client_y,
&HandleCorridorGeometry {
stage_left: stage_rect.left(),
stage_top: stage_rect.top(),
block_left,
block_top,
block_bottom,
handle_left,
handle_right,
},
)
}
pub(crate) fn top_level_block_index(root: &Element, block: &Element) -> Option<usize> {
let children = root.children();
(0..children.length()).find_map(|index| {