mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
61 lines
1.9 KiB
Dart
61 lines
1.9 KiB
Dart
// Copyright 2016 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
|
|
/// Provides an iterable that efficiently returns all the elements
|
|
/// rooted at the given element. See [CachingIterable] for details.
|
|
///
|
|
/// This method must be called again if the tree changes. You cannot
|
|
/// call this function once, then reuse the iterable after having
|
|
/// changed the state of the tree, because the iterable returned by
|
|
/// this function caches the results and only walks the tree once.
|
|
///
|
|
/// The same applies to any iterable obtained indirectly through this
|
|
/// one, for example the results of calling `where` on this iterable
|
|
/// are also cached.
|
|
Iterable<Element> collectAllElementsFrom(Element rootElement, {
|
|
@required bool skipOffstage,
|
|
}) {
|
|
return new CachingIterable<Element>(new _DepthFirstChildIterator(rootElement, skipOffstage));
|
|
}
|
|
|
|
class _DepthFirstChildIterator implements Iterator<Element> {
|
|
_DepthFirstChildIterator(Element rootElement, this.skipOffstage)
|
|
: _stack = _reverseChildrenOf(rootElement, skipOffstage).toList();
|
|
|
|
final bool skipOffstage;
|
|
|
|
Element _current;
|
|
|
|
final List<Element> _stack;
|
|
|
|
@override
|
|
Element get current => _current;
|
|
|
|
@override
|
|
bool moveNext() {
|
|
if (_stack.isEmpty)
|
|
return false;
|
|
|
|
_current = _stack.removeLast();
|
|
// Stack children in reverse order to traverse first branch first
|
|
_stack.addAll(_reverseChildrenOf(_current, skipOffstage));
|
|
|
|
return true;
|
|
}
|
|
|
|
static Iterable<Element> _reverseChildrenOf(Element element, bool skipOffstage) {
|
|
assert(element != null);
|
|
final List<Element> children = <Element>[];
|
|
if (skipOffstage) {
|
|
element.visitChildrenForSemantics(children.add);
|
|
} else {
|
|
element.visitChildren(children.add);
|
|
}
|
|
return children.reversed;
|
|
}
|
|
}
|