Permalink
Browse files

Navigation: Tag replaceState() and internal history state with unique id

Closes gh-7613
Fixes gh-7602
  • Loading branch information...
gabrielschulhof committed Aug 7, 2014
1 parent 9951e54 commit 3993257be17e3b13479337d840cdd3bd41f0f88c
View
@@ -74,10 +74,29 @@ define([ "jquery", "./../ns", "./path" ], function( jQuery ) {
return index;
},
closest: function( url ) {
var closest, a = this.activeIndex;
_findById: function( id ) {
var stackIndex,
stackLength = this.stack.length;
// First, take the slice of the history stack before the current index and search
for ( stackIndex = 0 ; stackIndex < stackLength ; stackIndex++ ) {
if ( this.stack[ stackIndex ].id === id ) {
break;
}
}
return ( stackIndex < stackLength ? stackIndex : undefined );
},
closest: function( url, id ) {
var closest = ( id === undefined ? undefined : this._findById( id ) ),
a = this.activeIndex;
// First, we check whether we've found an entry by id. If so, we're done.
if ( closest !== undefined ) {
return closest;
}
// Failing that take the slice of the history stack before the current index and search
// for a url match. If one is found, we'll avoid avoid looking through forward history
// NOTE the preference for backward history movement is driven by the fact that
// most mobile browsers only have a dedicated back button, and users rarely use
@@ -100,7 +119,7 @@ define([ "jquery", "./../ns", "./path" ], function( jQuery ) {
},
direct: function( opts ) {
var newActiveIndex = this.closest( opts.url ), a = this.activeIndex;
var newActiveIndex = this.closest( opts.url, opts.id ), a = this.activeIndex;
// save new page index, null check to prevent falsey 0 result
// record the previous index for reference
@@ -24,6 +24,7 @@ define(["jquery",
};
$.extend($.mobile.Navigator.prototype, {
historyEntryId: 0,
squash: function( url, data ) {
var state, href, hash = path.isPath(url) ? path.stripHash(url) : url;
@@ -32,6 +33,7 @@ define(["jquery",
// make sure to provide this information when it isn't explicitly set in the
// data object that was passed to the squash method
state = $.extend({
id: ++this.historyEntryId,
hash: hash,
url: href
}, data);
@@ -129,7 +131,7 @@ define(["jquery",
state: null
};
this.squash( url, state );
state.id = ( this.squash( url, state ) || {} ).id;
// Trigger a new faux popstate event to replace the one that we
// caught that was triggered by the hash setting above.
@@ -220,6 +222,7 @@ define(["jquery",
// If all else fails this is a popstate that comes from the back or forward buttons
// make sure to set the state of our history stack properly, and record the directionality
this.history.direct({
id: ( event.originalEvent.state || {} ).id,
url: (event.originalEvent.state || {}).url || hash,
// When the url is either forward or backward in history include the entry
@@ -117,6 +117,36 @@ $.testHelper.setPushState();
]);
});
asyncTest( "Entries with identical URLs are distinguishable when pushState is enabled",
function() {
$.testHelper.eventSequence( "navigate", [
function() {
$.mobile.navigate( "#foo" );
},
function() {
$.mobile.navigate( "#bar" );
},
function() {
$.mobile.navigate( "#foo" );
},
function() {
deepEqual( $.mobile.navigate.history.activeIndex, $.support.pushState ? 2 : 0,
"After sequence start -> #foo -> #bar -> #foo activeIndex is correct" );
window.history.back();
},
function() {
deepEqual( $.mobile.navigate.history.activeIndex, 1,
"After going back once in the sequence the activeIndex is correct" );
window.history.forward();
},
function() {
deepEqual( $.mobile.navigate.history.activeIndex, $.support.pushState ? 2 : 0,
"After returning to the last sequnce entry the activeIndex is correct" );
start();
}
]);
});
asyncTest( "setting the hash with a url not in history should always create a new history entry", function() {
$.testHelper.eventTarget = $( window );
@@ -61,11 +61,11 @@ $.testHelper.delayStart();
function(){
ok( $.mobile.activePage[0] === $( "#active-state-page1" )[ 0 ], "successful navigation to internal page." );
$.testHelper.openPage("#/tests/integration/navigation/external.html");
$.testHelper.openPage( "#" + $.mobile.path.parseLocation().directory + "external.html" );
},
function() {
ok( $.mobile.activePage.attr("id"), "external-test", "successful navigation to external page." );
deepEqual( $.mobile.activePage.attr("id"), "external-test", "successful navigation to external page." );
window.history.back();
},

0 comments on commit 3993257

Please sign in to comment.