mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
support history entry replace in multi entries browser history (flutter/engine#26456)
This commit is contained in:
parent
5b6518d416
commit
d4cb4f3a3d
@ -63,7 +63,7 @@ abstract class BrowserHistory {
|
||||
Object? get currentState => urlStrategy?.getState();
|
||||
|
||||
/// Update the url with the given [routeName] and [state].
|
||||
void setRouteName(String? routeName, {Object? state});
|
||||
void setRouteName(String? routeName, {Object? state, bool replace = false});
|
||||
|
||||
/// A callback method to handle browser backward or forward buttons.
|
||||
///
|
||||
@ -131,15 +131,23 @@ class MultiEntriesBrowserHistory extends BrowserHistory {
|
||||
}
|
||||
|
||||
@override
|
||||
void setRouteName(String? routeName, {Object? state}) {
|
||||
void setRouteName(String? routeName, {Object? state, bool replace = false}) {
|
||||
if (urlStrategy != null) {
|
||||
assert(routeName != null);
|
||||
_lastSeenSerialCount += 1;
|
||||
urlStrategy!.pushState(
|
||||
_tagWithSerialCount(state, _lastSeenSerialCount),
|
||||
'flutter',
|
||||
routeName!,
|
||||
);
|
||||
if (replace) {
|
||||
urlStrategy!.replaceState(
|
||||
_tagWithSerialCount(state, _lastSeenSerialCount),
|
||||
'flutter',
|
||||
routeName!,
|
||||
);
|
||||
} else {
|
||||
_lastSeenSerialCount += 1;
|
||||
urlStrategy!.pushState(
|
||||
_tagWithSerialCount(state, _lastSeenSerialCount),
|
||||
'flutter',
|
||||
routeName!,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,7 +271,7 @@ class SingleEntryBrowserHistory extends BrowserHistory {
|
||||
}
|
||||
|
||||
@override
|
||||
void setRouteName(String? routeName, {Object? state}) {
|
||||
void setRouteName(String? routeName, {Object? state, bool replace = false}) {
|
||||
if (urlStrategy != null) {
|
||||
_setupFlutterEntry(urlStrategy!, replace: true, path: routeName);
|
||||
}
|
||||
|
||||
@ -132,6 +132,7 @@ class EngineFlutterWindow extends ui.SingletonFlutterWindow {
|
||||
browserHistory.setRouteName(
|
||||
arguments!['location'],
|
||||
state: arguments['state'],
|
||||
replace: arguments['replace'] ?? false,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -16,6 +16,13 @@ import 'matchers.dart';
|
||||
|
||||
const MethodCodec codec = JSONMethodCodec();
|
||||
|
||||
Map<String, dynamic> _tagStateWithSerialCount(dynamic state, int serialCount) {
|
||||
return <String, dynamic> {
|
||||
'serialCount': serialCount,
|
||||
'state': state,
|
||||
};
|
||||
}
|
||||
|
||||
void main() {
|
||||
internalBootstrapBrowserTest(() => testMain);
|
||||
}
|
||||
@ -175,6 +182,67 @@ void testMain() {
|
||||
expect(window.browserHistory.urlStrategy!.getPath(), '/foo');
|
||||
});
|
||||
|
||||
test('can replace in MultiEntriesBrowserHistory',
|
||||
() async {
|
||||
await window.debugInitializeHistory(TestUrlStrategy.fromEntry(
|
||||
TestHistoryEntry('initial state', null, '/initial'),
|
||||
), useSingle: false);
|
||||
expect(window.browserHistory, isA<MultiEntriesBrowserHistory>());
|
||||
|
||||
Completer<void> callback = Completer<void>();
|
||||
window.sendPlatformMessage(
|
||||
'flutter/navigation',
|
||||
JSONMethodCodec().encodeMethodCall(MethodCall(
|
||||
'routeInformationUpdated',
|
||||
<String, dynamic>{
|
||||
'location': '/baz',
|
||||
'state': '/state',
|
||||
},
|
||||
)),
|
||||
(_) { callback.complete(); },
|
||||
);
|
||||
await callback.future;
|
||||
expect(window.browserHistory.urlStrategy!.getPath(), '/baz');
|
||||
expect(window.browserHistory.urlStrategy!.getState(), _tagStateWithSerialCount('/state', 1));
|
||||
|
||||
callback = Completer<void>();
|
||||
window.sendPlatformMessage(
|
||||
'flutter/navigation',
|
||||
JSONMethodCodec().encodeMethodCall(MethodCall(
|
||||
'routeInformationUpdated',
|
||||
<String, dynamic>{
|
||||
'location': '/baz',
|
||||
'state': '/state1',
|
||||
'replace': true
|
||||
},
|
||||
)),
|
||||
(_) { callback.complete(); },
|
||||
);
|
||||
await callback.future;
|
||||
expect(window.browserHistory.urlStrategy!.getPath(), '/baz');
|
||||
expect(window.browserHistory.urlStrategy!.getState(), _tagStateWithSerialCount('/state1', 1));
|
||||
|
||||
callback = Completer<void>();
|
||||
window.sendPlatformMessage(
|
||||
'flutter/navigation',
|
||||
JSONMethodCodec().encodeMethodCall(MethodCall(
|
||||
'routeInformationUpdated',
|
||||
<String, dynamic>{
|
||||
'location': '/foo',
|
||||
'state': '/foostate1',
|
||||
},
|
||||
)),
|
||||
(_) { callback.complete(); },
|
||||
);
|
||||
await callback.future;
|
||||
expect(window.browserHistory.urlStrategy!.getPath(), '/foo');
|
||||
expect(window.browserHistory.urlStrategy!.getState(), _tagStateWithSerialCount('/foostate1', 2));
|
||||
|
||||
await window.browserHistory.back();
|
||||
expect(window.browserHistory.urlStrategy!.getPath(), '/baz');
|
||||
expect(window.browserHistory.urlStrategy!.getState(), _tagStateWithSerialCount('/state1', 1));
|
||||
});
|
||||
|
||||
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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user