BloomRouterController constructor

BloomRouterController(
  1. BloomRouter _router, {
  2. bool scrollRestoration = true,
  3. bool announceNavigation = true,
  4. bool autoFocus = true,
  5. 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();
  currentPath = signal(web.window.location.pathname);
  currentQuery = signal(parseQueryString(initialLocation));
  currentQueryAll = signal(parseQueryStringAll(initialLocation));
  currentFragment = signal(parseFragment(initialLocation));

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

  _schedulePostNavigationWork(
    restoreKey: null,
    fragment: currentFragment.value,
    isInitial: true,
  );
}