atproto blogging
1//! Browser DOM layer for the weaver markdown editor.
2//!
3//! This crate provides DOM manipulation and browser event handling,
4//! generic over any `EditorDocument` implementation. It assumes a
5//! `wasm32-unknown-unknown` target environment.
6//!
7//! # Architecture
8//!
9//! - `cursor`: Selection API handling and cursor restoration
10//! - `dom_sync`: DOM ↔ document state synchronization
11//! - `events`: beforeinput event handling and clipboard helpers
12//! - `platform`: Browser/OS detection for platform-specific behavior
13//!
14//! # DOM Update Strategy
15//!
16//! The [`FORCE_INNERHTML_UPDATE`] constant controls how DOM updates are handled:
17//!
18//! - `true`: Editor always owns DOM updates. `handle_beforeinput` returns `Handled`,
19//! and `update_paragraph_dom` always replaces innerHTML. This is more predictable
20//! but can interfere with IME and cause flickering.
21//!
22//! - `false`: For simple edits (plain text insertion, single char deletion),
23//! `handle_beforeinput` can return `PassThrough` to let the browser update the DOM
24//! directly while we just track changes in the model. `update_paragraph_dom` will
25//! skip innerHTML replacement for the cursor paragraph if syntax is unchanged.
26//! This is smoother but requires careful coordination.
27//!
28//! # Re-exports
29//!
30//! This crate re-exports `weaver-editor-core` for convenience, so consumers
31//! only need to depend on `weaver-editor-browser`.
32
33// Re-export core crate
34pub use weaver_editor_core;
35pub use weaver_editor_core::*;
36
37/// Controls DOM update strategy.
38///
39/// When `true`, the editor always owns DOM updates:
40/// - `handle_beforeinput` returns `Handled` (preventDefault)
41/// - `update_paragraph_dom` always replaces innerHTML
42///
43/// When `false`, simple edits can be handled by the browser:
44/// - `handle_beforeinput` returns `PassThrough` for plain text inserts/deletes
45/// - `update_paragraph_dom` skips innerHTML for cursor paragraph if syntax unchanged
46///
47/// Set to `true` for maximum control, `false` for smoother typing experience.
48pub const FORCE_INNERHTML_UPDATE: bool = true;
49
50pub mod clipboard;
51pub mod color;
52pub mod cursor;
53pub mod dom_sync;
54pub mod events;
55pub mod platform;
56pub mod visibility;
57
58// Browser cursor implementation
59pub use cursor::{
60 BrowserCursor, find_text_node_at_offset, get_cursor_rect, get_cursor_rect_relative,
61 get_selection_rects_relative, restore_cursor_position,
62};
63
64// DOM sync types
65pub use dom_sync::{
66 BrowserCursorSync, CursorSyncResult, dom_position_to_text_offset, sync_cursor_and_visibility,
67 sync_cursor_from_dom, sync_cursor_from_dom_impl, update_paragraph_dom,
68};
69
70// Event handling
71pub use events::{
72 BeforeInputContext, BeforeInputResult, StaticRange, get_current_range, get_data_from_event,
73 get_input_type_from_event, get_math_click_offset, get_target_range_from_event,
74 handle_beforeinput, handle_math_click, is_composing, parse_browser_input_type,
75 read_clipboard_text, write_clipboard_with_custom_type,
76};
77
78// Platform detection
79pub use platform::{Platform, platform};
80
81// Visibility updates
82pub use visibility::update_syntax_visibility;
83
84// Color utilities
85pub use color::{rgba_u32_to_css, rgba_u32_to_css_alpha};
86
87// Clipboard
88pub use clipboard::{BrowserClipboard, write_html_to_clipboard};
89#[cfg(feature = "dioxus")]
90pub use clipboard::{handle_copy, handle_cut, handle_paste};
91
92// Composition (IME) handlers
93#[cfg(feature = "dioxus")]
94pub use events::{handle_compositionend, handle_compositionstart, handle_compositionupdate};