pub struct TextEditManager {
pub multi_cursor: Option<MultiCursorState>,
pub blink: BlinkState,
pub preedit_text: Option<String>,
pub preedit_cursor_begin: i32,
pub preedit_cursor_end: i32,
pub display_list_dirty: bool,
}Expand description
Unified text editing manager.
multi_cursor is the single source of truth for cursor/selection positions.
blink manages the caret blink animation.
SelectionManager (sibling module) handles non-editable text drag-select.
Fields§
§multi_cursor: Option<MultiCursorState>Multi-cursor state for contenteditable elements (Sublime Text style).
Some whenever a contenteditable element has focus.
Source of truth for edit_text() and display list painting.
blink: BlinkStateCursor blink animation state.
preedit_text: Option<String>IME preedit (composition) text currently being composed. Applies to the primary cursor only.
preedit_cursor_begin: i32Byte offset of cursor within preedit text (from IME), or -1 if unset.
Uses -1 sentinel (rather than Option) to match platform IME C API conventions.
preedit_cursor_end: i32Byte offset of cursor end within preedit text (from IME), or -1 if unset.
Uses -1 sentinel (rather than Option) to match platform IME C API conventions.
display_list_dirty: boolSet to true by any mutation that changes visual output.
Implementations§
Source§impl TextEditManager
impl TextEditManager
Sourcepub const fn mark_dirty(&mut self)
pub const fn mark_dirty(&mut self)
Mark that the display list needs regeneration.
Sourcepub const fn has_active_editing(&self) -> bool
pub const fn has_active_editing(&self) -> bool
Whether a contenteditable element is currently being edited.
Sourcepub fn get_editing_dom_id(&self) -> Option<DomId>
pub fn get_editing_dom_id(&self) -> Option<DomId>
Get the DomId of the node being edited.
Sourcepub fn get_editing_node_id(&self) -> Option<NodeId>
pub fn get_editing_node_id(&self) -> Option<NodeId>
Get the NodeId of the node being edited.
Sourcepub fn get_primary_cursor(&self) -> Option<TextCursor>
pub fn get_primary_cursor(&self) -> Option<TextCursor>
Get the primary cursor position (last-added cursor).
Sourcepub const fn should_draw_cursor(&self) -> bool
pub const fn should_draw_cursor(&self) -> bool
Whether the cursor should be drawn (editing active AND blink visible).
Sourcepub fn initialize_editing(
&mut self,
cursor: TextCursor,
dom_id: DomId,
node_id: NodeId,
contenteditable_key: u64,
)
pub fn initialize_editing( &mut self, cursor: TextCursor, dom_id: DomId, node_id: NodeId, contenteditable_key: u64, )
Initialize editing for a newly focused contenteditable element.
Creates a MultiCursorState with a single cursor, starts the blink,
and sets preedit to None.
§The caret is SOLID for the first half-period, not just “visible”
This used to set is_visible = true and, in the same breath,
last_input_time = None. Those two statements contradict each other:
None is the “no input has EVER been recorded” encoding, for which
BlinkState::should_blink is true immediately — so the blink timer’s
FIRST tick (a Timer with an interval and no delay runs on the first
pump) toggled the freshly-shown caret straight back OFF. Clicking or
tabbing into a field made the caret disappear on the next frame and only
reappear a blink-interval later, which reads as a glitch and matches no
other toolkit.
It also made every caller responsible for repairing the state this
method had just broken. Two of the three did:
LayoutWindow::handle_focus_change_for_cursor_blink calls
reset_blink_on_input BEFORE the deferred finalize_pending_focus_changes
gets here (so its timestamp was overwritten with None), and
process_mouse_click_for_selection calls it immediately AFTER (so its
caret survived). The third, process_accessibility_action, did not — an
AT-driven focus got the broken phase.
reset_blink_on_input(now) sets BOTH halves consistently: caret shown
AND the blink phase anchored at this instant, so should_blink stays
false for CURSOR_BLINK_INTERVAL_MS and the first toggle happens one
half-period after focus. That is the behaviour every other toolkit ships,
and it makes the callers’ own reset_blink_on_input calls redundant
rather than load-bearing.
Instant::now() honours the thread-scoped E2E test clock, so this stays
deterministic under tick_ms.
Sourcepub fn clear_editing(&mut self)
pub fn clear_editing(&mut self)
End editing (focus left the contenteditable element).
Sourcepub fn set_preedit(&mut self, text: String, cursor_begin: i32, cursor_end: i32)
pub fn set_preedit(&mut self, text: String, cursor_begin: i32, cursor_end: i32)
Set the IME preedit (composition) text.
Sourcepub fn clear_preedit(&mut self)
pub fn clear_preedit(&mut self)
Clear the IME preedit text (composition ended or cancelled).
Sourcepub fn build_cursor_locations(&self) -> Vec<(DomId, NodeId, TextCursor)>
pub fn build_cursor_locations(&self) -> Vec<(DomId, NodeId, TextCursor)>
Build the Vec of cursor locations for LayoutContext.
Returns all cursor positions from MultiCursorState, or empty if not editing.
Sourcepub fn build_text_selections_map(&self) -> BTreeMap<DomId, TextSelection>
pub fn build_text_selections_map(&self) -> BTreeMap<DomId, TextSelection>
Build a TextSelection map for the display list’s paint_selections.
Extracts Range selections from MultiCursorState into the format that
LayoutContext.text_selections expects: BTreeMap<DomId, TextSelection>.
The affected_nodes map uses the editing node’s NodeId as key.
NOTE: only one range per node is supported — if multiple cursors have
range selections on the same node, later ranges overwrite earlier ones.
Trait Implementations§
Source§impl Clone for TextEditManager
impl Clone for TextEditManager
Source§fn clone(&self) -> TextEditManager
fn clone(&self) -> TextEditManager
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for TextEditManager
impl Debug for TextEditManager
Source§impl Default for TextEditManager
impl Default for TextEditManager
Source§impl NodeIdRemap for TextEditManager
impl NodeIdRemap for TextEditManager
Source§fn remap_node_ids(&mut self, dom: DomId, map: &NodeIdMap)
fn remap_node_ids(&mut self, dom: DomId, map: &NodeIdMap)
Remap the multi-cursor / selection state onto the rebuilt DOM.
MultiCursorState::remap_node_ids clears the selections when the edited
node is gone; here we additionally drop the whole editing session, since a
cursor whose IFC root no longer exists is not an editing session.
Source§impl PartialEq for TextEditManager
Only compares multi_cursor — blink state, preedit, and dirty flag are
transient visual state that should not affect logical equality of the
editing session.
impl PartialEq for TextEditManager
Only compares multi_cursor — blink state, preedit, and dirty flag are
transient visual state that should not affect logical equality of the
editing session.
Auto Trait Implementations§
impl Freeze for TextEditManager
impl RefUnwindSafe for TextEditManager
impl Send for TextEditManager
impl Sync for TextEditManager
impl Unpin for TextEditManager
impl UnsafeUnpin for TextEditManager
impl UnwindSafe for TextEditManager
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more