Skip to content

Commit 785b249

Browse files
authored
Update CompositionAwareMixin to correctly compute composingBase in Web engine (flutter#44139)
It fixes an issue in `CompositionAwareMixin` causing wrong deltas being computed and reported to input clients resulting in wrong state when compositing text in rich text editors like [Fleather](https://github.com/fleather-editor/fleather) and possibly others. Reported deltas on Mac: ```console TextEditingDeltaInsertion: start: 0, end: 0, data: k TextEditingDeltaInsertion: start: 1, end: 0, data: y TextEditingDeltaReplacement: start: 0, end: 2, data: �� TextEditingDeltaInsertion: start: 2, end: 0, data: � TextEditingDeltaInsertion: start: 3, end: 0, data: h TextEditingDeltaReplacement: start: 0, end: 4, data: ���� TextEditingDeltaReplacement: start: 0, end: 4, data: ��� ``` Reported deltas on Web (Before): ```console TextEditingDeltaInsertion: start: 0, end: 0, data: k TextEditingDeltaInsertion: start: 1, end: 0, data: y TextEditingDeltaReplacement: start: 0, end: 2, data: �� TextEditingDeltaInsertion: start: 2, end: 0, data: � TextEditingDeltaInsertion: start: 3, end: 0, data: h TextEditingDeltaReplacement: start: 0, end: 4, data: ���� TextEditingDeltaInsertion: start: 4, end: 0, data: ��� ``` Reported deltas on Web (After): ```console TextEditingDeltaInsertion: start: 0, end: 0, data: k TextEditingDeltaInsertion: start: 1, end: 0, data: y TextEditingDeltaReplacement: start: 0, end: 2, data: �� TextEditingDeltaInsertion: start: 2, end: 0, data: � TextEditingDeltaInsertion: start: 3, end: 0, data: h TextEditingDeltaReplacement: start: 0, end: 4, data: ���� TextEditingDeltaReplacement: start: 0, end: 4, data: ��� ``` * Fixes flutter/flutter#131335 * Fixes fleather-editor/fleather#150 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 99417da commit 785b249

File tree

3 files changed

+29
-4
lines changed

3 files changed

+29
-4
lines changed

AUTHORS

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,5 @@ Koutaro Mori <[email protected]>
2323
TheOneWithTheBraid <[email protected]>
2424
Twin Sun, LLC <[email protected]>
2525
Qixing Cao <[email protected]>
26-
LinXunFeng <[email protected]>
26+
LinXunFeng <[email protected]>
27+
Amir Panahandeh <[email protected]>

lib/web_ui/lib/src/engine/text_editing/composition_aware_mixin.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ mixin CompositionAwareMixin {
7171
}
7272

7373
EditingState determineCompositionState(EditingState editingState) {
74-
if (editingState.baseOffset == null || composingText == null || editingState.text == null) {
74+
if (editingState.extentOffset == null || composingText == null || editingState.text == null) {
7575
return editingState;
7676
}
7777

78-
final int composingBase = editingState.baseOffset! - composingText!.length;
78+
final int composingBase = editingState.extentOffset! - composingText!.length;
7979

8080
if (composingBase < 0) {
8181
return editingState;

lib/web_ui/test/engine/composition_test.dart

+25-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ Future<void> testMain() async {
106106
});
107107

108108
group('determine composition state', () {
109-
test('should return new composition state if valid new composition', () {
109+
test('should return new composition state - compositing middle of text', () {
110110
const int baseOffset = 100;
111111
const String composingText = 'composeMe';
112112

@@ -128,6 +128,30 @@ Future<void> testMain() async {
128128
composingBaseOffset: expectedComposingBase,
129129
composingExtentOffset: expectedComposingBase + composingText.length));
130130
});
131+
132+
test('should return new composition state - compositing from beginning of text', () {
133+
const String composingText = '今日は';
134+
135+
final EditingState editingState = EditingState(
136+
text: '今日は',
137+
baseOffset: 0,
138+
extentOffset: 3,
139+
);
140+
141+
final _MockWithCompositionAwareMixin mockWithCompositionAwareMixin =
142+
_MockWithCompositionAwareMixin();
143+
mockWithCompositionAwareMixin.composingText = composingText;
144+
145+
const int expectedComposingBase = 0;
146+
147+
expect(
148+
mockWithCompositionAwareMixin
149+
.determineCompositionState(editingState),
150+
editingState.copyWith(
151+
composingBaseOffset: expectedComposingBase,
152+
composingExtentOffset:
153+
expectedComposingBase + composingText.length));
154+
});
131155
});
132156
});
133157

0 commit comments

Comments
 (0)