vendor: 8,578 bytes, lines 1-305
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.
vendor: 11,194 bytes, lines 305-690
305meta){ 306 $('head').children('meta').remove(); 307 $('head').prepend(container.meta); 308 309 } 310 if (container.title) document.title = container.title 311 312 fire('pjax:beforeReplace', [container.contents, options], { 313 state: pjax.state, 314 previousState: previousState 315 }) 316 context.html(container.contents) 317 318 // FF bug: Won't autofocus fields that are inserted via JS. 319 // This behavior is incorrect. So if theres no current focus, autofocus 320 // the last field. 321 // 322 // http://www.w3.org/html/wg/drafts/html/master/forms.html 323 var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0] 324 if (autofocusEl && document.activeElement !== autofocusEl) { 325 autofocusEl.focus() 326 } 327 328 executeScriptTags(container.scripts) 329 330 var scrollTo = options.scrollTo 331 332 // Ensure browser scrolls to the element referenced by the URL anchor 333 if (hash) { 334 var name = decodeURIComponent(hash.slice(1)) 335 var target = document.getElementById(name) || document.getElementsByName(name)[0] 336 if (target) scrollTo = $(target).offset().top 337 } 338 339 if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo) 340 341 fire('pjax:success', [data, status, xhr, options]) 342 } 343 344 345 // Initialize pjax.state for the initial page load. Assume we're 346 // using the container and options of the link we're loading for the 347 // back button to the initial page. This ensures good back button 348 // behavior. 349 if (!pjax.state) { 350 pjax.state = { 351 id: uniqueId(), 352 url: window.location.href, 353 title: document.title, 354 container: options.container, 355 fragment: options.fragment, 356 timeout: options.timeout 357 } 358 window.history.replaceState(pjax.state, document.title) 359 } 360 361 // Cancel the current request if we're already pjaxing 362 abortXHR(pjax.xhr) 363 364 pjax.options = options 365 var xhr = pjax.xhr = $.ajax(options) 366 367 if (xhr.readyState > 0) { 368 if (options.push && !options.replace) { 369 // Cache current container element before replacing it 370 cachePush(pjax.state.id, [options.container, cloneContents(context)]) 371 372 window.history.pushState(null, "", options.requestUrl) 373 } 374 375 fire('pjax:start', [xhr, options]) 376 fire('pjax:send', [xhr, options]) 377 } 378 379 return pjax.xhr 380} 381 382// Public: Reload current page with pjax. 383// 384// Returns whatever $.pjax returns. 385function pjaxReload(container, options) { 386 var defaults = { 387 url: window.location.href, 388 push: false, 389 replace: true, 390 scrollTo: false 391 } 392 393 return pjax($.extend(defaults, optionsFor(container, options))) 394} 395 396// Internal: Hard replace current state with url. 397// 398// Work for around WebKit 399// https://bugs.webkit.org/show_bug.cgi?id=93506 400// 401// Returns nothing. 402function locationReplace(url) { 403 window.history.replaceState(null, "", pjax.state.url) 404 window.location.replace(url) 405} 406 407 408var initialPop = true 409var initialURL = window.location.href 410var initialState = window.history.state 411 412// Initialize $.pjax.state if possible 413// Happens when reloading a page and coming forward from a different 414// session history. 415if (initialState && initialState.container) { 416 pjax.state = initialState 417} 418 419// Non-webkit browsers don't fire an initial popstate event 420if ('state' in window.history) { 421 initialPop = false 422} 423 424// popstate handler takes care of the back and forward buttons 425// 426// You probably shouldn't use pjax on pages with other pushState 427// stuff yet. 428function onPjaxPopstate(event) { 429 430 // Hitting back or forward should override any pending PJAX request. 431 if (!initialPop) { 432 abortXHR(pjax.xhr) 433 } 434 435 var previousState = pjax.state 436 var state = event.state 437 var direction 438 439 if (state && state.container) { 440 // When coming forward from a separate history session, will get an 441 // initial pop with a state we are already at. Skip reloading the current 442 // page. 443 if (initialPop && initialURL == state.url) return 444 445 if (previousState) { 446 // If popping back to the same state, just skip. 447 // Could be clicking back from hashchange rather than a pushState. 448 if (previousState.id === state.id) return 449 450 // Since state IDs always increase, we can deduce the navigation direction 451 direction = previousState.id < state.id ? 'forward' : 'back' 452 } 453 454 var cache = cacheMapping[state.id] || [] 455 var containerSelector = cache[0] || state.container 456 var container = $(containerSelector), contents = cache[1] 457 458 if (container.length) { 459 if (previousState) { 460 // Cache current container before replacement and inform the 461 // cache which direction the history shifted. 462 cachePop(direction, previousState.id, [containerSelector, cloneContents(container)]) 463 } 464 465 var popstateEvent = $.Event('pjax:popstate', { 466 state: state, 467 direction: direction 468 }) 469 container.trigger(popstateEvent) 470 471 var options = { 472 id: state.id, 473 url: state.url, 474 container: containerSelector, 475 push: false, 476 fragment: state.fragment, 477 timeout: state.timeout, 478 scrollTo: false 479 } 480 481 // if (contents) { 482 // container.trigger('pjax:start', [null, options]) 483 // 484 // pjax.state = state 485 // if (state.title) document.title = state.title 486 // var beforeReplaceEvent = $.Event('pjax:beforeReplace', { 487 // state: state, 488 // previousState: previousState 489 // }) 490 // container.trigger(beforeReplaceEvent, [contents, options]) 491 // container.html(contents) 492 // 493 // container.trigger('pjax:end', [null, options]) 494 // } else { 495 // pjax(options) 496 // } 497 pjax(options) 498 // Force reflow/relayout before the browser tries to restore the 499 // scroll position. 500 container[0].offsetHeight // eslint-disable-line no-unused-expressions 501 } else { 502 locationReplace(location.href) 503 } 504 } 505 initialPop = false 506} 507 508// Fallback version of main pjax function for browsers that don't 509// support pushState. 510// 511// Returns nothing since it retriggers a hard form submission. 512function fallbackPjax(options) { 513 var url = $.isFunction(options.url) ? options.url() : options.url, 514 method = options.type ? options.type.toUpperCase() : 'GET' 515 516 var form = $('<form>', { 517 method: method === 'GET' ? 'GET' : 'POST', 518 action: url, 519 style: 'display:none' 520 }) 521 522 if (method !== 'GET' && method !== 'POST') { 523 form.append($('<input>', { 524 type: 'hidden', 525 name: '_method', 526 value: method.toLowerCase() 527 })) 528 } 529 530 var data = options.data 531 if (typeof data === 'string') { 532 $.each(data.split('&'), function(index, value) { 533 var pair = value.split('=') 534 form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]})) 535 }) 536 } else if ($.isArray(data)) { 537 $.each(data, function(index, value) { 538 form.append($('<input>', {type: 'hidden', name: value.name, value: value.value})) 539 }) 540 } else if (typeof data === 'object') { 541 var key 542 for (key in data) 543 form.append($('<input>', {type: 'hidden', name: key, value: data[key]})) 544 } 545 546 $(document.body).append(form) 547 form.submit() 548} 549 550// Internal: Abort an XmlHttpRequest if it hasn't been completed, 551// also removing its event handlers. 552function abortXHR(xhr) { 553 if ( xhr && xhr.readyState < 4) { 554 xhr.onreadystatechange = $.noop 555 xhr.abort() 556 } 557} 558 559// Internal: Generate unique id for state object. 560// 561// Use a timestamp instead of a counter since ids should still be 562// unique across page loads. 563// 564// Returns Number. 565function uniqueId() { 566 return (new Date).getTime() 567} 568 569function cloneContents(container) { 570 var cloned = container.clone() 571 // Unmark script tags as already being eval'd so they can get executed again 572 // when restored from cache. HAXX: Uses jQuery internal method. 573 cloned.find('script').each(function(){ 574 if (!this.src) $._data(this, 'globalEval', false) 575 }) 576 return cloned.contents() 577} 578 579// Internal: Strip internal query params from parsed URL. 580// 581// Returns sanitized url.href String. 582function stripInternalParams(url) { 583 url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '').replace(/^&/, '') 584 return url.href.replace(/\?($|#)/, '$1') 585} 586 587// Internal: Parse URL components and returns a Locationish object. 588// 589// url - String URL 590// 591// Returns HTMLAnchorElement that acts like Location. 592function parseURL(url) { 593 var a = document.createElement('a') 594 a.href = url 595 return a 596} 597 598// Internal: Return the `href` component of given URL object with the hash 599// portion removed. 600// 601// location - Location or HTMLAnchorElement 602// 603// Returns String 604function stripHash(location) { 605 return location.href.replace(/#.*/, '') 606} 607 608// Internal: Build options Object for arguments. 609// 610// For convenience the first parameter can be either the container or 611// the options object. 612// 613// Examples 614// 615// optionsFor('#container') 616// // => {container: '#container'} 617// 618// optionsFor('#container', {push: true}) 619// // => {container: '#container', push: true} 620// 621// optionsFor({container: '#container', push: true}) 622// // => {container: '#container', push: true} 623// 624// Returns options Object. 625function optionsFor(container, options) { 626 if (container && options) { 627 options = $.extend({}, options) 628 options.container = container 629 return options 630 } else if ($.isPlainObject(container)) { 631 return container 632 } else { 633 return {container: container} 634 } 635} 636 637// Internal: Filter and find all elements matching the selector. 638// 639// Where $.fn.find only matches descendants, findAll will test all the 640// top level elements in the jQuery object as well. 641// 642// elems - jQuery object of Elements 643// selector - String selector to match 644// 645// Returns a jQuery object. 646function findAll(elems, selector) { 647 return elems.filter(selector).add(elems.find(selector)) 648} 649 650function parseHTML(html) { 651 return $.parseHTML(html, document, true) 652} 653 654// Internal: Extracts container and metadata from response. 655// 656// 1. Extracts X-PJAX-URL header if set 657// 2. Extracts inline <title> tags 658// 3. Builds response Element and extracts fragment if set 659// 660// data - String response data 661// xhr - XHR response 662// options - pjax options Object 663// 664// Returns an Object with url, title, and contents keys. 665function extractContainer(data, xhr, options) { 666 var obj = {}, fullDocument = /<html/i.test(data) 667 668 // Prefer X-PJAX-URL header if it was set, otherwise fallback to 669 // using the original requested url. 670 var serverUrl = xhr.getResponseHeader('X-PJAX-URL') 671 obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl 672 673 var $head, $body 674 // Attempt to parse response html into elements 675 if (fullDocument) { 676 $body = $(parseHTML(data.match(/<body[^>]*>([\s\S.]*)<\/body>/i)[0])) 677 var head = data.match(/<head[^>]*>([\s\S.]*)<\/head>/i) 678 $head = head != null ? $(parseHTML(head[0])) : $body 679 } else { 680 $head = $body = $(parseHTML(data)) 681 } 682 683 // If response data is empty, return fast 684 if ($body.length === 0) 685 return obj 686 687 // If there's a <title> tag in the header, use it as 688 // the page's title. 689 obj.meta = findAll($head, 'meta'); 690 obj.title = findAll($head, 'title').last().text();
vendor: 5,719 bytes, lines 690-909
690 691 692 if (options.fragment) { 693 var $fragment = $body 694 // If they specified a fragment, look for it in the response 695 // and pull it out. 696 if (options.fragment !== 'body') { 697 $fragment = findAll($fragment, options.fragment).first() 698 } 699 700 if ($fragment.length) { 701 obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents() 702 703 // If there's no title, look for data-title and title attributes 704 // on the fragment 705 if (!obj.title) 706 obj.title = $fragment.attr('title') || $fragment.data('title') 707 } 708 709 } else if (!fullDocument) { 710 obj.contents = $body 711 } 712 713 // Clean up any <title> tags 714 if (obj.contents) { 715 // Remove any parent title elements 716 obj.contents = obj.contents.not(function() { return $(this).is('title') }) 717 718 // Then scrub any titles from their descendants 719 obj.contents.find('title').remove() 720 721 // Gather all script[src] elements 722 obj.scripts = findAll(obj.contents, 'script[src]').remove() 723 obj.contents = obj.contents.not(obj.scripts) 724 } 725 726 // Trim any whitespace off the title 727 if (obj.title) obj.title = $.trim(obj.title) 728 729 return obj 730} 731 732// Load an execute scripts using standard script request. 733// 734// Avoids jQuery's traditional $.getScript which does a XHR request and 735// globalEval. 736// 737// scripts - jQuery object of script Elements 738// 739// Returns nothing. 740function executeScriptTags(scripts) { 741 if (!scripts) return 742 743 var existingScripts = $('script[src]') 744 745 scripts.each(function() { 746 var src = this.src 747 var matchedScripts = existingScripts.filter(function() { 748 return this.src === src 749 }) 750 if (matchedScripts.length) return 751 752 var script = document.createElement('script') 753 var type = $(this).attr('type') 754 if (type) script.type = type 755 script.src = $(this).attr('src') 756 document.head.appendChild(script) 757 }) 758} 759 760// Internal: History DOM caching class. 761var cacheMapping = {} 762var cacheForwardStack = [] 763var cacheBackStack = [] 764 765// Push previous state id and container contents into the history 766// cache. Should be called in conjunction with `pushState` to save the 767// previous container contents. 768// 769// id - State ID Number 770// value - DOM Element to cache 771// 772// Returns nothing. 773function cachePush(id, value) { 774 cacheMapping[id] = value 775 cacheBackStack.push(id) 776 777 // Remove all entries in forward history stack after pushing a new page. 778 trimCacheStack(cacheForwardStack, 0) 779 780 // Trim back history stack to max cache length. 781 trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength) 782} 783 784// Shifts cache from directional history cache. Should be 785// called on `popstate` with the previous state id and container 786// contents. 787// 788// direction - "forward" or "back" String 789// id - State ID Number 790// value - DOM Element to cache 791// 792// Returns nothing. 793function cachePop(direction, id, value) { 794 var pushStack, popStack 795 cacheMapping[id] = value 796 797 if (direction === 'forward') { 798 pushStack = cacheBackStack 799 popStack = cacheForwardStack 800 } else { 801 pushStack = cacheForwardStack 802 popStack = cacheBackStack 803 } 804 805 pushStack.push(id) 806 id = popStack.pop() 807 if (id) delete cacheMapping[id] 808 809 // Trim whichever stack we just pushed to to max cache length. 810 trimCacheStack(pushStack, pjax.defaults.maxCacheLength) 811} 812 813// Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no 814// longer than the specified length, deleting cached DOM elements as necessary. 815// 816// stack - Array of state IDs 817// length - Maximum length to trim to 818// 819// Returns nothing. 820function trimCacheStack(stack, length) { 821 while (stack.length > length) 822 delete cacheMapping[stack.shift()] 823} 824 825// Public: Find version identifier for the initial page load. 826// 827// Returns String version or undefined. 828function findVersion() { 829 return $('meta').filter(function() { 830 var name = $(this).attr('http-equiv') 831 return name && name.toUpperCase() === 'X-PJAX-VERSION' 832 }).attr('content') 833} 834 835// Install pjax functions on $.pjax to enable pushState behavior. 836// 837// Does nothing if already enabled. 838// 839// Examples 840// 841// $.pjax.enable() 842// 843// Returns nothing. 844function enable() { 845 $.fn.pjax = fnPjax 846 $.pjax = pjax 847 $.pjax.enable = $.noop 848 $.pjax.disable = disable 849 $.pjax.click = handleClick 850 $.pjax.submit = handleSubmit 851 $.pjax.reload = pjaxReload 852 $.pjax.defaults = { 853 timeout: 650, 854 push: true, 855 replace: false, 856 type: 'GET', 857 dataType: 'html', 858 scrollTo: 0, 859 maxCacheLength: 20, 860 version: findVersion 861 } 862 $(window).on('popstate.pjax', onPjaxPopstate) 863} 864 865// Disable pushState behavior. 866// 867// This is the case when a browser doesn't support pushState. It is 868// sometimes useful to disable pushState for debugging on a modern 869// browser. 870// 871// Examples 872// 873// $.pjax.disable() 874// 875// Returns nothing. 876function disable() { 877 $.fn.pjax = function() { return this } 878 $.pjax = fallbackPjax 879 $.pjax.enable = enable 880 $.pjax.disable = $.noop 881 $.pjax.click = $.noop 882 $.pjax.submit = $.noop 883 $.pjax.reload = function() { window.location.reload() } 884 885 $(window).off('popstate.pjax', onPjaxPopstate) 886} 887 888 889// Add the state property to jQuery's event object so we can use it in 890// $(window).bind('popstate') 891if ($.event.props && $.inArray('state', $.event.props) < 0) { 892 $.event.props.push('state') 893} else if (!('state' in $.Event.prototype)) { 894 $.event.addProp('state') 895} 896 897// Is pjax supported by this browser? 898$.support.pjax = 899 window.history && window.history.pushState && window.history.replaceState && 900 // pushState isn't reliable on iOS until 5. 901 !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/) 902 903if ($.support.pjax) { 904 enable() 905} else { 906 disable() 907} 908 909})(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.