forked from dart-lang/sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UIState.dart
78 lines (64 loc) · 2.3 KB
/
UIState.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart = 2.9
part of swarmlib;
/**
* The base class for UI state that intends to support browser history.
*/
abstract class UIState {
/**
* The event listener we hook to the window's "popstate" event.
* This event is triggered by the back button or by the first page load.
*/
StreamSubscription _historyTracking;
UIState();
void startHistoryTracking() {
stopHistoryTracking();
bool firstEvent = true;
var handler = EventBatch.wrap((event) {
String state = window.location.hash;
if (state.startsWith('#')) {
// TODO(jimhug): Support default argument on substring.
state = state.substring(1, state.length);
}
if (firstEvent && state != '') {
// TODO(jmesserly): When loading a bookmark or refreshing, we replace
// the app state with a clean app state so the back button works. It
// would be better to support jumping to the previous story.
// We'd need to do some history manipulation here and some fixes to
// the views for this.
window.history.replaceState(null, document.title, '#');
} else if (state != '') {
loadFromHistory(jsonDecode(state));
}
firstEvent = false;
});
_historyTracking = window.onPopState.listen(handler);
}
void stopHistoryTracking() {
if (_historyTracking != null) {
_historyTracking.cancel();
}
}
/** Pushes a state onto the browser history stack */
void pushToHistory() {
if (_historyTracking == null) {
throw 'history tracking not started';
}
String state = jsonEncode(toHistory());
// TODO(jmesserly): [state] should be an Object, and we should pass it to
// the state parameter instead of as a #hash URL. Right now we're working
// around b/4582542.
window.history
.pushState(null, '${document.title}', '${document.title}#$state');
}
/**
* Serialize the state to a form suitable for storing in browser history.
*/
Map<String, String> toHistory();
/**
* Load the UI state from the given [values].
*/
void loadFromHistory(Map<String, String> values);
}