Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

value change should not trigger when typeing ( compositionstart -> compositionend ) #13196

Open
i18nsite opened this issue Sep 11, 2024 · 11 comments

Comments

@i18nsite
Copy link

i18nsite commented Sep 11, 2024

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.
CleanShot 2024-09-11 at 10 41 45

You can refer to the implementation in vue

https://github.com/vuejs/core/blob/main/packages/runtime-dom/src/directives/vModel.ts
CleanShot 2024-09-11 at 10 44 36

now svelte is
CleanShot 2024-09-11 at 10 58 50

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

@brunnerh
Copy link
Member

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?

@trueadm
Copy link
Contributor

trueadm commented Sep 11, 2024

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.

@7nik
Copy link

7nik commented Sep 11, 2024

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 contenteditable rather than input and textarea as 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.

@i18nsite
Copy link
Author

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 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.

@trueadm
Copy link
Contributor

trueadm commented Sep 11, 2024

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 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?

@i18nsite
Copy link
Author

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 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

@i18nsite
Copy link
Author

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.

CleanShot 2024-09-12 at 07 36 37

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.

@i18nsite
Copy link
Author

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.

CleanShot 2024-09-12 at 07 36 37

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.

CleanShot 2024-09-12 at 07 54 03
or use KeyboardEvent.isComposing https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/isComposing

@jasonlyu123
Copy link
Member

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.

@i18nsite
Copy link
Author

i18nsite commented Sep 12, 2024

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.

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

@7nik
Copy link

7nik commented Sep 12, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants