value change should not trigger when typeing ( compositionstart -> compositionend )
Describe the problem
https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event
When using the input method, the user has not formally entered text and the value change event should not be triggered.
You can refer to the implementation in vue
https://github.com/vuejs/core/blob/main/packages/runtime-dom/src/directives/vModel.ts
now svelte is
Describe the proposed solution
When the user starts inputting Chinese characters using the Pinyin input method, the compositionstart event will be triggered. When the composition of a text paragraph is completed or canceled, the compositionend event will be fired.
That is to say, when we start inputting Chinese, a compositionstart event will be triggered. During the Chinese input process, the compositionstart event will not be triggered again. Finally, the compositionend event will be triggered when the Chinese input is completed.
And after experiments, it was found that when inputting Chinese, compositionstart is triggered before the input event.
Importance
nice to have
What exactly are you referring to?
My assumption would be that you want to have the behavior of bind:value changed for input and textarea?
I'm assuming this is for contenteditable rather than input and textarea as they should just work.
Having worked on Lexical, I can tell you that it's really difficult to get IME input correct. Listening to compositionstart and compositionend is simply not good enough. This doesn't take into account that content can be inserted via other methods during this time – such as copy+paste, screenreaders, or speech to text etc and thus you can't always reliably state the value. You also will need a DOM Mutation Observer to capture changes that sometimes happen but don't invoke events – such as when you're on some browsers in Android.
If you want to reliably capture text input yourself, it's recommended that you use a rich text library such as ProseMirror or Lexical instead of trying to do it yourself.
the user has not formally entered text
If you imply that the semi-composed text is meaningless, then the same can be said about the unfinished word or sentence/query. A composition-aware debouncer makes more sense to me here.
the value change event
A reminder: for the text fields, the change event is fired when the field loses focus (the user has finished editing the text), while the input event, which is used in bind:value, is fired immediately after any change. And Svelte has no analogue to Vue's v-model.lazy, which uses a change event.
I'm assuming this is for
contenteditablerather thaninputandtextareaas they should just work.
vModelText typing supposes it is used on input and textarea.
And contenteditable brings more problems than solves, but it's another topic.
What exactly are you referring to? My assumption would be that you want to have the behavior of
bind:valuechanged forinputandtextarea?
I'm writing a real-time search that will trigger the search when the user enters new content. If the user does not enter the complete content using the Chinese input method, then the value binding should not trigger the search. If using vue, the performance is as expected, but using svelte is not.
What exactly are you referring to? My assumption would be that you want to have the behavior of
bind:valuechanged forinputandtextarea?I'm writing a real-time search that will trigger the search when the user enters new content. If the user does not enter the complete content using the Chinese input method, then the value binding should not trigger the search. If using vue, the performance is as expected, but using svelte is not.
What element is the search?
What exactly are you referring to? My assumption would be that you want to have the behavior of
bind:valuechanged forinputandtextarea?I'm writing a real-time search that will trigger the search when the user enters new content. If the user does not enter the complete content using the Chinese input method, then the value binding should not trigger the search. If using vue, the performance is as expected, but using svelte is not.
What element is the search?
input
I'm assuming this is for
contenteditablerather thaninputandtextareaas they should just work.Having worked on Lexical, I can tell you that it's really difficult to get IME input correct. Listening to
compositionstartandcompositionendis simply not good enough. This doesn't take into account that content can be inserted via other methods during this time – such as copy+paste, screenreaders, or speech to text etc and thus you can't always reliably state the value. You also will need a DOM Mutation Observer to capture changes that sometimes happen but don't invoke events – such as when you're on some browsers in Android.If you want to reliably capture text input yourself, it's recommended that you use a rich text library such as ProseMirror or Lexical instead of trying to do it yourself.
I tested it on my Mac. When inputting Chinese, using shortcut keys to paste does not work. Pasting with the mouse will cause the focus to be lost and trigger a change event.
For me, triggering a value modification check on both compositionend and input works as expected.
I'm assuming this is for
contenteditablerather thaninputandtextareaas they should just work. Having worked on Lexical, I can tell you that it's really difficult to get IME input correct. Listening tocompositionstartandcompositionendis simply not good enough. This doesn't take into account that content can be inserted via other methods during this time – such as copy+paste, screenreaders, or speech to text etc and thus you can't always reliably state the value. You also will need a DOM Mutation Observer to capture changes that sometimes happen but don't invoke events – such as when you're on some browsers in Android. If you want to reliably capture text input yourself, it's recommended that you use a rich text library such as ProseMirror or Lexical instead of trying to do it yourself.
I tested it on my Mac. When inputting Chinese, using shortcut keys to paste does not work. Pasting with the mouse will cause the focus to be lost and trigger a change event.
For me, triggering a value modification check on both compositionend and input works as expected.
or use KeyboardEvent.isComposing https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/isComposing
When inputting Chinese, using shortcut keys to paste does not work
Different IMEs can have vaguely different behaviour. Mine does allow pasting while in composing. I remember debugging a VSCode problem with the composing. In that Github issue, the people using Simplified Chinese IME reported very different behaviour than mine.
Also, not everyone wants this "value change not triggering during composition". Changing this behaviour is a weird breaking change in my opinion. I think you can manually handle it on your own with on:input (or oninput in svelte 5) instead.
When inputting Chinese, using shortcut keys to paste does not work
Different IMEs can have vaguely different behaviour. Mine does allow pasting while in composing. I remember debugging a VSCode problem with the
composing. In that Github issue, the people using Simplified Chinese IME reported very different behaviour than mine.Also, not everyone wants this "value change not triggering during composition". Changing this behaviour is a weird breaking change in my opinion. I think you can manually handle it on your own with
on:input(oroninputin svelte 5) instead.
Does svelte have something similar to vue's Modifiers?
https://v2.vuejs.org/v2/guide/forms.html#Modifiers
If there is such a thing, it can be more convenient to customize the behavior of bind:value
or else , define new bind, for example: bind:valime
Svelte doesn't have modifiers. The simplest way is
<input bind:value on:compositionstart={() => composing = true} on:compositionend={() => composing = false} />
and do nothing when composing is true.
