getVisualPages method
Computes the page stack hosted by the root navigator from the navigation history.
When no page of any activePages entry declares GetPage.participatesInRootNavigator, every history entry contributes its leaf route (the default behavior: all routes participate in the root navigator).
Otherwise the stack is derived across all history entries in stack
order: an entry whose tree branch carries participation marks
contributes its pages marked true, while an unmarked entry (a plain
top-level route) contributes its leaf route. Pages are deduplicated by
key, so several entries sharing a marked ancestor (e.g. two children
of the same nested shell) keep a single instance of that ancestor
mounted. Deriving the stack from the whole history — instead of only
the current entry's branch — keeps a nested shell, its navigator and
its controllers alive when an unrelated sibling route is pushed on top
of it.
Implementation
Iterable<GetPage> getVisualPages(RouteDecoder? currentHistory) {
final anyMarked = _activePages.any(
(entry) => entry.currentTreeBranch.any(
(page) => page.participatesInRootNavigator != null,
),
);
if (!anyMarked) {
//default behavior, all routes participate in root navigator
return _activePages.map((e) => e.route!);
}
final seenKeys = <LocalKey?>{};
final pages = <GetPage>[];
for (final entry in _activePages) {
final marked = entry.currentTreeBranch
.where((page) => page.participatesInRootNavigator != null)
.toList();
final contribution = marked.isEmpty
? [if (entry.route != null) entry.route!]
: marked.where((page) => page.participatesInRootNavigator == true);
for (final page in contribution) {
if (seenKeys.add(page.key)) pages.add(page);
}
}
return pages;
}