Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/web_ui/lib/src/engine/navigation/js_url_strategy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef _HistoryMove = Future<void> Function(int count);
/// bridge from the app to the engine.
@JS()
@anonymous
@staticInterop
abstract class JsUrlStrategy {
/// Creates an instance of [JsUrlStrategy] from a bag of URL strategy
/// functions.
Expand All @@ -41,7 +42,9 @@ abstract class JsUrlStrategy {
required _StateOperation replaceState,
required _HistoryMove go,
});
}

extension JsUrlStrategyExtension on JsUrlStrategy {
/// Adds a listener to the `popstate` event and returns a function that, when
/// invoked, removes the listener.
external ui.VoidCallback addPopStateListener(html.EventListener fn);
Expand Down
3 changes: 2 additions & 1 deletion lib/web_ui/lib/src/engine/navigation/url_strategy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import 'dart:async';
import 'dart:html' as html;

import 'package:js/js.dart' as js;
import 'package:ui/ui.dart' as ui;

import 'js_url_strategy.dart';
Expand Down Expand Up @@ -156,7 +157,7 @@ class CustomUrlStrategy extends UrlStrategy {

@override
ui.VoidCallback addPopStateListener(html.EventListener fn) =>
delegate.addPopStateListener(fn);
delegate.addPopStateListener(js.allowInterop(fn));

@override
String getPath() => delegate.getPath();
Expand Down
23 changes: 23 additions & 0 deletions lib/web_ui/test/window_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ void testMain() {
await window.resetHistory();
});

test('window.defaultRouteName should work with JsUrlStrategy', () async {
dynamic state = <dynamic, dynamic>{};
final JsUrlStrategy jsUrlStrategy = JsUrlStrategy(
getPath: allowInterop(() => '/initial'),
getState: allowInterop(() => state),
addPopStateListener: allowInterop((html.EventListener listener) => () {}),
prepareExternalUrl: allowInterop((String value) => ''),
pushState: allowInterop((Object? newState, String title, String url) {
expect(newState is Map, true);
}),
replaceState: allowInterop((Object? newState, String title, String url) {
expect(newState is Map, true);
state = newState;
}),
go: allowInterop(([int? delta]) async {
expect(delta, -1);
}));
final CustomUrlStrategy strategy =
CustomUrlStrategy.fromJs(jsUrlStrategy);
await window.debugInitializeHistory(strategy, useSingle: true);
expect(window.defaultRouteName, '/initial');
});

test('window.defaultRouteName should not change', () async {
final TestUrlStrategy strategy = TestUrlStrategy.fromEntry(
const TestHistoryEntry('initial state', null, '/initial'),
Expand Down