File tree Expand file tree Collapse file tree 2 files changed +56
-5
lines changed Expand file tree Collapse file tree 2 files changed +56
-5
lines changed Original file line number Diff line number Diff line change @@ -349,11 +349,7 @@ function pjax(options) {
349349 }
350350
351351 // Cancel the current request if we're already pjaxing
352- var xhr = pjax . xhr
353- if ( xhr && xhr . readyState < 4 ) {
354- xhr . onreadystatechange = $ . noop
355- xhr . abort ( )
356- }
352+ abortXHR ( pjax . xhr )
357353
358354 pjax . options = options
359355 var xhr = pjax . xhr = $ . ajax ( options )
@@ -420,6 +416,12 @@ if ('state' in window.history) {
420416// You probably shouldn't use pjax on pages with other pushState
421417// stuff yet.
422418function onPjaxPopstate ( event ) {
419+
420+ // Hitting back or forward should override any pending PJAX request.
421+ if ( ! initialPop ) {
422+ abortXHR ( pjax . xhr )
423+ }
424+
423425 var previousState = pjax . state
424426 var state = event . state
425427
@@ -536,6 +538,15 @@ function fallbackPjax(options) {
536538 form . submit ( )
537539}
538540
541+ // Internal: Abort an XmlHttpRequest if it hasn't been completed,
542+ // also removing its event handlers.
543+ function abortXHR ( xhr ) {
544+ if ( xhr && xhr . readyState < 4 ) {
545+ xhr . onreadystatechange = $ . noop
546+ xhr . abort ( )
547+ }
548+ }
549+
539550// Internal: Generate unique id for state object.
540551//
541552// Use a timestamp instead of a counter since ids should still be
Original file line number Diff line number Diff line change @@ -845,6 +845,46 @@ if ($.support.pjax) {
845845 } , 0 )
846846 }
847847
848+ asyncTest ( "clicking back while loading cancels XHR" , function ( ) {
849+ var frame = this . frame
850+
851+ frame . $ ( '#main' ) . on ( 'pjax:timeout' , function ( event ) {
852+ event . preventDefault ( )
853+ } )
854+
855+ frame . $ ( "#main" ) . one ( 'pjax:send' , function ( ) {
856+
857+ // Check that our request is aborted (need to check
858+ // how robust this is across browsers)
859+ frame . $ ( "#main" ) . one ( 'pjax:complete' , function ( e , xhr , textStatus ) {
860+ equal ( xhr . status , 0 )
861+ equal ( textStatus , 'abort' )
862+ } )
863+
864+ setTimeout ( function ( ) {
865+ frame . history . back ( )
866+ } , 250 )
867+
868+ // Make sure the URL and content remain the same after the
869+ // XHR would have arrived (delay on timeout.html is 1s)
870+ setTimeout ( function ( ) {
871+ var afterBackLocation = frame . location . pathname
872+ var afterBackTitle = frame . document . title
873+
874+ setTimeout ( function ( ) {
875+ equal ( frame . location . pathname , afterBackLocation )
876+ equal ( frame . document . title , afterBackTitle )
877+ start ( )
878+ } , 1000 )
879+ } , 500 )
880+ } )
881+
882+ frame . $ . pjax ( {
883+ url : "timeout.html" ,
884+ container : "#main"
885+ } )
886+ } )
887+
848888 asyncTest ( "popstate going back to page" , function ( ) {
849889 var frame = this . frame
850890
You can’t perform that action at this time.
0 commit comments