// 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 toHistory(); /** * Load the UI state from the given [values]. */ void loadFromHistory(Map values); }