refactor: extract editor focus helpers
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
use leptos_tiptap::TiptapEditorHandle;
|
||||
use wasm_bindgen::{closure::Closure, JsCast};
|
||||
use web_sys::window;
|
||||
|
||||
use crate::{
|
||||
editor_root_element, editor_runtime::dom_selection::node_is_within_root, EDITOR_STAGE_SELECTOR,
|
||||
};
|
||||
|
||||
pub(crate) fn schedule_editor_focus(editor: TiptapEditorHandle) {
|
||||
let Some(win) = window() else {
|
||||
return;
|
||||
};
|
||||
let callback = Closure::<dyn FnMut()>::new(move || {
|
||||
let _ = editor.focus();
|
||||
});
|
||||
let _ = win.set_timeout_with_callback_and_timeout_and_arguments_0(
|
||||
callback.as_ref().unchecked_ref(),
|
||||
0,
|
||||
);
|
||||
callback.forget();
|
||||
}
|
||||
|
||||
pub(crate) fn active_editor_stage() -> bool {
|
||||
let active_element_inside_stage = window()
|
||||
.and_then(|win| win.document())
|
||||
.and_then(|document| document.active_element())
|
||||
.and_then(|element| element.closest(EDITOR_STAGE_SELECTOR).ok().flatten())
|
||||
.is_some();
|
||||
|
||||
if active_element_inside_stage {
|
||||
return true;
|
||||
}
|
||||
|
||||
let Some(root) = editor_root_element() else {
|
||||
return false;
|
||||
};
|
||||
let Some(selection) = window().and_then(|win| win.get_selection().ok().flatten()) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let anchor_inside = selection
|
||||
.anchor_node()
|
||||
.map(|node| node_is_within_root(node, &root))
|
||||
.unwrap_or(false);
|
||||
let focus_inside = selection
|
||||
.focus_node()
|
||||
.map(|node| node_is_within_root(node, &root))
|
||||
.unwrap_or(false);
|
||||
|
||||
anchor_inside || focus_inside
|
||||
}
|
||||
@@ -4,6 +4,7 @@ pub(crate) mod block_menu_document;
|
||||
pub(crate) mod block_menu_legacy_html;
|
||||
pub(crate) mod command_sync;
|
||||
pub(crate) mod dom_selection;
|
||||
pub(crate) mod editor_focus;
|
||||
pub(crate) mod history_safe_commands;
|
||||
pub(crate) mod overlays;
|
||||
pub(crate) mod persistence;
|
||||
|
||||
@@ -28,8 +28,9 @@ use editor_runtime::command_sync::{
|
||||
read_editor_snapshot, sync_editor_outputs, sync_persisted_editor_command,
|
||||
};
|
||||
use editor_runtime::dom_selection::{
|
||||
has_active_text_selection, node_is_within_root, selection_summary,
|
||||
has_active_text_selection, selection_summary,
|
||||
};
|
||||
use editor_runtime::editor_focus::{active_editor_stage, schedule_editor_focus};
|
||||
use editor_runtime::overlays::{
|
||||
floating_toolbar_anchor_from_selection, sync_text_selection_overlay, FloatingToolbarAnchor,
|
||||
};
|
||||
@@ -3655,20 +3656,6 @@ fn schedule_scroll_mnote_block_anchor_from_hash_retry(remaining: u8) {
|
||||
callback.forget();
|
||||
}
|
||||
|
||||
fn schedule_editor_focus(editor: TiptapEditorHandle) {
|
||||
let Some(win) = window() else {
|
||||
return;
|
||||
};
|
||||
let callback = Closure::<dyn FnMut()>::new(move || {
|
||||
let _ = editor.focus();
|
||||
});
|
||||
let _ = win.set_timeout_with_callback_and_timeout_and_arguments_0(
|
||||
callback.as_ref().unchecked_ref(),
|
||||
0,
|
||||
);
|
||||
callback.forget();
|
||||
}
|
||||
|
||||
fn current_viewport_scroll() -> Option<(f64, f64)> {
|
||||
let win = window()?;
|
||||
let x = win.scroll_x().ok()?;
|
||||
@@ -6310,36 +6297,6 @@ fn p0_extensions() -> Vec<TiptapExtension> {
|
||||
]
|
||||
}
|
||||
|
||||
fn active_editor_stage() -> bool {
|
||||
let active_element_inside_stage = window()
|
||||
.and_then(|win| win.document())
|
||||
.and_then(|document| document.active_element())
|
||||
.and_then(|element| element.closest(EDITOR_STAGE_SELECTOR).ok().flatten())
|
||||
.is_some();
|
||||
|
||||
if active_element_inside_stage {
|
||||
return true;
|
||||
}
|
||||
|
||||
let Some(root) = editor_root_element() else {
|
||||
return false;
|
||||
};
|
||||
let Some(selection) = window().and_then(|win| win.get_selection().ok().flatten()) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let anchor_inside = selection
|
||||
.anchor_node()
|
||||
.map(|node| node_is_within_root(node, &root))
|
||||
.unwrap_or(false);
|
||||
let focus_inside = selection
|
||||
.focus_node()
|
||||
.map(|node| node_is_within_root(node, &root))
|
||||
.unwrap_or(false);
|
||||
|
||||
anchor_inside || focus_inside
|
||||
}
|
||||
|
||||
fn current_block_info_from_index(index: Option<usize>) -> CurrentBlockInfo {
|
||||
index
|
||||
.map(|value| CurrentBlockInfo {
|
||||
|
||||
Reference in New Issue
Block a user