refactor: extract attachment link history commands

This commit is contained in:
lix-2026
2026-05-24 22:18:44 +08:00
parent db7c3cb319
commit 418f8ff8b0
7 changed files with 162 additions and 83 deletions
+7 -70
View File
@@ -54,6 +54,9 @@ const STANDALONE_ROOT_ID: &str = "mnote-leptos-tiptap-standalone-root";
const E24_IMAGE_PLACEHOLDER_SRC: &str = "/api/editor/image-placeholder.svg";
const E24_IMAGE_PLACEHOLDER_ALT: &str = "E24 图片占位";
const E24_IMAGE_PLACEHOLDER_TITLE: &str = "E24 图片";
mod editor_runtime;
#[wasm_bindgen(inline_js = r#"
export function write_mnote_text_to_clipboard(text) {
try {
@@ -5262,73 +5265,6 @@ fn hovered_block_from_selection() -> Option<HoveredBlockState> {
block_state_from_index(index)
}
fn selected_local_attachment_link_text() -> bool {
let selection = match window().and_then(|win| win.get_selection().ok().flatten()) {
Some(selection) if !selection.is_collapsed() => selection,
_ => return false,
};
let selected_text = String::from(selection.to_string()).trim().to_string();
if selected_text.is_empty() {
return false;
}
let Some(root) = editor_root_element() else {
return false;
};
let links = root.get_elements_by_tag_name("a");
for index in 0..links.length() {
let Some(link) = links.item(index) else {
continue;
};
let href = link.get_attribute("href").unwrap_or_default();
if !href.contains("/api/local-folder/files/open") {
continue;
}
if link.text_content().unwrap_or_default().trim() == selected_text {
return true;
}
}
false
}
fn selected_local_attachment_link_in_editor_state() -> bool {
let Some(root) = editor_root_element() else {
return false;
};
let Ok(editor_value) = js_sys::Reflect::get(root.as_ref(), &JsValue::from_str("editor"))
else {
return false;
};
let Ok(state_value) = js_sys::Reflect::get(&editor_value, &JsValue::from_str("state")) else {
return false;
};
let Ok(selection_value) = js_sys::Reflect::get(&state_value, &JsValue::from_str("selection"))
else {
return false;
};
let is_empty = js_sys::Reflect::get(&selection_value, &JsValue::from_str("empty"))
.ok()
.and_then(|value| value.as_bool())
.unwrap_or(true);
if is_empty {
return false;
}
let Some(get_attributes) = js_sys::Reflect::get(&editor_value, &JsValue::from_str("getAttributes"))
.ok()
.and_then(|value| value.dyn_into::<js_sys::Function>().ok())
else {
return false;
};
let Ok(attributes) = get_attributes.call1(&editor_value, &JsValue::from_str("link")) else {
return false;
};
js_sys::Reflect::get(&attributes, &JsValue::from_str("href"))
.ok()
.and_then(|value| value.as_string())
.is_some_and(|href| href.contains("/api/local-folder/files/open"))
}
fn block_state_from_index(index: usize) -> Option<HoveredBlockState> {
let root = editor_root_element()?;
let stage = editor_stage_element()?;
@@ -8821,15 +8757,16 @@ fn App(mount_options: MountOptions) -> impl IntoView {
|| event.meta_key()
|| event.alt_key()
|| !matches!(event.key().as_str(), "Backspace" | "Delete")
|| !(selected_local_attachment_link_in_editor_state()
|| selected_local_attachment_link_text())
|| !editor_runtime::attachment_links::is_local_attachment_link_selected()
{
return;
}
event.prevent_default();
event.stop_immediate_propagation();
match editor.delete_selection() {
match editor_runtime::history_safe_commands::delete_selected_attachment_link_with_history(
&editor,
) {
Ok(()) => {
sync_persisted_editor_command(
editor,