PageSourceSearch

https://idionline.org/assets/7677cf75/jquery.pjax.js?v=1790294359

js idionline.org collected 2026-09-24 23:59:42 UTC 29,273 bytes, 1,018 lines download raw bytes

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