@@ -18,7 +18,7 @@ define([ "jquery", "../events/navigate", "./path", "./history" ], function( $ )
1818
1919 $ . extend ( $ . Navigator . prototype , {
2020 squash : function ( url , data ) {
21- var state , href ,
21+ var state , href , self = this ,
2222 hash = path . isPath ( url ) ? path . stripHash ( url ) : url ;
2323
2424 href = path . squash ( url ) ;
@@ -42,6 +42,19 @@ define([ "jquery", "../events/navigate", "./path", "./history" ], function( $ )
4242 // is not fired.
4343 window . history . replaceState ( state , state . title || document . title , href ) ;
4444
45+
46+ // If popstate is enabled and the browser triggers `popstate` events when the hash
47+ // is set (this often happens immediately in browsers like Chrome), then the
48+ // this flag will be set to false already. If it's a browser that does not trigger
49+ // a `popstate` on hash assignement or `replaceState` then we need to unlock the
50+ // At the time of this writing this happens with Opera 12
51+ // NOTE I hate the fact that we have to do this but it captures all the possible
52+ // issues with browsers that won't trigger a popstate in either case
53+ // ie, hash assignment/replaceState
54+ setTimeout ( function ( ) {
55+ self . ignoreNextHashChange = false ;
56+ } , 100 ) ;
57+
4558 return state ;
4659 } ,
4760
@@ -72,7 +85,7 @@ define([ "jquery", "../events/navigate", "./path", "./history" ], function( $ )
7285
7386 // TODO reconsider name
7487 go : function ( url , data , noEvents ) {
75- var state , href , hash , popstateEvent ,
88+ var state , href , hash , popstateEvent ;
7689 isPopStateEvent = $ . event . special . navigate . isPushStateEnabled ( ) ;
7790
7891 // Get the url as it would look squashed on to the current resolution url
@@ -109,6 +122,8 @@ define([ "jquery", "../events/navigate", "./path", "./history" ], function( $ )
109122 } , data ) ;
110123
111124 if ( isPopStateEvent ) {
125+
126+
112127 popstateEvent = new $ . Event ( "popstate" ) ;
113128 popstateEvent . originalEvent = {
114129 type : "popstate" ,
@@ -169,15 +184,13 @@ define([ "jquery", "../events/navigate", "./path", "./history" ], function( $ )
169184 // matches an existing history entry
170185 if ( ! event . originalEvent . state ) {
171186 hash = path . parseLocation ( ) . hash ;
172- closestIndex = this . history . closest ( hash ) ;
173- var index = this . history . activeIndex ;
174187 active = this . history . getActive ( ) ;
175188
176189 // Avoid adding a history entry in two cases
177190 // 1) on the initial hashchange
178191 // 2) when the current history entry hash is identical to the
179192 // current location hash
180- if ( this . history . stack . length !== 1 || hash !== this . history . getActive ( ) . hash ) {
193+ if ( this . history . stack . length !== 1 || hash !== active . hash ) {
181194 state = $ . navigate . navigator . squash ( hash ) ;
182195 // TODO it might be better to only add to the history stack
183196 // when the hash is adjacent to the active history entry
@@ -229,24 +242,10 @@ define([ "jquery", "../events/navigate", "./path", "./history" ], function( $ )
229242 // with to alter the url to represent the new state do so here
230243 if ( this . preventNextHashChange ) {
231244 this . preventNextHashChange = false ;
232- this . ignoreNextHashChange = false ;
233245 event . stopImmediatePropagation ( ) ;
234246 return ;
235247 }
236248
237- // If the hashchange has been explicitly ignored or we have no history at
238- // this point skip the history managment and the addition of the history
239- // entry to the event for the `navigate` bindings
240- if ( this . ignoreNextHashChange ) {
241- this . ignoreNextHashChange = false ;
242- }
243-
244- // If the stack is empty (it's been reset or some such) don't return,
245- // we need to record it in the missing callback below.
246- if ( this . ignoreNextHashChange && this . history . stack . length > 0 ) {
247- return ;
248- }
249-
250249 // If this is a hashchange caused by the back or forward button
251250 // make sure to set the state of our history stack properly
252251 this . history . direct ( {
0 commit comments