diff --git a/lib/web_ui/lib/src/engine/window.dart b/lib/web_ui/lib/src/engine/window.dart index c6fee6697e4ca..4ae0b7f09eaf1 100644 --- a/lib/web_ui/lib/src/engine/window.dart +++ b/lib/web_ui/lib/src/engine/window.dart @@ -44,13 +44,17 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { /// button, etc. @visibleForTesting BrowserHistory get browserHistory { + return _browserHistory ??= + MultiEntriesBrowserHistory(urlStrategy: _urlStrategyForInitialization); + } + + UrlStrategy? get _urlStrategyForInitialization { final UrlStrategy? urlStrategy = _isUrlStrategySet ? _customUrlStrategy : _createDefaultUrlStrategy(); // Prevent any further customization of URL strategy. _isUrlStrategySet = true; - return _browserHistory ??= - MultiEntriesBrowserHistory(urlStrategy: urlStrategy); + return urlStrategy; } BrowserHistory? _browserHistory; @@ -59,8 +63,14 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { if (_browserHistory is SingleEntryBrowserHistory) { return; } - final UrlStrategy? strategy = _browserHistory?.urlStrategy; - await _browserHistory?.tearDown(); + + final UrlStrategy? strategy; + if (_browserHistory == null) { + strategy = _urlStrategyForInitialization; + } else { + strategy = _browserHistory?.urlStrategy; + await _browserHistory?.tearDown(); + } _browserHistory = SingleEntryBrowserHistory(urlStrategy: strategy); } @@ -68,8 +78,14 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow { if (_browserHistory is MultiEntriesBrowserHistory) { return; } - final UrlStrategy? strategy = _browserHistory?.urlStrategy; - await _browserHistory?.tearDown(); + + final UrlStrategy? strategy; + if (_browserHistory == null) { + strategy = _urlStrategyForInitialization; + } else { + strategy = _browserHistory?.urlStrategy; + await _browserHistory?.tearDown(); + } _browserHistory = MultiEntriesBrowserHistory(urlStrategy: strategy); } @@ -261,7 +277,7 @@ external set _jsSetUrlStrategy(_JsSetUrlStrategy? newJsSetUrlStrategy); UrlStrategy? _createDefaultUrlStrategy() { return ui.debugEmulateFlutterTesterEnvironment - ? null + ? TestUrlStrategy.fromEntry(TestHistoryEntry('default', null, '/default')) : const HashUrlStrategy(); } diff --git a/lib/web_ui/test/window_test.dart b/lib/web_ui/test/window_test.dart index 3d49ec25002e0..565796ea7625d 100644 --- a/lib/web_ui/test/window_test.dart +++ b/lib/web_ui/test/window_test.dart @@ -128,6 +128,51 @@ void testMain() { expect(window.browserHistory.urlStrategy.getPath(), '/baz'); }); + test('initialize browser history with default url strategy (single)', () async { + // On purpose, we don't initialize history on the window. We want to let the + // window to self-initialize when it receives a navigation message. + + Completer callback = Completer(); + window.sendPlatformMessage( + 'flutter/navigation', + JSONMethodCodec().encodeMethodCall(MethodCall( + 'routeUpdated', + {'routeName': '/bar'}, + )), + (_) { callback.complete(); }, + ); + await callback.future; + expect(window.browserHistory is SingleEntryBrowserHistory, true); + // The url strategy should've been set to the default, and the path + // should've been correctly set to "/bar". + expect(window.browserHistory.urlStrategy, isNot(isNull)); + expect(window.browserHistory.urlStrategy.getPath(), '/bar'); + }, skip: browserEngine == BrowserEngine.webkit); // https://github.com/flutter/flutter/issues/50836 + + test('initialize browser history with default url strategy (multiple)', () async { + // On purpose, we don't initialize history on the window. We want to let the + // window to self-initialize when it receives a navigation message. + + Completer callback = Completer(); + window.sendPlatformMessage( + 'flutter/navigation', + JSONMethodCodec().encodeMethodCall(MethodCall( + 'routeInformationUpdated', + { + 'location': '/baz', + 'state': null, + }, + )), + (_) { callback.complete(); }, + ); + await callback.future; + expect(window.browserHistory is MultiEntriesBrowserHistory, true); + // The url strategy should've been set to the default, and the path + // should've been correctly set to "/baz". + expect(window.browserHistory.urlStrategy, isNot(isNull)); + expect(window.browserHistory.urlStrategy.getPath(), '/baz'); + }, skip: browserEngine == BrowserEngine.webkit); // https://github.com/flutter/flutter/issues/50836 + test('can disable location strategy', () async { // Disable URL strategy. expect(() => jsSetUrlStrategy(null), returnsNormally);