| Index: runtime/bin/vmservice/client/lib/src/app/location_manager.dart
|
| diff --git a/runtime/bin/vmservice/client/lib/src/app/location_manager.dart b/runtime/bin/vmservice/client/lib/src/app/location_manager.dart
|
| index b541bf3982e161239c84169dc52e38ed1da09c91..11fb0a036c0704d502565ad5ec6cb305ea732b1c 100644
|
| --- a/runtime/bin/vmservice/client/lib/src/app/location_manager.dart
|
| +++ b/runtime/bin/vmservice/client/lib/src/app/location_manager.dart
|
| @@ -4,50 +4,114 @@
|
|
|
| part of app;
|
|
|
| -/// The LocationManager class observes and parses the hash ('#') portion of the
|
| -/// URL in window.location. The text after the '#' is used as the request
|
| -/// string for the VM service.
|
| -class LocationManager extends Observable {
|
| - static const String defaultHash = '#/vm';
|
| -
|
| +abstract class LocationManager extends Observable {
|
| + final _initialPath = '/vm';
|
| ObservatoryApplication _app;
|
| - @observable String currentHash = '';
|
| -
|
| - void init() {
|
| - window.onHashChange.listen((event) {
|
| - // Request the current anchor.
|
| - requestCurrentHash();
|
| - });
|
| -
|
| - if (window.location.hash == '') {
|
| - // Fresh start, load the vm page.
|
| - window.location.hash = defaultHash;
|
| - } else {
|
| - // The page is being reloaded.
|
| - requestCurrentHash();
|
| +
|
| + String _lastUrl;
|
| +
|
| + void _init(ObservatoryApplication app) {
|
| + // Called once.
|
| + assert(_app == null);
|
| + _app = app;
|
| + // Register for history events.
|
| + window.onPopState.listen(_onLocationChange);
|
| + _onStartup();
|
| + }
|
| +
|
| + void _onStartup();
|
| + void _onLocationChange(PopStateEvent event);
|
| +
|
| + /// Go to a specific url.
|
| + void go(String url) {
|
| + if (_lastUrl != url) {
|
| + Logger.root.info('Navigated to ${url}');
|
| + window.history.pushState(url, document.title, url);
|
| + _lastUrl = url;
|
| + }
|
| + _go(url);
|
| + }
|
| +
|
| + void _go(String url) {
|
| + // Chop off leading '#'.
|
| + if (url.startsWith('#')) {
|
| + url = url.substring(1);
|
| }
|
| + // Fall through handles '#/'
|
| + // Chop off leading '/'.
|
| + if (url.startsWith('/')) {
|
| + url = url.substring(1);
|
| + }
|
| + _app._visit(url);
|
| }
|
|
|
| - /// Clear the current hash.
|
| - void clearCurrentHash() {
|
| - window.location.hash = '';
|
| + /// Go back.
|
| + void back() {
|
| + window.history.go(-1);
|
| }
|
|
|
| - /// Refresh the service object reference in the location entry.
|
| - void requestCurrentHash() {
|
| - currentHash = window.location.hash;
|
| - if (!currentHash.startsWith('#/')) {
|
| + /// Go forward.
|
| + void forward() {
|
| + window.history.go(1);
|
| + }
|
| +
|
| + /// Handle clicking on an application url link.
|
| + void onGoto(MouseEvent event, var detail, Element target) {
|
| + var href = target.attributes['href'];
|
| + if (event.button > 1 || event.metaKey || event.ctrlKey ||
|
| + event.shiftKey || event.altKey) {
|
| + // Not a left-click or a left-click with a modifier key:
|
| + // Let browser handle.
|
| return;
|
| }
|
| - var parts = currentHash.substring(2).split('#');
|
| - var location = parts[0];
|
| - var args = (parts.length > 1 ? parts[1] : '');
|
| - if (parts.length > 2) {
|
| - Logger.root.warning('Found more than 2 #-characters in $currentHash');
|
| + location.go(href);
|
| + event.preventDefault();
|
| + }
|
| +
|
| + /// Given an application url, generate a link.
|
| + String makeLink(String url);
|
| +}
|
| +
|
| +/// Uses location.hash to encode application urls.
|
| +class HashLocationManager extends LocationManager {
|
| + void _onStartup() {
|
| + String initialPath = '/${window.location.hash}';
|
| + if ((window.location.hash == '') || (window.location.hash == '#')) {
|
| + initialPath = '/#${_initialPath}';
|
| }
|
| - _app.vm.get(currentHash.substring(2)).then((obj) {
|
| - _app.response = obj;
|
| - _app.args = args;
|
| - });
|
| + window.history.replaceState(initialPath, document.title, initialPath);
|
| + _go(window.location.hash);
|
| + }
|
| +
|
| + void _onLocationChange(PopStateEvent _) {
|
| + _go(window.location.hash);
|
| }
|
| +
|
| + /// Given an application url, generate a link for an anchor tag.
|
| + String makeLink(String url) {
|
| + return '#$url';
|
| + }
|
| +}
|
| +
|
| +/// Uses location.pathname to encode application urls. Requires server side
|
| +/// rewriting to support copy and paste linking. pub serve makes this hard.
|
| +/// STATUS: Work in progress.
|
| +class LinkLocationManager extends LocationManager {
|
| + void _onStartup() {
|
| + Logger.root.warning('Using untested LinkLocationManager');
|
| + String initialPath = window.location.pathname;
|
| + if ((window.location.pathname == '/index.html') ||
|
| + (window.location.pathname == '/')) {
|
| + initialPath = '/vm';
|
| + }
|
| + window.history.replaceState(initialPath, document.title, initialPath);
|
| + _go(window.location.pathname);
|
| + }
|
| +
|
| + void _onLocationChange(PopStateEvent _) {
|
| + _go(window.location.pathname);
|
| + }
|
| +
|
| + /// Given an application url, generate a link for an anchor tag.
|
| + String makeLink(String url) => url;
|
| }
|
|
|