PageSourceSearch

https://www.makanany.com/js/jquery.pjax.js

js makanany.com collected 2026-10-09 00:41:53 UTC 26,233 bytes, 935 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 - Where to stick the response body. Usually a String selector.
23//             $(container).html(xhr.responseBody)
24//             (default: current jquery context)
25//      push - Whether to pushState the URL. Defaults to true (of course).
26//   replace - Want to use replaceState instead? That's cool.
27//
28// For convenience the second parameter can be either the container or
29// the options object.
30//
31// Returns the jQuery object
32function fnPjax(selector, container, options) {
33  var context = this
34  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
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//  $(document).on('click', 'a', function(event) {
56//    var container = $(this).closest('[data-pjax-container]')
57//    $.pjax.click(event, container)
58//  })
59//
60// Returns nothing.
61function handleClick(event, container, options) {
62  options = optionsFor(container, options)
63
64  var link = event.currentTarget
65
66  if (link.tagName.toUpperCase() !== 'A')
67    throw "$.fn.pjax or $.pjax.click requires an anchor element"
68
69  // Middle click, cmd click, and ctrl click should open
70  // links in a new tab as normal.
71  if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )
72    return
73
74  // Ignore cross origin links
75  if ( location.protocol !== link.protocol || location.hostname !== link.hostname )
76    return
77
78  // Ignore case when a hash is being tacked on the current URL
79  if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )
80    return
81
82  // Ignore event with default prevented
83  if (event.isDefaultPrevented())
84    return
85
86  var defaults = {
87    url: link.href,
88    container: $(link).attr('data-pjax'),
89    target: link
90  }
91
92  var opts = $.extend({}, defaults, options)
93  var clickEvent = $.Event('pjax:click')
94  $(link).trigger(clickEvent, [opts])
95
96  if (!clickEvent.isDefaultPrevented()) {
97    pjax(opts)
98    event.preventDefault()
99    $(link).trigger('pjax:clicked', [opts])
100  }
101}
102
103// Public: pjax on form submit handler
104//
105// Exported as $.pjax.submit
106//
107// event   - "click" jQuery.Event
108// options - pjax options
109//
110// Examples
111//
112//  $(document).on('submit', 'form', function(event) {
113//    var container = $(this).closest('[data-pjax-container]')
114//    $.pjax.submit(event, container)
115//  })
116//
117// Returns nothing.
118function handleSubmit(event, container, options) {
119  options = optionsFor(container, options)
120
121  var form = event.currentTarget
122  var $form = $(form)
123
124  if (form.tagName.toUpperCase() !== 'FORM')
125    throw "$.pjax.submit requires a form element"
126
127  var defaults = {
128    type: ($form.attr('method') || 'GET').toUpperCase(),
129    url: $form.attr('action'),
130    container: $form.attr('data-pjax'),
131    target: form
132  }
133
134  if (defaults.type !== 'GET' && window.FormData !== undefined) {
135    defaults.data = new FormData(form);
136    defaults.processData = false;
137    defaults.contentType = false;
vendor: 9,684 bytes, lines 138-471
138  } else {
139    // Can't handle file uploads, exit
140    if ($(form).find(':file').length) {
141      return;
142    }
143
144    // Fallback to manually serializing the fields
145    defaults.data = $(form).serializeArray();
146  }
147
148  pjax($.extend({}, defaults, options))
149
150  event.preventDefault()
151}
152
153// Loads a URL with ajax, puts the response body inside a container,
154// then pushState()'s the loaded URL.
155//
156// Works just like $.ajax in that it accepts a jQuery ajax
157// settings object (with keys like url, type, data, etc).
158//
159// Accepts these extra keys:
160//
161// container - Where to stick the response body.
162//             $(container).html(xhr.responseBody)
163//      push - Whether to pushState the URL. Defaults to true (of course).
164//   replace - Want to use replaceState instead? That's cool.
165//
166// Use it just like $.ajax:
167//
168//   var xhr = $.pjax({ url: this.href, container: '#main' })
169//   console.log( xhr.readyState )
170//
171// Returns whatever $.ajax returns.
172function pjax(options) {
173  options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)
174
175  if ($.isFunction(options.url)) {
176    options.url = options.url()
177  }
178
179  var target = options.target
180
181  var hash = parseURL(options.url).hash
182
183  var context = options.context = findContainerFor(options.container)
184
185  // We want the browser to maintain two separate internal caches: one
186  // for pjax'd partial page loads and one for normal page loads.
187  // Without adding this secret parameter, some browsers will often
188  // confuse the two.
189  if (!options.data) options.data = {}
190  if ($.isArray(options.data)) {
191    options.data.push({name: '_pjax', value: context.selector})
192  } else {
193    options.data._pjax = context.selector
194  }
195
196  function fire(type, args, props) {
197    if (!props) props = {}
198    props.relatedTarget = target
199    var event = $.Event(type, props)
200    context.trigger(event, args)
201    return !event.isDefaultPrevented()
202  }
203
204  var timeoutTimer
205
206  options.beforeSend = function(xhr, settings) {
207    // No timeout for non-GET requests
208    // Its not safe to request the resource again with a fallback method.
209    if (settings.type !== 'GET') {
210      settings.timeout = 0
211    }
212
213    xhr.setRequestHeader('X-PJAX', 'true')
214    xhr.setRequestHeader('X-PJAX-Container', context.selector)
215
216    if (!fire('pjax:beforeSend', [xhr, settings]))
217      return false
218
219    if (settings.timeout > 0) {
220      timeoutTimer = setTimeout(function() {
221        if (fire('pjax:timeout', [xhr, options]))
222          xhr.abort('timeout')
223      }, settings.timeout)
224
225      // Clear timeout setting so jquerys internal timeout isn't invoked
226      settings.timeout = 0
227    }
228
229    var url = parseURL(settings.url)
230    if (hash) url.hash = hash
231    options.requestUrl = stripInternalParams(url)
232  }
233
234  options.complete = function(xhr, textStatus) {
235    if (timeoutTimer)
236      clearTimeout(timeoutTimer)
237
238    fire('pjax:complete', [xhr, textStatus, options])
239
240    fire('pjax:end', [xhr, options])
241  }
242
243  options.error = function(xhr, textStatus, errorThrown) {
244    var container = extractContainer("", xhr, options)
245
246    var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])
247    if (options.type == 'GET' && textStatus !== 'abort' && allowed) {
248      locationReplace(container.url)
249    }
250  }
251
252  options.success = function(data, status, xhr) {
253    var previousState = pjax.state;
254
255    // If $.pjax.defaults.version is a function, invoke it first.
256    // Otherwise it can be a static string.
257    var currentVersion = (typeof $.pjax.defaults.version === 'function') ?
258      $.pjax.defaults.version() :
259      $.pjax.defaults.version
260
261    var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
262
263    var container = extractContainer(data, xhr, options)
264
265    var url = parseURL(container.url)
266    if (hash) {
267      url.hash = hash
268      container.url = url.href
269    }
270
271    // If there is a layout version mismatch, hard load the new url
272    if (currentVersion && latestVersion && currentVersion !== latestVersion) {
273      locationReplace(container.url)
274      return
275    }
276
277    // If the new response is missing a body, hard load the page
278    if (!container.contents) {
279      locationReplace(container.url)
280      return
281    }
282
283    pjax.state = {
284      id: options.id || uniqueId(),
285      url: container.url,
286      title: container.title,
287      container: context.selector,
288      fragment: options.fragment,
289      timeout: options.timeout
290    }
291
292    if (options.push || options.replace) {
293      window.history.replaceState(pjax.state, container.title, container.url)
294    }
295
296    // Only blur the focus if the focused element is within the container.
297    var blurFocus = $.contains(options.container, document.activeElement)
298
299    // Clear out any focused controls before inserting new page contents.
300    if (blurFocus) {
301      try {
302        document.activeElement.blur()
303      } catch (e) { }
304    }
305
306    if (container.title) document.title = container.title
307
308    fire('pjax:beforeReplace', [container.contents, options], {
309      state: pjax.state,
310      previousState: previousState
311    })
312    context.html(container.contents)
313
314    // FF bug: Won't autofocus fields that are inserted via JS.
315    // This behavior is incorrect. So if theres no current focus, autofocus
316    // the last field.
317    //
318    // http://www.w3.org/html/wg/drafts/html/master/forms.html
319    var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]
320    if (autofocusEl && document.activeElement !== autofocusEl) {
321      autofocusEl.focus();
322    }
323
324    executeScriptTags(container.scripts)
325
326    var scrollTo = options.scrollTo
327
328    // Ensure browser scrolls to the element referenced by the URL anchor
329    if (hash) {
330      var name = decodeURIComponent(hash.slice(1))
331      var target = document.getElementById(name) || document.getElementsByName(name)[0]
332      if (target) scrollTo = $(target).offset().top
333    }
334
335    if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)
336
337    fire('pjax:success', [data, status, xhr, options])
338  }
339
340
341  // Initialize pjax.state for the initial page load. Assume we're
342  // using the container and options of the link we're loading for the
343  // back button to the initial page. This ensures good back button
344  // behavior.
345  if (!pjax.state) {
346    pjax.state = {
347      id: uniqueId(),
348      url: window.location.href,
349      title: document.title,
350      container: context.selector,
351      fragment: options.fragment,
352      timeout: options.timeout
353    }
354    window.history.replaceState(pjax.state, document.title)
355  }
356
357  // Cancel the current request if we're already pjaxing
358  abortXHR(pjax.xhr)
359
360  pjax.options = options
361  var xhr = pjax.xhr = $.ajax(options)
362
363  if (xhr.readyState > 0) {
364    if (options.push && !options.replace) {
365      // Cache current container element before replacing it
366      cachePush(pjax.state.id, cloneContents(context))
367
368      window.history.pushState(null, "", options.requestUrl)
369    }
370
371    fire('pjax:start', [xhr, options])
372    fire('pjax:send', [xhr, options])
373  }
374
375  return pjax.xhr
376}
377
378// Public: Reload current page with pjax.
379//
380// Returns whatever $.pjax returns.
381function pjaxReload(container, options) {
382  var defaults = {
383    url: window.location.href,
384    push: false,
385    replace: true,
386    scrollTo: false
387  }
388
389  return pjax($.extend(defaults, optionsFor(container, options)))
390}
391
392// Internal: Hard replace current state with url.
393//
394// Work for around WebKit
395//   https://bugs.webkit.org/show_bug.cgi?id=93506
396//
397// Returns nothing.
398function locationReplace(url) {
399  window.history.replaceState(null, "", pjax.state.url)
400  window.location.replace(url)
401}
402
403
404var initialPop = true
405var initialURL = window.location.href
406var initialState = window.history.state
407
408// Initialize $.pjax.state if possible
409// Happens when reloading a page and coming forward from a different
410// session history.
411if (initialState && initialState.container) {
412  pjax.state = initialState
413}
414
415// Non-webkit browsers don't fire an initial popstate event
416if ('state' in window.history) {
417  initialPop = false
418}
419
420// popstate handler takes care of the back and forward buttons
421//
422// You probably shouldn't use pjax on pages with other pushState
423// stuff yet.
424function onPjaxPopstate(event) {
425
426  // Hitting back or forward should override any pending PJAX request.
427  if (!initialPop) {
428    abortXHR(pjax.xhr)
429  }
430
431  var previousState = pjax.state
432  var state = event.state
433  var direction
434
435  if (state && state.container) {
436    // When coming forward from a separate history session, will get an
437    // initial pop with a state we are already at. Skip reloading the current
438    // page.
439    if (initialPop && initialURL == state.url) return
440
441    if (previousState) {
442      // If popping back to the same state, just skip.
443      // Could be clicking back from hashchange rather than a pushState.
444      if (previousState.id === state.id) return
445
446      // Since state IDs always increase, we can deduce the navigation direction
447      direction = previousState.id < state.id ? 'forward' : 'back'
448    }
449
450    var cache = cacheMapping[state.id] || []
451    var container = $(cache[0] || state.container), 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, 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: container,
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
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) jQuery._data(this, 'globalEval', false)
570  })
571  return [container.selector, 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, '')
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  // Both container and options
622  if ( container && options )
623    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.
648function 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 ) {
654    return container
655  } else if ( container.attr('id') ) {
656    return $('#' + container.attr('id'))
657  } else {
658    throw "cant get selector for pjax container!"
659  }
660}
661
662// Internal: Filter and find all elements matching the selector.
663//
664// Where $.fn.find only matches descendants, findAll will test all the
665// top level elements in the jQuery object as well.
666//
667// elems    - jQuery object of Elements
668// selector - String selector to match
669//
670// Returns a jQuery object.
671function findAll(elems, selector) {
672  return elems.filter(selector).add(elems.find(selector));
673}
674
675function parseHTML(html) {
676  return $.parseHTML(html, document, true)
677}
678
679// Internal: Extracts container and metadata from response.
680//
681// 1. Extracts X-PJAX-URL header if set
682// 2. Extracts inline <title> tags
683// 3. Builds response Element and extracts fragment if set
684//
685// data    - String response data
686// xhr     - XHR response
687// options - pjax options Object
688//
689// Returns an Object with url, title, and contents keys.
690function extractContainer(data, xhr, options) {
691  var obj = {}, fullDocument = /<html/i.test(data)
692
693  // Prefer X-PJAX-URL header if it was set, otherwise fallback to
694  // using the original requested url.
695  var serverUrl = xhr.getResponseHeader('X-PJAX-URL')
vendor: 5,929 bytes, lines 696-917
696  obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl
697
698  // Attempt to parse response html into elements
699  if (fullDocument) {
700    var $head = $(parseHTML(data.match(/<head[^>]*>([\s\S.]*)<\/head>/i)[0]))
701    var $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0]))
702  } else {
703    var $head = $body = $(parseHTML(data))
704  }
705
706  // If response data is empty, return fast
707  if ($body.length === 0)
708    return obj
709
710  // If there's a <title> tag in the header, use it as
711  // the page's title.
712  obj.title = findAll($head, 'title').last().text()
713
714  if (options.fragment) {
715    // If they specified a fragment, look for it in the response
716    // and pull it out.
717    if (options.fragment === 'body') {
718      var $fragment = $body
719    } else {
720      var $fragment = findAll($body, options.fragment).first()
721    }
722
723    if ($fragment.length) {
724      obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()
725
726      // If there's no title, look for data-title and title attributes
727      // on the fragment
728      if (!obj.title)
729        obj.title = $fragment.attr('title') || $fragment.data('title')
730    }
731
732  } else if (!fullDocument) {
733    obj.contents = $body
734  }
735
736  // Clean up any <title> tags
737  if (obj.contents) {
738    // Remove any parent title elements
739    obj.contents = obj.contents.not(function() { return $(this).is('title') })
740
741    // Then scrub any titles from their descendants
742    obj.contents.find('title').remove()
743
744    // Gather all script[src] elements
745    obj.scripts = findAll(obj.contents, 'script[src]').remove()
746    obj.contents = obj.contents.not(obj.scripts)
747  }
748
749  // Trim any whitespace off the title
750  if (obj.title) obj.title = $.trim(obj.title)
751
752  return obj
753}
754
755// Load an execute scripts using standard script request.
756//
757// Avoids jQuery's traditional $.getScript which does a XHR request and
758// globalEval.
759//
760// scripts - jQuery object of script Elements
761//
762// Returns nothing.
763function executeScriptTags(scripts) {
764  if (!scripts) return
765
766  var existingScripts = $('script[src]')
767
768  scripts.each(function() {
769    var src = this.src
770    var matchedScripts = existingScripts.filter(function() {
771      return this.src === src
772    })
773    if (matchedScripts.length) return
774
775    var script = document.createElement('script')
776    var type = $(this).attr('type')
777    if (type) script.type = type
778    script.src = $(this).attr('src')
779    document.head.appendChild(script)
780  })
781}
782
783// Internal: History DOM caching class.
784var cacheMapping      = {}
785var cacheForwardStack = []
786var cacheBackStack    = []
787
788// Push previous state id and container contents into the history
789// cache. Should be called in conjunction with `pushState` to save the
790// previous container contents.
791//
792// id    - State ID Number
793// value - DOM Element to cache
794//
795// Returns nothing.
796function cachePush(id, value) {
797  cacheMapping[id] = value
798  cacheBackStack.push(id)
799
800  // Remove all entries in forward history stack after pushing a new page.
801  trimCacheStack(cacheForwardStack, 0)
802
803  // Trim back history stack to max cache length.
804  trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)
805}
806
807// Shifts cache from directional history cache. Should be
808// called on `popstate` with the previous state id and container
809// contents.
810//
811// direction - "forward" or "back" String
812// id        - State ID Number
813// value     - DOM Element to cache
814//
815// Returns nothing.
816function cachePop(direction, id, value) {
817  var pushStack, popStack
818  cacheMapping[id] = value
819
820  if (direction === 'forward') {
821    pushStack = cacheBackStack
822    popStack  = cacheForwardStack
823  } else {
824    pushStack = cacheForwardStack
825    popStack  = cacheBackStack
826  }
827
828  pushStack.push(id)
829  if (id = popStack.pop())
830    delete cacheMapping[id]
831
832  // Trim whichever stack we just pushed to to max cache length.
833  trimCacheStack(pushStack, pjax.defaults.maxCacheLength)
834}
835
836// Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no
837// longer than the specified length, deleting cached DOM elements as necessary.
838//
839// stack  - Array of state IDs
840// length - Maximum length to trim to
841//
842// Returns nothing.
843function trimCacheStack(stack, length) {
844  while (stack.length > length)
845    delete cacheMapping[stack.shift()]
846}
847
848// Public: Find version identifier for the initial page load.
849//
850// Returns String version or undefined.
851function findVersion() {
852  return $('meta').filter(function() {
853    var name = $(this).attr('http-equiv')
854    return name && name.toUpperCase() === 'X-PJAX-VERSION'
855  }).attr('content')
856}
857
858// Install pjax functions on $.pjax to enable pushState behavior.
859//
860// Does nothing if already enabled.
861//
862// Examples
863//
864//     $.pjax.enable()
865//
866// Returns nothing.
867function enable() {
868  $.fn.pjax = fnPjax
869  $.pjax = pjax
870  $.pjax.enable = $.noop
871  $.pjax.disable = disable
872  $.pjax.click = handleClick
873  $.pjax.submit = handleSubmit
874  $.pjax.reload = pjaxReload
875  $.pjax.defaults = {
876    timeout: 650,
877    push: true,
878    replace: false,
879    type: 'GET',
880    dataType: 'html',
881    scrollTo: 0,
882    maxCacheLength: 20,
883    version: findVersion
884  }
885  $(window).on('popstate.pjax', onPjaxPopstate)
886}
887
888// Disable pushState behavior.
889//
890// This is the case when a browser doesn't support pushState. It is
891// sometimes useful to disable pushState for debugging on a modern
892// browser.
893//
894// Examples
895//
896//     $.pjax.disable()
897//
898// Returns nothing.
899function disable() {
900  $.fn.pjax = function() { return this }
901  $.pjax = fallbackPjax
902  $.pjax.enable = enable
903  $.pjax.disable = $.noop
904  $.pjax.click = $.noop
905  $.pjax.submit = $.noop
906  $.pjax.reload = function() { window.location.reload() }
907
908  $(window).off('popstate.pjax', onPjaxPopstate)
909}
910
911
912// Add the state property to jQuery's event object so we can use it in
913// $(window).bind('popstate')
914if ( $.inArray('state', $.event.props) < 0 )
915  $.event.props.push('state')
916
917// Is pjax supported by this browser?
918$.support.pjax =
919  window.history && window.history.pushState && window.history.replaceState &&
920  // pushState isn't reliable on iOS until 5.
921  !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)
922
923$.support.pjax ? enable() : disable()
924
925})(jQuery);
926
927
928
929(function(){
930    var cururl = window.location.href;
931    var bp = document.createElement('script');
932    bp.src = '/baidu_push_api.php?url='+encodeURI(cururl);
933    var s = document.getElementsByTagName("script")[0];
934    s.parentNode.insertBefore(bp, s);
935})();

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.