From 736b414f13ed58037de3f8db1a8efd0da618f674 Mon Sep 17 00:00:00 2001 From: Michael Goderbauer Date: Tue, 14 Nov 2017 09:52:24 -0800 Subject: [PATCH] Add text field content to semantics (#13000) * Add text field content to semantics * remove controller dup --- .../flutter/lib/src/rendering/editable.dart | 4 ++ .../test/widgets/editable_text_test.dart | 37 +++++++++++++++++++ .../test/widgets/semantics_tester.dart | 10 ++++- 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/rendering/editable.dart b/packages/flutter/lib/src/rendering/editable.dart index d8ae24bb559..70db4384551 100644 --- a/packages/flutter/lib/src/rendering/editable.dart +++ b/packages/flutter/lib/src/rendering/editable.dart @@ -169,6 +169,7 @@ class RenderEditable extends RenderBox { return; _textPainter.text = value; markNeedsTextLayout(); + markNeedsSemanticsUpdate(); } /// How the text should be aligned horizontally. @@ -203,6 +204,7 @@ class RenderEditable extends RenderBox { return; _textPainter.textDirection = value; markNeedsTextLayout(); + markNeedsSemanticsUpdate(); } /// The color to use when painting the cursor. @@ -322,6 +324,8 @@ class RenderEditable extends RenderBox { super.describeSemanticsConfiguration(config); config + ..value = text.toPlainText() + ..textDirection = textDirection ..isFocused = hasFocus ..isTextField = true; } diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart index a80f75d76b1..c9158b4baf4 100644 --- a/packages/flutter/test/widgets/editable_text_test.dart +++ b/packages/flutter/test/widgets/editable_text_test.dart @@ -284,6 +284,43 @@ void main() { await tester.pump(); expect(semantics, includesNodeWith(flags: [SemanticsFlags.isTextField, SemanticsFlags.isFocused])); + }); + testWidgets('EditableText includes text as value in semantics', (WidgetTester tester) async { + final SemanticsTester semantics = new SemanticsTester(tester); + + const String value1 = 'EditableText content'; + + controller.text = value1; + + await tester.pumpWidget( + new Directionality( + textDirection: TextDirection.ltr, + child: new FocusScope( + node: focusScopeNode, + child: new EditableText( + controller: controller, + focusNode: focusNode, + style: textStyle, + cursorColor: cursorColor, + ), + ), + ), + ); + + expect(semantics, includesNodeWith( + flags: [SemanticsFlags.isTextField], + value: value1, + )); + + const String value2 = 'Changed the EditableText content'; + controller.text = value2; + await tester.idle(); + await tester.pump(); + + expect(semantics, includesNodeWith( + flags: [SemanticsFlags.isTextField], + value: value2, + )); }); } diff --git a/packages/flutter/test/widgets/semantics_tester.dart b/packages/flutter/test/widgets/semantics_tester.dart index 16327034baa..02a2c024b9c 100644 --- a/packages/flutter/test/widgets/semantics_tester.dart +++ b/packages/flutter/test/widgets/semantics_tester.dart @@ -314,12 +314,14 @@ Matcher hasSemantics(TestSemantics semantics, { class _IncludesNodeWith extends Matcher { const _IncludesNodeWith({ this.label, + this.value, this.textDirection, this.actions, this.flags, -}) : assert(label != null || actions != null || flags != null); +}) : assert(label != null || value != null || actions != null || flags != null); final String label; + final String value; final TextDirection textDirection; final List actions; final List flags; @@ -344,6 +346,8 @@ class _IncludesNodeWith extends Matcher { bool checkNode(SemanticsNode node) { if (label != null && node.label != label) return false; + if (value != null && node.value != value) + return false; if (textDirection != null && node.textDirection != textDirection) return false; if (actions != null) { @@ -375,6 +379,8 @@ class _IncludesNodeWith extends Matcher { final List strings = []; if (label != null) strings.add('label "$label"'); + if (value != null) + strings.add('value "$value"'); if (textDirection != null) strings.add(' (${describeEnum(textDirection)})'); if (actions != null) @@ -391,12 +397,14 @@ class _IncludesNodeWith extends Matcher { /// If null is provided for an argument, it will match against any value. Matcher includesNodeWith({ String label, + String value, TextDirection textDirection, List actions, List flags, }) { return new _IncludesNodeWith( label: label, + value: value, textDirection: textDirection, actions: actions, flags: flags,