-
Notifications
You must be signed in to change notification settings - Fork 6k
Fix web EditableText Widget composing range error #25673
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR!
I apologize for the delay in review as I wasn't aware of this PR. Please add us as reviewers. That's the most reliable way to get our attention.
| domElement.addEventListener('compositionstart', _handleCompositionStart); | ||
| domElement.addEventListener('compositionupdate', _handleCompositionChange); | ||
| domElement.addEventListener('compositionend', _handleCompositionEnd); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The same needs to be repeated in a few places. Let's put it in a method:
html.EventListener? compositionStart;
html.EventListener? compositionUpdate;
html.EventListener? compositionEnd;
void addCompositionHandlers() {
compositionStart = _handleCompositionStart;
compositionUpdate = _handleCompositionUpdate;
compositionEnd = _handleCompositionEnd;
domElement.addEventListener('compositionstart', compositionStart);
domElement.addEventListener('compositionupdate', compositionChange);
domElement.addEventListener('compositionend', compositionEnd);
}and call this method in all subclass of TextEditingStrategy.
| domElement.removeEventListener('compositionstart', _handleCompositionStart); | ||
| domElement.removeEventListener( | ||
| 'compositionupdate', _handleCompositionChange); | ||
| domElement.removeEventListener('compositionend', _handleCompositionEnd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the suggestion above, let's put this into a method:
void removeCompositionHandlers() {
domElement.removeEventListener('compositionstart', compositionStart);
domElement.removeEventListener(
'compositionupdate', compositionChange);
domElement.removeEventListener('compositionend', compositionEnd);
}and call from this disable() implementation and the one in: https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/semantics/text_field.dart#L106
| this.composingBase, | ||
| this.composingExtent}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we set a default value of -1 here?
| if (composingText != null && newEditingState.text != null) { | ||
| int composingBase = newEditingState.text!.lastIndexOf(composingText!); | ||
| if (composingBase >= 0) { | ||
| newEditingState = newEditingState.copyWith( | ||
| composingBase: composingBase, | ||
| composingExtent: composingBase + composingText!.length); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, the PR looks good, except this part. Doing a lastIndexOf() doesn't always get you the right index. The cursor could be in the middle of the text when composing starts.
From a quick try, I noticed that compositionupdate is always fired before the input event. So composingText is always up to date by the time we reach the _handleChange code here.
Instead of doing a lastIndexOf() to find the index of composingText, what if we use newEditingState.baseOffset? Something like this maybe:
final int compositionExtent = newEditingState.baseOffset
final int compositionBase = compositionExtent - composingText.length;| 'selectionExtent': 9 | ||
| 'selectionExtent': 9, | ||
| 'composingBase': -1, | ||
| 'composingExtent': -1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a test (or more) that sends a few composition events and makes sure they are handled correctly.
|
Is there any problem that hinders this PR from merging into main branch? I want to help if any because our project is also affected by this issue. |
b1a8771 to
2962099
Compare
|
This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold. |
|
@songfei Looks like there are some review comments to fix before we can land this, are you still interested in working on it? @tkfinitefield if @songfei is no longer able to work on this I imagine they would be perfectly happy for you to take over and finish it. See the comments above for what needs to happen before it can land. Thanks! |
|
@songfei Thanks for your contribution. Unfortunately as written we can't take this patch, as per the review comments above. I'm going to close this PR since there has been no progress for a while, but please don't hesitate to file a new one if you do have time to get back to it. Equally if anyone else would like to start with this PR and take it forward, you are most welcome to do so. |
EditableText widget should receive correct composing range, I fix it.
example code:
before:
https://user-images.githubusercontent.com/1343893/115393137-ef6e6580-a213-11eb-8246-6540ba6da13d.mov
fixed:
https://user-images.githubusercontent.com/1343893/115393169-fac19100-a213-11eb-866e-0cea96a626fe.mov
List which issues are fixed by this PR. You must list at least one issue.
flutter/flutter#65357
Pre-launch Checklist
writing and running engine tests.
///).