1/* 2 * This file contains modifications! 3 */ 4 5 6(function() { 7 var CSRFToken, Click, ComponentUrl, EVENTS, Link, ProgressBar, browserIsntBuggy, browserSupportsCustomEvents, browserSupportsPushState, browserSupportsTurbolinks, bypassOnLoadPopstate, cacheCurrentPage, cacheSize, changePage, clone, constrainPageCacheTo, createDocument, crossOriginRedirect, currentState, enableProgressBar, enableTransitionCache, executeScriptTags, extractTitleAndBody, fetch, fetchHistory, fetchReplacement, historyStateIsDefined, initializeTurbolinks, installDocumentReadyPageEventTriggers, installHistoryChangeHandler, installJqueryAjaxSuccessPageUpdateTrigger, loadedAssets, manuallyTriggerHashChangeForFirefox, pageCache, pageChangePrevented, pagesCached, popCookie, processResponse, progressBar, recallScrollPosition, ref, referer, reflectNewUrl, reflectRedirectedUrl, rememberCurrentState, rememberCurrentUrl, rememberReferer, removeNoscriptTags, requestMethodIsSafe, resetScrollPosition, setAutofocusElement, transitionCacheEnabled, transitionCacheFor, triggerEvent, visit, xhr, 8 indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, 9 extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, 10 hasProp = {}.hasOwnProperty, 11 slice = [].slice, 12 bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; 13 14 pageCache = {}; 15 16 cacheSize = 10; 17 18 transitionCacheEnabled = false; 19 20 progressBar = null; 21 22 currentState = null; 23 24 loadedAssets = null; 25 26 referer = null; 27 28 xhr = null; 29 30 EVENTS = { 31 BEFORE_CHANGE: 'page:before-change', 32 FETCH: 'page:fetch', 33 RECEIVE: 'page:receive', 34 CHANGE: 'page:change', 35 UPDATE: 'page:update', 36 LOAD: 'page:load', 37 RESTORE: 'page:restore', 38 BEFORE_UNLOAD: 'page:before-unload', 39 EXPIRE: 'page:expire' 40 }; 41 42 fetch = function(url) { 43 var cachedPage; 44 url = new ComponentUrl(url); 45 rememberReferer(); 46 cacheCurrentPage(); 47 if (progressBar != null) { 48 progressBar.start(); 49 } 50 if (transitionCacheEnabled && (cachedPage = transitionCacheFor(url.absolute))) { 51 fetchHistory(cachedPage); 52 return fetchReplacement(url, null, false); 53 } else { 54 return fetchReplacement(url, resetScrollPosition); 55 } 56 }; 57 58 transitionCacheFor = function(url) { 59 var cachedPage; 60 cachedPage = pageCache[url]; 61 if (cachedPage && !cachedPage.transitionCacheDisabled) { 62 return cachedPage; 63 } 64 }; 65 66 enableTransitionCache = function(enable) { 67 if (enable == null) { 68 enable = true; 69 } 70 return transitionCacheEnabled = enable; 71 }; 72 73 enableProgressBar = function(enable) { 74 if (enable == null) { 75 enable = true; 76 } 77 if (!browserSupportsTurbolinks) { 78 return; 79 } 80 if (enable) { 81 return progressBar != null ? progressBar : progressBar = new ProgressBar('html'); 82 } else { 83 if (progressBar != null) { 84 progressBar.uninstall(); 85 } 86 return progressBar = null; 87 } 88 }; 89 90 fetchReplacement = function(url, onLoadFunction, showProgressBar) { 91 if (showProgressBar == null) { 92 showProgressBar = true; 93 } 94 triggerEvent(EVENTS.FETCH, { 95 url: url.absolute 96 }); 97 if (xhr != null) { 98 xhr.abort(); 99 } 100 xhr = new XMLHttpRequest; 101 xhr.open('GET', url.withoutHashForIE10compatibility(), true); 102 xhr.setRequestHeader('Accept', 'text/html, application/xhtml+xml, application/xml'); 103 xhr.setRequestHeader('X-XHR-Referer', referer); 104 xhr.onload = function() { 105 var doc; 106 triggerEvent(EVENTS.RECEIVE, { 107 url: url.absolute 108 }); 109 if (doc = processResponse()) { 110 reflectNewUrl(url); 111 reflectRedirectedUrl(); 112 changePage.apply(null, extractTitleAndBody(doc)); 113 manuallyTriggerHashChangeForFirefox(); 114 if (typeof onLoadFunction === "function") { 115 onLoadFunction(); 116 } 117 return triggerEvent(EVENTS.LOAD); 118 } else { 119 return document.location.href = crossOriginRedirect() || url.absolute; 120 } 121 }; 122 if (progressBar && showProgressBar) { 123 xhr.onprogress = (function(_this) { 124 return function(event) { 125 var percent; 126 percent = event.lengthComputable ? event.loaded / event.total * 100 : progressBar.value + (100 - progressBar.value) / 10; 127 return progressBar.advanceTo(percent); 128 }; 129 })(this); 130 } 131 xhr.onloadend = function() { 132 return xhr = null; 133 }; 134 xhr.onerror = function() { 135 return document.location.href = url.absolute; 136 }; 137 return xhr.send(); 138 }; 139 140 fetchHistory = function(cachedPage) { 141 if (xhr != null) { 142 xhr.abort(); 143 } 144 changePage(cachedPage.title, cachedPage.body); 145 recallScrollPosition(cachedPage); 146 return triggerEvent(EVENTS.RESTORE); 147 }; 148 149 cacheCurrentPage = function() { 150 var currentStateUrl; 151 currentStateUrl = new ComponentUrl(currentState.url); 152 pageCache[currentStateUrl.absolute] = { 153 url: currentStateUrl.relative, 154 body: document.body, 155 title: document.title, 156 positionY: window.pageYOffset, 157 positionX: window.pageXOffset, 158 cachedAt: new Date().getTime(), 159 transitionCacheDisabled: document.querySelector('[data-no-transition-cache]') != null 160 }; 161 return constrainPageCacheTo(cacheSize); 162 }; 163 164 pagesCached = function(size) { 165 if (size == null) { 166 size = cacheSize; 167 } 168 if (/^[\d]+$/.test(size)) { 169 return cacheSize = parseInt(size); 170 } 171 }; 172 173 constrainPageCacheTo = function(limit) { 174 var cacheTimesRecentFirst, i, key, len, pageCacheKeys, results; 175 pageCacheKeys = Object.keys(pageCache); 176 cacheTimesRecentFirst = pageCacheKeys.map(function(url) { 177 return pageCache[url].cachedAt; 178 }).sort(function(a, b) { 179 return b - a; 180 }); 181 results = [];
182 for (i = 0, len = pageCacheKeys.length; i < len; i++) { 183 key = pageCacheKeys[i]; 184 if (!(pageCache[key].cachedAt <= cacheTimesRecentFirst[limit])) { 185 continue; 186 } 187 triggerEvent(EVENTS.EXPIRE, pageCache[key]); 188 results.push(delete pageCache[key]); 189 } 190 return results; 191 }; 192 193 changePage = function(title, body, csrfToken, runScripts) { 194 triggerEvent(EVENTS.BEFORE_UNLOAD); 195 document.title = title; 196 document.documentElement.replaceChild(body, document.body); 197 if (csrfToken != null) { 198 CSRFToken.update(csrfToken); 199 } 200 setAutofocusElement(); 201 if (runScripts) { 202 executeScriptTags(); 203 } 204 currentState = window.history.state; 205 if (progressBar != null) { 206 progressBar.done(); 207 } 208 triggerEvent(EVENTS.CHANGE); 209 return triggerEvent(EVENTS.UPDATE); 210 }; 211 212 executeScriptTags = function() { 213 var attr, copy, i, j, len, len1, nextSibling, parentNode, ref, ref1, script, scripts; 214 scripts = Array.prototype.slice.call(document.body.querySelectorAll('script:not([data-turbolinks-eval="false"])')); 215 for (i = 0, len = scripts.length; i < len; i++) { 216 script = scripts[i]; 217 if (!((ref = script.type) === '' || ref === 'text/javascript')) { 218 continue; 219 } 220 copy = document.createElement('script'); 221 ref1 = script.attributes; 222 for (j = 0, len1 = ref1.length; j < len1; j++) { 223 attr = ref1[j]; 224 copy.setAttribute(attr.name, attr.value); 225 } 226 if (!script.hasAttribute('async')) { 227 copy.async = false; 228 } 229 copy.appendChild(document.createTextNode(script.innerHTML)); 230 parentNode = script.parentNode, nextSibling = script.nextSibling; 231 parentNode.removeChild(script); 232 parentNode.insertBefore(copy, nextSibling); 233 } 234 }; 235 236 removeNoscriptTags = function(node) { 237 node.innerHTML = node.innerHTML.replace(/<noscript[\S\s]*?<\/noscript>/ig, ''); 238 return node; 239 }; 240 241 setAutofocusElement = function() { 242 var autofocusElement, list; 243 autofocusElement = (list = document.querySelectorAll('input[autofocus], textarea[autofocus]'))[list.length - 1]; 244 if (autofocusElement && document.activeElement !== autofocusElement) { 245 return autofocusElement.focus(); 246 } 247 }; 248 249 reflectNewUrl = function(url) { 250 if ((url = new ComponentUrl(url)).absolute !== referer) { 251 return window.history.pushState({ 252 turbolinks: true, 253 url: url.absolute 254 }, '', url.absolute); 255 } 256 }; 257 258 reflectRedirectedUrl = function() { 259 var location, preservedHash, 260 currentLocation = window.location.pathname; 261 if (xhr.getResponseHeader('X-Format-Path')) { 262 location = '/' + xhr.getResponseHeader('X-Format-Path'); 263 if (currentLocation != location) { 264 location = new ComponentUrl(location); 265 preservedHash = location.hasNoHash() ? document.location.hash : ''; 266 return window.history.replaceState(window.history.state, '', location.href + preservedHash); 267 } 268 } 269 }; 270 271 crossOriginRedirect = function() { 272 var redirect; 273 if (((redirect = xhr.getResponseHeader('Location')) != null) && (new ComponentUrl(redirect)).crossOrigin()) { 274 return redirect; 275 } 276 }; 277 278 rememberReferer = function() { 279 return referer = document.location.href; 280 }; 281 282 rememberCurrentUrl = function() { 283 return window.history.replaceState({ 284 turbolinks: true, 285 url: document.location.href 286 }, '', document.location.href); 287 }; 288 289 rememberCurrentState = function() { 290 return currentState = window.history.state; 291 }; 292 293 manuallyTriggerHashChangeForFirefox = function() { 294 var url; 295 if (navigator.userAgent.match(/Firefox/) && !(url = new ComponentUrl).hasNoHash()) { 296 window.history.replaceState(currentState, '', url.withoutHash()); 297 return document.location.hash = url.hash; 298 } 299 }; 300 301 recallScrollPosition = function(page) {
302 return window.scrollTo(page.positionX, page.positionY); 303 }; 304 305 resetScrollPosition = function() { 306 if (document.location.hash) { 307 return document.location.href = document.location.href; 308 } else { 309 return window.scrollTo(0, 0); 310 } 311 }; 312 313 clone = function(original) { 314 var copy, key, value; 315 if ((original == null) || typeof original !== 'object') { 316 return original; 317 } 318 copy = new original.constructor(); 319 for (key in original) { 320 value = original[key]; 321 copy[key] = clone(value); 322 } 323 return copy; 324 }; 325 326 popCookie = function(name) { 327 var ref, value; 328 value = ((ref = document.cookie.match(new RegExp(name + "=(\\w+)"))) != null ? ref[1].toUpperCase() : void 0) || ''; 329 document.cookie = name + '=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/'; 330 return value; 331 }; 332 333 triggerEvent = function(name, data) { 334 var event; 335 if (typeof Prototype !== 'undefined') { 336 Event.fire(document, name, data, true); 337 } 338 event = document.createEvent('Events'); 339 if (data) { 340 event.data = data; 341 } 342 event.initEvent(name, true, true); 343 return document.dispatchEvent(event); 344 }; 345 346 pageChangePrevented = function(url) { 347 return !triggerEvent(EVENTS.BEFORE_CHANGE, { 348 url: url 349 }); 350 }; 351 352 processResponse = function() { 353 var assetsChanged, clientOrServerError, doc, extractTrackAssets, intersection, validContent; 354 clientOrServerError = function() { 355 var ref; 356 return (400 <= (ref = xhr.status) && ref < 600); 357 }; 358 validContent = function() { 359 var contentType; 360 return ((contentType = xhr.getResponseHeader('Content-Type')) != null) && contentType.match(/^(?:text\/html|application\/xhtml\+xml|application\/xml)(?:;|$)/); 361 }; 362 extractTrackAssets = function(doc) { 363 var i, len, node, ref, results; 364 ref = doc.querySelector('head').childNodes; 365 results = []; 366 for (i = 0, len = ref.length; i < len; i++) { 367 node = ref[i]; 368 if ((typeof node.getAttribute === "function" ? node.getAttribute('data-turbolinks-track') : void 0) != null) { 369 results.push(node.getAttribute('src') || node.getAttribute('href')); 370 } 371 } 372 return results; 373 }; 374 assetsChanged = function(doc) { 375 var fetchedAssets; 376 loadedAssets || (loadedAssets = extractTrackAssets(document)); 377 fetchedAssets = extractTrackAssets(doc); 378 return fetchedAssets.length !== loadedAssets.length || intersection(fetchedAssets, loadedAssets).length !== loadedAssets.length; 379 }; 380 intersection = function(a, b) { 381 var i, len, ref, results, value; 382 if (a.length > b.length) { 383 ref = [b, a], a = ref[0], b = ref[1]; 384 } 385 results = []; 386 for (i = 0, len = a.length; i < len; i++) { 387 value = a[i]; 388 if (indexOf.call(b, value) >= 0) { 389 results.push(value); 390 } 391 } 392 return results; 393 }; 394 if (!clientOrServerError() && validContent()) { 395 doc = createDocument(xhr.responseText); 396 if (doc && !assetsChanged(doc)) { 397 return doc; 398 } 399 } 400 }; 401 402 extractTitleAndBody = function(doc) { 403 var title; 404 title = doc.querySelector('title'); 405 return [title != null ? title.textContent : void 0, removeNoscriptTags(doc.querySelector('body')), CSRFToken.get(doc).token, 'runScripts']; 406 }; 407 408 CSRFToken = { 409 get: function(doc) { 410 var tag; 411 if (doc == null) { 412 doc = document; 413 } 414 return { 415 node: tag = doc.querySelector('meta[name="csrf-token"]'), 416 token: tag != null ? typeof tag.getAttribute === "function" ? tag.getAttribute('content') : void 0 : void 0 417 }; 418 }, 419 update: function(latest) { 420 var current; 421 current = this.get(); 422 if ((current.token != null) && (latest != null) && current.token !== latest) { 423 return current.node.setAttribute('content', latest); 424 } 425 } 426 }; 427 428 createDocument = function(html) { 429 var doc; 430 doc = document.documentElement.cloneNode(); 431 doc.innerHTML = html; 432 doc.head = doc.querySelector('head'); 433 doc.body = doc.querySelector('body'); 434 return doc; 435 }; 436 437 ComponentUrl = (function() { 438 function ComponentUrl(original1) { 439 this.original = original1 != null ? original1 : document.location.href; 440 if (this.original.constructor === ComponentUrl) { 441 return this.original; 442 } 443 this._parse(); 444 } 445 446 ComponentUrl.prototype.withoutHash = function() { 447 return this.href.replace(this.hash, '').replace('#', ''); 448 }; 449 450 ComponentUrl.prototype.withoutHashForIE10compatibility = function() { 451 return this.withoutHash(); 452 }; 453 454 ComponentUrl.prototype.hasNoHash = function() { 455 return this.hash.length === 0; 456 }; 457 458 ComponentUrl.prototype.crossOrigin = function() { 459 return this.origin !== (new ComponentUrl).origin; 460 }; 461 462 ComponentUrl.prototype._parse = function() { 463 var ref; 464 (this.link != null ? this.link : this.link = document.createElement('a')).href = this.original; 465 ref = this.link, this.href = ref.href, this.protocol = ref.protocol, this.host = ref.host, this.hostname = ref.hostname, this.port = ref.port, this.pathname = ref.pathname, this.search = ref.search, this.hash = ref.hash; 466 this.origin = [this.protocol, '//', this.hostname].join(''); 467 if (this.port.length !== 0) { 468 this.origin += ":" + this.port; 469 } 470 this.relative = [this.pathname, this.search, this.hash].join(''); 471 return this.absolute = this.href; 472 }; 473 474 return ComponentUrl; 475 476 })(); 477 478 Link = (function(superClass) { 479 extend(Link, superClass); 480
481 Link.HTML_EXTENSIONS = ['html']; 482 483 Link.allowExtensions = function() { 484 var extension, extensions, i, len; 485 extensions = 1 <= arguments.length ? slice.call(arguments, 0) : []; 486 for (i = 0, len = extensions.length; i < len; i++) { 487 extension = extensions[i]; 488 Link.HTML_EXTENSIONS.push(extension); 489 } 490 return Link.HTML_EXTENSIONS; 491 }; 492 493 function Link(link1) { 494 this.link = link1; 495 if (this.link.constructor === Link) { 496 return this.link; 497 } 498 this.original = this.link.href; 499 this.originalElement = this.link; 500 this.link = this.link.cloneNode(false); 501 Link.__super__.constructor.apply(this, arguments); 502 } 503 504 Link.prototype.shouldIgnore = function() { 505 return this.crossOrigin() || this._anchored() || this._nonHtml() || this._optOut() || this._target(); 506 }; 507 508 Link.prototype._anchored = function() { 509 return (this.hash.length > 0 || this.href.charAt(this.href.length - 1) === '#') && (this.withoutHash() === (new ComponentUrl).withoutHash()); 510 }; 511 512 Link.prototype._nonHtml = function() { 513 return this.pathname.match(/\.[a-z]+$/g) && !this.pathname.match(new RegExp("\\.(?:" + (Link.HTML_EXTENSIONS.join('|')) + ")?$", 'g')); 514 }; 515 516 Link.prototype._optOut = function() { 517 var ignore, link; 518 link = this.originalElement; 519 while (!(ignore || link === document)) { 520 ignore = link.getAttribute('data-no-turbolink') != null; 521 link = link.parentNode; 522 } 523 524 // Added in #266 to fix custom page + custom js page load issues 525 if (!ignore && typeof _4ORMAT_DATA !== "undefined" && typeof _4ORMAT_DATA.no_turbolinks_paths !== "undefined") { 526 ignore = _4ORMAT_DATA.no_turbolinks_paths.indexOf(link.getAttribute('href')) > -1; 527 } 528 return ignore; 529 }; 530 531 Link.prototype._target = function() { 532 return this.link.target.length !== 0; 533 }; 534 535 return Link; 536 537 })(ComponentUrl); 538 539 Click = (function() { 540 Click.installHandlerLast = function(event) { 541 if (!event.defaultPrevented) { 542 document.removeEventListener('click', Click.handle, false); 543 return document.addEventListener('click', Click.handle, false); 544 } 545 }; 546 547 Click.handle = function(event) { 548 return new Click(event); 549 }; 550 551 function Click(event1) { 552 this.event = event1; 553 if (this.event.defaultPrevented) { 554 return; 555 } 556 this._extractLink(); 557 if (this._validForTurbolinks()) { 558 if (!pageChangePrevented(this.link.absolute)) { 559 visit(this.link.href); 560 } 561 this.event.preventDefault(); 562 } 563 } 564 565 Click.prototype._extractLink = function() { 566 var link; 567 link = this.event.target; 568 while (!(!link.parentNode || link.nodeName === 'A')) { 569 link = link.parentNode; 570 } 571 if (link.nodeName === 'A' && link.href.length !== 0) { 572 return this.link = new Link(link); 573 } 574 }; 575 576 Click.prototype._validForTurbolinks = function() { 577 return (this.link != null) && !(this.link.shouldIgnore() || this._nonStandardClick()); 578 }; 579 580 Click.prototype._nonStandardClick = function() { 581 return this.event.which > 1 || this.event.metaKey || this.event.ctrlKey || this.event.shiftKey || this.event.altKey; 582 }; 583 584 return Click; 585 586 })(); 587 588 ProgressBar = (function() { 589 var className; 590 591 className = 'turbolinks-progress-bar'; 592 593 function ProgressBar(elementSelector) { 594 this.elementSelector = elementSelector; 595 this._trickle = bind(this._trickle, this); 596 this.value = 0; 597 this.content = ''; 598 this.speed = 300; 599 this.opacity = 0.99; 600 this.install(); 601 } 602 603 ProgressBar.prototype.install = function() { 604 this.element = document.querySelector(this.elementSelector); 605 this.element.classList.add(className); 606 this.styleElement = document.createElement('style'); 607 document.head.appendChild(this.styleElement); 608 return this._updateStyle(); 609 }; 610 611 ProgressBar.prototype.uninstall = function() { 612 this.element.classList.remove(className); 613 return document.head.removeChild(this.styleElement); 614 }; 615 616 ProgressBar.prototype.start = function() { 617 return this.advanceTo(5); 618 }; 619 620 ProgressBar.prototype.advanceTo = function(value) { 621 var ref; 622 if ((value > (ref = this.value) && ref <= 100)) { 623 this.value = value; 624 this._updateStyle(); 625 if (this.value === 100) { 626 return this._stopTrickle(); 627 } else if (this.value > 0) { 628 return this._startTrickle(); 629 } 630 } 631 }; 632 633 ProgressBar.prototype.done = function() { 634 if (this.value > 0) { 635 this.advanceTo(100); 636 return this._reset(); 637 } 638 }; 639 640 ProgressBar.prototype._reset = function() { 641 var originalOpacity; 642 originalOpacity = this.opacity; 643 setTimeout((function(_this) { 644 return function() { 645 _this.opacity = 0; 646 return _this._updateStyle(); 647 }; 648 })(this), this.speed / 2); 649 return setTimeout((function(_this) { 650 return function() { 651 _this.value = 0; 652 _this.opacity = originalOpacity; 653 return _this._withSpeed(0, function() { 654 return _this._updateStyle(true); 655 }); 656 }; 657 })(this), this.speed); 658 }; 659 660 ProgressBar.prototype._startTrickle = function() { 661 if (this.trickling) { 662 return; 663 } 664 this.trickling = true; 665 return setTimeout(this._trickle, this.speed); 666 }; 667 668 ProgressBar.prototype._stopTrickle = function() { 669 return delete this.trickling; 670 }; 671 672 ProgressBar.prototype._trickle = function() { 673 if (!this.trickling) { 674 return; 675 } 676 this.advanceTo(this.value + Math.random() / 2); 677 return setTimeout(this._trickle, this.speed); 678 }; 679 680 ProgressBar.prototype._withSpeed = function(speed, fn) { 681 var originalSpeed, result; 682 originalSpeed = this.speed; 683 this.speed = speed; 684 result = fn(); 685 this.speed = originalSpeed; 686 return result; 687 }; 688 689 ProgressBar.prototype._updateStyle = function(forceRepaint) { 690 if (forceRepaint == null) { 691 forceRepaint = false;
692 } 693 if (forceRepaint) { 694 this._changeContentToForceRepaint(); 695 } 696 return this.styleElement.textContent = this._createCSSRule(); 697 }; 698 699 ProgressBar.prototype._changeContentToForceRepaint = function() { 700 return this.content = this.content === '' ? ' ' : ''; 701 }; 702 703 ProgressBar.prototype._createCSSRule = function() { 704 return this.elementSelector + "." + className + "::before {\n content: '" + this.content + "';\n position: fixed;\n top: 0;\n left: 0;\n z-index: 2000;\n background-color: #0076ff;\n height: 3px;\n opacity: " + this.opacity + ";\n width: " + this.value + "%;\n transition: width " + this.speed + "ms ease-out, opacity " + (this.speed / 2) + "ms ease-in;\n transform: translate3d(0,0,0);\n}"; 705 }; 706 707 return ProgressBar; 708 709 })(); 710 711 bypassOnLoadPopstate = function(fn) { 712 return setTimeout(fn, 500); 713 }; 714 715 installDocumentReadyPageEventTriggers = function() { 716 return document.addEventListener('DOMContentLoaded', (function() { 717 triggerEvent(EVENTS.CHANGE); 718 return triggerEvent(EVENTS.UPDATE); 719 }), true); 720 }; 721 722 installJqueryAjaxSuccessPageUpdateTrigger = function() { 723 if (typeof jQuery !== 'undefined') { 724 return jQuery(document).on('ajaxSuccess', function(event, xhr, settings) { 725 if (!jQuery.trim(xhr.responseText)) { 726 return; 727 } 728 return triggerEvent(EVENTS.UPDATE); 729 }); 730 } 731 }; 732 733 installHistoryChangeHandler = function(event) { 734 var cachedPage, ref; 735 if ((ref = event.state) != null ? ref.turbolinks : void 0) { 736 if (cachedPage = pageCache[(new ComponentUrl(event.state.url)).absolute]) { 737 cacheCurrentPage(); 738 return fetchHistory(cachedPage); 739 } else { 740 return visit(event.target.location.href); 741 } 742 } 743 }; 744 745 initializeTurbolinks = function() { 746 rememberCurrentUrl(); 747 rememberCurrentState(); 748 document.addEventListener('click', Click.installHandlerLast, true); 749 window.addEventListener('hashchange', function(event) { 750 rememberCurrentUrl(); 751 return rememberCurrentState(); 752 }, false); 753 return bypassOnLoadPopstate(function() { 754 return window.addEventListener('popstate', installHistoryChangeHandler, false); 755 }); 756 }; 757 758 historyStateIsDefined = window.history.state !== void 0 || navigator.userAgent.match(/Firefox\/2[6|7]/); 759 760 browserSupportsPushState = window.history && window.history.pushState && window.history.replaceState && historyStateIsDefined; 761 762 browserIsntBuggy = !navigator.userAgent.match(/CriOS\//); 763 764 requestMethodIsSafe = (ref = popCookie('request_method')) === 'GET' || ref === ''; 765 766 browserSupportsTurbolinks = browserSupportsPushState && browserIsntBuggy && requestMethodIsSafe; 767 768 browserSupportsCustomEvents = document.addEventListener && document.createEvent; 769 770 if (browserSupportsCustomEvents) { 771 installDocumentReadyPageEventTriggers(); 772 installJqueryAjaxSuccessPageUpdateTrigger(); 773 } 774 775 if (browserSupportsTurbolinks) { 776 visit = fetch; 777 initializeTurbolinks(); 778 } else { 779 visit = function(url) { 780 return document.location.href = url; 781 }; 782 } 783 784 this.Turbolinks = { 785 visit: visit, 786 pagesCached: pagesCached, 787 enableTransitionCache: enableTransitionCache, 788 enableProgressBar: enableProgressBar, 789 allowLinkExtensions: Link.allowExtensions, 790 supported: browserSupportsTurbolinks, 791 EVENTS: clone(EVENTS) 792 }; 793 794}).call(this);
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.