fix: RangeError when selecting text in SelectionArea (#162228)

fix: RangeError when selecting text in SelectionArea
fixes #161931 

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
This commit is contained in:
Kishan Rathore 2025-02-06 02:41:26 +05:30 committed by GitHub
parent 17cb12d9bd
commit 211d83d772
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 87 additions and 1 deletions

View File

@ -3027,7 +3027,7 @@ abstract class MultiSelectableSelectionContainerDelegate extends SelectionContai
if (event.forward) {
currentSelectionStartIndex = currentSelectionEndIndex = 0;
} else {
currentSelectionStartIndex = currentSelectionEndIndex = selectables.length;
currentSelectionStartIndex = currentSelectionEndIndex = selectables.length - 1;
}
}
int targetIndex = event.isEnd ? currentSelectionEndIndex : currentSelectionStartIndex;

View File

@ -4827,6 +4827,92 @@ void main() {
expect(paragraph1.selections[0].end, 2);
}, variant: TargetPlatformVariant.all());
testWidgets(
'should not throw range error when selecting previous paragraph',
(WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: SelectableRegion(
selectionControls: materialTextSelectionControls,
child: const Column(
children: <Widget>[
Text('How are you?'),
Text('Good, and you?'),
Text('Fine, thank you.'),
],
),
),
),
);
// Select from offset 2 of paragraph3 to offset 6 of paragraph3.
final RenderParagraph paragraph3 = tester.renderObject<RenderParagraph>(
find.descendant(of: find.text('Fine, thank you.'), matching: find.byType(RichText)),
);
final TestGesture gesture = await tester.startGesture(
textOffsetToPosition(paragraph3, 2),
kind: PointerDeviceKind.mouse,
);
addTearDown(gesture.removePointer);
await tester.pump();
await gesture.moveTo(textOffsetToPosition(paragraph3, 6));
await gesture.up();
await tester.pump();
final bool alt;
final bool meta;
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
meta = false;
alt = true;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
meta = true;
alt = false;
}
// How are you?
// Good, and you?
// Fi[ne, ]thank you.
expect(paragraph3.selections.length, 1);
expect(paragraph3.selections[0].start, 2);
expect(paragraph3.selections[0].end, 6);
await sendKeyCombination(
tester,
SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, alt: alt, meta: meta),
);
await tester.pump();
// How are you?
// Good, and you?
// [Fine, ]thank you.
expect(paragraph3.selections.length, 1);
expect(paragraph3.selections[0].start, 0);
expect(paragraph3.selections[0].end, 6);
await sendKeyCombination(
tester,
const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true),
);
await tester.pump();
// How are you?
// Good, and you[?
// Fine, ]thank you.
final RenderParagraph paragraph2 = tester.renderObject<RenderParagraph>(
find.descendant(of: find.text('Good, and you?'), matching: find.byType(RichText)),
);
expect(paragraph3.selections.length, 1);
expect(paragraph3.selections[0].start, 0);
expect(paragraph3.selections[0].end, 6);
expect(paragraph2.selections.length, 1);
expect(paragraph2.selections[0].start, 13);
expect(paragraph2.selections[0].end, 14);
},
variant: TargetPlatformVariant.all(),
);
testWidgets(
'can use keyboard to granularly extend selection - document',
(WidgetTester tester) async {