Unverified Commit fa3d2e21 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Remove nullOk parameter from Focus.of, FocusTraversalOrder.of, and FocusTraversalGroup.of (#68917)

This removes the nullOk parameter from Focus.of, FocusTraversalOrder.of and FocusTraversalGroup.of, and creates maybeOf equivalents for each. The of methods now return non-nullable values, and the maybeOf equivalents return nullable values.
parent 4fa5fe5f
...@@ -1513,7 +1513,7 @@ class DropdownButtonFormField<T> extends FormField<T> { ...@@ -1513,7 +1513,7 @@ class DropdownButtonFormField<T> extends FormField<T> {
return InputDecorator( return InputDecorator(
decoration: effectiveDecoration.copyWith(errorText: field.errorText), decoration: effectiveDecoration.copyWith(errorText: field.errorText),
isEmpty: state.value == null, isEmpty: state.value == null,
isFocused: Focus.of(context)!.hasFocus, isFocused: Focus.of(context).hasFocus,
child: DropdownButtonHideUnderline( child: DropdownButtonHideUnderline(
child: DropdownButton<T>( child: DropdownButton<T>(
items: items, items: items,
......
...@@ -143,7 +143,7 @@ class FocusAttachment { ...@@ -143,7 +143,7 @@ class FocusAttachment {
assert(_node != null); assert(_node != null);
if (isAttached) { if (isAttached) {
assert(_node.context != null); assert(_node.context != null);
parent ??= Focus.of(_node.context!, nullOk: true, scopeOk: true); parent ??= Focus.maybeOf(_node.context!, scopeOk: true);
parent ??= _node.context!.owner!.focusManager.rootScope; parent ??= _node.context!.owner!.focusManager.rootScope;
assert(parent != null); assert(parent != null);
parent._reparent(_node); parent._reparent(_node);
...@@ -1005,7 +1005,7 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier { ...@@ -1005,7 +1005,7 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
_manager?.primaryFocus?._setAsFocusedChildForScope(); _manager?.primaryFocus?._setAsFocusedChildForScope();
} }
if (oldScope != null && child.context != null && child.enclosingScope != oldScope) { if (oldScope != null && child.context != null && child.enclosingScope != oldScope) {
FocusTraversalGroup.of(child.context!, nullOk: true)?.changedScope(node: child, oldScope: oldScope); FocusTraversalGroup.maybeOf(child.context!)?.changedScope(node: child, oldScope: oldScope);
} }
if (child._requestFocusWhenReparented) { if (child._requestFocusWhenReparented) {
child._doRequestFocus(findFirstFocus: true); child._doRequestFocus(findFirstFocus: true);
...@@ -1145,19 +1145,19 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier { ...@@ -1145,19 +1145,19 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
/// [FocusTraversalPolicy.next] method. /// [FocusTraversalPolicy.next] method.
/// ///
/// Returns true if it successfully found a node and requested focus. /// Returns true if it successfully found a node and requested focus.
bool nextFocus() => FocusTraversalGroup.of(context!)!.next(this); bool nextFocus() => FocusTraversalGroup.of(context!).next(this);
/// Request to move the focus to the previous focus node, by calling the /// Request to move the focus to the previous focus node, by calling the
/// [FocusTraversalPolicy.previous] method. /// [FocusTraversalPolicy.previous] method.
/// ///
/// Returns true if it successfully found a node and requested focus. /// Returns true if it successfully found a node and requested focus.
bool previousFocus() => FocusTraversalGroup.of(context!)!.previous(this); bool previousFocus() => FocusTraversalGroup.of(context!).previous(this);
/// Request to move the focus to the nearest focus node in the given /// Request to move the focus to the nearest focus node in the given
/// direction, by calling the [FocusTraversalPolicy.inDirection] method. /// direction, by calling the [FocusTraversalPolicy.inDirection] method.
/// ///
/// Returns true if it successfully found a node and requested focus. /// Returns true if it successfully found a node and requested focus.
bool focusInDirection(TraversalDirection direction) => FocusTraversalGroup.of(context!)!.inDirection(this, direction); bool focusInDirection(TraversalDirection direction) => FocusTraversalGroup.of(context!).inDirection(this, direction);
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
......
...@@ -433,21 +433,24 @@ class Focus extends StatefulWidget { ...@@ -433,21 +433,24 @@ class Focus extends StatefulWidget {
/// ///
/// If no [Focus] node is found before reaching the nearest [FocusScope] /// If no [Focus] node is found before reaching the nearest [FocusScope]
/// widget, or there is no [Focus] widget in scope, then this method will /// widget, or there is no [Focus] widget in scope, then this method will
/// throw an exception. To return null instead of throwing, pass true for /// throw an exception.
/// [nullOk].
/// ///
/// The [context] and [nullOk] arguments must not be null. /// The `context` and `scopeOk` arguments must not be null.
/// ///
/// Calling this function creates a dependency that will rebuild the given /// Calling this function creates a dependency that will rebuild the given
/// context when the focus changes. /// context when the focus changes.
static FocusNode? of(BuildContext context, { bool nullOk = false, bool scopeOk = false }) { ///
/// See also:
///
/// * [maybeOf], which is similar to this function, but will return null
/// instead of throwing if it doesn't find a [Focus] node.
static FocusNode of(BuildContext context, { bool scopeOk = false }) {
assert(context != null); assert(context != null);
assert(nullOk != null);
assert(scopeOk != null); assert(scopeOk != null);
final _FocusMarker? marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>(); final _FocusMarker? marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>();
final FocusNode? node = marker?.notifier; final FocusNode? node = marker?.notifier;
assert(() {
if (node == null) { if (node == null) {
if (!nullOk) {
throw FlutterError( throw FlutterError(
'Focus.of() was called with a context that does not contain a Focus widget.\n' 'Focus.of() was called with a context that does not contain a Focus widget.\n'
'No Focus widget ancestor could be found starting from the context that was passed to ' 'No Focus widget ancestor could be found starting from the context that was passed to '
...@@ -457,10 +460,10 @@ class Focus extends StatefulWidget { ...@@ -457,10 +460,10 @@ class Focus extends StatefulWidget {
' $context' ' $context'
); );
} }
return null; return true;
} }());
assert(() {
if (!scopeOk && node is FocusScopeNode) { if (!scopeOk && node is FocusScopeNode) {
if (!nullOk) {
throw FlutterError( throw FlutterError(
'Focus.of() was called with a context that does not contain a Focus between the given ' 'Focus.of() was called with a context that does not contain a Focus between the given '
'context and the nearest FocusScope widget.\n' 'context and the nearest FocusScope widget.\n'
...@@ -472,6 +475,36 @@ class Focus extends StatefulWidget { ...@@ -472,6 +475,36 @@ class Focus extends StatefulWidget {
' $context' ' $context'
); );
} }
return true;
}());
return node!;
}
/// Returns the [focusNode] of the [Focus] that most tightly encloses the
/// given [BuildContext].
///
/// If no [Focus] node is found before reaching the nearest [FocusScope]
/// widget, or there is no [Focus] widget in scope, then this method will
/// return null.
///
/// The `context` and `scopeOk` arguments must not be null.
///
/// Calling this function creates a dependency that will rebuild the given
/// context when the focus changes.
///
/// See also:
///
/// * [of], which is similar to this function, but will throw an exception if
/// it doesn't find a [Focus] node instead of returning null.
static FocusNode? maybeOf(BuildContext context, { bool scopeOk = false }) {
assert(context != null);
assert(scopeOk != null);
final _FocusMarker? marker = context.dependOnInheritedWidgetOfExactType<_FocusMarker>();
final FocusNode? node = marker?.notifier;
if (node == null) {
return null;
}
if (!scopeOk && node is FocusScopeNode) {
return null; return null;
} }
return node; return node;
...@@ -489,7 +522,7 @@ class Focus extends StatefulWidget { ...@@ -489,7 +522,7 @@ class Focus extends StatefulWidget {
/// ///
/// Calling this function creates a dependency that will rebuild the given /// Calling this function creates a dependency that will rebuild the given
/// context when the focus changes. /// context when the focus changes.
static bool isAt(BuildContext context) => Focus.of(context, nullOk: true)?.hasFocus ?? false; static bool isAt(BuildContext context) => Focus.maybeOf(context)?.hasFocus ?? false;
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
......
...@@ -1363,7 +1363,7 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT ...@@ -1363,7 +1363,7 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT
final List<FocusNode> unordered = <FocusNode>[]; final List<FocusNode> unordered = <FocusNode>[];
final List<_OrderedFocusInfo> ordered = <_OrderedFocusInfo>[]; final List<_OrderedFocusInfo> ordered = <_OrderedFocusInfo>[];
for (final FocusNode node in sortedDescendants) { for (final FocusNode node in sortedDescendants) {
final FocusOrder? order = FocusTraversalOrder.of(node.context!, nullOk: true); final FocusOrder? order = FocusTraversalOrder.maybeOf(node.context!);
if (order != null) { if (order != null) {
ordered.add(_OrderedFocusInfo(node: node, order: order)); ordered.add(_OrderedFocusInfo(node: node, order: order));
} else { } else {
...@@ -1393,30 +1393,49 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT ...@@ -1393,30 +1393,49 @@ class OrderedTraversalPolicy extends FocusTraversalPolicy with DirectionalFocusT
/// [FocusTraversalOrder.of] for a particular context. /// [FocusTraversalOrder.of] for a particular context.
class FocusTraversalOrder extends InheritedWidget { class FocusTraversalOrder extends InheritedWidget {
/// A const constructor so that subclasses can be const. /// A const constructor so that subclasses can be const.
const FocusTraversalOrder({Key? key, this.order, required Widget child}) : super(key: key, child: child); const FocusTraversalOrder({Key? key, required this.order, required Widget child}) : super(key: key, child: child);
/// The order for the widget descendants of this [FocusTraversalOrder]. /// The order for the widget descendants of this [FocusTraversalOrder].
final FocusOrder? order; final FocusOrder order;
/// Finds the [FocusOrder] in the nearest ancestor [FocusTraversalOrder] widget. /// Finds the [FocusOrder] in the nearest ancestor [FocusTraversalOrder] widget.
/// ///
/// It does not create a rebuild dependency because changing the traversal /// It does not create a rebuild dependency because changing the traversal
/// order doesn't change the widget tree, so nothing needs to be rebuilt as a /// order doesn't change the widget tree, so nothing needs to be rebuilt as a
/// result of an order change. /// result of an order change.
static FocusOrder? of(BuildContext context, {bool nullOk = false}) { ///
/// If no [FocusTraversalOrder] ancestor exists, or the order is null, this
/// will assert in debug mode, and throw an exception in release mode.
static FocusOrder of(BuildContext context) {
assert(context != null); assert(context != null);
assert(nullOk != null);
final FocusTraversalOrder? marker = context.getElementForInheritedWidgetOfExactType<FocusTraversalOrder>()?.widget as FocusTraversalOrder?; final FocusTraversalOrder? marker = context.getElementForInheritedWidgetOfExactType<FocusTraversalOrder>()?.widget as FocusTraversalOrder?;
final FocusOrder? order = marker?.order; assert((){
if (order == null && !nullOk) { if (marker == null) {
throw FlutterError('FocusTraversalOrder.of() was called with a context that ' throw FlutterError(
'does not contain a TraversalOrder widget. No TraversalOrder widget ' 'FocusTraversalOrder.of() was called with a context that '
'does not contain a FocusTraversalOrder widget. No TraversalOrder widget '
'ancestor could be found starting from the context that was passed to ' 'ancestor could be found starting from the context that was passed to '
'FocusTraversalOrder.of().\n' 'FocusTraversalOrder.of().\n'
'The context used was:\n' 'The context used was:\n'
' $context'); ' $context',
);
} }
return order; return true;
}());
return marker!.order;
}
/// Finds the [FocusOrder] in the nearest ancestor [FocusTraversalOrder] widget.
///
/// It does not create a rebuild dependency because changing the traversal
/// order doesn't change the widget tree, so nothing needs to be rebuilt as a
/// result of an order change.
///
/// If no [FocusTraversalOrder] ancestor exists, or the order is null, returns null.
static FocusOrder? maybeOf(BuildContext context) {
assert(context != null);
final FocusTraversalOrder? marker = context.getElementForInheritedWidgetOfExactType<FocusTraversalOrder>()?.widget as FocusTraversalOrder?;
return marker?.order;
} }
// Since the order of traversal doesn't affect display of anything, we don't // Since the order of traversal doesn't affect display of anything, we don't
...@@ -1670,17 +1689,16 @@ class FocusTraversalGroup extends StatefulWidget { ...@@ -1670,17 +1689,16 @@ class FocusTraversalGroup extends StatefulWidget {
/// order doesn't change the widget tree, so nothing needs to be rebuilt as a /// order doesn't change the widget tree, so nothing needs to be rebuilt as a
/// result of an order change. /// result of an order change.
/// ///
/// Will assert if no [FocusTraversalGroup] ancestor is found, and `nullOk` is false. /// Will assert if no [FocusTraversalGroup] ancestor is found.
/// ///
/// If `nullOk` is true, then it will return null if it doesn't find a /// See also:
/// [FocusTraversalGroup] ancestor. ///
static FocusTraversalPolicy? of(BuildContext context, {bool nullOk = false}) { /// * [maybeOf] for a similar function that will return null if no
/// [FocusTraversalGroup] ancestor is found.
static FocusTraversalPolicy of(BuildContext context) {
assert(context != null); assert(context != null);
final _FocusTraversalGroupMarker? inherited = context.dependOnInheritedWidgetOfExactType<_FocusTraversalGroupMarker>(); final _FocusTraversalGroupMarker? inherited = context.dependOnInheritedWidgetOfExactType<_FocusTraversalGroupMarker>();
assert(() { assert(() {
if (nullOk) {
return true;
}
if (inherited == null) { if (inherited == null) {
throw FlutterError( throw FlutterError(
'Unable to find a FocusTraversalGroup widget in the context.\n' 'Unable to find a FocusTraversalGroup widget in the context.\n'
...@@ -1696,6 +1714,25 @@ class FocusTraversalGroup extends StatefulWidget { ...@@ -1696,6 +1714,25 @@ class FocusTraversalGroup extends StatefulWidget {
} }
return true; return true;
}()); }());
return inherited!.policy;
}
/// Returns the focus policy set by the [FocusTraversalGroup] that most
/// tightly encloses the given [BuildContext].
///
/// It does not create a rebuild dependency because changing the traversal
/// order doesn't change the widget tree, so nothing needs to be rebuilt as a
/// result of an order change.
///
/// Will return null if it doesn't find a [FocusTraversalGroup] ancestor.
///
/// See also:
///
/// * [of] for a similar function that will throw if no [FocusTraversalGroup]
/// ancestor is found.
static FocusTraversalPolicy? maybeOf(BuildContext context) {
assert(context != null);
final _FocusTraversalGroupMarker? inherited = context.dependOnInheritedWidgetOfExactType<_FocusTraversalGroupMarker>();
return inherited?.policy; return inherited?.policy;
} }
......
...@@ -98,7 +98,7 @@ void main() { ...@@ -98,7 +98,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isTrue); expect(Focus.maybeOf(childKey.currentContext!)!.hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
wrap( wrap(
...@@ -112,7 +112,7 @@ void main() { ...@@ -112,7 +112,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isFalse); expect(Focus.maybeOf(childKey.currentContext!)!.hasPrimaryFocus, isFalse);
}); });
testWidgets('CheckboxListTile contentPadding test', (WidgetTester tester) async { testWidgets('CheckboxListTile contentPadding test', (WidgetTester tester) async {
......
...@@ -2328,7 +2328,7 @@ void main() { ...@@ -2328,7 +2328,7 @@ void main() {
await tester.pump(); await tester.pump();
await tester.pump(const Duration(seconds: 1)); // finish the menu open animation await tester.pump(const Duration(seconds: 1)); // finish the menu open animation
expect(value, equals('one')); expect(value, equals('one'));
expect(Focus.of(tester.element(find.byKey(const ValueKey<String>('one')).last))!.hasPrimaryFocus, isTrue); expect(Focus.of(tester.element(find.byKey(const ValueKey<String>('one')).last)).hasPrimaryFocus, isTrue);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Focus 'two' await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Focus 'two'
await tester.pump(); await tester.pump();
...@@ -2345,7 +2345,7 @@ void main() { ...@@ -2345,7 +2345,7 @@ void main() {
await tester.pump(const Duration(seconds: 1)); // finish the menu open animation await tester.pump(const Duration(seconds: 1)); // finish the menu open animation
expect(value, equals('two')); expect(value, equals('two'));
final Element element = tester.element(find.byKey(const ValueKey<String>('two')).last); final Element element = tester.element(find.byKey(const ValueKey<String>('two')).last);
final FocusNode node = Focus.of(element)!; final FocusNode node = Focus.of(element);
expect(node.hasFocus, isTrue); expect(node.hasFocus, isTrue);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320
...@@ -2392,7 +2392,7 @@ void main() { ...@@ -2392,7 +2392,7 @@ void main() {
await tester.pump(); await tester.pump();
await tester.pump(const Duration(seconds: 1)); // finish the menu open animation await tester.pump(const Duration(seconds: 1)); // finish the menu open animation
expect(value, equals(1)); expect(value, equals(1));
expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(1)).last))!.hasPrimaryFocus, isTrue); expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(1)).last)).hasPrimaryFocus, isTrue);
for (int i = 0; i < 41; ++i) { for (int i = 0; i < 41; ++i) {
await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one. await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one.
...@@ -2408,7 +2408,7 @@ void main() { ...@@ -2408,7 +2408,7 @@ void main() {
await tester.pump(const Duration(seconds: 1)); // finish the menu open animation await tester.pump(const Duration(seconds: 1)); // finish the menu open animation
expect(value, equals(42)); expect(value, equals(42));
final Element element = tester.element(find.byKey(const ValueKey<int>(42)).last); final Element element = tester.element(find.byKey(const ValueKey<int>(42)).last);
final FocusNode node = Focus.of(element)!; final FocusNode node = Focus.of(element);
expect(node.hasFocus, isTrue); expect(node.hasFocus, isTrue);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320
...@@ -2454,14 +2454,14 @@ void main() { ...@@ -2454,14 +2454,14 @@ void main() {
await tester.sendKeyEvent(LogicalKeyboardKey.enter); await tester.sendKeyEvent(LogicalKeyboardKey.enter);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(value, equals(1)); expect(value, equals(1));
expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(1)).last))!.hasPrimaryFocus, isTrue); expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(1)).last)).hasPrimaryFocus, isTrue);
// Move to an item very far down the menu. // Move to an item very far down the menu.
for (int i = 0; i < 90; ++i) { for (int i = 0; i < 90; ++i) {
await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one. await tester.sendKeyEvent(LogicalKeyboardKey.tab); // Move to the next one.
await tester.pumpAndSettle(); // Wait for it to animate the menu. await tester.pumpAndSettle(); // Wait for it to animate the menu.
} }
expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(91)).last))!.hasPrimaryFocus, isTrue); expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(91)).last)).hasPrimaryFocus, isTrue);
// Scroll back to the top using touch, and make sure we end up there. // Scroll back to the top using touch, and make sure we end up there.
final Finder menu = find.byWidgetPredicate((Widget widget) { final Finder menu = find.byWidgetPredicate((Widget widget) {
...@@ -2483,7 +2483,7 @@ void main() { ...@@ -2483,7 +2483,7 @@ void main() {
// Scrolling to the top again has removed the one the focus was on from the // Scrolling to the top again has removed the one the focus was on from the
// tree, causing it to lose focus. // tree, causing it to lose focus.
expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(91)).last))!.hasPrimaryFocus, isFalse); expect(Focus.of(tester.element(find.byKey(const ValueKey<int>(91)).last)).hasPrimaryFocus, isFalse);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/55320
testWidgets('DropdownButton onTap callback is called when defined', (WidgetTester tester) async { testWidgets('DropdownButton onTap callback is called when defined', (WidgetTester tester) async {
......
...@@ -1173,10 +1173,10 @@ void main() { ...@@ -1173,10 +1173,10 @@ void main() {
); );
await tester.pump(); // Let the focus take effect. await tester.pump(); // Let the focus take effect.
final FocusNode? tileNode = Focus.of(childKey.currentContext!); final FocusNode tileNode = Focus.of(childKey.currentContext!);
tileNode!.requestFocus(); tileNode.requestFocus();
await tester.pump(); // Let the focus take effect. await tester.pump(); // Let the focus take effect.
expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isTrue); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue);
expect(tileNode.hasPrimaryFocus, isTrue); expect(tileNode.hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1197,7 +1197,7 @@ void main() { ...@@ -1197,7 +1197,7 @@ void main() {
); );
expect(tester.binding.focusManager.primaryFocus, isNot(equals(tileNode))); expect(tester.binding.focusManager.primaryFocus, isNot(equals(tileNode)));
expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse);
}); });
testWidgets('ListTile can autofocus unless disabled.', (WidgetTester tester) async { testWidgets('ListTile can autofocus unless disabled.', (WidgetTester tester) async {
...@@ -1222,7 +1222,7 @@ void main() { ...@@ -1222,7 +1222,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isTrue); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1243,7 +1243,7 @@ void main() { ...@@ -1243,7 +1243,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!, nullOk: true)!.hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse);
}); });
testWidgets('ListTile is focusable and has correct focus color', (WidgetTester tester) async { testWidgets('ListTile is focusable and has correct focus color', (WidgetTester tester) async {
......
...@@ -189,7 +189,7 @@ void main() { ...@@ -189,7 +189,7 @@ void main() {
await tester.pumpWidget(buildApp(directional: true)); await tester.pumpWidget(buildApp(directional: true));
// Try to bring up the popup menu and select the first item from it // Try to bring up the popup menu and select the first item from it
Focus.of(popupButtonKey.currentContext!)!.requestFocus(); Focus.of(popupButtonKey.currentContext!).requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await tester.tap(find.byKey(popupButtonKey)); await tester.tap(find.byKey(popupButtonKey));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -238,10 +238,10 @@ void main() { ...@@ -238,10 +238,10 @@ void main() {
), ),
), ),
); );
Focus.of(childKey.currentContext!)!.requestFocus(); Focus.of(childKey.currentContext!).requestFocus();
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse);
expect(itemBuilderCalled, isFalse); expect(itemBuilderCalled, isFalse);
expect(onSelectedCalled, isFalse); expect(onSelectedCalled, isFalse);
}); });
...@@ -281,10 +281,10 @@ void main() { ...@@ -281,10 +281,10 @@ void main() {
}), }),
), ),
); );
Focus.of(childKey.currentContext!)!.requestFocus(); Focus.of(childKey.currentContext!).requestFocus();
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue);
}); });
testWidgets('PopupMenuItem is only focusable when enabled', (WidgetTester tester) async { testWidgets('PopupMenuItem is only focusable when enabled', (WidgetTester tester) async {
...@@ -319,7 +319,7 @@ void main() { ...@@ -319,7 +319,7 @@ void main() {
// Open the popup to build and show the menu contents. // Open the popup to build and show the menu contents.
await tester.tap(find.byKey(popupButtonKey)); await tester.tap(find.byKey(popupButtonKey));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final FocusNode childNode = Focus.of(childKey.currentContext!)!; final FocusNode childNode = Focus.of(childKey.currentContext!);
// Now that the contents are shown, request focus on the child text. // Now that the contents are shown, request focus on the child text.
childNode.requestFocus(); childNode.requestFocus();
await tester.pumpAndSettle(); await tester.pumpAndSettle();
...@@ -362,7 +362,7 @@ void main() { ...@@ -362,7 +362,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(itemBuilderCalled, isTrue); expect(itemBuilderCalled, isTrue);
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse);
}); });
testWidgets('PopupMenuButton is horizontal on iOS', (WidgetTester tester) async { testWidgets('PopupMenuButton is horizontal on iOS', (WidgetTester tester) async {
......
...@@ -589,7 +589,7 @@ void main() { ...@@ -589,7 +589,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
wrap( wrap(
...@@ -604,7 +604,7 @@ void main() { ...@@ -604,7 +604,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse);
}); });
testWidgets('RadioListTile contentPadding test', (WidgetTester tester) async { testWidgets('RadioListTile contentPadding test', (WidgetTester tester) async {
......
...@@ -624,7 +624,7 @@ void main() { ...@@ -624,7 +624,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
final FocusNode disabledNode = Focus.of(tester.element(find.text('Step 0')), nullOk: true, scopeOk: true)!; final FocusNode disabledNode = Focus.of(tester.element(find.text('Step 0')), scopeOk: true);
disabledNode.requestFocus(); disabledNode.requestFocus();
await tester.pump(); await tester.pump();
expect(disabledNode.hasPrimaryFocus, isFalse); expect(disabledNode.hasPrimaryFocus, isFalse);
...@@ -650,7 +650,7 @@ void main() { ...@@ -650,7 +650,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
final FocusNode disabledNode = Focus.of(tester.element(find.text('Step 0')), nullOk: true, scopeOk: true)!; final FocusNode disabledNode = Focus.of(tester.element(find.text('Step 0')), scopeOk: true);
disabledNode.requestFocus(); disabledNode.requestFocus();
await tester.pump(); await tester.pump();
expect(disabledNode.hasPrimaryFocus, isFalse); expect(disabledNode.hasPrimaryFocus, isFalse);
......
...@@ -276,7 +276,7 @@ void main() { ...@@ -276,7 +276,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -296,7 +296,7 @@ void main() { ...@@ -296,7 +296,7 @@ void main() {
); );
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext!)!.hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext!).hasPrimaryFocus, isFalse);
}); });
testWidgets('SwitchListTile controlAffinity test', (WidgetTester tester) async { testWidgets('SwitchListTile controlAffinity test', (WidgetTester tester) async {
......
...@@ -1597,8 +1597,8 @@ void main() { ...@@ -1597,8 +1597,8 @@ void main() {
await tester.testTextInput.receiveAction(action); await tester.testTextInput.receiveAction(action);
await tester.pump(); await tester.pump();
expect(Focus.of(nextKey.currentContext!)!.hasFocus, equals(shouldFocusNext)); expect(Focus.of(nextKey.currentContext!).hasFocus, equals(shouldFocusNext));
expect(Focus.of(previousKey.currentContext!)!.hasFocus, equals(shouldFocusPrevious)); expect(Focus.of(previousKey.currentContext!).hasFocus, equals(shouldFocusPrevious));
expect(focusNode.hasFocus, equals(!shouldLoseFocus)); expect(focusNode.hasFocus, equals(!shouldLoseFocus));
} }
......
...@@ -1117,12 +1117,12 @@ void main() { ...@@ -1117,12 +1117,12 @@ void main() {
final Element element6 = tester.element(find.byKey(key6)); final Element element6 = tester.element(find.byKey(key6));
final FocusNode root = element1.owner!.focusManager.rootScope; final FocusNode root = element1.owner!.focusManager.rootScope;
expect(Focus.of(element1, nullOk: true), isNull); expect(Focus.maybeOf(element1), isNull);
expect(Focus.of(element2, nullOk: true), isNull); expect(Focus.maybeOf(element2), isNull);
expect(Focus.of(element3, nullOk: true), isNull); expect(Focus.maybeOf(element3), isNull);
expect(Focus.of(element4)!.parent!.parent, equals(root)); expect(Focus.of(element4).parent!.parent, equals(root));
expect(Focus.of(element5)!.parent!.parent, equals(root)); expect(Focus.of(element5).parent!.parent, equals(root));
expect(Focus.of(element6)!.parent!.parent!.parent, equals(root)); expect(Focus.of(element6).parent!.parent!.parent, equals(root));
}); });
testWidgets('Can traverse Focus children.', (WidgetTester tester) async { testWidgets('Can traverse Focus children.', (WidgetTester tester) async {
final GlobalKey key1 = GlobalKey(debugLabel: '1'); final GlobalKey key1 = GlobalKey(debugLabel: '1');
...@@ -1187,7 +1187,7 @@ void main() { ...@@ -1187,7 +1187,7 @@ void main() {
await tester.pump(); await tester.pump();
Focus.of(firstScope)!.descendants.forEach(visitor); Focus.of(firstScope).descendants.forEach(visitor);
expect(nodes.length, equals(7)); expect(nodes.length, equals(7));
expect(keys.length, equals(7)); expect(keys.length, equals(7));
// Depth first. // Depth first.
...@@ -1197,7 +1197,7 @@ void main() { ...@@ -1197,7 +1197,7 @@ void main() {
final Element secondScope = tester.element(find.byKey(key7)); final Element secondScope = tester.element(find.byKey(key7));
nodes.clear(); nodes.clear();
keys.clear(); keys.clear();
Focus.of(secondScope)!.descendants.forEach(visitor); Focus.of(secondScope).descendants.forEach(visitor);
expect(nodes.length, equals(2)); expect(nodes.length, equals(2));
expect(keys, equals(<Key>[key7, key8])); expect(keys, equals(<Key>[key7, key8]));
}); });
...@@ -1213,7 +1213,7 @@ void main() { ...@@ -1213,7 +1213,7 @@ void main() {
); );
final Element firstNode = tester.element(find.byKey(key1)); final Element firstNode = tester.element(find.byKey(key1));
final FocusNode node = Focus.of(firstNode)!; final FocusNode node = Focus.of(firstNode);
node.requestFocus(); node.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1234,7 +1234,7 @@ void main() { ...@@ -1234,7 +1234,7 @@ void main() {
); );
final Element firstNode = tester.element(find.byKey(key1)); final Element firstNode = tester.element(find.byKey(key1));
final FocusNode node = Focus.of(firstNode)!; final FocusNode node = Focus.of(firstNode);
node.requestFocus(); node.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1256,7 +1256,7 @@ void main() { ...@@ -1256,7 +1256,7 @@ void main() {
); );
Element firstNode = tester.element(find.byKey(key1)); Element firstNode = tester.element(find.byKey(key1));
FocusNode node = Focus.of(firstNode)!; FocusNode node = Focus.of(firstNode);
node.requestFocus(); node.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1274,7 +1274,7 @@ void main() { ...@@ -1274,7 +1274,7 @@ void main() {
); );
firstNode = tester.element(find.byKey(key1)); firstNode = tester.element(find.byKey(key1));
node = Focus.of(firstNode)!; node = Focus.of(firstNode);
node.requestFocus(); node.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1297,7 +1297,7 @@ void main() { ...@@ -1297,7 +1297,7 @@ void main() {
); );
final Element childWidget = tester.element(find.byKey(key1)); final Element childWidget = tester.element(find.byKey(key1));
final FocusNode unfocusableNode = Focus.of(childWidget)!; final FocusNode unfocusableNode = Focus.of(childWidget);
unfocusableNode.requestFocus(); unfocusableNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1306,7 +1306,7 @@ void main() { ...@@ -1306,7 +1306,7 @@ void main() {
expect(unfocusableNode.hasFocus, isFalse); expect(unfocusableNode.hasFocus, isFalse);
final Element containerWidget = tester.element(find.byKey(key2)); final Element containerWidget = tester.element(find.byKey(key2));
final FocusNode focusableNode = Focus.of(containerWidget)!; final FocusNode focusableNode = Focus.of(containerWidget);
focusableNode.requestFocus(); focusableNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1328,7 +1328,7 @@ void main() { ...@@ -1328,7 +1328,7 @@ void main() {
); );
final Element firstNode = tester.element(find.byKey(key1)); final Element firstNode = tester.element(find.byKey(key1));
final FocusNode node = Focus.of(firstNode)!; final FocusNode node = Focus.of(firstNode);
node.requestFocus(); node.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1425,75 +1425,75 @@ void main() { ...@@ -1425,75 +1425,75 @@ void main() {
// Check childless node (focus2). // Check childless node (focus2).
await pumpTest(); await pumpTest();
Focus.of(container1.currentContext!)!.requestFocus(); Focus.of(container1.currentContext!).requestFocus();
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); expect(Focus.of(container1.currentContext!).hasFocus, isTrue);
await pumpTest(allowFocus2: false); await pumpTest(allowFocus2: false);
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
Focus.of(container1.currentContext!)!.requestFocus(); Focus.of(container1.currentContext!).requestFocus();
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
await pumpTest(); await pumpTest();
Focus.of(container1.currentContext!)!.requestFocus(); Focus.of(container1.currentContext!).requestFocus();
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); expect(Focus.of(container1.currentContext!).hasFocus, isTrue);
// Check FocusNode with child (focus1). Shouldn't affect children. // Check FocusNode with child (focus1). Shouldn't affect children.
await pumpTest(allowFocus1: false); await pumpTest(allowFocus1: false);
expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); // focus2 has focus. expect(Focus.of(container1.currentContext!).hasFocus, isTrue); // focus2 has focus.
Focus.of(focus2.currentContext!)!.requestFocus(); // Try to focus focus1 Focus.of(focus2.currentContext!).requestFocus(); // Try to focus focus1
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); // focus2 still has focus. expect(Focus.of(container1.currentContext!).hasFocus, isTrue); // focus2 still has focus.
Focus.of(container1.currentContext!)!.requestFocus(); // Now try to focus focus2 Focus.of(container1.currentContext!).requestFocus(); // Now try to focus focus2
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); expect(Focus.of(container1.currentContext!).hasFocus, isTrue);
await pumpTest(); await pumpTest();
// Try again, now that we've set focus1's canRequestFocus to true again. // Try again, now that we've set focus1's canRequestFocus to true again.
Focus.of(container1.currentContext!)!.unfocus(); Focus.of(container1.currentContext!).unfocus();
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
Focus.of(container1.currentContext!)!.requestFocus(); Focus.of(container1.currentContext!).requestFocus();
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); expect(Focus.of(container1.currentContext!).hasFocus, isTrue);
// Check FocusScopeNode with only FocusNode children (scope2). Should affect children. // Check FocusScopeNode with only FocusNode children (scope2). Should affect children.
await pumpTest(allowScope2: false); await pumpTest(allowScope2: false);
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
FocusScope.of(focus1.currentContext!).requestFocus(); // Try to focus scope2 FocusScope.of(focus1.currentContext!).requestFocus(); // Try to focus scope2
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
Focus.of(focus2.currentContext!)!.requestFocus(); // Try to focus focus1 Focus.of(focus2.currentContext!).requestFocus(); // Try to focus focus1
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
Focus.of(container1.currentContext!)!.requestFocus(); // Try to focus focus2 Focus.of(container1.currentContext!).requestFocus(); // Try to focus focus2
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
await pumpTest(); await pumpTest();
// Try again, now that we've set scope2's canRequestFocus to true again. // Try again, now that we've set scope2's canRequestFocus to true again.
Focus.of(container1.currentContext!)!.requestFocus(); Focus.of(container1.currentContext!).requestFocus();
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); expect(Focus.of(container1.currentContext!).hasFocus, isTrue);
// Check FocusScopeNode with both FocusNode children and FocusScope children (scope1). Should affect children. // Check FocusScopeNode with both FocusNode children and FocusScope children (scope1). Should affect children.
await pumpTest(allowScope1: false); await pumpTest(allowScope1: false);
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
FocusScope.of(scope2.currentContext!).requestFocus(); // Try to focus scope1 FocusScope.of(scope2.currentContext!).requestFocus(); // Try to focus scope1
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
FocusScope.of(focus1.currentContext!).requestFocus(); // Try to focus scope2 FocusScope.of(focus1.currentContext!).requestFocus(); // Try to focus scope2
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
Focus.of(focus2.currentContext!)!.requestFocus(); // Try to focus focus1 Focus.of(focus2.currentContext!).requestFocus(); // Try to focus focus1
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
Focus.of(container1.currentContext!)!.requestFocus(); // Try to focus focus2 Focus.of(container1.currentContext!).requestFocus(); // Try to focus focus2
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isFalse); expect(Focus.of(container1.currentContext!).hasFocus, isFalse);
await pumpTest(); await pumpTest();
// Try again, now that we've set scope1's canRequestFocus to true again. // Try again, now that we've set scope1's canRequestFocus to true again.
Focus.of(container1.currentContext!)!.requestFocus(); Focus.of(container1.currentContext!).requestFocus();
await tester.pump(); await tester.pump();
expect(Focus.of(container1.currentContext!)!.hasFocus, isTrue); expect(Focus.of(container1.currentContext!).hasFocus, isTrue);
}); });
testWidgets('skipTraversal works as expected.', (WidgetTester tester) async { testWidgets('skipTraversal works as expected.', (WidgetTester tester) async {
...@@ -1569,9 +1569,9 @@ void main() { ...@@ -1569,9 +1569,9 @@ void main() {
); );
final Element childWidget = tester.element(find.byKey(key1)); final Element childWidget = tester.element(find.byKey(key1));
final FocusNode unfocusableNode = Focus.of(childWidget)!; final FocusNode unfocusableNode = Focus.of(childWidget);
final Element containerWidget = tester.element(find.byKey(key2)); final Element containerWidget = tester.element(find.byKey(key2));
final FocusNode containerNode = Focus.of(containerWidget)!; final FocusNode containerNode = Focus.of(containerWidget);
unfocusableNode.requestFocus(); unfocusableNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1615,9 +1615,9 @@ void main() { ...@@ -1615,9 +1615,9 @@ void main() {
); );
final Element childWidget = tester.element(find.byKey(key1)); final Element childWidget = tester.element(find.byKey(key1));
final FocusNode unfocusableNode = Focus.of(childWidget)!; final FocusNode unfocusableNode = Focus.of(childWidget);
final Element containerWidget = tester.element(find.byKey(key2)); final Element containerWidget = tester.element(find.byKey(key2));
final FocusNode containerNode = Focus.of(containerWidget)!; final FocusNode containerNode = Focus.of(containerWidget);
unfocusableNode.requestFocus(); unfocusableNode.requestFocus();
await tester.pump(); await tester.pump();
......
...@@ -53,9 +53,9 @@ void main() { ...@@ -53,9 +53,9 @@ void main() {
final Element firstChild = tester.element(find.byKey(key3)); final Element firstChild = tester.element(find.byKey(key3));
final Element secondChild = tester.element(find.byKey(key5)); final Element secondChild = tester.element(find.byKey(key5));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
secondFocusNode.nextFocus(); secondFocusNode.nextFocus();
await tester.pump(); await tester.pump();
...@@ -92,9 +92,9 @@ void main() { ...@@ -92,9 +92,9 @@ void main() {
final Element firstChild = tester.element(find.byKey(key3)); final Element firstChild = tester.element(find.byKey(key3));
final Element secondChild = tester.element(find.byKey(key5)); final Element secondChild = tester.element(find.byKey(key5));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
expect(firstFocusNode.hasFocus, isFalse); expect(firstFocusNode.hasFocus, isFalse);
expect(secondFocusNode.hasFocus, isFalse); expect(secondFocusNode.hasFocus, isFalse);
...@@ -157,9 +157,9 @@ void main() { ...@@ -157,9 +157,9 @@ void main() {
final Element firstChild = tester.element(find.byKey(key4)); final Element firstChild = tester.element(find.byKey(key4));
final Element secondChild = tester.element(find.byKey(key6)); final Element secondChild = tester.element(find.byKey(key6));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
firstFocusNode.requestFocus(); firstFocusNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -177,7 +177,7 @@ void main() { ...@@ -177,7 +177,7 @@ void main() {
focus3 = null; focus3 = null;
focus5 = null; focus5 = null;
Focus.of(firstChild)!.nextFocus(); Focus.of(firstChild).nextFocus();
await tester.pump(); await tester.pump();
...@@ -194,7 +194,7 @@ void main() { ...@@ -194,7 +194,7 @@ void main() {
focus3 = null; focus3 = null;
focus5 = null; focus5 = null;
Focus.of(firstChild)!.nextFocus(); Focus.of(firstChild).nextFocus();
await tester.pump(); await tester.pump();
...@@ -212,7 +212,7 @@ void main() { ...@@ -212,7 +212,7 @@ void main() {
focus5 = null; focus5 = null;
// Tests that can still move back to original node. // Tests that can still move back to original node.
Focus.of(firstChild)!.previousFocus(); Focus.of(firstChild).previousFocus();
await tester.pump(); await tester.pump();
...@@ -262,9 +262,9 @@ void main() { ...@@ -262,9 +262,9 @@ void main() {
final Element firstChild = tester.element(find.byKey(key4)); final Element firstChild = tester.element(find.byKey(key4));
final Element secondChild = tester.element(find.byKey(key6)); final Element secondChild = tester.element(find.byKey(key6));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
secondFocusNode.requestFocus(); secondFocusNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -273,7 +273,7 @@ void main() { ...@@ -273,7 +273,7 @@ void main() {
expect(secondFocusNode.hasFocus, isTrue); expect(secondFocusNode.hasFocus, isTrue);
expect(scope.hasFocus, isTrue); expect(scope.hasFocus, isTrue);
Focus.of(firstChild)!.previousFocus(); Focus.of(firstChild).previousFocus();
await tester.pump(); await tester.pump();
...@@ -281,7 +281,7 @@ void main() { ...@@ -281,7 +281,7 @@ void main() {
expect(secondFocusNode.hasFocus, isFalse); expect(secondFocusNode.hasFocus, isFalse);
expect(scope.hasFocus, isTrue); expect(scope.hasFocus, isTrue);
Focus.of(firstChild)!.previousFocus(); Focus.of(firstChild).previousFocus();
await tester.pump(); await tester.pump();
...@@ -290,7 +290,7 @@ void main() { ...@@ -290,7 +290,7 @@ void main() {
expect(scope.hasFocus, isTrue); expect(scope.hasFocus, isTrue);
// Tests that can still move back to original node. // Tests that can still move back to original node.
Focus.of(firstChild)!.nextFocus(); Focus.of(firstChild).nextFocus();
await tester.pump(); await tester.pump();
...@@ -376,8 +376,8 @@ void main() { ...@@ -376,8 +376,8 @@ void main() {
); );
final Element firstChild = tester.element(find.text('Go Forward')); final Element firstChild = tester.element(find.text('Go Forward'));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
await tester.pump(); await tester.pump();
expect(firstFocusNode.hasFocus, isTrue); expect(firstFocusNode.hasFocus, isTrue);
...@@ -387,7 +387,7 @@ void main() { ...@@ -387,7 +387,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final Element secondChild = tester.element(find.text('Go Back')); final Element secondChild = tester.element(find.text('Go Back'));
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
expect(firstFocusNode.hasFocus, isFalse); expect(firstFocusNode.hasFocus, isFalse);
expect(secondFocusNode.hasFocus, isTrue); expect(secondFocusNode.hasFocus, isTrue);
...@@ -428,9 +428,9 @@ void main() { ...@@ -428,9 +428,9 @@ void main() {
final Element firstChild = tester.element(find.byKey(key3)); final Element firstChild = tester.element(find.byKey(key3));
final Element secondChild = tester.element(find.byKey(key5)); final Element secondChild = tester.element(find.byKey(key5));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
secondFocusNode.nextFocus(); secondFocusNode.nextFocus();
await tester.pump(); await tester.pump();
...@@ -499,9 +499,9 @@ void main() { ...@@ -499,9 +499,9 @@ void main() {
final Element firstChild = tester.element(find.byKey(key4)); final Element firstChild = tester.element(find.byKey(key4));
final Element secondChild = tester.element(find.byKey(key6)); final Element secondChild = tester.element(find.byKey(key6));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
firstFocusNode.requestFocus(); firstFocusNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -515,7 +515,7 @@ void main() { ...@@ -515,7 +515,7 @@ void main() {
expect(scope.hasFocus, isTrue); expect(scope.hasFocus, isTrue);
clear(); clear();
Focus.of(firstChild)!.nextFocus(); Focus.of(firstChild).nextFocus();
await tester.pump(); await tester.pump();
...@@ -528,7 +528,7 @@ void main() { ...@@ -528,7 +528,7 @@ void main() {
expect(scope.hasFocus, isTrue); expect(scope.hasFocus, isTrue);
clear(); clear();
Focus.of(firstChild)!.nextFocus(); Focus.of(firstChild).nextFocus();
await tester.pump(); await tester.pump();
...@@ -542,7 +542,7 @@ void main() { ...@@ -542,7 +542,7 @@ void main() {
clear(); clear();
// Tests that can still move back to original node. // Tests that can still move back to original node.
Focus.of(firstChild)!.previousFocus(); Focus.of(firstChild).previousFocus();
await tester.pump(); await tester.pump();
...@@ -592,9 +592,9 @@ void main() { ...@@ -592,9 +592,9 @@ void main() {
final Element firstChild = tester.element(find.byKey(key4)); final Element firstChild = tester.element(find.byKey(key4));
final Element secondChild = tester.element(find.byKey(key6)); final Element secondChild = tester.element(find.byKey(key6));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
secondFocusNode.requestFocus(); secondFocusNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -603,7 +603,7 @@ void main() { ...@@ -603,7 +603,7 @@ void main() {
expect(secondFocusNode.hasFocus, isTrue); expect(secondFocusNode.hasFocus, isTrue);
expect(scope.hasFocus, isTrue); expect(scope.hasFocus, isTrue);
Focus.of(firstChild)!.previousFocus(); Focus.of(firstChild).previousFocus();
await tester.pump(); await tester.pump();
...@@ -611,7 +611,7 @@ void main() { ...@@ -611,7 +611,7 @@ void main() {
expect(secondFocusNode.hasFocus, isFalse); expect(secondFocusNode.hasFocus, isFalse);
expect(scope.hasFocus, isTrue); expect(scope.hasFocus, isTrue);
Focus.of(firstChild)!.previousFocus(); Focus.of(firstChild).previousFocus();
await tester.pump(); await tester.pump();
...@@ -620,7 +620,7 @@ void main() { ...@@ -620,7 +620,7 @@ void main() {
expect(scope.hasFocus, isTrue); expect(scope.hasFocus, isTrue);
// Tests that can still move back to original node. // Tests that can still move back to original node.
Focus.of(firstChild)!.nextFocus(); Focus.of(firstChild).nextFocus();
await tester.pump(); await tester.pump();
...@@ -867,9 +867,9 @@ void main() { ...@@ -867,9 +867,9 @@ void main() {
final Element firstChild = tester.element(find.byKey(key1)); final Element firstChild = tester.element(find.byKey(key1));
final Element secondChild = tester.element(find.byKey(key2)); final Element secondChild = tester.element(find.byKey(key2));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
secondFocusNode.nextFocus(); secondFocusNode.nextFocus();
await tester.pump(); await tester.pump();
...@@ -1179,8 +1179,8 @@ void main() { ...@@ -1179,8 +1179,8 @@ void main() {
); );
final Element firstChild = tester.element(find.text('Go Forward')); final Element firstChild = tester.element(find.text('Go Forward'));
final FocusNode firstFocusNode = Focus.of(firstChild)!; final FocusNode firstFocusNode = Focus.of(firstChild);
final FocusNode scope = Focus.of(firstChild)!.enclosingScope!; final FocusNode scope = Focus.of(firstChild).enclosingScope!;
await tester.pump(); await tester.pump();
expect(firstFocusNode.hasFocus, isTrue); expect(firstFocusNode.hasFocus, isTrue);
...@@ -1190,7 +1190,7 @@ void main() { ...@@ -1190,7 +1190,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final Element secondChild = tester.element(find.text('Go Back')); final Element secondChild = tester.element(find.text('Go Back'));
final FocusNode secondFocusNode = Focus.of(secondChild)!; final FocusNode secondFocusNode = Focus.of(secondChild);
expect(firstFocusNode.hasFocus, isFalse); expect(firstFocusNode.hasFocus, isFalse);
expect(secondFocusNode.hasFocus, isTrue); expect(secondFocusNode.hasFocus, isTrue);
...@@ -1264,10 +1264,10 @@ void main() { ...@@ -1264,10 +1264,10 @@ void main() {
focusLowerRight = null; focusLowerRight = null;
} }
final FocusNode upperLeftNode = Focus.of(tester.element(find.byKey(upperLeftKey)))!; final FocusNode upperLeftNode = Focus.of(tester.element(find.byKey(upperLeftKey)));
final FocusNode upperRightNode = Focus.of(tester.element(find.byKey(upperRightKey)))!; final FocusNode upperRightNode = Focus.of(tester.element(find.byKey(upperRightKey)));
final FocusNode lowerLeftNode = Focus.of(tester.element(find.byKey(lowerLeftKey)))!; final FocusNode lowerLeftNode = Focus.of(tester.element(find.byKey(lowerLeftKey)));
final FocusNode lowerRightNode = Focus.of(tester.element(find.byKey(lowerRightKey)))!; final FocusNode lowerRightNode = Focus.of(tester.element(find.byKey(lowerRightKey)));
final FocusNode scope = upperLeftNode.enclosingScope!; final FocusNode scope = upperLeftNode.enclosingScope!;
upperLeftNode.requestFocus(); upperLeftNode.requestFocus();
...@@ -1408,7 +1408,7 @@ void main() { ...@@ -1408,7 +1408,7 @@ void main() {
focus = List<bool?>.generate(keys.length, (int _) => null); focus = List<bool?>.generate(keys.length, (int _) => null);
} }
final List<FocusNode> nodes = keys.map<FocusNode>((GlobalKey key) => Focus.of(tester.element(find.byKey(key)))!).toList(); final List<FocusNode> nodes = keys.map<FocusNode>((GlobalKey key) => Focus.of(tester.element(find.byKey(key)))).toList();
final FocusNode scope = nodes[0].enclosingScope!; final FocusNode scope = nodes[0].enclosingScope!;
nodes[4].requestFocus(); nodes[4].requestFocus();
...@@ -1527,14 +1527,14 @@ void main() { ...@@ -1527,14 +1527,14 @@ void main() {
), ),
); );
final FocusNode upperLeftNode = Focus.of(tester.element(find.byKey(upperLeftKey)))!; final FocusNode upperLeftNode = Focus.of(tester.element(find.byKey(upperLeftKey)));
final FocusNode upperRightNode = Focus.of(tester.element(find.byKey(upperRightKey)))!; final FocusNode upperRightNode = Focus.of(tester.element(find.byKey(upperRightKey)));
final FocusNode lowerLeftNode = Focus.of(tester.element(find.byKey(lowerLeftKey)))!; final FocusNode lowerLeftNode = Focus.of(tester.element(find.byKey(lowerLeftKey)));
final FocusNode scope = upperLeftNode.enclosingScope!; final FocusNode scope = upperLeftNode.enclosingScope!;
await tester.pump(); await tester.pump();
final FocusTraversalPolicy policy = FocusTraversalGroup.of(upperLeftKey.currentContext!)!; final FocusTraversalPolicy policy = FocusTraversalGroup.of(upperLeftKey.currentContext!);
expect(policy.findFirstFocusInDirection(scope, TraversalDirection.up), equals(lowerLeftNode)); expect(policy.findFirstFocusInDirection(scope, TraversalDirection.up), equals(lowerLeftNode));
expect(policy.findFirstFocusInDirection(scope, TraversalDirection.down), equals(upperLeftNode)); expect(policy.findFirstFocusInDirection(scope, TraversalDirection.down), equals(upperLeftNode));
...@@ -1644,42 +1644,42 @@ void main() { ...@@ -1644,42 +1644,42 @@ void main() {
), ),
); );
expect(Focus.of(upperLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(upperLeftKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyEvent(LogicalKeyboardKey.tab);
expect(Focus.of(upperRightKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(upperRightKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyEvent(LogicalKeyboardKey.tab);
expect(Focus.of(lowerLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(lowerLeftKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyEvent(LogicalKeyboardKey.tab);
expect(Focus.of(lowerRightKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(lowerRightKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyEvent(LogicalKeyboardKey.tab);
expect(Focus.of(upperLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(upperLeftKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift); await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyUpEvent(LogicalKeyboardKey.shift); await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
expect(Focus.of(lowerRightKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(lowerRightKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift); await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyUpEvent(LogicalKeyboardKey.shift); await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
expect(Focus.of(lowerLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(lowerLeftKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift); await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyUpEvent(LogicalKeyboardKey.shift); await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
expect(Focus.of(upperRightKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(upperRightKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift); await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.sendKeyEvent(LogicalKeyboardKey.tab);
await tester.sendKeyUpEvent(LogicalKeyboardKey.shift); await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);
expect(Focus.of(upperLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(upperLeftKey.currentContext!).hasPrimaryFocus, isTrue);
// Traverse in a direction // Traverse in a direction
await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight); await tester.sendKeyEvent(LogicalKeyboardKey.arrowRight);
expect(Focus.of(upperRightKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(upperRightKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown);
expect(Focus.of(lowerRightKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(lowerRightKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft); await tester.sendKeyEvent(LogicalKeyboardKey.arrowLeft);
expect(Focus.of(lowerLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(lowerLeftKey.currentContext!).hasPrimaryFocus, isTrue);
await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp); await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp);
expect(Focus.of(upperLeftKey.currentContext!)!.hasPrimaryFocus, isTrue); expect(Focus.of(upperLeftKey.currentContext!).hasPrimaryFocus, isTrue);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
testWidgets('Focus traversal inside a vertical scrollable scrolls to stay visible.', (WidgetTester tester) async { testWidgets('Focus traversal inside a vertical scrollable scrolls to stay visible.', (WidgetTester tester) async {
...@@ -2070,9 +2070,9 @@ void main() { ...@@ -2070,9 +2070,9 @@ void main() {
); );
final Element childWidget = tester.element(find.byKey(key1)); final Element childWidget = tester.element(find.byKey(key1));
final FocusNode unfocusableNode = Focus.of(childWidget)!; final FocusNode unfocusableNode = Focus.of(childWidget);
final Element containerWidget = tester.element(find.byKey(key2)); final Element containerWidget = tester.element(find.byKey(key2));
final FocusNode containerNode = Focus.of(containerWidget)!; final FocusNode containerNode = Focus.of(containerWidget);
unfocusableNode.requestFocus(); unfocusableNode.requestFocus();
await tester.pump(); await tester.pump();
......
...@@ -991,7 +991,7 @@ void main() { ...@@ -991,7 +991,7 @@ void main() {
); );
final Element containerElement = tester.element(find.byKey(containerKey)); final Element containerElement = tester.element(find.byKey(containerKey));
final FocusNode androidViewFocusNode = androidViewFocusWidget.focusNode!; final FocusNode androidViewFocusNode = androidViewFocusWidget.focusNode!;
final FocusNode containerFocusNode = Focus.of(containerElement)!; final FocusNode containerFocusNode = Focus.of(containerElement);
containerFocusNode.requestFocus(); containerFocusNode.requestFocus();
...@@ -1038,7 +1038,7 @@ void main() { ...@@ -1038,7 +1038,7 @@ void main() {
final Element containerElement = tester.element(find.byKey(containerKey)); final Element containerElement = tester.element(find.byKey(containerKey));
final FocusNode containerFocusNode = Focus.of(containerElement)!; final FocusNode containerFocusNode = Focus.of(containerElement);
containerFocusNode.requestFocus(); containerFocusNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -1086,7 +1086,7 @@ void main() { ...@@ -1086,7 +1086,7 @@ void main() {
viewsController.createCompleter!.complete(); viewsController.createCompleter!.complete();
final Element containerElement = tester.element(find.byKey(containerKey)); final Element containerElement = tester.element(find.byKey(containerKey));
final FocusNode containerFocusNode = Focus.of(containerElement)!; final FocusNode containerFocusNode = Focus.of(containerElement);
containerFocusNode.requestFocus(); containerFocusNode.requestFocus();
await tester.pump(); await tester.pump();
...@@ -2491,7 +2491,7 @@ void main() { ...@@ -2491,7 +2491,7 @@ void main() {
); );
final FocusNode platformViewFocusNode = platformViewFocusWidget.focusNode!; final FocusNode platformViewFocusNode = platformViewFocusWidget.focusNode!;
final Element containerElement = tester.element(find.byKey(containerKey)); final Element containerElement = tester.element(find.byKey(containerKey));
final FocusNode containerFocusNode = Focus.of(containerElement)!; final FocusNode containerFocusNode = Focus.of(containerElement);
containerFocusNode.requestFocus(); containerFocusNode.requestFocus();
await tester.pump(); await tester.pump();
......
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