BloomRouterController constructor
BloomRouterController(
- BloomRouter _router, {
- bool scrollRestoration = true,
- bool autoFocus = true,
- BloomAnnouncer? announcer,
Creates a client-side router controller managing browser navigation for _router.
Attaches a popstate event listener to web.window, initializes history state keys,
configures viewport prefetching observation, and initializes reactive location signals.
Implementation
BloomRouterController(
this._router, {
this.scrollRestoration = true,
this.announceNavigation = true,
this.autoFocus = true,
this.announcer,
}) {
final initialLocation = _readCurrentBrowserLocation();
_currentLocation = initialLocation;
currentPath = signal(web.window.location.pathname);
currentQuery = signal(parseQueryString(initialLocation));
currentQueryAll = signal(parseQueryStringAll(initialLocation));
currentFragment = signal(parseFragment(initialLocation));
final initialMatch = _router.match(initialLocation);
final needsInitialGuardResolution =
initialMatch != null && initialMatch.guards.isNotEmpty;
_initialRouteReady = signal(!needsInitialGuardResolution);
_initialRouteBlocked = signal(false);
_initialRouteError = signal<Object?>(null);
if (scrollRestoration) {
try {
_previousScrollRestoration = web.window.history.scrollRestoration;
web.window.history.scrollRestoration = 'manual';
} catch (_) {}
}
final existingKey = _extractKey(web.window.history.state);
if (existingKey != null) {
_currentKey = existingKey;
} else {
_currentKey = _generateKey();
if (scrollRestoration) {
try {
web.window.history.replaceState(
_createState(_currentKey!),
'',
web.window.location.href,
);
} catch (_) {}
}
}
_initIntersectionObserver();
_popStateListener = (web.Event e) {
_saveScroll();
JSAny? eventState;
if (e.isA<web.PopStateEvent>()) {
eventState = (e as web.PopStateEvent).state;
}
eventState ??= web.window.history.state;
final destKey = _extractKey(eventState);
_currentKey = destKey ?? _generateKey();
final newLocation = _readCurrentBrowserLocation();
_handleNavigation(
newLocation,
replaceState: false,
isPopState: true,
restoreKey: destKey,
);
};
web.window.addEventListener('popstate', _popStateListener.toJS);
if (needsInitialGuardResolution) {
unawaited(_resolveInitialLocation(initialLocation));
}
_schedulePostNavigationWork(
restoreKey: null,
fragment: currentFragment.value,
isInitial: true,
);
}