PageSourceSearch

https://www.eraled.sk/catalog/view/javascript/jquery/jquery.pjax.js

js eraled.sk collected 2026-10-06 13:15:34 UTC 25,260 bytes, 903 lines download raw bytes

vendor: 25,260 bytes, lines 1-903
1/*!
2 * Copyright 2012, Chris Wanstrath
3 * Released under the MIT License
4 * https://github.com/defunkt/jquery-pjax
5 */
6
7(function($){
8
9// When called on a container with a selector, fetches the href with
10// ajax into the container or with the data-pjax attribute on the link
11// itself.
12//
13// Tries to make sure the back button and ctrl+click work the way
14// you'd expect.
15//
16// Exported as $.fn.pjax
17//
18// Accepts a jQuery ajax options object that may include these
19// pjax specific options:
20//
21//
22// container - String selector for the element where to place the response body.
23//      push - Whether to pushState the URL. Defaults to true (of course).
24//   replace - Want to use replaceState instead? That's cool.
25//
26// For convenience the second parameter can be either the container or
27// the options object.
28//
29// Returns the jQuery object
30function fnPjax(selector, container, options) {
31  options = optionsFor(container, options)
32  return this.on('click.pjax', selector, function(event) {
33    var opts = options
34    if (!opts.container) {
35      opts = $.extend({}, options)
36      opts.container = $(this).attr('data-pjax')
37    }
38    handleClick(event, opts)
39  })
40}
41
42// Public: pjax on click handler
43//
44// Exported as $.pjax.click.
45//
46// event   - "click" jQuery.Event
47// options - pjax options
48//
49// Examples
50//
51//   $(document).on('click', 'a', $.pjax.click)
52//   // is the same as
53//   $(document).pjax('a')
54//
55// Returns nothing.
56function handleClick(event, container, options) {
57  options = optionsFor(container, options)
58
59  var link = event.currentTarget
60  var $link = $(link)
61
62  if (link.tagName.toUpperCase() !== 'A')
63    throw "$.fn.pjax or $.pjax.click requires an anchor element"
64
65  // Middle click, cmd click, and ctrl click should open
66  // links in a new tab as normal.
67  if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
68    return
69
70  // Ignore cross origin links
71  if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
72    return
73
74  // Ignore case when a hash is being tacked on the current URL
75  if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )
76    return
77
78  // Ignore event with default prevented
79  if (event.isDefaultPrevented())
80    return
81
82  var defaults = {
83    url: link.href,
84    container: $link.attr('data-pjax'),
85    target: link
86  }
87
88  var opts = $.extend({}, defaults, options)
89  var clickEvent = $.Event('pjax:click')
90  $link.trigger(clickEvent, [opts])
91
92  if (!clickEvent.isDefaultPrevented()) {
93    pjax(opts)
94    event.preventDefault()
95    $link.trigger('pjax:clicked', [opts])
96  }
97}
98
99// Public: pjax on form submit handler
100//
101// Exported as $.pjax.submit
102//
103// event   - "click" jQuery.Event
104// options - pjax options
105//
106// Examples
107//
108//  $(document).on('submit', 'form', function(event) {
109//    $.pjax.submit(event, '[data-pjax-container]')
110//  })
111//
112// Returns nothing.
113function handleSubmit(event, container, options) {
114  options = optionsFor(container, options)
115
116  var form = event.currentTarget
117  var $form = $(form)
118
119  if (form.tagName.toUpperCase() !== 'FORM')
120    throw "$.pjax.submit requires a form element"
121
122  var defaults = {
123    type: ($form.attr('method') || 'GET').toUpperCase(),
124    url: $form.attr('action'),
125    container: $form.attr('data-pjax'),
126    target: form
127  }
128
129  if (defaults.type !== 'GET' && window.FormData !== undefined) {
130    defaults.data = new FormData(form)
131    defaults.processData = false
132    defaults.contentType = false
133  } else {
134    // Can't handle file uploads, exit
135    if ($form.find(':file').length) {
136      return
137    }
138
139    // Fallback to manually serializing the fields
140    defaults.data = $form.serializeArray()
141  }
142
143  pjax($.extend({}, defaults, options))
144
145  event.preventDefault()
146}
147
148// Loads a URL with ajax, puts the response body inside a container,
149// then pushState()'s the loaded URL.
150//
151// Works just like $.ajax in that it accepts a jQuery ajax
152// settings object (with keys like url, type, data, etc).
153//
154// Accepts these extra keys:
155//
156// container - String selector for where to stick the response body.
157//      push - Whether to pushState the URL. Defaults to true (of course).
158//   replace - Want to use replaceState instead? That's cool.
159//
160// Use it just like $.ajax:
161//
162//   var xhr = $.pjax({ url: this.href, container: '#main' })
163//   console.log( xhr.readyState )
164//
165// Returns whatever $.ajax returns.
166function pjax(options) {
167  options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
168
169  if ($.isFunction(options.url)) {
170    options.url = options.url()
171  }
172
173  var hash = parseURL(options.url).hash
174
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  }
183
184  // We want the browser to maintain two separate internal caches: one
185  // for pjax'd partial page loads and one for normal page loads.
186  // Without adding this secret parameter, some browsers will often
187  // confuse the two.
188  if (!options.data) options.data = {}
189  if ($.isArray(options.data)) {
190    options.data.push({name: '_pjax', value: options.container})
191  } else {
192    options.data._pjax = options.container
193  }
194
195  function fire(type, args, props) {
196    if (!props) props = {}
197    props.relatedTarget = options.target
198    var event = $.Event(type, props)
199    context.trigger(event, args)
200    return !event.isDefaultPrevented()
201  }
202
203  var timeoutTimer
204
205  options.beforeSend = function(xhr, settings) {
206    // No timeout for non-GET requests
207    // Its not safe to request the resource again with a fallback method.
208    if (settings.type !== 'GET') {
209      settings.timeout = 0
210    }
211
212    xhr.setRequestHeader('X-PJAX', 'true')
213    xhr.setRequestHeader('X-PJAX-Container', options.container)
214
215    if (!fire('pjax:beforeSend', [xhr, settings]))
216      return false
217
218    if (settings.timeout > 0) {
219      timeoutTimer = setTimeout(function() {
220        if (fire('pjax:timeout', [xhr, options]))
221          xhr.abort('timeout')
222      }, settings.timeout)
223
224      // Clear timeout setting so jquerys internal timeout isn't invoked
225      settings.timeout = 0
226    }
227
228    var url = parseURL(settings.url)
229    if (hash) url.hash = hash
230    options.requestUrl = stripInternalParams(url)
231  }
232
233  options.complete = function(xhr, textStatus) {
234    if (timeoutTimer)
235      clearTimeout(timeoutTimer)
236
237    fire('pjax:complete', [xhr, textStatus, options])
238
239    fire('pjax:end', [xhr, options])
240  }
241
242  options.error = function(xhr, textStatus, errorThrown) {
243    var container = extractContainer("", xhr, options)
244
245    var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
246    if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
247      locationReplace(container.url)
248    }
249  }
250
251  options.success = function(data, status, xhr) {
252    var previousState = pjax.state
253
254    // If $.pjax.defaults.version is a function, invoke it first.
255    // Otherwise it can be a static string.
256    var currentVersion = typeof $.pjax.defaults.version === 'function' ?
257      $.pjax.defaults.version() :
258      $.pjax.defaults.version
259
260    var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
261
262    var container = extractContainer(data, xhr, options)
263
264    var url = parseURL(container.url)
265    if (hash) {
266      url.hash = hash
267      container.url = url.href
268    }
269
270    // If there is a layout version mismatch, hard load the new url
271    if (currentVersion && latestVersion && currentVersion !== latestVersion) {
272      locationReplace(container.url)
273      return
274    }
275
276    // If the new response is missing a body, hard load the page
277    if (!container.contents) {
278      locationReplace(container.url)
279      return
280    }
281
282    pjax.state = {
283      id: options.id || uniqueId(),
284      url: container.url,
285      title: container.title,
286      container: options.container,
287      fragment: options.fragment,
288      timeout: options.timeout
289    }
290
291    if (options.push || options.replace) {
292      window.history.replaceState(pjax.state, container.title, container.url)
293    }
294
295    // Only blur the focus if the focused element is within the container.
296    var blurFocus = $.contains(context, document.activeElement)
297
298    // Clear out any focused controls before inserting new page contents.
299    if (blurFocus) {
300      try {
301        document.activeElement.blur()
302      } catch (e) { /* ignore */ }
303    }
304
305    if (container.title) document.title = container.title
306
307    fire('pjax:beforeReplace', [container.contents, options], {
308      state: pjax.state,
309      previousState: previousState
310    })
311    context.html(container.contents)
312
313    // FF bug: Won't autofocus fields that are inserted via JS.
314    // This behavior is incorrect. So if theres no current focus, autofocus
315    // the last field.
316    //
317    // http://www.w3.org/html/wg/drafts/html/master/forms.html
318    var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
319    if (autofocusEl && document.activeElement !== autofocusEl) {
320      autofocusEl.focus()
321    }
322
323    executeScriptTags(container.scripts)
324
325    var scrollTo = options.scrollTo
326
327    // Ensure browser scrolls to the element referenced by the URL anchor
328    if (hash) {
329      var name = decodeURIComponent(hash.slice(1))
330      var target = document.getElementById(name) || document.getElementsByName(name)[0]
331      if (target) scrollTo = $(target).offset().top
332    }
333
334    if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)
335
336    fire('pjax:success', [data, status, xhr, options])
337  }
338
339
340  // Initialize pjax.state for the initial page load. Assume we're
341  // using the container and options of the link we're loading for the
342  // back button to the initial page. This ensures good back button
343  // behavior.
344  if (!pjax.state) {
345    pjax.state = {
346      id: uniqueId(),
347      url: window.location.href,
348      title: document.title,
349      container: options.container,
350      fragment: options.fragment,
351      timeout: options.timeout
352    }
353    window.history.replaceState(pjax.state, document.title)
354  }
355
356  // Cancel the current request if we're already pjaxing
357  abortXHR(pjax.xhr)
358
359  pjax.options = options
360  var xhr = pjax.xhr = $.ajax(options)
361
362  if (xhr.readyState > 0) {
363    if (options.push && !options.replace) {
364      // Cache current container element before replacing it
365      cachePush(pjax.state.id, [options.container, cloneContents(context)])
366
367      window.history.pushState(null, "", options.requestUrl)
368    }
369
370    fire('pjax:start', [xhr, options])
371    fire('pjax:send', [xhr, options])
372  }
373
374  return pjax.xhr
375}
376
377// Public: Reload current page with pjax.
378//
379// Returns whatever $.pjax returns.
380function pjaxReload(container, options) {
381  var defaults = {
382    url: window.location.href,
383    push: false,
384    replace: true,
385    scrollTo: false
386  }
387
388  return pjax($.extend(defaults, optionsFor(container, options)))
389}
390
391// Internal: Hard replace current state with url.
392//
393// Work for around WebKit
394//   https://bugs.webkit.org/show_bug.cgi?id=93506
395//
396// Returns nothing.
397function locationReplace(url) {
398  window.history.replaceState(null, "", pjax.state.url)
399  window.location.replace(url)
400}
401
402
403var initialPop = true
404var initialURL = window.location.href
405var initialState = window.history.state
406
407// Initialize $.pjax.state if possible
408// Happens when reloading a page and coming forward from a different
409// session history.
410if (initialState && initialState.container) {
411  pjax.state = initialState
412}
413
414// Non-webkit browsers don't fire an initial popstate event
415if ('state' in window.history) {
416  initialPop = false
417}
418
419// popstate handler takes care of the back and forward buttons
420//
421// You probably shouldn't use pjax on pages with other pushState
422// stuff yet.
423function onPjaxPopstate(event) {
424
425  // Hitting back or forward should override any pending PJAX request.
426  if (!initialPop) {
427    abortXHR(pjax.xhr)
428  }
429
430  var previousState = pjax.state
431  var state = event.state
432  var direction
433
434  if (state && state.container) {
435    // When coming forward from a separate history session, will get an
436    // initial pop with a state we are already at. Skip reloading the current
437    // page.
438    if (initialPop && initialURL == state.url) return
439
440    if (previousState) {
441      // If popping back to the same state, just skip.
442      // Could be clicking back from hashchange rather than a pushState.
443      if (previousState.id === state.id) return
444
445      // Since state IDs always increase, we can deduce the navigation direction
446      direction = previousState.id < state.id ? 'forward' : 'back'
447    }
448
449    var cache = cacheMapping[state.id] || []
450    var containerSelector = cache[0] || state.container
451    var container = $(containerSelector), contents = cache[1]
452
453    if (container.length) {
454      if (previousState) {
455        // Cache current container before replacement and inform the
456        // cache which direction the history shifted.
457        cachePop(direction, previousState.id, [containerSelector, cloneContents(container)])
458      }
459
460      var popstateEvent = $.Event('pjax:popstate', {
461        state: state,
462        direction: direction
463      })
464      container.trigger(popstateEvent)
465
466      var options = {
467        id: state.id,
468        url: state.url,
469        container: containerSelector,
470        push: false,
471        fragment: state.fragment,
472        timeout: state.timeout,
473        scrollTo: false
474      }
475
476      if (contents) {
477        container.trigger('pjax:start', [null, options])
478
479        pjax.state = state
480        if (state.title) document.title = state.title
481        var beforeReplaceEvent = $.Event('pjax:beforeReplace', {
482          state: state,
483          previousState: previousState
484        })
485        container.trigger(beforeReplaceEvent, [contents, options])
486        container.html(contents)
487
488        container.trigger('pjax:end', [null, options])
489      } else {
490        pjax(options)
491      }
492
493      // Force reflow/relayout before the browser tries to restore the
494      // scroll position.
495      container[0].offsetHeight // eslint-disable-line no-unused-expressions
496    } else {
497      locationReplace(location.href)
498    }
499  }
500  initialPop = false
501}
502
503// Fallback version of main pjax function for browsers that don't
504// support pushState.
505//
506// Returns nothing since it retriggers a hard form submission.
507function fallbackPjax(options) {
508  var url = $.isFunction(options.url) ? options.url() : options.url,
509      method = options.type ? options.type.toUpperCase() : 'GET'
510
511  var form = $('<form>', {
512    method: method === 'GET' ? 'GET' : 'POST',
513    action: url,
514    style: 'display:none'
515  })
516
517  if (method !== 'GET' && method !== 'POST') {
518    form.append($('<input>', {
519      type: 'hidden',
520      name: '_method',
521      value: method.toLowerCase()
522    }))
523  }
524
525  var data = options.data
526  if (typeof data === 'string') {
527    $.each(data.split('&'), function(index, value) {
528      var pair = value.split('=')
529      form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))
530    })
531  } else if ($.isArray(data)) {
532    $.each(data, function(index, value) {
533      form.append($('<input>', {type: 'hidden', name: value.name, value: value.value}))
534    })
535  } else if (typeof data === 'object') {
536    var key
537    for (key in data)
538      form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))
539  }
540
541  $(document.body).append(form)
542  form.submit()
543}
544
545// Internal: Abort an XmlHttpRequest if it hasn't been completed,
546// also removing its event handlers.
547function abortXHR(xhr) {
548  if ( xhr && xhr.readyState < 4) {
549    xhr.onreadystatechange = $.noop
550    xhr.abort()
551  }
552}
553
554// Internal: Generate unique id for state object.
555//
556// Use a timestamp instead of a counter since ids should still be
557// unique across page loads.
558//
559// Returns Number.
560function uniqueId() {
561  return (new Date).getTime()
562}
563
564function cloneContents(container) {
565  var cloned = container.clone()
566  // Unmark script tags as already being eval'd so they can get executed again
567  // when restored from cache. HAXX: Uses jQuery internal method.
568  cloned.find('script').each(function(){
569    if (!this.src) $._data(this, 'globalEval', false)
570  })
571  return cloned.contents()
572}
573
574// Internal: Strip internal query params from parsed URL.
575//
576// Returns sanitized url.href String.
577function stripInternalParams(url) {
578  url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '').replace(/^&/, '')
579  return url.href.replace(/\?($|#)/, '$1')
580}
581
582// Internal: Parse URL components and returns a Locationish object.
583//
584// url - String URL
585//
586// Returns HTMLAnchorElement that acts like Location.
587function parseURL(url) {
588  var a = document.createElement('a')
589  a.href = url
590  return a
591}
592
593// Internal: Return the `href` component of given URL object with the hash
594// portion removed.
595//
596// location - Location or HTMLAnchorElement
597//
598// Returns String
599function stripHash(location) {
600  return location.href.replace(/#.*/, '')
601}
602
603// Internal: Build options Object for arguments.
604//
605// For convenience the first parameter can be either the container or
606// the options object.
607//
608// Examples
609//
610//   optionsFor('#container')
611//   // => {container: '#container'}
612//
613//   optionsFor('#container', {push: true})
614//   // => {container: '#container', push: true}
615//
616//   optionsFor({container: '#container', push: true})
617//   // => {container: '#container', push: true}
618//
619// Returns options Object.
620function optionsFor(container, options) {
621  if (container && options) {
622    options = $.extend({}, options)
623    options.container = container
624    return options
625  } else if ($.isPlainObject(container)) {
626    return container
627  } else {
628    return {container: container}
629  }
630}
631
632// Internal: Filter and find all elements matching the selector.
633//
634// Where $.fn.find only matches descendants, findAll will test all the
635// top level elements in the jQuery object as well.
636//
637// elems    - jQuery object of Elements
638// selector - String selector to match
639//
640// Returns a jQuery object.
641function findAll(elems, selector) {
642  return elems.filter(selector).add(elems.find(selector))
643}
644
645function parseHTML(html) {
646  return $.parseHTML(html, document, true)
647}
648
649// Internal: Extracts container and metadata from response.
650//
651// 1. Extracts X-PJAX-URL header if set
652// 2. Extracts inline <title> tags
653// 3. Builds response Element and extracts fragment if set
654//
655// data    - String response data
656// xhr     - XHR response
657// options - pjax options Object
658//
659// Returns an Object with url, title, and contents keys.
660function extractContainer(data, xhr, options) {
661  var obj = {}, fullDocument = /<html/i.test(data)
662
663  // Prefer X-PJAX-URL header if it was set, otherwise fallback to
664  // using the original requested url.
665  var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
666  obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl
667
668  var $head, $body
669  // Attempt to parse response html into elements
670  if (fullDocument) {
671    $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
672    var head = data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)
673    $head = head != null ? $(parseHTML(head[0])) : $body
674  } else {
675    $head = $body = $(parseHTML(data))
676  }
677
678  // If response data is empty, return fast
679  if ($body.length === 0)
680    return obj
681
682  // If there's a <title> tag in the header, use it as
683  // the page's title.
684  obj.title = findAll($head, 'title').last().text()
685
686  if (options.fragment) {
687    var $fragment = $body
688    // If they specified a fragment, look for it in the response
689    // and pull it out.
690    if (options.fragment !== 'body') {
691      $fragment = findAll($fragment, options.fragment).first()
692    }
693
694    if ($fragment.length) {
695      obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()
696
697      // If there's no title, look for data-title and title attributes
698      // on the fragment
699      if (!obj.title)
700        obj.title = $fragment.attr('title') || $fragment.data('title')
701    }
702
703  } else if (!fullDocument) {
704    obj.contents = $body
705  }
706
707  // Clean up any <title> tags
708  if (obj.contents) {
709    // Remove any parent title elements
710    obj.contents = obj.contents.not(function() { return $(this).is('title') })
711
712    // Then scrub any titles from their descendants
713    obj.contents.find('title').remove()
714
715    // Gather all script[src] elements
716    obj.scripts = findAll(obj.contents, 'script[src]').remove()
717    obj.contents = obj.contents.not(obj.scripts)
718  }
719
720  // Trim any whitespace off the title
721  if (obj.title) obj.title = $.trim(obj.title)
722
723  return obj
724}
725
726// Load an execute scripts using standard script request.
727//
728// Avoids jQuery's traditional $.getScript which does a XHR request and
729// globalEval.
730//
731// scripts - jQuery object of script Elements
732//
733// Returns nothing.
734function executeScriptTags(scripts) {
735  if (!scripts) return
736
737  var existingScripts = $('script[src]')
738
739  scripts.each(function() {
740    var src = this.src
741    var matchedScripts = existingScripts.filter(function() {
742      return this.src === src
743    })
744    if (matchedScripts.length) return
745
746    var script = document.createElement('script')
747    var type = $(this).attr('type')
748    if (type) script.type = type
749    script.src = $(this).attr('src')
750    document.head.appendChild(script)
751  })
752}
753
754// Internal: History DOM caching class.
755var cacheMapping      = {}
756var cacheForwardStack = []
757var cacheBackStack    = []
758
759// Push previous state id and container contents into the history
760// cache. Should be called in conjunction with `pushState` to save the
761// previous container contents.
762//
763// id    - State ID Number
764// value - DOM Element to cache
765//
766// Returns nothing.
767function cachePush(id, value) {
768  cacheMapping[id] = value
769  cacheBackStack.push(id)
770
771  // Remove all entries in forward history stack after pushing a new page.
772  trimCacheStack(cacheForwardStack, 0)
773
774  // Trim back history stack to max cache length.
775  trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)
776}
777
778// Shifts cache from directional history cache. Should be
779// called on `popstate` with the previous state id and container
780// contents.
781//
782// direction - "forward" or "back" String
783// id        - State ID Number
784// value     - DOM Element to cache
785//
786// Returns nothing.
787function cachePop(direction, id, value) {
788  var pushStack, popStack
789  cacheMapping[id] = value
790
791  if (direction === 'forward') {
792    pushStack = cacheBackStack
793    popStack  = cacheForwardStack
794  } else {
795    pushStack = cacheForwardStack
796    popStack  = cacheBackStack
797  }
798
799  pushStack.push(id)
800  id = popStack.pop()
801  if (id) delete cacheMapping[id]
802
803  // Trim whichever stack we just pushed to to max cache length.
804  trimCacheStack(pushStack, pjax.defaults.maxCacheLength)
805}
806
807// Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no
808// longer than the specified length, deleting cached DOM elements as necessary.
809//
810// stack  - Array of state IDs
811// length - Maximum length to trim to
812//
813// Returns nothing.
814function trimCacheStack(stack, length) {
815  while (stack.length > length)
816    delete cacheMapping[stack.shift()]
817}
818
819// Public: Find version identifier for the initial page load.
820//
821// Returns String version or undefined.
822function findVersion() {
823  return $('meta').filter(function() {
824    var name = $(this).attr('http-equiv')
825    return name && name.toUpperCase() === 'X-PJAX-VERSION'
826  }).attr('content')
827}
828
829// Install pjax functions on $.pjax to enable pushState behavior.
830//
831// Does nothing if already enabled.
832//
833// Examples
834//
835//     $.pjax.enable()
836//
837// Returns nothing.
838function enable() {
839  $.fn.pjax = fnPjax
840  $.pjax = pjax
841  $.pjax.enable = $.noop
842  $.pjax.disable = disable
843  $.pjax.click = handleClick
844  $.pjax.submit = handleSubmit
845  $.pjax.reload = pjaxReload
846  $.pjax.defaults = {
847    timeout: 650,
848    push: true,
849    replace: false,
850    type: 'GET',
851    dataType: 'html',
852    scrollTo: 0,
853    maxCacheLength: 20,
854    version: findVersion
855  }
856  $(window).on('popstate.pjax', onPjaxPopstate)
857}
858
859// Disable pushState behavior.
860//
861// This is the case when a browser doesn't support pushState. It is
862// sometimes useful to disable pushState for debugging on a modern
863// browser.
864//
865// Examples
866//
867//     $.pjax.disable()
868//
869// Returns nothing.
870function disable() {
871  $.fn.pjax = function() { return this }
872  $.pjax = fallbackPjax
873  $.pjax.enable = enable
874  $.pjax.disable = $.noop
875  $.pjax.click = $.noop
876  $.pjax.submit = $.noop
877  $.pjax.reload = function() { window.location.reload() }
878
879  $(window).off('popstate.pjax', onPjaxPopstate)
880}
881
882
883// Add the state property to jQuery's event object so we can use it in
884// $(window).bind('popstate')
885if ($.event.props && $.inArray('state', $.event.props) < 0) {
886  $.event.props.push('state')
887} else if (!('state' in $.Event.prototype)) {
888  $.event.addProp('state')
889}
890
891// Is pjax supported by this browser?
892$.support.pjax =
893  window.history && window.history.pushState && window.history.replaceState &&
894  // pushState isn't reliable on iOS until 5.
895  !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)
896
897if ($.support.pjax) {
898  enable()
899} else {
900  disable()
901}
902
903})(jQuery)

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.