From 42a85927c4582d57d7000e001e147ebc56ca9f66 Mon Sep 17 00:00:00 2001 From: John Bender Date: Wed, 10 Oct 2012 16:00:45 -0700 Subject: [PATCH] allow users to provide state to further normalize the navigation events --- js/navigation/events/navigate.js | 30 +++++++++++++++----- tests/unit/navigation/event/navigate_core.js | 17 ++++++++++- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/js/navigation/events/navigate.js b/js/navigation/events/navigate.js index 7a42019a580..29d20db910e 100644 --- a/js/navigation/events/navigate.js +++ b/js/navigation/events/navigate.js @@ -3,32 +3,48 @@ //>>label: AJAX Navigation System //>>group: Navigation -// TODO break out pushstate support test so we don't -// depend on the whole thing +// TODO break out pushstate support test so we don't depend on the whole thing define([ "jquery", - "./../../jquery.mobile.support" ], function( $ ) { + "./../../jquery.mobile.support" ], function( $ ) { //>>excludeEnd("jqmBuildExclude"); (function( $, undefined ) { - var $win = $( window ), self, bound; + var $win = $( window ), self, history; $.event.special.navigate = self = { bound: false, + // TODO use the originalEvent property on the event object + // instead of from popstate: function( event ) { + var state = event.originalEvent.state; + + // NOTE the `|| {}` is there to ensure consistency between + // the popstate navigate event and the hashchange navigate + // event data $win.trigger( new $.Event( "navigate" ), { from: "popstate", - state: event.originalEvent.state + state: state || {} }); }, - hashchange: function( event ) { + // TODO use the originalEvent property on the event object + // instead of from + hashchange: function( event, data ) { + // Trigger the hashchange with state provided by the user + // that altered the hash $win.trigger( new $.Event( "navigate" ), { from: "hashchange", - state: {} + // Users that want to fully normalize the two events + // will need to do history management down the stack and + // add the state to the event before this binding is fired + state: event.hashchangeState || {} }); }, + // TODO We really only want to set this up once + // but I'm not clear if there's a beter way to achieve + // this with the jQuery special event structure setup: function( data, namespaces ) { if( self.bound ) { return; diff --git a/tests/unit/navigation/event/navigate_core.js b/tests/unit/navigation/event/navigate_core.js index 479c98badb4..a4c1bd6351f 100644 --- a/tests/unit/navigation/event/navigate_core.js +++ b/tests/unit/navigation/event/navigate_core.js @@ -47,7 +47,7 @@ $.testHelper.setPushState(); asyncTest( "popstate navigation events contain pushed state", function() { $( window ).one( "navigate", function( event, data ) { $( window ).one( "navigate", function( event, data ) { - equal( data.state.foo, "bar", "tagged as popstate" ); + equal( data.state.foo, "bar", "state provided properly" ); start(); }); @@ -55,6 +55,21 @@ $.testHelper.setPushState(); }); window.history.replaceState({ foo: "bar" }, document.title, location.href.replace(/#.*/, "" ) + "#foo"); + location.hash = "#foo2"; + }); + } else { + // Make sure the binding happends before any of the navigate bindings + $( window ).bind( "hashchange", function( event ) { + event.hashchangeState = { foo: "bar" }; + }); + + asyncTest( "hashchange navigation provides for data added in a later binding", function() { + $( window ).one( "navigate", function( event, data ) { + equal( data.from, "hashchange", "event triggered by a hashchange" ); + equal( data.state.foo, "bar", "state provided properly" ); + start(); + }); + location.hash = "#foo2"; }); }