Skip to content
This repository was archived by the owner on Oct 8, 2021. It is now read-only.

Commit 66edbea

Browse files
committed
provide history and directionality to popstate based navigate event
1 parent 94dbe55 commit 66edbea

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

js/navigation/events/navigate.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ define([ "jquery",
1616

1717
popstate: function( event ) {
1818
var newEvent = new $.Event( "navigate" ),
19-
state = event.originalEvent.state;
19+
state = event.originalEvent.state || {};
20+
21+
if( event.historyState ){
22+
state.direction = event.historyState.direction;
23+
}
2024

2125
// Make sure the original event is tracked for the end
2226
// user to inspect incase they want to do something special
@@ -26,7 +30,7 @@ define([ "jquery",
2630
// the popstate navigate event and the hashchange navigate
2731
// event data
2832
$win.trigger( newEvent, {
29-
state: state || {}
33+
state: state
3034
});
3135
},
3236

js/navigation/navigate.js

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ define([
77
"./../jquery.mobile.core",
88
"./../jquery.mobile.support",
99
"./events/navigate",
10-
"./path"], function( $ ) {
10+
"./path" ], function( $ ) {
1111
//>>excludeEnd("jqmBuildExclude");
1212

1313
(function( $, undefined ) {
@@ -17,8 +17,7 @@ define([
1717
// so that end users don't have to think about it. Punting for now
1818
$.navigate = function( url, data ) {
1919
var href, state,
20-
// firefox auto decodes the url when using location.hash but not href
21-
hash = path.parseUrl(url).hash,
20+
hash = path.parseUrl( url ).hash,
2221
isPath = path.isPath( hash ),
2322
resolutionUrl = isPath ? path.getLocation() : $.mobile.getDocumentUrl();
2423

@@ -41,7 +40,8 @@ define([
4140

4241
// NOTE we currently _leave_ the appended hash in the hash in the interest
4342
// of seeing what happens and if we can support that before the hash is
44-
// pushed down
43+
// pushed down, though we note here that the # char is not permitted by
44+
// rfc3986
4545
// IMPORTANT in the case where popstate is supported the event will be triggered
4646
// directly, stopping further execution - ie, interupting the flow of this
4747
// method call to fire bindings at this expression. Below the navigate method
@@ -73,6 +73,7 @@ define([
7373

7474
// Trigger a new faux popstate event to replace the one that we
7575
// caught that was triggered by the hash setting above.
76+
history.ignoreNextPopState = true;
7677
$( window ).trigger( popstateEvent );
7778
}
7879

@@ -89,17 +90,37 @@ define([
8990
//
9091
// TODO grab the original event here and use it for the synthetic event in the
9192
// second half of the navigate execution that will follow this binding
92-
$( window ).bind( "popstate", function( event ) {
93+
$( window ).bind( "popstate.history", function( event ) {
9394
// Partly to support our test suite which manually alters the support
9495
// value to test hashchange. Partly to prevent all around weirdness
9596
if( !$.support.pushState ){
9697
return;
9798
}
9899

100+
// If this is the popstate triggered by the actual alteration of the hash
101+
// swallow it completely to prevent handling
99102
if( history.ignoreNextHashChange ) {
100103
history.ignoreNextHashChange = false;
101104
event.stopImmediatePropagation();
105+
return;
102106
}
107+
108+
// if this is the popstate triggered after the replaceState call in the navigate
109+
// method, then simply ignore it
110+
if( history.ignoreNextPopState ) {
111+
history.ignoreNextPopState = false;
112+
return;
113+
}
114+
115+
// If this is a popstate that comes from the back or forward buttons
116+
// make sure to set the state of our history stack properly
117+
history.direct({
118+
url: event.originalEvent.state.hash,
119+
either: function( historyEntry, direction ) {
120+
event.historyState = historyEntry;
121+
event.historyState.direction = direction;
122+
}
123+
});
103124
});
104125

105126
// NOTE must bind before `navigate` special event hashchange binding otherwise the
@@ -122,9 +143,10 @@ define([
122143
return;
123144
}
124145

125-
146+
// If this is a hashchange caused by the back or forward button
147+
// make sure to set the state of our history stack properly
126148
history.direct({
127-
url: path.parseLocation().hash ,
149+
url: path.parseLocation().hash,
128150
either: function( historyEntry, direction ) {
129151
event.hashchangeState = historyEntry;
130152
event.hashchangeState.direction = direction;
@@ -219,7 +241,7 @@ define([
219241
ignoreNextHashChange: false
220242
};
221243

222-
// Set the initial url history state
244+
// NOTE Set the initial url history state, so that we have a history entry to match
223245
history.add( path.parseLocation().pathname + path.parseLocation().search, {});
224246
})( jQuery );
225247

tests/unit/navigation/navigate_method.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ $.testHelper.setPushState();
119119
},
120120

121121
function( timedOut, data ) {
122+
equal( $.navigate.history.stack.length, 3, "the history stack hasn't been truncated" );
122123
equal( $.navigate.history.activeIndex, 0 );
123124
equal( data.state.direction, "back", "the direction should be back and not forward" );
124125
start();

0 commit comments

Comments
 (0)