feat: support pre-edit text display for IME (#35535)

* feat: support pre-edit text display for IME

Signed-off-by: DK Liao <dklassic@gmail.com>

* enable ime by show_ime

Signed-off-by: DK Liao <dklassic@gmail.com>

---------

Signed-off-by: DK Liao <dklassic@gmail.com>
This commit is contained in:
DK Liao 2025-02-19 20:22:57 +09:00 committed by GitHub
parent 42e873e9d9
commit 720bc725b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 91 additions and 4 deletions

View file

@ -2652,8 +2652,6 @@ impl VirtualMethods for HTMLInputElement {
event.type_() == atom!("compositionend")) &&
self.input_type().is_textual_or_password()
{
// TODO: Update DOM on start and continue
// and generally do proper CompositionEvent handling.
if let Some(compositionevent) = event.downcast::<CompositionEvent>() {
if event.type_() == atom!("compositionend") {
let _ = self
@ -2661,6 +2659,12 @@ impl VirtualMethods for HTMLInputElement {
.borrow_mut()
.handle_compositionend(compositionevent);
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
} else if event.type_() == atom!("compositionupdate") {
let _ = self
.textinput
.borrow_mut()
.handle_compositionupdate(compositionevent);
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
}
event.mark_as_handled();
}

View file

@ -668,8 +668,6 @@ impl VirtualMethods for HTMLTextAreaElement {
event.type_() == atom!("compositionupdate") ||
event.type_() == atom!("compositionend")
{
// TODO: Update DOM on start and continue
// and generally do proper CompositionEvent handling.
if let Some(compositionevent) = event.downcast::<CompositionEvent>() {
if event.type_() == atom!("compositionend") {
let _ = self
@ -677,6 +675,12 @@ impl VirtualMethods for HTMLTextAreaElement {
.borrow_mut()
.handle_compositionend(compositionevent);
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
} else if event.type_() == atom!("compositionupdate") {
let _ = self
.textinput
.borrow_mut()
.handle_compositionupdate(compositionevent);
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
}
event.mark_as_handled();
}

View file

@ -988,6 +988,17 @@ impl<T: ClipboardProvider> TextInput<T> {
KeyReaction::DispatchInput
}
pub(crate) fn handle_compositionupdate(&mut self, event: &CompositionEvent) -> KeyReaction {
let start = self.selection_start_offset().0;
self.insert_string(event.data());
self.set_selection_range(
start as u32,
(start + event.data().len_utf8().0) as u32,
SelectionDirection::Forward,
);
KeyReaction::DispatchInput
}
/// Whether the content is empty.
pub(crate) fn is_empty(&self) -> bool {
self.lines.len() <= 1 && self.lines.first().map_or(true, |line| line.is_empty())