Unverified Commit fa3fbc89 authored by Tong Mu's avatar Tong Mu Committed by GitHub

Material allows "select all" when not collapsed (#32950)

This PR enables "Select all" on MaterialTextSelection when text is partially selected.
parent 07aede4c
25ab3c95b1ac02a41973c05f96e664370857ce55
d79941e3d9c6e761189ac8aefa3a40c7fb98413e
......@@ -212,6 +212,15 @@ class _MaterialTextSelectionControls extends TextSelectionControls {
assert(type != null);
return null;
}
@override
bool canSelectAll(TextSelectionDelegate delegate) {
// Android allows SelectAll when selection is not collapsed, unless
// everything has already been selected.
final TextEditingValue value = delegate.textEditingValue;
return value.text.isNotEmpty &&
!(value.selection.start == 0 && value.selection.end == value.text.length);
}
}
/// Text selection controls that follow the Material Design specification.
......
// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/cupertino.dart';
void main() {
group('canSelectAll', () {
Widget createEditableText({
Key key,
String text,
TextSelection selection,
}) {
final TextEditingController controller = TextEditingController(text: text)
..selection = selection ?? const TextSelection.collapsed(offset: -1);
return CupertinoApp(
home: EditableText(
key: key,
controller: controller,
focusNode: FocusNode(),
style: const TextStyle(),
cursorColor: const Color.fromARGB(0, 0, 0, 0),
backgroundCursorColor: const Color.fromARGB(0, 0, 0, 0),
)
);
}
testWidgets('should return false when there is no text', (WidgetTester tester) async {
final GlobalKey<EditableTextState> key = GlobalKey();
await tester.pumpWidget(createEditableText(key: key));
expect(cupertinoTextSelectionControls.canSelectAll(key.currentState), false);
});
testWidgets('should return true when there is text and collapsed selection', (WidgetTester tester) async {
final GlobalKey<EditableTextState> key = GlobalKey();
await tester.pumpWidget(createEditableText(
key: key,
text: '123',
));
expect(cupertinoTextSelectionControls.canSelectAll(key.currentState), true);
});
testWidgets('should return false when there is text and partial uncollapsed selection', (WidgetTester tester) async {
final GlobalKey<EditableTextState> key = GlobalKey();
await tester.pumpWidget(createEditableText(
key: key,
text: '123',
selection: const TextSelection(baseOffset: 1, extentOffset: 2),
));
expect(cupertinoTextSelectionControls.canSelectAll(key.currentState), false);
});
testWidgets('should return false when there is text and full selection', (WidgetTester tester) async {
final GlobalKey<EditableTextState> key = GlobalKey();
await tester.pumpWidget(createEditableText(
key: key,
text: '123',
selection: const TextSelection(baseOffset: 0, extentOffset: 3),
));
expect(cupertinoTextSelectionControls.canSelectAll(key.currentState), false);
});
});
}
......@@ -483,7 +483,7 @@ void main() {
await expectLater(
// The toolbar exists in the Overlay above the MaterialApp.
find.byType(Overlay),
matchesGoldenFile('text_field_opacity_test.0.1.png'),
matchesGoldenFile('text_field_opacity_test.0.2.png'),
skip: !Platform.isLinux,
);
});
......@@ -4921,8 +4921,8 @@ void main() {
const TextSelection(baseOffset: 8, extentOffset: 12),
);
// Selected text shows 3 toolbar buttons.
expect(find.byType(FlatButton), findsNWidgets(3));
// Selected text shows 4 toolbar buttons: cut, copy, paste, select all
expect(find.byType(FlatButton), findsNWidgets(4));
},
);
......@@ -5086,8 +5086,8 @@ void main() {
const TextSelection(baseOffset: 0, extentOffset: 7),
);
// Collapsed toolbar shows 3 buttons.
expect(find.byType(FlatButton), findsNWidgets(3));
// Collapsed toolbar shows 4 buttons: cut, copy, paste, select all
expect(find.byType(FlatButton), findsNWidgets(4));
},
);
......
// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
void main() {
group('canSelectAll', () {
Widget createEditableText({
Key key,
String text,
TextSelection selection,
}) {
final TextEditingController controller = TextEditingController(text: text)
..selection = selection ?? const TextSelection.collapsed(offset: -1);
return MaterialApp(
home: EditableText(
key: key,
controller: controller,
focusNode: FocusNode(),
style: const TextStyle(),
cursorColor: Colors.black,
backgroundCursorColor: Colors.black,
)
);
}
testWidgets('should return false when there is no text', (WidgetTester tester) async {
final GlobalKey<EditableTextState> key = GlobalKey();
await tester.pumpWidget(createEditableText(key: key));
expect(materialTextSelectionControls.canSelectAll(key.currentState), false);
});
testWidgets('should return true when there is text and collapsed selection', (WidgetTester tester) async {
final GlobalKey<EditableTextState> key = GlobalKey();
await tester.pumpWidget(createEditableText(
key: key,
text: '123',
));
expect(materialTextSelectionControls.canSelectAll(key.currentState), true);
});
testWidgets('should return true when there is text and partial uncollapsed selection', (WidgetTester tester) async {
final GlobalKey<EditableTextState> key = GlobalKey();
await tester.pumpWidget(createEditableText(
key: key,
text: '123',
selection: const TextSelection(baseOffset: 1, extentOffset: 2),
));
expect(materialTextSelectionControls.canSelectAll(key.currentState), true);
});
testWidgets('should return false when there is text and full selection', (WidgetTester tester) async {
final GlobalKey<EditableTextState> key = GlobalKey();
await tester.pumpWidget(createEditableText(
key: key,
text: '123',
selection: const TextSelection(baseOffset: 0, extentOffset: 3),
));
expect(materialTextSelectionControls.canSelectAll(key.currentState), false);
});
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment