How to effectively handle browser history (namely the back button) in Dart?

browser, browser-history, dart, html

Solution

HTML5 defines new APIs for manipulating history, letting you change the location without reloading the window. There's a great article on Dive Into HTML5 that shows how to emulate multi-page navigation in a single-page app using the history API. It's easily translatable to Dart.

Here's the article: http://diveintohtml5.info/history.html

And here's the Dart docs for History: http://api.dartlang.org/docs/continuous/dart_html/History.html

In a single-page app with navigation, the way I generally set up my client-side code is similar to how a RoR or Django app, or Dart http server for that matter, is setup on the server:

- Define a set of matchers that work against the window location

- Map the matchers to functions that show a virtual page or some other location

Then to make it a seamless experience:

- Give all anchors an href for bookmarking, but add an onclick handler to invoke a function that pushes history state, and preventDefault to prevent a reload.

- On initial page load, read the URL and send it to the map in (2)

Sample:

main() {
  // handle the back button
  window.on.popState.add((_) => showPage());
}

showPage() {
  String path = window.location.pathname;
  if (path == '/') {
    showFrontPage();
  } else if (DETAIL_PAGE_URL.hasMatch(path)) {
    String id = DETAIL_PAGE_URL.firstMatch(path).group(1);
    showDetailPage(i);
  }
}

showFrontPage() {
  //... code to build a link to a detail page
  detailAnchor.on.click.add((MouseEvent e) {
    window.history.pushState(null, detail.title, detail.url);
    e.preventDefault();
    showDetailPage(detail);
  }, false);
}

Problem

Is there any facility to help dealing with state and the back button in Dart's standard library? Or would I need to emulate a Javascript solution to implement navigation through a web application's state? I intend to apply this to a personal project so browser compatibility is not an issue (ie an HTML5-only solution would be fine). Many thanks.

Original source