getVisualPages method

Iterable<GetPage> getVisualPages(
  1. RouteDecoder? currentHistory
)

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;
}