mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
update browser history switching (flutter/engine#23471)
This commit is contained in:
parent
ca255e3794
commit
367ce3fcf3
@ -51,7 +51,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
|
||||
}
|
||||
|
||||
BrowserHistory? _browserHistory;
|
||||
|
||||
bool _usingRouter = false;
|
||||
Future<void> _useSingleEntryBrowserHistory() async {
|
||||
if (_browserHistory is SingleEntryBrowserHistory) {
|
||||
return;
|
||||
@ -61,6 +61,15 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
|
||||
_browserHistory = SingleEntryBrowserHistory(urlStrategy: strategy);
|
||||
}
|
||||
|
||||
Future<void> _useMultiEntryBrowserHistory() async {
|
||||
if (_browserHistory is MultiEntriesBrowserHistory) {
|
||||
return;
|
||||
}
|
||||
final UrlStrategy? strategy = _browserHistory?.urlStrategy;
|
||||
await _browserHistory?.tearDown();
|
||||
_browserHistory = MultiEntriesBrowserHistory(urlStrategy: strategy);
|
||||
}
|
||||
|
||||
@visibleForTesting
|
||||
Future<void> debugInitializeHistory(
|
||||
UrlStrategy? strategy, {
|
||||
@ -68,7 +77,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
|
||||
}) async {
|
||||
// Prevent any further customization of URL strategy.
|
||||
_isUrlStrategySet = true;
|
||||
|
||||
_usingRouter = false;
|
||||
await _browserHistory?.tearDown();
|
||||
if (useSingle) {
|
||||
_browserHistory = SingleEntryBrowserHistory(urlStrategy: strategy);
|
||||
@ -95,11 +104,22 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
|
||||
|
||||
switch (decoded.method) {
|
||||
case 'routeUpdated':
|
||||
await _useSingleEntryBrowserHistory();
|
||||
browserHistory.setRouteName(arguments['routeName']);
|
||||
if (!_usingRouter) {
|
||||
await _useSingleEntryBrowserHistory();
|
||||
browserHistory.setRouteName(arguments['routeName']);
|
||||
} else {
|
||||
assert(
|
||||
false,
|
||||
'Receives old navigator update in a router application. '
|
||||
'This can happen if you use non-router versions of MaterialApp/'
|
||||
'CupertinoApp/WidgetsApp together with the router versions of them.'
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
case 'routeInformationUpdated':
|
||||
assert(browserHistory is MultiEntriesBrowserHistory);
|
||||
await _useMultiEntryBrowserHistory();
|
||||
_usingRouter = true;
|
||||
browserHistory.setRouteName(
|
||||
arguments['location'],
|
||||
state: arguments['state'],
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.6
|
||||
import 'dart:async';
|
||||
import 'dart:html' as html;
|
||||
import 'dart:js_util' as js_util;
|
||||
import 'dart:typed_data';
|
||||
@ -69,6 +70,64 @@ void testMain() {
|
||||
expect(window.defaultRouteName, '/');
|
||||
});
|
||||
|
||||
test('should throw when using nav1 and nav2 together',
|
||||
() async {
|
||||
await window.debugInitializeHistory(TestUrlStrategy.fromEntry(
|
||||
TestHistoryEntry('initial state', null, '/initial'),
|
||||
), useSingle: false);
|
||||
// Receive nav1 update first.
|
||||
Completer<void> callback = Completer<void>();
|
||||
window.sendPlatformMessage(
|
||||
'flutter/navigation',
|
||||
JSONMethodCodec().encodeMethodCall(MethodCall(
|
||||
'routeUpdated',
|
||||
<String, dynamic>{'routeName': '/bar'},
|
||||
)),
|
||||
(_) { callback.complete(); },
|
||||
);
|
||||
await callback.future;
|
||||
expect(window.browserHistory is SingleEntryBrowserHistory, true);
|
||||
expect(window.browserHistory.urlStrategy.getPath(), '/bar');
|
||||
|
||||
// We can still receive nav2 update.
|
||||
callback = Completer<void>();
|
||||
window.sendPlatformMessage(
|
||||
'flutter/navigation',
|
||||
JSONMethodCodec().encodeMethodCall(MethodCall(
|
||||
'routeInformationUpdated',
|
||||
<String, dynamic>{
|
||||
'location': '/baz',
|
||||
'state': null,
|
||||
},
|
||||
)),
|
||||
(_) { callback.complete(); },
|
||||
);
|
||||
await callback.future;
|
||||
expect(window.browserHistory is MultiEntriesBrowserHistory, true);
|
||||
expect(window.browserHistory.urlStrategy.getPath(), '/baz');
|
||||
|
||||
// Throws assertion error if it receives nav1 update after nav2 update.
|
||||
AssertionError caughtAssertion;
|
||||
await window.handleNavigationMessage(
|
||||
JSONMethodCodec().encodeMethodCall(MethodCall(
|
||||
'routeUpdated',
|
||||
<String, dynamic>{'routeName': '/foo'},
|
||||
))
|
||||
).catchError((Object e) {
|
||||
caughtAssertion = e as AssertionError;
|
||||
});
|
||||
|
||||
expect(
|
||||
caughtAssertion.message,
|
||||
'Receives old navigator update in a router application. This can '
|
||||
'happen if you use non-router versions of '
|
||||
'MaterialApp/CupertinoApp/WidgetsApp together with the router versions of them.'
|
||||
);
|
||||
// The history does not change.
|
||||
expect(window.browserHistory is MultiEntriesBrowserHistory, true);
|
||||
expect(window.browserHistory.urlStrategy.getPath(), '/baz');
|
||||
});
|
||||
|
||||
test('can disable location strategy', () async {
|
||||
// Disable URL strategy.
|
||||
expect(() => jsSetUrlStrategy(null), returnsNormally);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user