refactor: move selection payload helpers
This commit is contained in:
@@ -1,8 +1,21 @@
|
||||
use leptos_tiptap::TiptapSelectionState;
|
||||
use serde::Serialize;
|
||||
use serde_json::Value;
|
||||
use wasm_bindgen::{JsCast, JsValue};
|
||||
use web_sys::{window, Element, Node};
|
||||
|
||||
use crate::editor_root_element;
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub(crate) struct SelectionPayload {
|
||||
pub(crate) selection: TiptapSelectionState,
|
||||
pub(crate) summary: String,
|
||||
pub(crate) editor_focused: bool,
|
||||
pub(crate) current_block_index: Option<usize>,
|
||||
pub(crate) current_block_id: Option<String>,
|
||||
}
|
||||
|
||||
pub(crate) fn node_is_within_root(node: Node, root: &Element) -> bool {
|
||||
let mut current = Some(node);
|
||||
while let Some(node) = current {
|
||||
@@ -103,3 +116,59 @@ pub(crate) fn selection_has_rich_marks(selection: &TiptapSelectionState) -> bool
|
||||
|| selection.text_style
|
||||
|| selection.link
|
||||
}
|
||||
|
||||
pub(crate) fn block_id_from_element(block: &Element) -> Option<String> {
|
||||
block
|
||||
.get_attribute("data-block-id")
|
||||
.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
}
|
||||
|
||||
pub(crate) fn block_id_from_json_node(node: &Value) -> Option<String> {
|
||||
node.get("attrs")
|
||||
.and_then(|attrs| attrs.get("blockId"))
|
||||
.and_then(Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.map(str::to_string)
|
||||
}
|
||||
|
||||
pub(crate) fn runtime_block_id_from_index(index: usize) -> Option<String> {
|
||||
editor_root_element()
|
||||
.and_then(|root| root.children().item(index as u32))
|
||||
.and_then(|block| block_id_from_element(&block))
|
||||
.or_else(|| {
|
||||
editor_root_element()
|
||||
.and_then(|root| {
|
||||
js_sys::Reflect::get(root.as_ref(), &JsValue::from_str("editor")).ok()
|
||||
})
|
||||
.and_then(|editor_value| {
|
||||
js_sys::Reflect::get(&editor_value, &JsValue::from_str("getJSON"))
|
||||
.ok()
|
||||
.and_then(|callback| callback.dyn_into::<js_sys::Function>().ok())
|
||||
.and_then(|callback| callback.call0(&editor_value).ok())
|
||||
})
|
||||
.and_then(|value| serde_wasm_bindgen::from_value::<Value>(value).ok())
|
||||
.and_then(|document| {
|
||||
document
|
||||
.get("content")
|
||||
.and_then(Value::as_array)
|
||||
.and_then(|content| content.get(index))
|
||||
.and_then(block_id_from_json_node)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn selection_payload(
|
||||
selection: &TiptapSelectionState,
|
||||
editor_focused: bool,
|
||||
current_block_index: Option<usize>,
|
||||
) -> SelectionPayload {
|
||||
SelectionPayload {
|
||||
selection: selection.clone(),
|
||||
summary: selection_summary(selection),
|
||||
editor_focused,
|
||||
current_block_index,
|
||||
current_block_id: current_block_index.and_then(runtime_block_id_from_index),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user