1(function (global, factory) { 2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 3 typeof define === 'function' && define.amd ? define(factory) : 4 (global = global || self, global.Pjax = factory()); 5}(this, function () { 'use strict'; 6 7 function _typeof(obj) { 8 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 9 _typeof = function (obj) { 10 return typeof obj; 11 }; 12 } else { 13 _typeof = function (obj) { 14 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 15 }; 16 } 17 18 return _typeof(obj); 19 } 20 21 function _classCallCheck(instance, Constructor) { 22 if (!(instance instanceof Constructor)) { 23 throw new TypeError("Cannot call a class as a function"); 24 } 25 } 26 27 function _defineProperties(target, props) { 28 for (var i = 0; i < props.length; i++) { 29 var descriptor = props[i]; 30 descriptor.enumerable = descriptor.enumerable || false; 31 descriptor.configurable = true; 32 if ("value" in descriptor) descriptor.writable = true; 33 Object.defineProperty(target, descriptor.key, descriptor); 34 } 35 } 36 37 function _createClass(Constructor, protoProps, staticProps) { 38 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 39 if (staticProps) _defineProperties(Constructor, staticProps); 40 return Constructor; 41 } 42 43 function _toConsumableArray(arr) { 44 return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); 45 } 46 47 function _arrayWithoutHoles(arr) { 48 if (Array.isArray(arr)) { 49 for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; 50 51 return arr2; 52 } 53 } 54 55 function _iterableToArray(iter) { 56 if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); 57 } 58 59 function _nonIterableSpread() { 60 throw new TypeError("Invalid attempt to spread non-iterable instance"); 61 } 62 63 if (!Array.prototype.from) { 64 Array.prototype.from = function (enumerable) { 65 var arr = []; 66 67 for (var i = enumerable.length; i--; arr.unshift(enumerable[i])) { 68 } 69 70 return arr; 71 }; 72 } 73 74 var forEachEls = function forEachEls(els, fn, ctx) { 75 if (els instanceof HTMLCollection || els instanceof NodeList || els instanceof Array) { 76 return Array.prototype.from(els).forEach(function (el, i) { 77 return fn.call(ctx, el, i); 78 }); 79 } // assume simple dom element 80 81 82 return fn.call(ctx, els); 83 }; 84 var getElements = function getElements(el) { 85 return el.querySelectorAll(this.options.elements); 86 }; 87 var clone = function clone(obj) { 88 if (null === obj || "object" != _typeof(obj)) { 89 return obj; 90 } 91 92 var copy = obj.constructor(); 93 94 for (var attr in obj) { 95 if (attr in obj) { 96 copy[attr] = obj[attr]; 97 } 98 } 99 100 return copy; 101 }; 102 var isSupported = function isSupported() { 103 // Borrowed wholesale from https://github.com/defunkt/jquery-pjax 104 return window.history && window.history.pushState && window.history.replaceState && // pushState isnât reliable on iOS until 5. 105 !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/); 106 }; 107 var newUid = function () { 108 var counter = 0; 109 return function () { 110 var id = "pjax" + new Date().getTime() + "_" + counter; 111 counter++; 112 return id; 113 }; 114 }(); 115 function getUtility () { 116 return { 117 forEachEls: forEachEls, 118 getElements: getElements, 119 clone: clone, 120 isSupported: isSupported, 121 newUid: newUid 122 }; 123 } 124 125 function on (els, events, listener, useCapture) { 126 events = typeof events === "string" ? events.split(" ") : events; 127 events.forEach(function (e) { 128 forEachEls(els, function (el) { 129 el.addEventListener(e, listener, useCapture); 130 }); 131 }); 132 } 133 134 /* eslint no-console: "off" */ 135 var ConsoleShim = 136 /*#__PURE__*/ 137 function () { 138 function ConsoleShim() { 139 var param = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; 140 var silencer = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
141 142 _classCallCheck(this, ConsoleShim); 143 144 this.param = param; 145 this.silencer = silencer; 146 this.collector = []; 147 this.currentGroupDescription = ''; 148 this.activeGroups = 0; 149 this.timeHolder = null; 150 this.methods = ['group', 'groupEnd', 'log', 'trace', 'time', 'timeEnd', 'error', 'warn']; 151 this.silent = { 152 group: function group() { 153 return; 154 }, 155 groupEnd: function groupEnd() { 156 return; 157 }, 158 log: function log() { 159 return; 160 }, 161 trace: function trace() { 162 return; 163 }, 164 time: function time() { 165 return; 166 }, 167 timeEnd: function timeEnd() { 168 return; 169 }, 170 error: function error() { 171 return; 172 }, 173 err: function err() { 174 return; 175 }, 176 debug: function debug() { 177 return; 178 }, 179 warn: function warn() { 180 return; 181 } 182 }; 183 } 184 185 _createClass(ConsoleShim, [{ 186 key: "_generateError", 187 value: function _generateError() { 188 try { 189 throw new Error(); 190 } catch (err) { 191 return err; 192 } 193 } 194 }, { 195 key: "_insertParamToArguments", 196 value: function _insertParamToArguments(rawArgs) { 197 if (this.param !== '') { 198 var args = _toConsumableArray(rawArgs); 199 200 args.unshift(this.param); 201 return args; 202 } 203 204 return Array.from(arguments); 205 } 206 }, { 207 key: "setSilent", 208 value: function setSilent() { 209 var newValue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; 210 this.silencer = newValue || !this.silencer; 211 } //Start grouping logs 212 213 }, { 214 key: "group", 215 value: function group() { 216 if (this.silencer) { 217 return; 218 } 219 220 var args = this._insertParamToArguments(arguments); 221 222 if (typeof console.group === 'function') { 223 console.group.apply(console, args); 224 return; 225 } 226 227 var description = args[0] || 'GROUP'; 228 this.currentGroupDescription = description; 229 this.activeGroups++; 230 } //Stop grouping logs 231 232 }, { 233 key: "groupEnd", 234 value: function groupEnd() { 235 if (this.silencer) { 236 return; 237 } 238 239 var args = this._insertParamToArguments(arguments); 240 241 if (typeof console.groupEnd === 'function') { 242 console.groupEnd.apply(console, args); 243 return; 244 } 245 246 this.currentGroupDescription = ''; 247 this.activeGroups--; 248 this.activeGroups = this.activeGroups === 0 ? 0 : this.activeGroups--; 249 } //Simplest mechanism to log stuff 250 // Aware of the group shim 251 252 }, { 253 key: "log", 254 value: function log() { 255 if (this.silencer) { 256 return; 257 } 258 259 var args = this._insertParamToArguments(arguments); 260 261 if (typeof console.group === 'function') { 262 console.log.apply(console, args); 263 return; 264 } 265 266 args.shift(); 267 args.unshift(' '.repeat(this.activeGroups * 2)); 268 this.log.apply(this, args); 269 } //Trace back the apply. 270 //Uses either the inbuilt function console trace or opens a shim to trace by calling this._insertParamToArguments(arguments).callee 271 272 }, { 273 key: "trace", 274 value: function trace() { 275 if (this.silencer) { 276 return; 277 } 278 279 var args = this._insertParamToArguments(arguments); 280 281 if (typeof console.trace === 'function') { 282 console.trace.apply(console, args); 283 return; 284 } 285 286 var artificialError = this._generateError(); 287 288 if (artificialError.stack) { 289 this.log.apply(console, artificialError.stack); 290 return; 291 } 292 293 this.log.log(args); 294 295 if (arguments.callee != undefined) { 296 this.trace.apply(console, arguments.callee); 297 } 298 } 299 }, { 300 key: "time", 301 value: function time() { 302 if (this.silencer) { 303 return; 304 } 305 306 var args = this._insertParamToArguments(arguments); 307 308 if (typeof console.time === 'function') { 309 console.time.apply(console, args); 310 return; 311 } 312 313 this.timeHolder = new Date(); 314 } 315 }, {
316 key: "timeEnd", 317 value: function timeEnd() { 318 if (this.silencer) { 319 return; 320 } 321 322 var args = this._insertParamToArguments(arguments); 323 324 if (typeof console.timeEnd === 'function') { 325 console.timeEnd.apply(console, args); 326 return; 327 } 328 329 var diff = new Date() - this.timeHolder; 330 this.log.log("Took ".concat(Math.floor(diff / (1000 * 60 * 60)), " hours, ").concat(Math.floor(diff / (1000 * 60)), " minutes and ").concat(Math.floor(diff / 1000), " seconds ( ").concat(diff, " ms)")); 331 this.time = new Date(); 332 } 333 }, { 334 key: "error", 335 value: function error() { 336 var args = this._insertParamToArguments(arguments); 337 338 if (typeof console.error === 'function') { 339 console.error.apply(console, args); 340 return; 341 } 342 343 this.log.log('--- ERROR ---'); 344 this.log.log(args); 345 } 346 }, { 347 key: "warn", 348 value: function warn() { 349 var args = this._insertParamToArguments(arguments); 350 351 if (typeof console.warn === 'function') { 352 console.warn.apply(console, args); 353 return; 354 } 355 356 this.log.log('--- WARN ---'); 357 this.log.log(args); 358 } 359 }]); 360 361 return ConsoleShim; 362 }(); 363 364 function log () { 365 console.log("PJAX options", this.options); 366 this.options.logObject = new ConsoleShim('PJAX ->', !this.options.debug); 367 return this.options.logObject; 368 } 369 370 function trigger (els, events, opts) { 371 events = typeof events === "string" ? events.split(" ") : events; 372 events.forEach(function (e) { 373 var event; // = new CustomEvent(e) // doesn't everywhere yet 374 375 event = document.createEvent("HTMLEvents"); 376 event.initEvent(e, true, true); 377 event.eventName = e; 378 379 if (opts) { 380 Object.keys(opts).forEach(function (key) { 381 event[key] = opts[key]; 382 }); 383 } 384 385 forEachEls(els, function (el) { 386 var domFix = false; 387 388 if (!el.parentNode && el !== document && el !== window) { 389 // THANKS YOU IE (9/10//11 concerned) 390 // dispatchEvent doesn't work if element is not in the dom 391 domFix = true; 392 document.body.appendChild(el); 393 } 394 395 el.dispatchEvent(event); 396 397 if (domFix) { 398 el.parentNode.removeChild(el); 399 } 400 }); 401 }); 402 } 403 404 function doRequest (location, options, callback) { 405 options = options || {}; 406 var requestMethod = options.requestMethod || "GET"; 407 var requestPayload = options.requestPayloadString || null; 408 var request = new XMLHttpRequest(); 409 410 request.onreadystatechange = function () { 411 if (request.readyState === 4) { 412 if (request.status === 200) { 413 callback(request.responseText, request); 414 } else { 415 callback(null, request); 416 } 417 } 418 }; // Add a timestamp as part of the query string if cache busting is enabled 419 420 421 if (this.options.cacheBust) { 422 location += (!/[?&]/.test(location) ? "?" : "&") + new Date().getTime(); 423 } 424 425 request.open(requestMethod.toUpperCase(), location, true); 426 request.setRequestHeader("X-Requested-With", "XMLHttpRequest"); // Add the request payload if available 427 428 if (options.requestPayloadString != undefined && options.requestPayloadString != "") { 429 // Send the proper header information along with the request 430 request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 431 } 432 433 request.send(requestPayload); 434 return request; 435 } 436 437 // var trigger = require("./lib/events/trigger.js") 438 439 var defaultSwitches = { 440 outerHTML: function outerHTML(oldEl, newEl) { 441 oldEl.outerHTML = newEl.outerHTML; 442 this.onSwitch(); 443 }, 444 innerHTML: function innerHTML(oldEl, newEl) { 445 oldEl.innerHTML = newEl.innerHTML; 446 oldEl.className = newEl.className; 447 this.onSwitch(); 448 }, 449 sideBySide: function sideBySide(oldEl, newEl, options, switchOptions) { 450 var elsToRemove = []; 451 var elsToAdd = []; 452 var fragToAppend = document.createDocumentFragment(); // height transition are shitty on safari 453 // so commented for now (until I found something ?) 454 // var relevantHeight = 0 455 456 var animationEventNames = "animationend webkitAnimationEnd MSAnimationEnd oanimationend"; 457 var animatedElsNumber = 0; 458 459 var sexyAnimationEnd = function (e) { 460 if (e.target != e.currentTarget) { 461 // end triggered by an animation on a child 462 return; 463 } 464 465 animatedElsNumber--; 466 467 if (animatedElsNumber <= 0 && elsToRemove) { 468 elsToRemove.forEach(function (el) { 469 // browsing quickly can make the el 470 // already removed by last page update ? 471 if (el.parentNode) { 472 el.parentNode.removeChild(el); 473 } 474 });
475 elsToAdd.forEach(function (el) { 476 el.className = el.className.replace(el.getAttribute("data-pjax-classes"), ""); 477 el.removeAttribute("data-pjax-classes"); // Pjax.off(el, animationEventNames, sexyAnimationEnd, true) 478 }); 479 elsToAdd = null; // free memory 480 481 elsToRemove = null; // free memory 482 // assume the height is now useless (avoid bug since there is overflow hidden on the parent) 483 // oldEl.style.height = "auto" 484 // this is to trigger some repaint (example: picturefill) 485 486 this.onSwitch(); // Pjax.trigger(window, "scroll") 487 } 488 }.bind(this); // Force height to be able to trigger css animation 489 // here we get the relevant height 490 // oldEl.parentNode.appendChild(newEl) 491 // relevantHeight = newEl.getBoundingClientRect().height 492 // oldEl.parentNode.removeChild(newEl) 493 // oldEl.style.height = oldEl.getBoundingClientRect().height + "px" 494 495 496 switchOptions = switchOptions || {}; 497 Array.from(oldEl.childNodes).forEach(function (el) { 498 elsToRemove.push(el); 499 500 if (el.classList && !el.classList.contains("js-Pjax-remove")) { 501 // for fast switch, clean element that just have been added, & not cleaned yet. 502 if (el.hasAttribute("data-pjax-classes")) { 503 el.className = el.className.replace(el.getAttribute("data-pjax-classes"), ""); 504 el.removeAttribute("data-pjax-classes"); 505 } 506 507 el.classList.add("js-Pjax-remove"); 508 509 if (switchOptions.callbacks && switchOptions.callbacks.removeElement) { 510 switchOptions.callbacks.removeElement(el); 511 } 512 513 if (switchOptions.classNames) { 514 el.className += " " + switchOptions.classNames.remove + " " + (options.backward ? switchOptions.classNames.backward : switchOptions.classNames.forward); 515 } 516 517 animatedElsNumber++; 518 on(el, animationEventNames, sexyAnimationEnd, true); 519 } 520 }); 521 Array.from(newEl.childNodes).forEach(function (el) { 522 if (el.classList) { 523 var addClasses = ""; 524 525 if (switchOptions.classNames) { 526 addClasses = " js-Pjax-add " + switchOptions.classNames.add + " " + (options.backward ? switchOptions.classNames.forward : switchOptions.classNames.backward); 527 } 528 529 if (switchOptions.callbacks && switchOptions.callbacks.addElement) { 530 switchOptions.callbacks.addElement(el); 531 } 532 533 el.className += addClasses; 534 el.setAttribute("data-pjax-classes", addClasses); 535 elsToAdd.push(el); 536 fragToAppend.appendChild(el); 537 animatedElsNumber++; 538 on(el, animationEventNames, sexyAnimationEnd, true); 539 } 540 }); // pass all className of the parent 541 542 oldEl.className = newEl.className; 543 oldEl.appendChild(fragToAppend); // oldEl.style.height = relevantHeight + "px" 544 } 545 }; 546 547 function getSwitchSelectors () { 548 var _this = this; 549 550 return function (switches, switchesOptions, selectors, fromEl, toEl, options) { 551 selectors.forEach(function (selector) { 552 var newEls = fromEl.querySelectorAll(selector); 553 var oldEls = toEl.querySelectorAll(selector); 554 555 _this.log.log("Pjax switch", selector, newEls, oldEls); 556 557 if (newEls.length !== oldEls.length) { 558 var throwError = options.onDomDiffers(toEl, fromEl); 559 560 if (throwError) { 561 throw "DOM doesnât look the same on new loaded page: â" + selector + "â - new " + newEls.length + ", old " + oldEls.length; 562 } 563 } 564 565 forEachEls(newEls, function (newEl, i) { 566 var oldEl = oldEls[i]; 567 568 if (oldEl == undefined) { 569 return; 570 } 571 572 this.log.log("newEl", newEl, "oldEl", oldEl); 573 574 if (switches[selector]) { 575 switches[selector].call(this, oldEl, newEl, options, switchesOptions[selector]); 576 } else { 577 defaultSwitches.outerHTML.call(this, oldEl, newEl, options); 578 } 579 }, _this); 580 }); 581 }; 582 } 583 584 if (!Function.prototype.bind) { 585 Function.prototype.bind = function (oThis) { 586 if (typeof this !== "function") { 587 // closest thing possible to the ECMAScript 5 internal IsCallable function 588 throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); 589 } 590 591 var aArgs = Array.prototype.slice.call(arguments, 1); 592 var that = this; 593 594 var Fnoop = function Fnoop() {}; 595 596 var fBound = function fBound() { 597 return that.apply(this instanceof Fnoop && oThis ? this
597: oThis, aArgs.concat(Array.prototype.slice.call(arguments))); 598 }; 599 600 Fnoop.prototype = this.prototype; 601 fBound.prototype = new Fnoop(); 602 return fBound; 603 }; 604 } 605 606 var attrClick = "data-pjax-click-state"; 607 var attrKey = "data-pjax-keyup-state"; 608 609 var linkAction = function linkAction(el, event) { 610 // Donât break browser special behavior on links (like page in new window) 611 if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { 612 el.setAttribute(attrClick, "modifier"); 613 return; 614 } // we do test on href now to prevent unexpected behavior if for some reason 615 // user have href that can be dynamically updated 616 // Ignore external links. 617 618 619 if (el.protocol !== window.location.protocol || el.host !== window.location.host) { 620 el.setAttribute(attrClick, "external"); 621 return; 622 } // Ignore click if we are on an anchor on the same page 623 624 625 if (el.pathname === window.location.pathname && el.hash.length > 0) { 626 el.setAttribute(attrClick, "anchor-present"); 627 return; 628 } // Ignore anchors on the same page (keep native behavior) 629 630 631 if (el.hash && el.href.replace(el.hash, "") === window.location.href.replace(location.hash, "")) { 632 el.setAttribute(attrClick, "anchor"); 633 return; 634 } // Ignore empty anchor "foo.html#" 635 636 637 if (el.href === window.location.href.split("#")[0] + "#") { 638 el.setAttribute(attrClick, "anchor-empty"); 639 return; 640 } 641 642 event.preventDefault(); // donât do "nothing" if user try to reload the page by clicking the same link twice 643 644 if (this.options.currentUrlFullReload && el.href === window.location.href.split("#")[0]) { 645 el.setAttribute(attrClick, "reload"); 646 this.reload(); 647 return; 648 } 649 650 this.options.requestOptions = this.options.requestOptions || {}; 651 el.setAttribute(attrClick, "load"); 652 this.loadUrl(el.href, clone(this.options)); 653 }; 654 655 var isDefaultPrevented = function isDefaultPrevented(event) { 656 return event.defaultPrevented || event.returnValue === false; 657 }; 658 659 function getAttachLink () { 660 var _this = this; 661 662 return function (el) { 663 on(el, "click", function (event) { 664 if (isDefaultPrevented(event)) { 665 return; 666 } 667 668 linkAction.call(_this, el, event); 669 }); 670 on(el, "keyup", function (event) { 671 if (isDefaultPrevented(event)) { 672 return; 673 } // Donât break browser special behavior on links (like page in new window) 674 675 676 if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { 677 el.setAttribute(attrKey, "modifier"); 678 return; 679 } 680 681 if (event.keyCode == 13) { 682 linkAction.call(_this, el, event); 683 } 684 }); 685 }; 686 } 687 688 var attrClick$1 = "data-pjax-submit-state"; 689 690 var formAction = function formAction(el, event) { 691 this.options.requestOptions = { 692 requestUrl: el.getAttribute('action') || window.location.href, 693 requestMethod: el.getAttribute('method') || 'GET' 694 }; //create a testable virtual link of the form action 695 696 var virtLinkElement = document.createElement('a'); 697 virtLinkElement.setAttribute('href', this.options.requestOptions.requestUrl); // Ignore external links. 698 699 if (virtLinkElement.protocol !== window.location.protocol || virtLinkElement.host !== window.location.host) { 700 el.setAttribute(attrClick$1, "external"); 701 return; 702 } // Ignore click if we are on an anchor on the same page 703 704 705 if (virtLinkElement.pathname === window.location.pathname && virtLinkElement.hash.length > 0) { 706 el.setAttribute(attrClick$1, "anchor-present"); 707 return; 708 } // Ignore empty anchor "foo.html#" 709 710 711 if (virtLinkElement.href === window.location.href.split("#")[0] + "#") { 712 el.setAttribute(attrClick$1, "anchor-empty"); 713 return; 714 } // if declared as a full reload, just normally submit the form 715 716 717 if (this.options.currentUrlFullReload) { 718 el.setAttribute(attrClick$1, "reload"); 719 return; 720 } 721 722 event.preventDefault(); 723 var nameList = []; 724 var paramObject = []; 725
726 for (var elementKey in el.elements) { 727 var element = el.elements[elementKey]; 728 729 if (!!element.name && element.attributes !== undefined && element.tagName.toLowerCase() !== 'button') { 730 if (element.type !== 'checkbox' && element.type !== 'radio' || element.checked) { 731 if (nameList.indexOf(element.name) === -1) { 732 nameList.push(element.name); 733 734 if (String(element.nodeName).toLowerCase() === 'select' && element.multiple == true) { 735 var selected = Array.from(element.options).map(function (item) { 736 return item.selected ? item.value : null; 737 }); 738 paramObject.push({ 739 name: encodeURIComponent(element.name), 740 value: selected 741 }); 742 return; 743 } 744 745 paramObject.push({ 746 name: encodeURIComponent(element.name), 747 value: encodeURIComponent(element.value) 748 }); 749 } 750 } 751 } 752 } //Creating a getString 753 754 755 var paramsString = paramObject.map(function (value) { 756 return value.name + "=" + value.value; 757 }).join('&'); 758 this.options.requestOptions.requestPayload = paramObject; 759 this.options.requestOptions.requestPayloadString = paramsString; 760 el.setAttribute(attrClick$1, "submit"); 761 this.loadUrl(virtLinkElement.href, clone(this.options)); 762 }; 763 764 var isDefaultPrevented$1 = function isDefaultPrevented(event) { 765 return event.defaultPrevented || event.returnValue === false; 766 }; 767 768 function getAttachForm () { 769 var _this = this; 770 771 return function (el) { 772 on(el, "submit", function (event) { 773 if (isDefaultPrevented$1(event)) { 774 return; 775 } 776 777 formAction.call(_this, el, event); 778 }); 779 }; 780 } 781 782 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; 783 784 function createCommonjsModule(fn, module) { 785 return module = { exports: {} }, fn(module, module.exports), module.exports; 786 } 787 788 var promise = createCommonjsModule(function (module) { 789 (function (root) { 790 791 // Store setTimeout reference so promise-polyfill will be unaffected by 792 // other code modifying setTimeout (like sinon.useFakeTimers()) 793 var setTimeoutFunc = setTimeout; 794 795 function noop() {} 796 797 // Polyfill for Function.prototype.bind 798 function bind(fn, thisArg) { 799 return function () { 800 fn.apply(thisArg, arguments); 801 }; 802 } 803 804 function Promise(fn) { 805 if (!(this instanceof Promise)) throw new TypeError('Promises must be constructed via new'); 806 if (typeof fn !== 'function') throw new TypeError('not a function'); 807 this._state = 0; 808 this._handled = false; 809 this._value = undefined; 810 this._deferreds = []; 811 812 doResolve(fn, this); 813 } 814 815 function handle(self, deferred) { 816 while (self._state === 3) { 817 self = self._value; 818 } 819 if (self._state === 0) { 820 self._deferreds.push(deferred); 821 return; 822 } 823 self._handled = true; 824 Promise._immediateFn(function () { 825 var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; 826 if (cb === null) { 827 (self._state === 1 ? resolve : reject)(deferred.promise, self._value); 828 return; 829 } 830 var ret; 831 try { 832 ret = cb(self._value); 833 } catch (e) { 834 reject(deferred.promise, e); 835 return; 836 } 837 resolve(deferred.promise, ret); 838 }); 839 } 840 841 function resolve(self, newValue) { 842 try { 843 // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure 844 if (newValue === self) throw new TypeError('A promise cannot be resolved with itself.'); 845 if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { 846 var then = newValue.then; 847 if (newValue instanceof Promise) { 848 self._state = 3; 849 self._value = newValue; 850 finale(self); 851 return; 852 } else if (typeof then === 'function') { 853 doResolve(bind(then, newValue), self); 854 return; 855 } 856 } 857 self._state = 1; 858 self._value = newValue; 859 finale(self); 860 } catch (e) { 861 reject(self, e); 862 } 863 } 864 865 function reject(self, newValue) { 866 self._state = 2; 867 self._value = newValue; 868 finale(self); 869 } 870 871 function finale(self) { 872 if (self._state === 2 && self._deferreds.length === 0) { 873 Promise._immediateFn(function() { 874 if (!self._handled) { 875 Promise._unhandledRejectionFn(self._value); 876 } 877 }); 878 } 879 880 for (var i = 0, len = self._deferreds.length; i < len; i++) { 881 handle(self, self._deferreds[i]); 882 } 883 self._deferreds = null; 884 } 885 886 function Handler(onFulfilled, onRejected, promise) { 887 this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; 888 this.onRejected = typeof onRejected === 'function' ? onRejected : null; 889 this.promise = promise; 890 } 891 892 /** 893 * Take a potentially misbehaving resolver function and make sure 894 * onFulfilled and onRejected are only called once. 895 * 896 * Makes no guarantees about asynchrony. 897 */ 898 function doResolve(fn, self) { 899 var done = false;
900 try { 901 fn(function (value) { 902 if (done) return; 903 done = true; 904 resolve(self, value); 905 }, function (reason) { 906 if (done) return; 907 done = true; 908 reject(self, reason); 909 }); 910 } catch (ex) { 911 if (done) return; 912 done = true; 913 reject(self, ex); 914 } 915 } 916 917 Promise.prototype['catch'] = function (onRejected) { 918 return this.then(null, onRejected); 919 }; 920 921 Promise.prototype.then = function (onFulfilled, onRejected) { 922 var prom = new (this.constructor)(noop); 923 924 handle(this, new Handler(onFulfilled, onRejected, prom)); 925 return prom; 926 }; 927 928 Promise.all = function (arr) { 929 return new Promise(function (resolve, reject) { 930 if (!arr || typeof arr.length === 'undefined') throw new TypeError('Promise.all accepts an array'); 931 var args = Array.prototype.slice.call(arr); 932 if (args.length === 0) return resolve([]); 933 var remaining = args.length; 934 935 function res(i, val) { 936 try { 937 if (val && (typeof val === 'object' || typeof val === 'function')) { 938 var then = val.then; 939 if (typeof then === 'function') { 940 then.call(val, function (val) { 941 res(i, val); 942 }, reject); 943 return; 944 } 945 } 946 args[i] = val; 947 if (--remaining === 0) { 948 resolve(args); 949 } 950 } catch (ex) { 951 reject(ex); 952 } 953 } 954 955 for (var i = 0; i < args.length; i++) { 956 res(i, args[i]); 957 } 958 }); 959 }; 960 961 Promise.resolve = function (value) { 962 if (value && typeof value === 'object' && value.constructor === Promise) { 963 return value; 964 } 965 966 return new Promise(function (resolve) { 967 resolve(value); 968 }); 969 }; 970 971 Promise.reject = function (value) { 972 return new Promise(function (resolve, reject) { 973 reject(value); 974 }); 975 }; 976 977 Promise.race = function (values) { 978 return new Promise(function (resolve, reject) { 979 for (var i = 0, len = values.length; i < len; i++) { 980 values[i].then(resolve, reject); 981 } 982 }); 983 }; 984 985 // Use polyfill for setImmediate for performance gains 986 Promise._immediateFn = (typeof setImmediate === 'function' && function (fn) { setImmediate(fn); }) || 987 function (fn) { 988 setTimeoutFunc(fn, 0); 989 }; 990 991 Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) { 992 if (typeof console !== 'undefined' && console) { 993 console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console 994 } 995 }; 996 997 /** 998 * Set the immediate function to execute callbacks 999 * @param fn {function} Function to execute 1000 * @deprecated 1001 */ 1002 Promise._setImmediateFn = function _setImmediateFn(fn) { 1003 Promise._immediateFn = fn; 1004 }; 1005 1006 /** 1007 * Change the function to execute on unhandled rejection 1008 * @param {function} fn Function to execute on unhandled rejection 1009 * @deprecated 1010 */ 1011 Promise._setUnhandledRejectionFn = function _setUnhandledRejectionFn(fn) { 1012 Promise._unhandledRejectionFn = fn; 1013 }; 1014 1015 if ( module.exports) { 1016 module.exports = Promise; 1017 } else if (!root.Promise) { 1018 root.Promise = Promise; 1019 } 1020 1021 })(commonjsGlobal); 1022 }); 1023 1024 function evalScript (el) { 1025 var querySelector = this.options.mainScriptElement; 1026 var code = el.text || el.textContent || el.innerHTML || ""; 1027 this.log.log("Evaluating Script: ", el); 1028 1029 if (code.match("document.write")) { 1030 if (console && this.options.logObject.log) { 1031 this.options.logObject.log("Script contains document.write. Canât be executed correctly. Code skipped ", el); 1032 } 1033 1034 return false; 1035 } 1036 1037 var src = el.src || ""; 1038 var parent = el.parentNode || document.querySelector(querySelector) || document.documentElement; 1039 var script = document.createElement("script"); 1040 var promise = new Promise(function (resolve) { 1041 script.type = "text/javascript"; 1042 1043 if (src != "") { 1044 script.src = src; 1045 script.addEventListener('load', function () { 1046 resolve(src); 1047 }); 1048 script.async = true; // force asynchronous loading of peripheral js 1049 } 1050 1051 if (code != "") { 1052 try { 1053 script.appendChild(document.createTextNode(code)); 1054 } catch (e) { 1055 // old IEs have funky script nodes 1056 script.text = code; 1057 } 1058 1059 resolve('text-node'); 1060 } 1061 }); 1062 this.log.log('ParentElement => ', parent); // execute 1063 1064 parent.appendChild(script); 1065 parent.removeChild(script); // avoid pollution only in head or body tags 1066 // of if the setting removeScriptsAfterParsing is active 1067 1068 if (["head", "body"].indexOf(parent.tagName.toLowerCase()) > 0 || this.options.removeScriptsAfterParsing === true) ; 1069 1070 return promise; 1071 } 1072 1073 // Needed since innerHTML does not run scripts 1074 1075 function getExecuteScripts () { 1076 var _this = this; 1077 1078 return function (el) { 1079 _this.log.log("Executing scripts for ", el); 1080 1081 var loadingScripts = []; 1082 if (el === undefined) return Promise.resolve(); 1083 1084 if (el.tagName.toLowerCase() === "script") { 1085 evalScript.call(_this, el); 1086 } 1087
1088 forEachEls(el.querySelectorAll("script"), function (script) { 1089 if (!script.type || script.type.toLowerCase() === "text/javascript") { 1090 if (!(script.parentNode && script.parentNode.tagName == 'textarea')) { 1091 loadingScripts.push(evalScript.call(_this, script)); 1092 } 1093 } 1094 }, _this); 1095 return loadingScripts; 1096 }; 1097 } 1098 1099 function off (els, events, listener, useCapture) { 1100 events = typeof events === "string" ? events.split(" ") : events; 1101 events.forEach(function (e) { 1102 forEachEls(els, function (el) { 1103 el.removeEventListener(e, listener, useCapture); 1104 }); 1105 }); 1106 } 1107 1108 var attrClick$2 = "data-pjax-click-state"; 1109 var attrKey$1 = "data-pjax-keyup-state"; 1110 1111 var linkAction$1 = function linkAction(el, event) { 1112 // Donât break browser special behavior on links (like page in new window) 1113 if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { 1114 el.setAttribute(attrClick$2, "modifier"); 1115 return; 1116 } // we do test on href now to prevent unexpected behavior if for some reason 1117 // user have href that can be dynamically updated 1118 // Ignore external links. 1119 1120 1121 if (el.protocol !== window.location.protocol || el.host !== window.location.host) { 1122 el.setAttribute(attrClick$2, "external"); 1123 return; 1124 } // Ignore click if we are on an anchor on the same page 1125 1126 1127 if (el.pathname === window.location.pathname && el.hash.length > 0) { 1128 el.setAttribute(attrClick$2, "anchor-present"); 1129 return; 1130 } // Ignore anchors on the same page (keep native behavior) 1131 1132 1133 if (el.hash && el.href.replace(el.hash, "") === window.location.href.replace(location.hash, "")) { 1134 el.setAttribute(attrClick$2, "anchor"); 1135 return; 1136 } // Ignore empty anchor "foo.html#" 1137 1138 1139 if (el.href === window.location.href.split("#")[0] + "#") { 1140 el.setAttribute(attrClick$2, "anchor-empty"); 1141 return; 1142 } 1143 1144 event.preventDefault(); // donât do "nothing" if user try to reload the page by clicking the same link twice 1145 1146 if (this.options.currentUrlFullReload && el.href === window.location.href.split("#")[0]) { 1147 el.setAttribute(attrClick$2, "reload"); 1148 this.reload(); 1149 return; 1150 } 1151 1152 this.options.requestOptions = this.options.requestOptions || {}; 1153 el.setAttribute(attrClick$2, "load"); 1154 this.loadUrl(el.href, clone(this.options)); 1155 }; 1156 1157 var isDefaultPrevented$2 = function isDefaultPrevented(event) { 1158 return event.defaultPrevented || event.returnValue === false; 1159 }; 1160 1161 function getUnattachLink () { 1162 var _this = this; 1163 1164 return function (el) { 1165 off(el, "click", function (event) { 1166 if (isDefaultPrevented$2(event)) { 1167 return; 1168 } 1169 1170 linkAction$1.call(_this, el, event); 1171 }); 1172 off(el, "keyup", function (event) { 1173 if (isDefaultPrevented$2(event)) { 1174 return; 1175 } // Donât break browser special behavior on links (like page in new window) 1176 1177 1178 if (event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) { 1179 el.setAttribute(attrKey$1, "modifier"); 1180 return; 1181 } 1182 1183 if (event.keyCode == 13) { 1184 linkAction$1.call(_this, el, event); 1185 } 1186 }); 1187 }; 1188 } 1189 1190 var attrClick$3 = "data-pjax-click-state"; 1191 1192 var formAction$1 = function formAction(el, event) { 1193 this.options.requestOptions = { 1194 requestUrl: el.getAttribute('action') || window.location.href, 1195 requestMethod: el.getAttribute('method') || 'GET' 1196 }; //create a testable virtual link of the form action 1197 1198 var virtLinkElement = document.createElement('a'); 1199 virtLinkElement.setAttribute('href', this.options.requestOptions.requestUrl); // Ignore external links. 1200 1201 if (virtLinkElement.protocol !== window.location.protocol || virtLinkElement.host !== window.location.host) { 1202 el.setAttribute(attrClick$3, "external"); 1203 return; 1204 } // Ignore click if we are on an anchor on the same page 1205 1206 1207 if (virtLinkElement.pathname === window.location.pathname && virtLinkElement.hash.length > 0) { 1208 el.setAttribute(attrClick$3, "anchor-present"); 1209 return; 1210 } // Ignore empty anchor "foo.html#" 1211 1212 1213 if (virtLinkElement.href === window.location.href.split("#")[0] + "#") { 1214 el.setAttribute(attrClick$3, "anchor-empty"); 1215 return; 1216 } // if declared as a full reload, just normally submit the form 1217 1218 1219 if (this.options.currentUrlFullReload) { 1220 el.setAttribute(attrClick$3, "reload"); 1221 return; 1222 } 1223 1224 event.preventDefault(); 1225 var nameList = []; 1226 var paramObject = []; 1227
1228 for (var elementKey in el.elements) { 1229 var element = el.elements[elementKey]; 1230 1231 if (!!element.name && element.attributes !== undefined && element.tagName.toLowerCase() !== 'button') { 1232 if (element.type !== 'checkbox' && element.type !== 'radio' || element.checked) { 1233 if (nameList.indexOf(element.name) === -1) { 1234 nameList.push(element.name); 1235 paramObject.push({ 1236 name: encodeURIComponent(element.name), 1237 value: encodeURIComponent(element.value) 1238 }); 1239 } 1240 } 1241 } 1242 } //Creating a getString 1243 1244 1245 var paramsString = paramObject.map(function (value) { 1246 return value.name + "=" + value.value; 1247 }).join('&'); 1248 this.options.requestOptions.requestPayload = paramObject; 1249 this.options.requestOptions.requestPayloadString = paramsString; 1250 el.setAttribute(attrClick$3, "submit"); 1251 this.loadUrl(virtLinkElement.href, clone(this.options)); 1252 }; 1253 1254 var isDefaultPrevented$3 = function isDefaultPrevented(event) { 1255 return event.defaultPrevented || event.returnValue === false; 1256 }; 1257 1258 function getUnattachForm () { 1259 var _this = this; 1260 1261 return function (el) { 1262 off(el, "submit", function (event) { 1263 if (isDefaultPrevented$3(event)) { 1264 return; 1265 } 1266 1267 formAction$1.call(this, el, event); 1268 }); 1269 off(el, "keyup", function (event) { 1270 if (isDefaultPrevented$3(event)) { 1271 return; 1272 } 1273 1274 if (event.keyCode == 13) { 1275 formAction$1.call(_this, el, event); 1276 } 1277 }); 1278 }; 1279 } 1280 1281 function getUpdateStylesheets () { 1282 var _this = this; 1283 1284 return function (elements, oldElements) { 1285 _this.log.log("styleheets old elements", oldElements); 1286 1287 _this.log.log("styleheets new elements", elements); 1288 1289 forEachEls(elements, function (newEl) { 1290 var resemblingOld = Array.from(oldElements).reduce(function (acc, oldEl) { 1291 acc = oldEl.href === newEl.href ? oldEl : acc; 1292 return acc; 1293 }, null); 1294 1295 if (resemblingOld !== null) { 1296 if (_this.log) { 1297 _this.log.log("old stylesheet found not resetting"); 1298 } 1299 } else { 1300 if (_this.log) { 1301 _this.log.log("new stylesheet => add to head"); 1302 } 1303 1304 var head = document.getElementsByTagName('head')[0]; 1305 var link = document.createElement('link'); 1306 link.setAttribute('href', newEl.href); 1307 link.setAttribute('rel', 'stylesheet'); 1308 link.setAttribute('type', 'text/css'); 1309 head.appendChild(link); 1310 } 1311 }); 1312 }; 1313 } 1314 1315 /** 1316 * Collection of parsing methods 1317 * Exports: 1318 * -> parseDOMUnload 1319 * -> parseDOM 1320 * -> parseElementUnload 1321 * -> parseElement 1322 * -> parseOptions 1323 */ 1324 function getParsers () { 1325 return { 1326 parseElementUnload: function parseElementUnload(el) { 1327 switch (el.tagName.toLowerCase()) { 1328 case "a": 1329 // only attach link if el does not already have link attached 1330 if (!el.hasAttribute('data-pjax-click-state')) { 1331 this.unattachLink(el); 1332 } 1333 1334 break; 1335 1336 case "form": 1337 // only attach link if el does not already have link attached 1338 if (!el.hasAttribute('data-pjax-click-state')) { 1339 this.unattachForm(el); 1340 } 1341 1342 break; 1343 1344 default: 1345 throw "Pjax can only be applied on <a> or <form> submit"; 1346 } 1347 }, 1348 parseElement: function parseElement(el) { 1349 switch (el.tagName.toLowerCase()) { 1350 case "a": 1351 // only attach link if el does not already have link attached 1352 if (!el.hasAttribute('data-pjax-click-state')) { 1353 this.attachLink(el); 1354 } 1355 1356 break; 1357 1358 case "form": 1359 // only attach link if el does not already have link attached 1360 if (!el.hasAttribute('data-pjax-click-state')) { 1361 this.attachForm(el); 1362 } 1363 1364 break; 1365 1366 default: 1367 throw "Pjax can only be applied on <a> or <form> submit"; 1368 } 1369 }, 1370 parseDOMUnload: function parseDOMUnload(el) {
1371 forEachEls(this.getElements(el), this.parseElementUnload, this); 1372 }, 1373 parseDOM: function parseDOM(el) { 1374 forEachEls(this.getElements(el), this.parseElement, this); 1375 }, 1376 parseOptions: function parseOptions(options) { 1377 this.options = options; 1378 this.options.elements = this.options.elements || "a[href], form[action]"; 1379 this.options.reRenderCSS = this.options.reRenderCSS || false; 1380 this.options.forceRedirectOnFail = this.options.forceRedirectOnFail || false; 1381 this.options.scriptloadtimeout = this.options.scriptloadtimeout || 1000; 1382 this.options.mainScriptElement = this.options.mainScriptElement || "head"; 1383 this.options.removeScriptsAfterParsing = this.options.removeScriptsAfterParsing || true; 1384 this.options.logObject = this.options.logObject || console; 1385 this.options.latestChance = this.options.latestChance || null; 1386 this.options.selectors = this.options.selectors || ["title", ".js-Pjax"]; 1387 this.options.switches = this.options.switches || {}; 1388 this.options.switchesOptions = this.options.switchesOptions || {}; 1389 this.options.history = this.options.history || true; 1390 1391 this.options.onDomDiffers = this.options.onDomDiffers || function () { 1392 return true; 1393 }; 1394 1395 this.options.pjaxErrorHandler = this.options.pjaxErrorHandler || function () { 1396 return false; 1397 }; 1398 1399 this.options.onJsonDocument = this.options.onJsonDocument || function () { 1400 return true; 1401 }; 1402 1403 this.options.analytics = this.options.analytics || function () { 1404 // options.backward or options.foward can be true or undefined 1405 // by default, we do track back/foward hit 1406 // https://productforums.google.com/forum/#!topic/analytics/WVwMDjLhXYk 1407 if (window._gaq) {
1408 window._gaq.push(["_trackPageview"]); 1409 } 1410 1411 if (window.ga) { 1412 window.ga("send", "pageview", { 1413 page: location.pathname, 1414 title: document.title 1415 }); 1416 } 1417 }; 1418 1419 this.options.scrollTo = typeof this.options.scrollTo === 'undefined' ? 0 : this.options.scrollTo; 1420 this.options.cacheBust = typeof this.options.cacheBust === 'undefined' ? true : this.options.cacheBust; 1421 this.options.debug = this.options.debug || false; // we canât replace body.outerHTML or head.outerHTML 1422 // it create a bug where new body or new head are created in the dom 1423 // if you set head.outerHTML, a new body tag is appended, so the dom get 2 body 1424 // & it break the switchFallback which replace head & body 1425 1426 if (!this.options.switches.head) { 1427 this.options.switches.head = this.switchElementsAlt; 1428 } 1429 1430 if (!this.options.switches.body) { 1431 this.options.switches.body = this.switchElementsAlt; 1432 } 1433 1434 if (typeof options.analytics !== "function") { 1435 options.analytics = function () {}; 1436 } 1437 } 1438 }; 1439 } 1440 1441 /** 1442 * Exports 1443 * -> refresh 1444 * -> reload 1445 * -> foreachSelectors 1446 * -> unattach 1447 */ 1448 function getDomUtils () { 1449 var _this = this; 1450 1451 return { 1452 refresh: function refresh(el) { 1453 _this.parseDOM(el || document); 1454 }, 1455 reload: function reload() { 1456 window.location.reload(); 1457 }, 1458 foreachSelectors: function foreachSelectors(selectors, cb, context, DOMcontext) { 1459 DOMcontext = DOMcontext || document; 1460 selectors.forEach(function (selector) { 1461 forEachEls(DOMcontext.querySelectorAll(selector), cb, context); 1462 }); 1463 }, 1464 unattach: function unattach(el) { 1465 forEachEls(_this.getElements(el), function (el) { 1466 off(el, 'click'); 1467 off(el, 'keyup'); 1468 }, _this); 1469 } 1470 }; 1471 } 1472 1473 var PjaxFactory = function PjaxFactory() { 1474 var Pjax = 1475 /*#__PURE__*/ 1476 function () { 1477 function Pjax(options) { 1478 var _this = this; 1479 1480 _classCallCheck(this, Pjax); 1481 1482 this.firstrun = true; 1483 this.oUtilities = getUtility(); 1484 this.oDomUtils = getDomUtils.call(this); 1485 this.oParsers = getParsers.call(this); 1486 this.oParsers.parseOptions.call(this, options); 1487 this.log = log.call(this); 1488 this.doRequest = doRequest; 1489 this.getElements = this.oUtilities.getElements; 1490 this.parseElementUnload = this.oParsers.parseElementUnload; 1491 this.parseElement = this.oParsers.parseElement; 1492 this.parseDOM = this.oParsers.parseDOM; 1493 this.parseDOMUnload = this.oParsers.parseDOMUnload; 1494 this.refresh = this.oDomUtils.refresh; 1495 this.reload = this.oDomUtils.reload; 1496 this.isSupported = this.oUtilities.isSupported; 1497 this.attachLink = getAttachLink.call(this); 1498 this.attachForm = getAttachForm.call(this); 1499 this.unattachLink = getUnattachLink.call(this); 1500 this.unattachForm = getUnattachForm.call(this); 1501 this.updateStylesheets = getUpdateStylesheets.call(this); 1502 this.log.log("Pjax options", this.options); 1503 this.maxUid = this.lastUid = this.oUtilities.newUid(); 1504 this.parseDOM(document); 1505 on(window, "popstate", function (st) { 1506 _this.log.log("OPT -> ", st); 1507 1508 if (st.state) { 1509 var opt = _this.oUtilities.clone(_this.options); 1510 1511 opt.url = st.state.url; 1512 opt.title = st.state.title; 1513 opt.history = false; 1514 opt.requestOptions = {}; 1515 1516 _this.log.log("OPT -> ", opt); 1517 1518 _this.log.log("State UID", st.state.uid); 1519 1520 _this.log.log("lastUID", _this.lastUid); 1521 1522 if (st.state.uid < _this.lastUid) { 1523 opt.backward = true; 1524 } else { 1525 opt.forward = true; 1526 } 1527 1528 _this.lastUid = st.state.uid; // @todo implement history cache here, based on uid 1529 1530 _this.loadUrl(st.state.url, opt); 1531 } 1532 }); 1533 return this; 1534 } 1535 1536 _createClass(Pjax, [{ 1537 key: "forEachSelectors", 1538 value: function forEachSelectors(cb, context, DOMcontext) { 1539 return this.oDomUtils.foreachSelectors(this.options.selectors, cb, context, DOMcontext); 1540 } 1541 }, { 1542 key: "switchSelectors", 1543 value: function switchSelectors(selectors, fromEl, toEl, options) { 1544 var fnSwitchSelectors = getSwitchSelectors.call(this); 1545 return fnSwitchSelectors(this.options.switches, this.options.switchesOptions, selectors, fromEl, toEl, options); 1546 } 1547 }, { 1548 key: "latestChance", 1549 value: function latestChance(href) { 1550 window.location.href = href; 1551 return false;
1552 } 1553 }, { 1554 key: "onSwitch", 1555 value: function onSwitch() { 1556 trigger(window, "resize scroll"); 1557 } 1558 }, { 1559 key: "loadContent", 1560 value: function loadContent(html, options) { 1561 var _this2 = this; 1562 1563 var fnExecuteScripts = getExecuteScripts.apply(this); 1564 var tmpEl = window.document.implementation.createHTMLDocument("pjax"); //Collector array to store the promises in 1565 1566 var collectForScriptcomplete = [Promise.resolve("basic resolve")]; //parse HTML attributes to copy them 1567 //since we are forced to use documentElement.innerHTML (outerHTML can't be used for <html>) 1568 1569 var htmlRegex = /<html[^>]+>/gi; 1570 var htmlAttribsRegex = /\s?[a-z:]+(?:=(?:'|")[^'">]+(?:'|"))*/gi; 1571 var matches = html.match(htmlRegex); 1572 1573 if (matches && matches.length) { 1574 matches = matches[0].match(htmlAttribsRegex); 1575 1576 if (matches.length) { 1577 matches.shift(); 1578 matches.forEach(function (htmlAttrib) { 1579 var attr = htmlAttrib.trim().split("="); 1580 1581 if (attr.length === 1) { 1582 tmpEl.documentElement.setAttribute(attr[0], true); 1583 } else { 1584 tmpEl.documentElement.setAttribute(attr[0], attr[1].slice(1, -1)); 1585 } 1586 }); 1587 } 1588 } 1589 1590 var jsonContent = null; 1591 1592 try { 1593 jsonContent = JSON.parse(html); 1594 } catch (e) { 1595 this.log.warn('No JSON found. If you expected it there was an error'); 1596 } 1597 1598 tmpEl.documentElement.innerHTML = html; 1599 this.log.log("load content", tmpEl.documentElement.attributes, tmpEl.documentElement.innerHTML.length); 1600 1601 if (jsonContent !== null) { 1602 this.log.log("found JSON document", jsonContent); 1603 this.options.onJsonDocument.call(this, jsonContent); 1604 } // Clear out any focused controls before inserting new page contents. 1605 // we clear focus on non form elements 1606 1607 1608 if (window.document.activeElement && !window.document.activeElement.value) { 1609 try { 1610 window.document.activeElement.blur(); 1611 } catch (e) {// Nothing to do, just ignore any issues 1612 } 1613 } 1614 1615 this.switchSelectors(this.options.selectors, tmpEl, document, options); //reset stylesheets if activated 1616 1617 if (this.options.reRenderCSS === true) { 1618 this.updateStylesheets(tmpEl.querySelectorAll('link[rel=stylesheet]'), document.querySelectorAll('link[rel=stylesheet]')); 1619 } // FF bug: Wonât autofocus fields that are inserted via JS. 1620 // This behavior is incorrect. So if theres no current focus, autofocus 1621 // the last field. 1622 // 1623 // http://www.w3.org/html/wg/drafts/html/master/forms.html 1624 1625 1626 var autofocusEl = Array.prototype.slice.call(document.querySelectorAll("[autofocus]")).pop(); 1627 1628 if (autofocusEl && document.activeElement !== autofocusEl) { 1629 autofocusEl.focus(); 1630 } // execute scripts when DOM have been completely updated 1631 1632 1633 this.options.selectors.forEach(function (selector) { 1634 _this2.oUtilities.forEachEls(document.querySelectorAll(selector), function (el) { 1635 collectForScriptcomplete.push.apply(collectForScriptcomplete, fnExecuteScripts(el)); 1636 }, _this2); 1637 }); // } 1638 // catch(e) { 1639 // if (this.options.debug) { 1640 // this.log.log("Pjax switch fail: ", e) 1641 // } 1642 // this.switchFallback(tmpEl, document) 1643 // } 1644 1645 this.log.log("waiting for scriptcomplete", collectForScriptcomplete); //Fallback! If something can't be loaded or is not loaded correctly -> just force eventing in error 1646 1647 var timeOutScriptEvent = null; 1648 timeOutScriptEvent = window.setTimeout(function () { 1649 trigger(document, "pjax:scriptcomplete pjax:scripttimeout", options); 1650 timeOutScriptEvent = null; 1651 }, this.options.scriptloadtimeout); 1652 Promise.all(collectForScriptcomplete).then( //resolved 1653 function () { 1654 if (timeOutScriptEvent !== null) { 1655 window.clearTimeout(timeOutScriptEvent); 1656 trigger(document, "pjax:scriptcomplete pjax:scriptsuccess", options); 1657 } 1658 }, function () { 1659 if (timeOutScriptEvent !== null) { 1660 window.clearTimeout(timeOutScriptEvent); 1661 trigger(document, "pjax:scriptcomplete pjax:scripterror", options); 1662 } 1663 }); 1664 } 1665 }, { 1666 key: "loadUrl", 1667 value: function loadUrl(href, options) { 1668 var _this3 = this; 1669 1670 this.log.log("load href", href, options); 1671 trigger(document, "pjax:send", options); // Do the request 1672 1673 this.doRequest(href, options.requestOptions, function (html, requestData) { 1674 // Fail if unable to load HTML via AJAX 1675 if (html === false || requestData.status !== 200) { 1676 trigger(document, "pjax:complete pjax:error", { 1677 options: options, 1678 requestData: requestData, 1679 href: href 1680 }); 1681 return options.pjaxErrorHandler(href, options, requestData); 1682 } // Clear out any focused controls before inserting new page contents. 1683 1684 1685 document.activeElement.blur(); 1686 1687 try { 1688 _this3.loadContent(html, options); 1689 } catch (e) { 1690 if (!_this3.options.debug) { 1691 if (console && _this3.options.logObject.error) { 1692 _this3.options.logObject.error("Pjax switch fail: ", e); 1693 } 1694 1695 return options.pjaxErrorHandler(href, options, requestData) || _this3.latestChance(href); 1696 } else { 1697 if (_this3.options.forceRedirectOnFail) { 1698 return options.pjaxErrorHandler(href, options, requestData) || _this3.latestChance(href); 1699 } 1700 1701 throw e; 1702 } 1703 } 1704 1705 if (options.history) { 1706 if (_this3.firstrun) { 1707 _this3.lastUid = _this3.maxUid = _this3.oUtilities.newUid(); 1708 _this3.firstrun = false;
1709 window.history.replaceState({ 1710 url: window.location.href, 1711 title: document.title, 1712 uid: _this3.maxUid 1713 }, document.title); 1714 } // Update browser history 1715 1716 1717 _this3.lastUid = _this3.maxUid = _this3.oUtilities.newUid(); 1718 window.history.pushState({ 1719 url: href, 1720 title: options.title, 1721 uid: _this3.maxUid 1722 }, options.title, href); 1723 } 1724 1725 _this3.forEachSelectors(function (el) { 1726 return _this3.parseDOM(el); 1727 }); // Fire Events 1728 1729 1730 trigger(document, "pjax:complete pjax:success", options); 1731 options.analytics(); // Scroll page to top on new page load 1732 1733 if (options.scrollTo !== false) { 1734 if (options.scrollTo.length > 1) { 1735 window.scrollTo(options.scrollTo[0], options.scrollTo[1]); 1736 } else { 1737 window.scrollTo(0, options.scrollTo); 1738 } 1739 } 1740 }); 1741 } 1742 }]); 1743 1744 return Pjax; 1745 }(); // if there isnât required browser functions, returning stupid api 1746 1747 1748 if (!isSupported()) { 1749 console.warn('Pjax not supported'); 1750 1751 var stupidPjax = function stupidPjax() {}; 1752 1753 for (var key in Pjax.prototype) { 1754 if (key in Pjax.prototype && typeof Pjax.prototype[key] === "function") { 1755 stupidPjax[key] = stupidPjax; 1756 } 1757 } 1758 1759 return stupidPjax; 1760 } 1761 1762 return Pjax; 1763 }; 1764 1765 var index = new PjaxFactory(); 1766 1767 return index; 1768 1769})); 1770//# sourceMappingURL=pjax.js.map
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.