Unverified Commit 297f094c authored by Michael Goderbauer's avatar Michael Goderbauer Committed by GitHub

LookupBoundary (#116429)

* LookupBoundary simplified

* tests

* doc and impl complete

* doc fixes

* add more tests

* review

* empty
parent cc256c3e
...@@ -2020,6 +2020,13 @@ class _InactiveElements { ...@@ -2020,6 +2020,13 @@ class _InactiveElements {
/// this callback. /// this callback.
typedef ElementVisitor = void Function(Element element); typedef ElementVisitor = void Function(Element element);
/// Signature for the callback to [BuildContext.visitAncestorElements].
///
/// The argument is the ancestor being visited.
///
/// Return false to stop the walk.
typedef ConditionalElementVisitor = bool Function(Element element);
/// A handle to the location of a widget in the widget tree. /// A handle to the location of a widget in the widget tree.
/// ///
/// This class presents a set of methods that can be used from /// This class presents a set of methods that can be used from
...@@ -2221,7 +2228,7 @@ abstract class BuildContext { ...@@ -2221,7 +2228,7 @@ abstract class BuildContext {
/// ///
/// All of the qualifications about when [dependOnInheritedWidgetOfExactType] can /// All of the qualifications about when [dependOnInheritedWidgetOfExactType] can
/// be called apply to this method as well. /// be called apply to this method as well.
InheritedWidget dependOnInheritedElement(InheritedElement ancestor, { Object aspect }); InheritedWidget dependOnInheritedElement(InheritedElement ancestor, { Object? aspect });
/// Obtains the nearest widget of the given type `T`, which must be the type of a /// Obtains the nearest widget of the given type `T`, which must be the type of a
/// concrete [InheritedWidget] subclass, and registers this build context with /// concrete [InheritedWidget] subclass, and registers this build context with
...@@ -2229,6 +2236,7 @@ abstract class BuildContext { ...@@ -2229,6 +2236,7 @@ abstract class BuildContext {
/// type is introduced, or the widget goes away), this build context is /// type is introduced, or the widget goes away), this build context is
/// rebuilt so that it can obtain new values from that widget. /// rebuilt so that it can obtain new values from that widget.
/// ///
/// {@template flutter.widgets.BuildContext.dependOnInheritedWidgetOfExactType}
/// This is typically called implicitly from `of()` static methods, e.g. /// This is typically called implicitly from `of()` static methods, e.g.
/// [Theme.of]. /// [Theme.of].
/// ///
...@@ -2262,6 +2270,7 @@ abstract class BuildContext { ...@@ -2262,6 +2270,7 @@ abstract class BuildContext {
/// [InheritedWidget] subclasses that supports partial updates, like /// [InheritedWidget] subclasses that supports partial updates, like
/// [InheritedModel]. It specifies what "aspect" of the inherited /// [InheritedModel]. It specifies what "aspect" of the inherited
/// widget this context depends on. /// widget this context depends on.
/// {@endtemplate}
T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({ Object? aspect }); T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({ Object? aspect });
/// Obtains the element corresponding to the nearest widget of the given type `T`, /// Obtains the element corresponding to the nearest widget of the given type `T`,
...@@ -2269,6 +2278,7 @@ abstract class BuildContext { ...@@ -2269,6 +2278,7 @@ abstract class BuildContext {
/// ///
/// Returns null if no such element is found. /// Returns null if no such element is found.
/// ///
/// {@template flutter.widgets.BuildContext.getElementForInheritedWidgetOfExactType}
/// Calling this method is O(1) with a small constant factor. /// Calling this method is O(1) with a small constant factor.
/// ///
/// This method does not establish a relationship with the target in the way /// This method does not establish a relationship with the target in the way
...@@ -2280,11 +2290,13 @@ abstract class BuildContext { ...@@ -2280,11 +2290,13 @@ abstract class BuildContext {
/// [dependOnInheritedWidgetOfExactType] in [State.didChangeDependencies]. It is /// [dependOnInheritedWidgetOfExactType] in [State.didChangeDependencies]. It is
/// safe to use this method from [State.deactivate], which is called whenever /// safe to use this method from [State.deactivate], which is called whenever
/// the widget is removed from the tree. /// the widget is removed from the tree.
/// {@endtemplate}
InheritedElement? getElementForInheritedWidgetOfExactType<T extends InheritedWidget>(); InheritedElement? getElementForInheritedWidgetOfExactType<T extends InheritedWidget>();
/// Returns the nearest ancestor widget of the given type `T`, which must be the /// Returns the nearest ancestor widget of the given type `T`, which must be the
/// type of a concrete [Widget] subclass. /// type of a concrete [Widget] subclass.
/// ///
/// {@template flutter.widgets.BuildContext.findAncestorWidgetOfExactType}
/// In general, [dependOnInheritedWidgetOfExactType] is more useful, since /// In general, [dependOnInheritedWidgetOfExactType] is more useful, since
/// inherited widgets will trigger consumers to rebuild when they change. This /// inherited widgets will trigger consumers to rebuild when they change. This
/// method is appropriate when used in interaction event handlers (e.g. /// method is appropriate when used in interaction event handlers (e.g.
...@@ -2306,11 +2318,13 @@ abstract class BuildContext { ...@@ -2306,11 +2318,13 @@ abstract class BuildContext {
/// ///
/// Returns null if a widget of the requested type does not appear in the /// Returns null if a widget of the requested type does not appear in the
/// ancestors of this context. /// ancestors of this context.
/// {@endtemplate}
T? findAncestorWidgetOfExactType<T extends Widget>(); T? findAncestorWidgetOfExactType<T extends Widget>();
/// Returns the [State] object of the nearest ancestor [StatefulWidget] widget /// Returns the [State] object of the nearest ancestor [StatefulWidget] widget
/// that is an instance of the given type `T`. /// that is an instance of the given type `T`.
/// ///
/// {@template flutter.widgets.BuildContext.findAncestorStateOfType}
/// This should not be used from build methods, because the build context will /// This should not be used from build methods, because the build context will
/// not be rebuilt if the value that would be returned by this method changes. /// not be rebuilt if the value that would be returned by this method changes.
/// In general, [dependOnInheritedWidgetOfExactType] is more appropriate for such /// In general, [dependOnInheritedWidgetOfExactType] is more appropriate for such
...@@ -2332,6 +2346,7 @@ abstract class BuildContext { ...@@ -2332,6 +2346,7 @@ abstract class BuildContext {
/// because the widget tree is no longer stable at that time. To refer to /// because the widget tree is no longer stable at that time. To refer to
/// an ancestor from one of those methods, save a reference to the ancestor /// an ancestor from one of those methods, save a reference to the ancestor
/// by calling [findAncestorStateOfType] in [State.didChangeDependencies]. /// by calling [findAncestorStateOfType] in [State.didChangeDependencies].
/// {@endtemplate}
/// ///
/// {@tool snippet} /// {@tool snippet}
/// ///
...@@ -2344,17 +2359,20 @@ abstract class BuildContext { ...@@ -2344,17 +2359,20 @@ abstract class BuildContext {
/// Returns the [State] object of the furthest ancestor [StatefulWidget] widget /// Returns the [State] object of the furthest ancestor [StatefulWidget] widget
/// that is an instance of the given type `T`. /// that is an instance of the given type `T`.
/// ///
/// {@template flutter.widgets.BuildContext.findRootAncestorStateOfType}
/// Functions the same way as [findAncestorStateOfType] but keeps visiting subsequent /// Functions the same way as [findAncestorStateOfType] but keeps visiting subsequent
/// ancestors until there are none of the type instance of `T` remaining. /// ancestors until there are none of the type instance of `T` remaining.
/// Then returns the last one found. /// Then returns the last one found.
/// ///
/// This operation is O(N) as well though N is the entire widget tree rather than /// This operation is O(N) as well though N is the entire widget tree rather than
/// a subtree. /// a subtree.
/// {@endtemplate}
T? findRootAncestorStateOfType<T extends State>(); T? findRootAncestorStateOfType<T extends State>();
/// Returns the [RenderObject] object of the nearest ancestor [RenderObjectWidget] widget /// Returns the [RenderObject] object of the nearest ancestor [RenderObjectWidget] widget
/// that is an instance of the given type `T`. /// that is an instance of the given type `T`.
/// ///
/// {@template flutter.widgets.BuildContext.findAncestorRenderObjectOfType}
/// This should not be used from build methods, because the build context will /// This should not be used from build methods, because the build context will
/// not be rebuilt if the value that would be returned by this method changes. /// not be rebuilt if the value that would be returned by this method changes.
/// In general, [dependOnInheritedWidgetOfExactType] is more appropriate for such /// In general, [dependOnInheritedWidgetOfExactType] is more appropriate for such
...@@ -2371,13 +2389,16 @@ abstract class BuildContext { ...@@ -2371,13 +2389,16 @@ abstract class BuildContext {
/// because the widget tree is no longer stable at that time. To refer to /// because the widget tree is no longer stable at that time. To refer to
/// an ancestor from one of those methods, save a reference to the ancestor /// an ancestor from one of those methods, save a reference to the ancestor
/// by calling [findAncestorRenderObjectOfType] in [State.didChangeDependencies]. /// by calling [findAncestorRenderObjectOfType] in [State.didChangeDependencies].
/// {@endtemplate}
T? findAncestorRenderObjectOfType<T extends RenderObject>(); T? findAncestorRenderObjectOfType<T extends RenderObject>();
/// Walks the ancestor chain, starting with the parent of this build context's /// Walks the ancestor chain, starting with the parent of this build context's
/// widget, invoking the argument for each ancestor. The callback is given a /// widget, invoking the argument for each ancestor.
/// reference to the ancestor widget's corresponding [Element] object. The ///
/// walk stops when it reaches the root widget or when the callback returns /// {@template flutter.widgets.BuildContext.visitAncestorElements}
/// false. The callback must not return null. /// The callback is given a reference to the ancestor widget's corresponding
/// [Element] object. The walk stops when it reaches the root widget or when
/// the callback returns false. The callback must not return null.
/// ///
/// This is useful for inspecting the widget tree. /// This is useful for inspecting the widget tree.
/// ///
...@@ -2387,10 +2408,12 @@ abstract class BuildContext { ...@@ -2387,10 +2408,12 @@ abstract class BuildContext {
/// because the element tree is no longer stable at that time. To refer to /// because the element tree is no longer stable at that time. To refer to
/// an ancestor from one of those methods, save a reference to the ancestor /// an ancestor from one of those methods, save a reference to the ancestor
/// by calling [visitAncestorElements] in [State.didChangeDependencies]. /// by calling [visitAncestorElements] in [State.didChangeDependencies].
void visitAncestorElements(bool Function(Element element) visitor); /// {@endtemplate}
void visitAncestorElements(ConditionalElementVisitor visitor);
/// Walks the children of this widget. /// Walks the children of this widget.
/// ///
/// {@template flutter.widgets.BuildContext.visitChildElements}
/// This is useful for applying changes to children after they are built /// This is useful for applying changes to children after they are built
/// without waiting for the next frame, especially if the children are known, /// without waiting for the next frame, especially if the children are known,
/// and especially if there is exactly one child (as is always the case for /// and especially if there is exactly one child (as is always the case for
...@@ -2408,6 +2431,7 @@ abstract class BuildContext { ...@@ -2408,6 +2431,7 @@ abstract class BuildContext {
/// significantly cheaper to use an [InheritedWidget] and have the descendants /// significantly cheaper to use an [InheritedWidget] and have the descendants
/// pull data down, than it is to use [visitChildElements] recursively to push /// pull data down, than it is to use [visitChildElements] recursively to push
/// data down to them. /// data down to them.
/// {@endtemplate}
void visitChildElements(ElementVisitor visitor); void visitChildElements(ElementVisitor visitor);
/// Start bubbling this notification at the given build context. /// Start bubbling this notification at the given build context.
...@@ -4452,7 +4476,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext { ...@@ -4452,7 +4476,7 @@ abstract class Element extends DiagnosticableTree implements BuildContext {
} }
@override @override
void visitAncestorElements(bool Function(Element element) visitor) { void visitAncestorElements(ConditionalElementVisitor visitor) {
assert(_debugCheckStateIsActiveForAncestorLookup()); assert(_debugCheckStateIsActiveForAncestorLookup());
Element? ancestor = _parent; Element? ancestor = _parent;
while (ancestor != null && visitor(ancestor)) { while (ancestor != null && visitor(ancestor)) {
......
This diff is collapsed.
...@@ -72,6 +72,7 @@ export 'src/widgets/keyboard_listener.dart'; ...@@ -72,6 +72,7 @@ export 'src/widgets/keyboard_listener.dart';
export 'src/widgets/layout_builder.dart'; export 'src/widgets/layout_builder.dart';
export 'src/widgets/list_wheel_scroll_view.dart'; export 'src/widgets/list_wheel_scroll_view.dart';
export 'src/widgets/localizations.dart'; export 'src/widgets/localizations.dart';
export 'src/widgets/lookup_boundary.dart';
export 'src/widgets/magnifier.dart'; export 'src/widgets/magnifier.dart';
export 'src/widgets/media_query.dart'; export 'src/widgets/media_query.dart';
export 'src/widgets/modal_barrier.dart'; export 'src/widgets/modal_barrier.dart';
......
This diff is collapsed.
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