Skip to content

Commit 75d751a

Browse files
mdebbarchriscraws
authored andcommitted
[web] Reland: Fix url updates when using Router (flutter#24876)
1 parent f5e6fa8 commit 75d751a

File tree

2 files changed

+76
-7
lines changed

2 files changed

+76
-7
lines changed

lib/web_ui/lib/src/engine/window.dart

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,17 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
4444
/// button, etc.
4545
@visibleForTesting
4646
BrowserHistory get browserHistory {
47+
return _browserHistory ??=
48+
MultiEntriesBrowserHistory(urlStrategy: _urlStrategyForInitialization);
49+
}
50+
51+
UrlStrategy? get _urlStrategyForInitialization {
4752
final UrlStrategy? urlStrategy = _isUrlStrategySet
4853
? _customUrlStrategy
4954
: _createDefaultUrlStrategy();
5055
// Prevent any further customization of URL strategy.
5156
_isUrlStrategySet = true;
52-
return _browserHistory ??=
53-
MultiEntriesBrowserHistory(urlStrategy: urlStrategy);
57+
return urlStrategy;
5458
}
5559

5660
BrowserHistory? _browserHistory;
@@ -59,17 +63,29 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
5963
if (_browserHistory is SingleEntryBrowserHistory) {
6064
return;
6165
}
62-
final UrlStrategy? strategy = _browserHistory?.urlStrategy;
63-
await _browserHistory?.tearDown();
66+
67+
final UrlStrategy? strategy;
68+
if (_browserHistory == null) {
69+
strategy = _urlStrategyForInitialization;
70+
} else {
71+
strategy = _browserHistory?.urlStrategy;
72+
await _browserHistory?.tearDown();
73+
}
6474
_browserHistory = SingleEntryBrowserHistory(urlStrategy: strategy);
6575
}
6676

6777
Future<void> _useMultiEntryBrowserHistory() async {
6878
if (_browserHistory is MultiEntriesBrowserHistory) {
6979
return;
7080
}
71-
final UrlStrategy? strategy = _browserHistory?.urlStrategy;
72-
await _browserHistory?.tearDown();
81+
82+
final UrlStrategy? strategy;
83+
if (_browserHistory == null) {
84+
strategy = _urlStrategyForInitialization;
85+
} else {
86+
strategy = _browserHistory?.urlStrategy;
87+
await _browserHistory?.tearDown();
88+
}
7389
_browserHistory = MultiEntriesBrowserHistory(urlStrategy: strategy);
7490
}
7591

@@ -261,7 +277,7 @@ external set _jsSetUrlStrategy(_JsSetUrlStrategy? newJsSetUrlStrategy);
261277

262278
UrlStrategy? _createDefaultUrlStrategy() {
263279
return ui.debugEmulateFlutterTesterEnvironment
264-
? null
280+
? TestUrlStrategy.fromEntry(TestHistoryEntry('default', null, '/'))
265281
: const HashUrlStrategy();
266282
}
267283

lib/web_ui/test/window_test.dart

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,59 @@ void testMain() {
128128
expect(window.browserHistory.urlStrategy.getPath(), '/baz');
129129
});
130130

131+
test('initialize browser history with default url strategy (single)', () async {
132+
// On purpose, we don't initialize history on the window. We want to let the
133+
// window to self-initialize when it receives a navigation message.
134+
135+
// Without initializing history, the default route name should be
136+
// initialized to "/" in tests.
137+
expect(window.defaultRouteName, '/');
138+
139+
Completer<void> callback = Completer<void>();
140+
window.sendPlatformMessage(
141+
'flutter/navigation',
142+
JSONMethodCodec().encodeMethodCall(MethodCall(
143+
'routeUpdated',
144+
<String, dynamic>{'routeName': '/bar'},
145+
)),
146+
(_) { callback.complete(); },
147+
);
148+
await callback.future;
149+
expect(window.browserHistory is SingleEntryBrowserHistory, true);
150+
// The url strategy should've been set to the default, and the path
151+
// should've been correctly set to "/bar".
152+
expect(window.browserHistory.urlStrategy, isNot(isNull));
153+
expect(window.browserHistory.urlStrategy.getPath(), '/bar');
154+
}, skip: browserEngine == BrowserEngine.webkit); // https://github.com/flutter/flutter/issues/50836
155+
156+
test('initialize browser history with default url strategy (multiple)', () async {
157+
// On purpose, we don't initialize history on the window. We want to let the
158+
// window to self-initialize when it receives a navigation message.
159+
160+
// Without initializing history, the default route name should be
161+
// initialized to "/" in tests.
162+
expect(window.defaultRouteName, '/');
163+
164+
Completer<void> callback = Completer<void>();
165+
window.sendPlatformMessage(
166+
'flutter/navigation',
167+
JSONMethodCodec().encodeMethodCall(MethodCall(
168+
'routeInformationUpdated',
169+
<String, dynamic>{
170+
'location': '/baz',
171+
'state': null,
172+
},
173+
)),
174+
(_) { callback.complete(); },
175+
);
176+
await callback.future;
177+
expect(window.browserHistory is MultiEntriesBrowserHistory, true);
178+
// The url strategy should've been set to the default, and the path
179+
// should've been correctly set to "/baz".
180+
expect(window.browserHistory.urlStrategy, isNot(isNull));
181+
expect(window.browserHistory.urlStrategy.getPath(), '/baz');
182+
}, skip: browserEngine == BrowserEngine.webkit); // https://github.com/flutter/flutter/issues/50836
183+
131184
test('can disable location strategy', () async {
132185
// Disable URL strategy.
133186
expect(() => jsSetUrlStrategy(null), returnsNormally);

0 commit comments

Comments
 (0)