1919// pjax specific options:
2020//
2121//
22- // container - Where to stick the response body. Usually a String selector.
23- // $(container).html(xhr.responseBody)
24- // (default: current jquery context)
22+ // container - String selector for the element where to place the response body.
2523// push - Whether to pushState the URL. Defaults to true (of course).
2624// replace - Want to use replaceState instead? That's cool.
2725//
3028//
3129// Returns the jQuery object
3230function fnPjax ( selector , container , options ) {
33- var context = this
31+ options = optionsFor ( container , options )
3432 return this . on ( 'click.pjax' , selector , function ( event ) {
35- var opts = $ . extend ( { } , optionsFor ( container , options ) )
36- if ( ! opts . container )
37- opts . container = $ ( this ) . attr ( 'data-pjax' ) || context
33+ var opts = options
34+ if ( ! opts . container ) {
35+ opts = $ . extend ( { } , options )
36+ opts . container = $ ( this ) . attr ( 'data-pjax' )
37+ }
3838 handleClick ( event , opts )
3939 } )
4040}
@@ -52,16 +52,12 @@ function fnPjax(selector, container, options) {
5252// // is the same as
5353// $(document).pjax('a')
5454//
55- // $(document).on('click', 'a', function(event) {
56- // var container = $(this).closest('[data-pjax-container]')
57- // $.pjax.click(event, container)
58- // })
59- //
6055// Returns nothing.
6156function handleClick ( event , container , options ) {
6257 options = optionsFor ( container , options )
6358
6459 var link = event . currentTarget
60+ var $link = $ ( link )
6561
6662 if ( link . tagName . toUpperCase ( ) !== 'A' )
6763 throw "$.fn.pjax or $.pjax.click requires an anchor element"
@@ -85,18 +81,18 @@ function handleClick(event, container, options) {
8581
8682 var defaults = {
8783 url : link . href ,
88- container : $ ( link ) . attr ( 'data-pjax' ) ,
84+ container : $link . attr ( 'data-pjax' ) ,
8985 target : link
9086 }
9187
9288 var opts = $ . extend ( { } , defaults , options )
9389 var clickEvent = $ . Event ( 'pjax:click' )
94- $ ( link ) . trigger ( clickEvent , [ opts ] )
90+ $link . trigger ( clickEvent , [ opts ] )
9591
9692 if ( ! clickEvent . isDefaultPrevented ( ) ) {
9793 pjax ( opts )
9894 event . preventDefault ( )
99- $ ( link ) . trigger ( 'pjax:clicked' , [ opts ] )
95+ $link . trigger ( 'pjax:clicked' , [ opts ] )
10096 }
10197}
10298
@@ -110,8 +106,7 @@ function handleClick(event, container, options) {
110106// Examples
111107//
112108// $(document).on('submit', 'form', function(event) {
113- // var container = $(this).closest('[data-pjax-container]')
114- // $.pjax.submit(event, container)
109+ // $.pjax.submit(event, '[data-pjax-container]')
115110// })
116111//
117112// Returns nothing.
@@ -132,17 +127,17 @@ function handleSubmit(event, container, options) {
132127 }
133128
134129 if ( defaults . type !== 'GET' && window . FormData !== undefined ) {
135- defaults . data = new FormData ( form ) ;
136- defaults . processData = false ;
137- defaults . contentType = false ;
130+ defaults . data = new FormData ( form )
131+ defaults . processData = false
132+ defaults . contentType = false
138133 } else {
139134 // Can't handle file uploads, exit
140- if ( $ ( form ) . find ( ':file' ) . length ) {
141- return ;
135+ if ( $form . find ( ':file' ) . length ) {
136+ return
142137 }
143138
144139 // Fallback to manually serializing the fields
145- defaults . data = $ ( form ) . serializeArray ( ) ;
140+ defaults . data = $form . serializeArray ( )
146141 }
147142
148143 pjax ( $ . extend ( { } , defaults , options ) )
@@ -158,8 +153,7 @@ function handleSubmit(event, container, options) {
158153//
159154// Accepts these extra keys:
160155//
161- // container - Where to stick the response body.
162- // $(container).html(xhr.responseBody)
156+ // container - String selector for where to stick the response body.
163157// push - Whether to pushState the URL. Defaults to true (of course).
164158// replace - Want to use replaceState instead? That's cool.
165159//
@@ -176,26 +170,31 @@ function pjax(options) {
176170 options . url = options . url ( )
177171 }
178172
179- var target = options . target
180- 181173 var hash = parseURL ( options . url ) . hash
182174
183- var context = options . context = findContainerFor ( options . container )
175+ var containerType = $ . type ( options . container )
176+ if ( containerType !== 'string' ) {
177+ throw "expected string value for 'container' option; got " + containerType
178+ }
179+ var context = options . context = $ ( options . container )
180+ if ( ! context . length ) {
181+ throw "the container selector '" + options . container + "' did not match anything"
182+ }
184183
185184 // We want the browser to maintain two separate internal caches: one
186185 // for pjax'd partial page loads and one for normal page loads.
187186 // Without adding this secret parameter, some browsers will often
188187 // confuse the two.
189188 if ( ! options . data ) options . data = { }
190189 if ( $ . isArray ( options . data ) ) {
191- options . data . push ( { name : '_pjax' , value : context . selector } )
190+ options . data . push ( { name : '_pjax' , value : options . container } )
192191 } else {
193- options . data . _pjax = context . selector
192+ options . data . _pjax = options . container
194193 }
195194
196195 function fire ( type , args , props ) {
197196 if ( ! props ) props = { }
198- props . relatedTarget = target
197+ props . relatedTarget = options . target
199198 var event = $ . Event ( type , props )
200199 context . trigger ( event , args )
201200 return ! event . isDefaultPrevented ( )
@@ -211,7 +210,7 @@ function pjax(options) {
211210 }
212211
213212 xhr . setRequestHeader ( 'X-PJAX' , 'true' )
214- xhr . setRequestHeader ( 'X-PJAX-Container' , context . selector )
213+ xhr . setRequestHeader ( 'X-PJAX-Container' , options . container )
215214
216215 if ( ! fire ( 'pjax:beforeSend' , [ xhr , settings ] ) )
217216 return false
@@ -250,7 +249,7 @@ function pjax(options) {
250249 }
251250
252251 options . success = function ( data , status , xhr ) {
253- var previousState = pjax . state ;
252+ var previousState = pjax . state
254253
255254 // If $.pjax.defaults.version is a function, invoke it first.
256255 // Otherwise it can be a static string.
@@ -284,7 +283,7 @@ function pjax(options) {
284283 id : options . id || uniqueId ( ) ,
285284 url : container . url ,
286285 title : container . title ,
287- container : context . selector ,
286+ container : options . container ,
288287 fragment : options . fragment ,
289288 timeout : options . timeout
290289 }
@@ -318,7 +317,7 @@ function pjax(options) {
318317 // http://www.w3.org/html/wg/drafts/html/master/forms.html
319318 var autofocusEl = context . find ( 'input[autofocus], textarea[autofocus]' ) . last ( ) [ 0 ]
320319 if ( autofocusEl && document . activeElement !== autofocusEl ) {
321- autofocusEl . focus ( ) ;
320+ autofocusEl . focus ( )
322321 }
323322
324323 executeScriptTags ( container . scripts )
@@ -347,7 +346,7 @@ function pjax(options) {
347346 id : uniqueId ( ) ,
348347 url : window . location . href ,
349348 title : document . title ,
350- container : context . selector ,
349+ container : options . container ,
351350 fragment : options . fragment ,
352351 timeout : options . timeout
353352 }
@@ -363,7 +362,7 @@ function pjax(options) {
363362 if ( xhr . readyState > 0 ) {
364363 if ( options . push && ! options . replace ) {
365364 // Cache current container element before replacing it
366- cachePush ( pjax . state . id , cloneContents ( context ) )
365+ cachePush ( pjax . state . id , [ options . container , cloneContents ( context ) ] )
367366
368367 window . history . pushState ( null , "" , options . requestUrl )
369368 }
@@ -448,13 +447,14 @@ function onPjaxPopstate(event) {
448447 }
449448
450449 var cache = cacheMapping [ state . id ] || [ ]
451- var container = $ ( cache [ 0 ] || state . container ) , contents = cache [ 1 ]
450+ var containerSelector = cache [ 0 ] || state . container
451+ var container = $ ( containerSelector ) , contents = cache [ 1 ]
452452
453453 if ( container . length ) {
454454 if ( previousState ) {
455455 // Cache current container before replacement and inform the
456456 // cache which direction the history shifted.
457- cachePop ( direction , previousState . id , cloneContents ( container ) )
457+ cachePop ( direction , previousState . id , [ containerSelector , cloneContents ( container ) ] )
458458 }
459459
460460 var popstateEvent = $ . Event ( 'pjax:popstate' , {
@@ -466,7 +466,7 @@ function onPjaxPopstate(event) {
466466 var options = {
467467 id : state . id ,
468468 url : state . url ,
469- container : container ,
469+ container : containerSelector ,
470470 push : false ,
471471 fragment : state . fragment ,
472472 timeout : state . timeout ,
@@ -568,7 +568,7 @@ function cloneContents(container) {
568568 cloned . find ( 'script' ) . each ( function ( ) {
569569 if ( ! this . src ) jQuery . _data ( this , 'globalEval' , false )
570570 } )
571- return [ container . selector , cloned . contents ( ) ]
571+ return cloned . contents ( )
572572}
573573
574574// Internal: Strip internal query params from parsed URL.
@@ -618,44 +618,14 @@ function stripHash(location) {
618618//
619619// Returns options Object.
620620function optionsFor ( container , options ) {
621- // Both container and options
622- if ( container && options )
621+ if ( container && options ) {
622+ options = $ . extend ( { } , options )
623623 options . container = container
624- 625- // First argument is options Object
626- else if ( $ . isPlainObject ( container ) )
627- options = container
628- 629- // Only container
630- else
631- options = { container : container }
632- 633- // Find and validate container
634- if ( options . container )
635- options . container = findContainerFor ( options . container )
636- 637- return options
638- }
639- 640- // Internal: Find container element for a variety of inputs.
641- //
642- // Because we can't persist elements using the history API, we must be
643- // able to find a String selector that will consistently find the Element.
644- //
645- // container - A selector String, jQuery object, or DOM Element.
646- //
647- // Returns a jQuery object whose context is `document` and has a selector.
648- function findContainerFor ( container ) {
649- container = $ ( container )
650- 651- if ( ! container . length ) {
652- throw "no pjax container for " + container . selector
653- } else if ( container . selector !== '' && container . context === document ) {
624+ return options
625+ } else if ( $ . isPlainObject ( container ) ) {
654626 return container
655- } else if ( container . attr ( 'id' ) ) {
656- return $ ( '#' + container . attr ( 'id' ) )
657627 } else {
658- throw "cant get selector for pjax container!"
628+ return { container : container }
659629 }
660630}
661631
@@ -669,7 +639,7 @@ function findContainerFor(container) {
669639//
670640// Returns a jQuery object.
671641function findAll ( elems , selector ) {
672- return elems . filter ( selector ) . add ( elems . find ( selector ) ) ;
642+ return elems . filter ( selector ) . add ( elems . find ( selector ) )
673643}
674644
675645function parseHTML ( html ) {
@@ -911,8 +881,11 @@ function disable() {
911881
912882// Add the state property to jQuery's event object so we can use it in
913883// $(window).bind('popstate')
914- if ( $ . inArray ( 'state' , $ . event . props ) < 0 )
884+ if ( $ . event . props && $ . inArray ( 'state' , $ . event . props ) < 0 ) {
915885 $ . event . props . push ( 'state' )
886+ } else if ( ! ( 'state' in $ . Event . prototype ) ) {
887+ $ . event . addProp ( 'state' )
888+ }
916889
917890// Is pjax supported by this browser?
918891$ . support . pjax =
@@ -922,4 +895,4 @@ $.support.pjax =
922895
923896$ . support . pjax ? enable ( ) : disable ( )
924897
925- } ) ( jQuery ) ;
898+ } ) ( jQuery )
0 commit comments