Unverified Commit f91ed2a3 authored by chunhtai's avatar chunhtai Committed by GitHub

Adds set text semantics action to render editable (#77024)

* Adds set text semantics action to render editable

* addressing comments

* re-enable test

* fix test

* fix more test

* fix bad merge

* addressing comment

* update dynamic to Object?
parent 406f6bcc
......@@ -987,6 +987,9 @@ class RenderCustomPaint extends RenderProxyBox {
if (properties.onSetSelection != null) {
config.onSetSelection = properties.onSetSelection;
}
if (properties.onSetText != null) {
config.onSetText = properties.onSetText;
}
if (properties.onDidGainAccessibilityFocus != null) {
config.onDidGainAccessibilityFocus = properties.onDidGainAccessibilityFocus;
}
......
......@@ -1492,6 +1492,9 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
if (hasFocus && selectionEnabled)
config.onSetSelection = _handleSetSelection;
if (hasFocus && !readOnly)
config.onSetText = _handleSetText;
if (selectionEnabled && selection?.isValid == true) {
config.textSelection = selection;
if (_textPainter.getOffsetBefore(selection!.extentOffset) != null) {
......@@ -1507,6 +1510,16 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
}
}
void _handleSetText(String text) {
textSelectionDelegate.userUpdateTextEditingValue(
TextEditingValue(
text: text,
selection: TextSelection.collapsed(offset: text.length),
),
SelectionChangedCause.keyboard,
);
}
// TODO(ianh): in theory, [selection] could become null between when
// we last called describeSemanticsConfiguration and when the
// callbacks are invoked, in which case the callbacks will crash...
......
......@@ -3750,6 +3750,7 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
MoveCursorHandler? onMoveCursorForwardByWord,
MoveCursorHandler? onMoveCursorBackwardByWord,
SetSelectionHandler? onSetSelection,
SetTextHandler? onSetText,
VoidCallback? onDidGainAccessibilityFocus,
VoidCallback? onDidLoseAccessibilityFocus,
Map<CustomSemanticsAction, VoidCallback>? customSemanticsActions,
......@@ -3805,6 +3806,7 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
_onMoveCursorForwardByWord = onMoveCursorForwardByWord,
_onMoveCursorBackwardByWord = onMoveCursorBackwardByWord,
_onSetSelection = onSetSelection,
_onSetText = onSetText,
_onDidGainAccessibilityFocus = onDidGainAccessibilityFocus,
_onDidLoseAccessibilityFocus = onDidLoseAccessibilityFocus,
_customSemanticsActions = customSemanticsActions,
......@@ -4540,6 +4542,24 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
markNeedsSemanticsUpdate();
}
/// The handler for [SemanticsAction.setText].
///
/// This handler is invoked when the user wants to replace the current text in
/// the text field with a new text.
///
/// Voice access users can trigger this handler by speaking "type <text>" to
/// their Android devices.
SetTextHandler? get onSetText => _onSetText;
SetTextHandler? _onSetText;
set onSetText(SetTextHandler? handler) {
if (_onSetText == handler)
return;
final bool hadValue = _onSetText != null;
_onSetText = handler;
if ((handler != null) != hadValue)
markNeedsSemanticsUpdate();
}
/// The handler for [SemanticsAction.didGainAccessibilityFocus].
///
/// This handler is invoked when the node annotated with this handler gains
......@@ -4732,6 +4752,8 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
config.onMoveCursorBackwardByWord = _performMoveCursorBackwardByWord;
if (onSetSelection != null)
config.onSetSelection = _performSetSelection;
if (onSetText != null)
config.onSetText = _performSetText;
if (onDidGainAccessibilityFocus != null)
config.onDidGainAccessibilityFocus = _performDidGainAccessibilityFocus;
if (onDidLoseAccessibilityFocus != null)
......@@ -4825,6 +4847,11 @@ class RenderSemanticsAnnotations extends RenderProxyBox {
onSetSelection!(selection);
}
void _performSetText(String text) {
if (onSetText != null)
onSetText!(text);
}
void _performDidGainAccessibilityFocus() {
if (onDidGainAccessibilityFocus != null)
onDidGainAccessibilityFocus!();
......
......@@ -36,7 +36,11 @@ typedef MoveCursorHandler = void Function(bool extendSelection);
/// text selection (or re-position the cursor) to `selection`.
typedef SetSelectionHandler = void Function(TextSelection selection);
typedef _SemanticsActionHandler = void Function(dynamic args);
/// Signature for the [SemanticsAction.setText] handlers to replace the
/// current text with the input `text`.
typedef SetTextHandler = void Function(String text);
typedef _SemanticsActionHandler = void Function(Object? args);
/// A tag for a [SemanticsNode].
///
......@@ -626,6 +630,7 @@ class SemanticsProperties extends DiagnosticableTree {
this.onMoveCursorForwardByWord,
this.onMoveCursorBackwardByWord,
this.onSetSelection,
this.onSetText,
this.onDidGainAccessibilityFocus,
this.onDidLoseAccessibilityFocus,
this.onDismiss,
......@@ -1097,6 +1102,15 @@ class SemanticsProperties extends DiagnosticableTree {
/// beginning/end" or "Select all" from the local context menu.
final SetSelectionHandler? onSetSelection;
/// The handler for [SemanticsAction.setText].
///
/// This handler is invoked when the user wants to replace the current text in
/// the text field with a new text.
///
/// Voice access users can trigger this handler by speaking "type <text>" to
/// their Android devices.
final SetTextHandler? onSetText;
/// The handler for [SemanticsAction.didGainAccessibilityFocus].
///
/// This handler is invoked when the node annotated with this handler gains
......@@ -2684,7 +2698,7 @@ class SemanticsOwner extends ChangeNotifier {
///
/// If the given `action` requires arguments they need to be passed in via
/// the `args` parameter.
void performAction(int id, SemanticsAction action, [ dynamic args ]) {
void performAction(int id, SemanticsAction action, [ Object? args ]) {
assert(action != null);
final _SemanticsActionHandler? handler = _getSemanticsActionHandlerForId(id, action);
if (handler != null) {
......@@ -2734,7 +2748,7 @@ class SemanticsOwner extends ChangeNotifier {
///
/// If the given `action` requires arguments they need to be passed in via
/// the `args` parameter.
void performActionAt(Offset position, SemanticsAction action, [ dynamic args ]) {
void performActionAt(Offset position, SemanticsAction action, [ Object? args ]) {
assert(action != null);
final SemanticsNode? node = rootSemanticsNode;
if (node == null)
......@@ -2848,7 +2862,7 @@ class SemanticsConfiguration {
/// `action`.
void _addArgumentlessAction(SemanticsAction action, VoidCallback handler) {
assert(handler != null);
_addAction(action, (dynamic args) {
_addAction(action, (Object? args) {
assert(args == null);
handler();
});
......@@ -3085,9 +3099,8 @@ class SemanticsConfiguration {
MoveCursorHandler? _onMoveCursorForwardByCharacter;
set onMoveCursorForwardByCharacter(MoveCursorHandler? value) {
assert(value != null);
_addAction(SemanticsAction.moveCursorForwardByCharacter, (dynamic args) {
final bool extentSelection = args as bool;
assert(extentSelection != null);
_addAction(SemanticsAction.moveCursorForwardByCharacter, (Object? args) {
final bool extentSelection = args! as bool;
value!(extentSelection);
});
_onMoveCursorForwardByCharacter = value;
......@@ -3104,9 +3117,8 @@ class SemanticsConfiguration {
MoveCursorHandler? _onMoveCursorBackwardByCharacter;
set onMoveCursorBackwardByCharacter(MoveCursorHandler? value) {
assert(value != null);
_addAction(SemanticsAction.moveCursorBackwardByCharacter, (dynamic args) {
final bool extentSelection = args as bool;
assert(extentSelection != null);
_addAction(SemanticsAction.moveCursorBackwardByCharacter, (Object? args) {
final bool extentSelection = args! as bool;
value!(extentSelection);
});
_onMoveCursorBackwardByCharacter = value;
......@@ -3123,9 +3135,8 @@ class SemanticsConfiguration {
MoveCursorHandler? _onMoveCursorForwardByWord;
set onMoveCursorForwardByWord(MoveCursorHandler? value) {
assert(value != null);
_addAction(SemanticsAction.moveCursorForwardByWord, (dynamic args) {
final bool extentSelection = args as bool;
assert(extentSelection != null);
_addAction(SemanticsAction.moveCursorForwardByWord, (Object? args) {
final bool extentSelection = args! as bool;
value!(extentSelection);
});
_onMoveCursorForwardByCharacter = value;
......@@ -3142,9 +3153,8 @@ class SemanticsConfiguration {
MoveCursorHandler? _onMoveCursorBackwardByWord;
set onMoveCursorBackwardByWord(MoveCursorHandler? value) {
assert(value != null);
_addAction(SemanticsAction.moveCursorBackwardByWord, (dynamic args) {
final bool extentSelection = args as bool;
assert(extentSelection != null);
_addAction(SemanticsAction.moveCursorBackwardByWord, (Object? args) {
final bool extentSelection = args! as bool;
value!(extentSelection);
});
_onMoveCursorBackwardByCharacter = value;
......@@ -3161,9 +3171,9 @@ class SemanticsConfiguration {
SetSelectionHandler? _onSetSelection;
set onSetSelection(SetSelectionHandler? value) {
assert(value != null);
_addAction(SemanticsAction.setSelection, (dynamic args) {
_addAction(SemanticsAction.setSelection, (Object? args) {
assert(args != null && args is Map);
final Map<String, int> selection = (args as Map<dynamic, dynamic>).cast<String, int>();
final Map<String, int> selection = (args! as Map<dynamic, dynamic>).cast<String, int>();
assert(selection != null && selection['base'] != null && selection['extent'] != null);
value!(TextSelection(
baseOffset: selection['base']!,
......@@ -3173,6 +3183,25 @@ class SemanticsConfiguration {
_onSetSelection = value;
}
/// The handler for [SemanticsAction.setText].
///
/// This handler is invoked when the user wants to replace the current text in
/// the text field with a new text.
///
/// Voice access users can trigger this handler by speaking "type <text>" to
/// their Android devices.
SetTextHandler? get onSetText => _onSetText;
SetTextHandler? _onSetText;
set onSetText(SetTextHandler? value) {
assert(value != null);
_addAction(SemanticsAction.setText, (Object? args) {
assert(args != null && args is String);
final String text = args! as String;
value!(text);
});
_onSetText = value;
}
/// The handler for [SemanticsAction.didGainAccessibilityFocus].
///
/// This handler is invoked when the node annotated with this handler gains
......@@ -3357,8 +3386,8 @@ class SemanticsConfiguration {
_actions[SemanticsAction.customAction] = _onCustomSemanticsAction;
}
void _onCustomSemanticsAction(dynamic args) {
final CustomSemanticsAction? action = CustomSemanticsAction.getAction(args as int);
void _onCustomSemanticsAction(Object? args) {
final CustomSemanticsAction? action = CustomSemanticsAction.getAction(args! as int);
if (action == null)
return;
final VoidCallback? callback = _customSemanticsActions[action];
......
......@@ -6968,6 +6968,7 @@ class Semantics extends SingleChildRenderObjectWidget {
MoveCursorHandler? onMoveCursorForwardByCharacter,
MoveCursorHandler? onMoveCursorBackwardByCharacter,
SetSelectionHandler? onSetSelection,
SetTextHandler? onSetText,
VoidCallback? onDidGainAccessibilityFocus,
VoidCallback? onDidLoseAccessibilityFocus,
Map<CustomSemanticsAction, VoidCallback>? customSemanticsActions,
......@@ -7025,6 +7026,7 @@ class Semantics extends SingleChildRenderObjectWidget {
onDidLoseAccessibilityFocus: onDidLoseAccessibilityFocus,
onDismiss: onDismiss,
onSetSelection: onSetSelection,
onSetText: onSetText,
customSemanticsActions: customSemanticsActions,
hintOverrides: onTapHint != null || onLongPressHint != null ?
SemanticsHintOverrides(
......@@ -7142,6 +7144,7 @@ class Semantics extends SingleChildRenderObjectWidget {
onMoveCursorForwardByWord: properties.onMoveCursorForwardByWord,
onMoveCursorBackwardByWord: properties.onMoveCursorBackwardByWord,
onSetSelection: properties.onSetSelection,
onSetText: properties.onSetText,
onDidGainAccessibilityFocus: properties.onDidGainAccessibilityFocus,
onDidLoseAccessibilityFocus: properties.onDidLoseAccessibilityFocus,
customSemanticsActions: properties.customSemanticsActions,
......@@ -7214,6 +7217,7 @@ class Semantics extends SingleChildRenderObjectWidget {
..onMoveCursorForwardByWord = properties.onMoveCursorForwardByWord
..onMoveCursorBackwardByWord = properties.onMoveCursorBackwardByWord
..onSetSelection = properties.onSetSelection
..onSetText = properties.onSetText
..onDidGainAccessibilityFocus = properties.onDidGainAccessibilityFocus
..onDidLoseAccessibilityFocus = properties.onDidLoseAccessibilityFocus
..customSemanticsActions = properties.customSemanticsActions;
......
......@@ -254,6 +254,7 @@ void main() {
isFocused: true,
value: '01/15/2016',
hasTapAction: true,
hasSetTextAction: true,
hasSetSelectionAction: true,
hasCopyAction: true,
hasCutAction: true,
......
......@@ -628,6 +628,7 @@ void main() {
actions: <SemanticsAction>[
SemanticsAction.tap,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
],
label: 'Search',
......
......@@ -1198,7 +1198,7 @@ void main() {
flags: <SemanticsFlag>[SemanticsFlag.isTextField, SemanticsFlag.isFocused],
actions: <SemanticsAction>[SemanticsAction.tap,
SemanticsAction.moveCursorBackwardByCharacter, SemanticsAction.setSelection, SemanticsAction.paste,
SemanticsAction.moveCursorBackwardByWord],
SemanticsAction.setText, SemanticsAction.moveCursorBackwardByWord],
value: 'abcdefghi',
textDirection: TextDirection.ltr,
textSelection: const TextSelection.collapsed(offset: 9),
......@@ -5325,6 +5325,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
],
flags: <SemanticsFlag>[
......@@ -5352,6 +5353,7 @@ void main() {
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
],
flags: <SemanticsFlag>[
......@@ -5378,6 +5380,7 @@ void main() {
SemanticsAction.moveCursorForwardByCharacter,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
],
flags: <SemanticsFlag>[
......@@ -5416,6 +5419,7 @@ void main() {
textDirection: TextDirection.ltr,
actions: <SemanticsAction>[
SemanticsAction.tap,
SemanticsAction.setText,
// Absent the following because enableInteractiveSelection: false
// SemanticsAction.moveCursorBackwardByCharacter,
// SemanticsAction.moveCursorBackwardByWord,
......@@ -5480,6 +5484,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
],
flags: <SemanticsFlag>[
......@@ -5507,6 +5512,7 @@ void main() {
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
SemanticsAction.cut,
SemanticsAction.copy,
......@@ -5557,6 +5563,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
],
flags: <SemanticsFlag>[
......@@ -5602,6 +5609,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
SemanticsAction.cut,
SemanticsAction.copy,
......@@ -5671,6 +5679,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
],
value: textInTextField,
......@@ -5743,6 +5752,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
// No paste option.
],
value: textInTextField,
......@@ -5939,6 +5949,7 @@ void main() {
actions: <SemanticsAction>[
SemanticsAction.tap,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
],
flags: <SemanticsFlag>[
......
......@@ -343,6 +343,7 @@ void _defineTests() {
onMoveCursorForwardByWord: (bool _) => performedActions.add(SemanticsAction.moveCursorForwardByWord),
onMoveCursorBackwardByWord: (bool _) => performedActions.add(SemanticsAction.moveCursorBackwardByWord),
onSetSelection: (TextSelection _) => performedActions.add(SemanticsAction.setSelection),
onSetText: (String text) => performedActions.add(SemanticsAction.setText),
onDidGainAccessibilityFocus: () => performedActions.add(SemanticsAction.didGainAccessibilityFocus),
onDidLoseAccessibilityFocus: () => performedActions.add(SemanticsAction.didLoseAccessibilityFocus),
),
......@@ -387,6 +388,9 @@ void _defineTests() {
'extent': 5,
});
break;
case SemanticsAction.setText:
semanticsOwner.performAction(expectedId, action, 'text');
break;
default:
semanticsOwner.performAction(expectedId, action);
}
......@@ -396,7 +400,7 @@ void _defineTests() {
}
semantics.dispose();
}, skip: true); // disable for soft transition https://github.com/flutter/flutter/issues/77271
});
testWidgets('Supports all flags', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
......
......@@ -2159,6 +2159,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2178,6 +2179,7 @@ void main() {
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2194,6 +2196,7 @@ void main() {
SemanticsAction.moveCursorForwardByCharacter,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2253,6 +2256,7 @@ void main() {
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2279,6 +2283,7 @@ void main() {
SemanticsAction.moveCursorForwardByCharacter,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2345,6 +2350,7 @@ void main() {
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2372,6 +2378,7 @@ void main() {
SemanticsAction.moveCursorForwardByCharacter,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2446,6 +2453,7 @@ void main() {
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2472,6 +2480,7 @@ void main() {
SemanticsAction.moveCursorForwardByCharacter,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2546,6 +2555,7 @@ void main() {
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2573,6 +2583,7 @@ void main() {
SemanticsAction.moveCursorForwardByCharacter,
SemanticsAction.moveCursorForwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2737,6 +2748,7 @@ void main() {
actions: <SemanticsAction>[
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.moveCursorBackwardByWord,
],
value: expectedValue,
......@@ -2825,6 +2837,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
],
),
);
......@@ -2839,6 +2852,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.copy,
],
),
......@@ -2856,6 +2870,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.paste,
],
),
......@@ -2872,6 +2887,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.cut,
],
),
......@@ -2889,6 +2905,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.cut,
SemanticsAction.copy,
SemanticsAction.paste,
......@@ -2935,6 +2952,7 @@ void main() {
SemanticsAction.moveCursorBackwardByCharacter,
SemanticsAction.moveCursorBackwardByWord,
SemanticsAction.setSelection,
SemanticsAction.setText,
SemanticsAction.copy,
SemanticsAction.cut,
SemanticsAction.paste,
......@@ -2970,6 +2988,73 @@ void main() {
});
});
testWidgets('can set text with a11y', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(MaterialApp(
home: EditableText(
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
),
));
await tester.tap(find.byType(EditableText));
await tester.pump();
final SemanticsOwner owner = tester.binding.pipelineOwner.semanticsOwner!;
const int expectedNodeId = 4;
expect(
semantics,
hasSemantics(
TestSemantics.root(
children: <TestSemantics>[
TestSemantics.rootChild(
id: 1,
children: <TestSemantics>[
TestSemantics(
id: 2,
children: <TestSemantics>[
TestSemantics(
id: 3,
flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
children: <TestSemantics>[
TestSemantics.rootChild(
id: expectedNodeId,
flags: <SemanticsFlag>[
SemanticsFlag.isTextField,
SemanticsFlag.isFocused,
],
actions: <SemanticsAction>[
SemanticsAction.setSelection,
SemanticsAction.setText,
],
value: '',
textSelection: TextSelection.collapsed(
offset: controller.text.length),
textDirection: TextDirection.ltr,
),
],
),
],
),
],
),
],
),
ignoreRect: true,
ignoreTransform: true,
),
);
expect(controller.text, '');
owner.performAction(expectedNodeId, SemanticsAction.setText, 'how are you');
expect(controller.text, 'how are you');
semantics.dispose();
});
testWidgets('allows customizing text style in subclasses', (WidgetTester tester) async {
controller.text = 'Hello World';
......
......@@ -451,6 +451,7 @@ void main() {
onMoveCursorForwardByCharacter: (bool _) => performedActions.add(SemanticsAction.moveCursorForwardByCharacter),
onMoveCursorBackwardByCharacter: (bool _) => performedActions.add(SemanticsAction.moveCursorBackwardByCharacter),
onSetSelection: (TextSelection _) => performedActions.add(SemanticsAction.setSelection),
onSetText: (String _) => performedActions.add(SemanticsAction.setText),
onDidGainAccessibilityFocus: () => performedActions.add(SemanticsAction.didGainAccessibilityFocus),
onDidLoseAccessibilityFocus: () => performedActions.add(SemanticsAction.didLoseAccessibilityFocus),
),
......@@ -489,6 +490,9 @@ void main() {
'extent': 5,
});
break;
case SemanticsAction.setText:
semanticsOwner.performAction(expectedId, action, 'text');
break;
default:
semanticsOwner.performAction(expectedId, action);
}
......@@ -498,7 +502,7 @@ void main() {
}
semantics.dispose();
}, skip: true); // disable for soft transition https://github.com/flutter/flutter/issues/77271
});
testWidgets('Semantics widget supports all flags', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
......
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