vendor: 5,559 bytes, lines 1-161
1/*! 2* fullPage 4.0.17 3* https://github.com/alvarotrigo/fullPage.js 4* 5* @license GPLv3 for open source use only 6* or Fullpage Commercial License for commercial use 7* http://alvarotrigo.com/fullPage/pricing/ 8* 9* Copyright (C) 2018 http://alvarotrigo.com/fullPage - A project by Alvaro Trigo 10*/ 11 12(function (global, factory) { 13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 14 typeof define === 'function' && define.amd ? define(factory) : 15 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.fullpage = factory()); 16})(this, (function () { 'use strict'; 17 18 // https://tc39.github.io/ecma262/#sec-array.prototype.find 19 if (!Array.prototype.find) { 20 Object.defineProperty(Array.prototype, 'find', { 21 value: function value(predicate) { 22 // 1. Let O be ? ToObject(this value). 23 if (this == null) { 24 throw new TypeError('"this" is null or not defined'); 25 } 26 27 var o = Object(this); // 2. Let len be ? ToLength(? Get(O, "length")). 28 29 var len = o.length >>> 0; // 3. If IsCallable(predicate) is false, throw a TypeError exception. 30 31 if (typeof predicate !== 'function') { 32 throw new TypeError('predicate must be a function'); 33 } // 4. If thisArg was supplied, let T be thisArg; else let T be undefined. 34 35 36 var thisArg = arguments[1]; // 5. Let k be 0. 37 38 var k = 0; // 6. Repeat, while k < len 39 40 while (k < len) { 41 // a. Let Pk be ! ToString(k). 42 // b. Let kValue be ? Get(O, Pk). 43 // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). 44 // d. If testResult is true, return kValue. 45 var kValue = o[k]; 46 47 if (predicate.call(thisArg, kValue, k, o)) { 48 return kValue; 49 } // e. Increase k by 1. 50 51 52 k++; 53 } // 7. Return undefined. 54 55 56 return undefined; 57 } 58 }); 59 } 60 61 // Production steps of ECMA-262, Edition 6, 22.1.2.1 62 if (!Array.from) { 63 Array.from = function () { 64 var toStr = Object.prototype.toString; 65 66 var isCallable = function isCallable(fn) { 67 return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; 68 }; 69 70 var toInteger = function toInteger(value) { 71 var number = Number(value); 72 73 if (isNaN(number)) { 74 return 0; 75 } 76 77 if (number === 0 || !isFinite(number)) { 78 return number; 79 } 80 81 return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); 82 }; 83 84 var maxSafeInteger = Math.pow(2, 53) - 1; 85 86 var toLength = function toLength(value) { 87 var len = toInteger(value); 88 return Math.min(Math.max(len, 0), maxSafeInteger); 89 }; // The length property of the from method is 1. 90 91 92 return function from(arrayLike 93 /*, mapFn, thisArg */ 94 ) { 95 // 1. Let C be the this value. 96 var C = this; // 2. Let items be ToObject(arrayLike). 97 98 var items = Object(arrayLike); // 3. ReturnIfAbrupt(items). 99 100 if (arrayLike == null) { 101 throw new TypeError('Array.from requires an array-like object - not null or undefined'); 102 } // 4. If mapfn is undefined, then let mapping be false. 103 104 105 var mapFn = arguments.length > 1 ? arguments[1] : void undefined; 106 var T; 107 108 if (typeof mapFn !== 'undefined') { 109 // 5. else 110 // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. 111 if (!isCallable(mapFn)) { 112 throw new TypeError('Array.from: when provided, the second argument must be a function'); 113 } // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. 114 115 116 if (arguments.length > 2) { 117 T = arguments[2]; 118 } 119 } // 10. Let lenValue be Get(items, "length"). 120 // 11. Let len be ToLength(lenValue). 121 122 123 var len = toLength(items.length); // 13. If IsConstructor(C) is true, then 124 // 13. a. Let A be the result of calling the [[Construct]] internal method 125 // of C with an argument list containing the single item len. 126 // 14. a. Else, Let A be ArrayCreate(len). 127 128 var A = isCallable(C) ? Object(new C(len)) : new Array(len); // 16. Let k be 0. 129 130 var k = 0; // 17. Repeat, while k < len⦠(also steps a - h) 131 132 var kValue; 133 134 while (k < len) { 135 kValue = items[k]; 136 137 if (mapFn) { 138 A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); 139 } else { 140 A[k] = kValue; 141 } 142 143 k += 1; 144 } // 18. Let putStatus be Put(A, "length", len, true). 145 146 147 A.length = len; // 20. Return A. 148 149 return A; 150 }; 151 }(); 152 } 153 154 var win = window; 155 var doc = document; 156 var isTouchDevice = navigator.userAgent.match(/(iPhone|iPod|iPad|Android|playbook|silk|BlackBerry|BB10|Windows Phone|Tizen|Bada|webOS|IEMobile|Opera Mini)/); 157 var isMacDevice = /(Mac|iPhone|iPod|iPad)/i.test(win.navigator.userAgent); // @ts-ignore 158 159 var isTouch = 'ontouchstart' in win || navigator.msMaxTouchPoints > 0 || navigator.maxTouchPoints; 160 var isIE11 = !!window.MSInputMethodContext && !!document.documentMode; // taken from https://github.com/udacity/ud891/blob/gh-pages/lesson2-focus/07-modals-and-keyboard-traps/solution/modal.js 161
162 var focusableElementsString = 'a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, [tabindex="0"], [contenteditable]'; // cache common elements 163 164 var FP = { 165 test: {}, 166 shared: {} 167 }; 168 var extensions = ['parallax', 'scrollOverflowReset', 'dragAndMove', 'offsetSections', 'fadingEffect', 'responsiveSlides', 'continuousHorizontal', 'interlockedSlides', 'scrollHorizontally', 'resetSliders', 'cards', 'dropEffect', 'waterEffect']
vendor: 21,332 bytes, lines 168-949
168; 169 170 /** 171 * forEach polyfill for IE 172 * https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Browser_Compatibility 173 */ 174 175 if (win.NodeList && !NodeList.prototype.forEach) { 176 NodeList.prototype.forEach = function (callback, thisArg) { 177 thisArg = thisArg || window; 178 179 for (var i = 0; i < this.length; i++) { 180 callback.call(thisArg, this[i], i, this); 181 } 182 }; 183 } 184 185 if (typeof Object.assign != 'function') { 186 // Must be writable: true, enumerable: false, configurable: true 187 Object.defineProperty(Object, 'assign', { 188 value: function assign(target, varArgs) { 189 190 if (target == null) { 191 // TypeError if undefined or null 192 throw new TypeError('Cannot convert undefined or null to object'); 193 } 194 195 var to = Object(target); 196 197 for (var index = 1; index < arguments.length; index++) { 198 var nextSource = arguments[index]; 199 200 if (nextSource != null) { 201 // Skip over if undefined or null 202 for (var nextKey in nextSource) { 203 // Avoid bugs when hasOwnProperty is shadowed 204 if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { 205 to[nextKey] = nextSource[nextKey]; 206 } 207 } 208 } 209 } 210 211 return to; 212 }, 213 writable: true, 214 configurable: true 215 }); 216 } 217 218 // https://stackoverflow.com/questions/51719553/padstart-not-working-in-ie11 219 // https://github.com/behnammodi/polyfill/blob/master/string.polyfill.js 220 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart 221 if (!String.prototype.padStart) { 222 String.prototype.padStart = function padStart(targetLength, padString) { 223 targetLength = targetLength >> 0; //truncate if number or convert non-number to 0; 224 225 padString = String(typeof padString !== 'undefined' ? padString : ' '); 226 227 if (this.length > targetLength) { 228 return String(this); 229 } else { 230 targetLength = targetLength - this.length; 231 232 if (targetLength > padString.length) { 233 padString += Array.apply(null, Array(targetLength)).map(function () { 234 return padString; 235 }).join(""); 236 } 237 238 return padString.slice(0, targetLength) + String(this); 239 } 240 }; 241 } 242 243 //utils 244 /** 245 * Shows a message in the console of the given type. 246 */ 247 248 function showError(type, text) { 249 win.console && win.console[type] && win.console[type]('fullPage: ' + text); 250 } 251 function isVisible(el) { 252 var style = win.getComputedStyle(el); 253 return style.display !== 'none'; 254 } 255 function getVisible(elements) { 256 return Array.from(elements).filter(function (e) { 257 return isVisible(e); 258 }); 259 } 260 /** 261 * Equivalent of jQuery function $(). 262 */ 263 264 function $(selector, context) { 265 context = arguments.length > 1 ? context : document; 266 return context ? context.querySelectorAll(selector) : null; 267 } 268 /** 269 * Extends a given Object properties and its childs. 270 */ 271 272 function deepExtend(out) { 273 out = out || {}; 274 275 for (var i = 1, len = arguments.length; i < len; ++i) { 276 var obj = arguments[i]; 277 278 if (!obj) { 279 continue; 280 } 281 282 for (var key in obj) { 283 if (!obj.hasOwnProperty(key) || key == '__proto__' || key == 'constructor') { 284 continue; 285 } // based on https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/ 286 287 288 if (Object.prototype.toString.call(obj[key]) === '[object Object]') { 289 out[key] = deepExtend(out[key], obj[key]); 290 continue; 291 } 292 293 out[key] = obj[key]; 294 } 295 } 296 297 return out; 298 } 299 /** 300 * Checks if the passed element contains the passed class. 301 */ 302 303 function hasClass(el, className) { 304 if (el == null) { 305 return false; 306 } 307 308 return el.classList.contains(className); 309 } 310 /** 311 * Gets the window height. Crossbrowser. 312 */ 313 314 function getWindowHeight() { 315 return 'innerHeight' in win ? win.innerHeight : doc.documentElement.offsetHeight; 316 } 317 /** 318 * Gets the window width. 319 */ 320 321 function getWindowWidth() { 322 return win.innerWidth; 323 } 324 /** 325 * Set's the CSS properties for the passed item/s. 326 * @param {NodeList|HTMLElement|Object} items 327 * @param {Object} props css properties and values. 328 */ 329 330 function css(items, props) { 331 items = getList(items); 332 var key; 333 334 for (key in props) { 335 if (props.hasOwnProperty(key)) { 336 if (key !== null) { 337 for (var i = 0; i < items.length; i++) { 338 var item = items[i]; 339 item.style[key] = props[key]; 340 } 341 } 342 } 343 } 344 345 return items; 346 } 347 /** 348 * Gets the previous element to the passed element. 349 */ 350 351 function prev(item) { 352 return item.previousElementSibling; 353 } 354 /** 355 * Gets the next element to the passed element. 356 */ 357 358 function next(item) { 359 return item.nextElementSibling; 360 } 361 /** 362 * Gets the last element from the passed list of elements. 363 */ 364 365 function last(item) { 366 return item[item.length - 1]; 367 } 368 /** 369 * Gets index from the passed element. 370 * @param {String} selector is optional. 371 */ 372 373 function index(item, selector) { 374 item = isArrayOrList(item) ? item[0] : item; 375 var children = selector != null ? $(selector, item.parentNode) : item.parentNode.childNodes; 376 var num = 0; 377 378 for (var i = 0; i < children.length; i++) { 379 if (children[i] == item) return num; 380 if (children[i].nodeType == 1) num++; 381 } 382 383 return -1; 384 } 385 /** 386 * Gets an iterable element for the passed element/s 387 */ 388 389 function getList(item) { 390 return !isArrayOrList(item) ? [item] : item; 391 } 392 /** 393 * Adds the display=none property for the passed element/s 394 */ 395 396 function hide(el) { 397 el = getList(el); 398 399 for (var i = 0; i < el.length; i++) { 400 el[i].style.display = 'none'; 401 } 402 403 return el; 404 } 405 /** 406 * Adds the display=block property for the passed element/s 407 */ 408 409 function show(el) { 410 el = getList(el); 411 412 for (var i = 0; i < el.length; i++) { 413 el[i].style.display = 'block'; 414 } 415 416 return el; 417 } 418 /** 419 * Checks if the passed element is an iterable element or not 420 */ 421 422 function isArrayOrList(el) { 423 return Object.prototype.toString.call(el) === '[object Array]' || Object.prototype.toString.call(el) === '[object NodeList]'; 424 } 425 /** 426 * Adds the passed class to the passed element/s 427 */ 428 429 function addClass(el, className) { 430 el = getList(el); 431 432 for (var i = 0; i < el.length; i++) { 433 var item = el[i]; 434 item.classList.add(className); 435 } 436 437 return el; 438 } 439 /** 440 * Removes the passed class to the passed element/s 441 * @param {String} `className` can be multiple classnames separated by whitespace 442 */ 443 444 function removeClass(el, className) { 445 el = getList(el); 446 var classNames = className.split(' '); 447 448 for (var a = 0; a < classNames.length; a++) { 449 className = classNames[a]; 450 451 for (var i = 0; i < el.length; i++) { 452 var item = el[i]; 453 item.classList.remove(className); 454 } 455 } 456 457 return el; 458 } 459 /** 460 * Appends the given element ot the given parent. 461 */ 462 463 function appendTo(el, parent) { 464 parent.appendChild(el); 465 } 466 /** 467 Usage: 468 469 var wrapper = document.createElement('div'); 470 wrapper.className = 'fp-slides'; 471 wrap($('.slide'), wrapper); 472 473 https://jsfiddle.net/qwzc7oy3/15/ (vanilla) 474 https://jsfiddle.net/oya6ndka/1/ (jquery equivalent) 475 */ 476 477 function wrap(toWrap, wrapper, isWrapAll) { 478 var newParent; 479 wrapper = wrapper || doc.createElement('div'); 480 481 for (var i = 0; i < toWrap.length; i++) { 482 var item = toWrap[i]; 483 484 if (isWrapAll && !i || !isWrapAll) { 485 newParent = wrapper.cloneNode(true); 486 item.parentNode.insertBefore(newParent, item); 487 } 488 489 newParent.appendChild(item); 490 } 491 492 return toWrap; 493 } 494 /** 495 Usage: 496 var wrapper = document.createElement('div'); 497 wrapper.className = 'fp-slides'; 498 wrap($('.slide'), wrapper); 499 500 https://jsfiddle.net/qwzc7oy3/27/ (vanilla) 501 https://jsfiddle.net/oya6ndka/4/ (jquery equivalent) 502 */ 503 504 function wrapAll(toWrap, wrapper) { 505 wrap(toWrap, wrapper, true); 506 } 507 /** 508 * Usage: 509 * wrapInner(document.querySelector('#pepe'), '<div class="test">afdas</div>'); 510 * wrapInner(document.querySelector('#pepe'), element); 511 * 512 * https://jsfiddle.net/zexxz0tw/6/ 513 * 514 * https://stackoverflow.com/a/21817590/1081396 515 */ 516 517 function wrapInner(parent, wrapper) { 518 parent.appendChild(wrapper); 519 520 while (parent.firstChild !== wrapper) { 521 wrapper.appendChild(parent.firstChild); 522 } 523 } 524 /** 525 * Usage: 526 * unwrap(document.querySelector('#pepe')); 527 * unwrap(element); 528 * 529 * https://jsfiddle.net/szjt0hxq/1/ 530 * 531 */ 532 533 function unwrap(wrapper) { 534 var wrapperContent = doc.createDocumentFragment(); 535 536 while (wrapper.firstChild) { 537 wrapperContent.appendChild(wrapper.firstChild); 538 } 539 540 wrapper.parentNode.replaceChild(wrapperContent, wrapper); 541 } 542 /** 543 * http://stackoverflow.com/questions/22100853/dom-pure-javascript-solution-to-jquery-closest-implementation 544 * Returns the element or `false` if there's none 545 */ 546 547 function closest(el, selector) { 548 if (el && el.nodeType === 1) { 549 if (matches(el, selector)) { 550 return el; 551 } 552 553 return closest(el.parentNode, selector); 554 } 555 556 return null; 557 } 558 /** 559 * Places one element (rel) after another one or group of them (reference). 560 * @param {HTMLElement} reference 561 * @param {HTMLElement|NodeList|String|Array} el 562 * https://jsfiddle.net/9s97hhzv/1/ 563 */ 564 565 function after(reference, el) { 566 insertBefore(reference, reference.nextSibling, el); 567 } 568 /** 569 * Places one element (rel) before another one or group of them (reference). 570 * @param {HTMLElement} reference 571 * @param {HTMLElement|NodeList|String|Array} el 572 * https://jsfiddle.net/9s97hhzv/1/ 573 */ 574 575 function before(reference, el) { 576 insertBefore(reference, reference, el); 577 } 578 /** 579 * Based in https://stackoverflow.com/a/19316024/1081396 580 * and https://stackoverflow.com/a/4793630/1081396 581 */ 582 583 function insertBefore(reference, beforeElement, el) { 584 if (!isArrayOrList(el)) { 585 if (typeof el == 'string') { 586 el = createElementFromHTML(el); 587 } 588 589 el = [el]; 590 } 591 592 for (var i = 0; i < el.length; i++) { 593 reference.parentNode.insertBefore(el[i], beforeElement); 594 } 595 } //http://stackoverflow.com/questions/3464876/javascript-get-window-x-y-position-for-scroll 596 597 function getScrollTop() { 598 var docElement = doc.documentElement; 599 return (win.pageYOffset || docElement.scrollTop) - (docElement.clientTop || 0); 600 } 601 /** 602 * Gets the siblings of the passed element 603 */ 604 605 function siblings(el) { 606 return Array.prototype.filter.call(el.parentNode.children, function (child) { 607 return child !== el; 608 }); 609 } 610 function preventDefault(event) { 611 event.preventDefault(); 612 } 613 function getAttr(el, attr) { 614 return el.getAttribute(attr); 615 } 616 function docAddEvent(event, callback, options) { 617 doc.addEventListener(event, callback, options === 'undefined' ? null : options); 618 } 619 function windowAddEvent(event, callback, options) { 620 win.addEventListener(event, callback, options === 'undefined' ? null : options); 621 } 622 function docRemoveEvent(event, callback, options) { 623 doc.removeEventListener(event, callback, options === 'undefined' ? null : options); 624 } 625 function windowRemoveEvent(event, callback, options) { 626 win.removeEventListener(event, callback, options === 'undefined' ? null : options); 627 } 628 /** 629 * Determines whether the passed item is of function type. 630 */ 631 632 function isFunction(item) { 633 if (typeof item === 'function') { 634 return true; 635 } 636 637 var type = Object.prototype.toString.call(item); 638 return type === '[object Function]' || type === '[object GeneratorFunction]'; 639 } 640 /** 641 * Trigger custom events 642 */ 643 644 function trigger(el, eventName, data) { 645 var event; 646 data = typeof data === 'undefined' ? {} : data; // Native 647 648 if (typeof win.CustomEvent === "function") { 649 event = new CustomEvent(eventName, { 650 detail: data 651 }); 652 } else { 653 event = doc.createEvent('CustomEvent'); 654 event.initCustomEvent(eventName, true, true, data); 655 } 656 657 el.dispatchEvent(event); 658 } 659 /** 660 * Polyfill of .matches() 661 */ 662 663 function matches(el, selector) { 664 return (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector).call(el, selector); 665 } 666 /** 667 * Toggles the visibility of the passed element el. 668 */ 669 670 function toggle(el, value) { 671 if (typeof value === "boolean") { 672 for (var i = 0; i < el.length; i++) { 673 el[i].style.display = value ? 'block' : 'none'; 674 } 675 } //we don't use it in other way, so no else :) 676 677 678 return el; 679 } 680 /** 681 * Creates a HTMLElement from the passed HTML string. 682 * https://stackoverflow.com/a/494348/1081396 683 */ 684 685 function createElementFromHTML(htmlString) { 686 var div = doc.createElement('div'); 687 div.innerHTML = htmlString.trim(); // Change this to div.childNodes to support multiple top-level nodes 688 689 return div.firstChild; 690 } 691 /** 692 * Removes the passed item/s from the DOM. 693 */ 694 695 function remove(items) { 696 items = getList(items); 697 698 for (var i = 0; i < items.length; i++) { 699 var item = items[i]; 700 701 if (item && item.parentElement) { 702 item.parentNode.removeChild(item); 703 } 704 } 705 } //https://jsfiddle.net/w1rktecz/ 706 707 function untilAll(item, selector, fn) { 708 var sibling = item[fn]; 709 var siblings = []; 710 711 while (sibling) { 712 if (matches(sibling, selector) || selector == null) { 713 siblings.push(sibling); 714 } 715 716 sibling = sibling[fn]; 717 } 718 719 return siblings; 720 } 721 /** 722 * Gets all next elements matching the passed selector. 723 */ 724 725 function nextAll(item, selector) { 726 return untilAll(item, selector, 'nextElementSibling'); 727 } 728 /** 729 * Gets all previous elements matching the passed selector. 730 */ 731 732 function prevAll(item, selector) { 733 return untilAll(item, selector, 'previousElementSibling'); 734 } 735 /** 736 * Converts an object to an array. 737 */ 738 739 function toArray(objectData) { 740 return Object.keys(objectData).map(function (key) { 741 return objectData[key]; 742 }); 743 } 744 function getLast(items) { 745 return items[items.length - 1]; 746 } 747 /** 748 * Gets the average of the last `number` elements of the given array. 749 */ 750 751 function getAverage(elements, number) { 752 var sum = 0; //taking `number` elements from the end to make the average, if there are not enought, 1 753 754 var lastElements = elements.slice(Math.max(elements.length - number, 1)); 755 756 for (var i = 0; i < lastElements.length; i++) { 757 sum = sum + lastElements[i]; 758 } 759 760 return Math.ceil(sum / number); 761 } 762 /** 763 * Sets the value for the given attribute from the `data-` attribute with the same suffix 764 * ie: data-srcset ==> srcset | data-src ==> src 765 */ 766 767 function setSrc(element, attribute) { 768 element.setAttribute(attribute, getAttr(element, 'data-' + attribute)); 769 element.removeAttribute('data-' + attribute); 770 } 771 function getParentsUntil(item, topParentSelector) { 772 var parents = [item]; 773 774 do { 775 item = item.parentNode; 776 parents.push(item); 777 } while (!matches(item, topParentSelector)); 778 779 return parents; 780 } 781 function isInsideInput() { 782 var activeElement = doc.activeElement; 783 return matches(activeElement, 'textarea') || matches(activeElement, 'input') || matches(activeElement, 'select') || getAttr(activeElement, 'contentEditable') == "true" || getAttr(activeElement, 'contentEditable') == ''; 784 } //utils are public, so we can use it wherever we want 785 // @ts-ignore 786 787 window["fp_utils"] = { 788 "$": $, 789 "deepExtend": deepExtend, 790 "hasClass": hasClass, 791 "getWindowHeight": getWindowHeight, 792 "css": css, 793 "prev": prev, 794 "next": next, 795 "last": last, 796 "index": index, 797 "getList": getList, 798 "hide": hide, 799 "show": show, 800 "isArrayOrList": isArrayOrList, 801 "addClass": addClass, 802 "removeClass": removeClass, 803 "appendTo": appendTo, 804 "wrap": wrap, 805 "wrapAll": wrapAll, 806 "unwrap": unwrap, 807 "closest": closest, 808 "after": after, 809 "before": before, 810 "insertBefore": insertBefore, 811 "getScrollTop": getScrollTop, 812 "siblings": siblings, 813 "preventDefault": preventDefault, 814 "isFunction": isFunction, 815 "trigger": trigger, 816 "matches": matches, 817 "toggle": toggle, 818 "createElementFromHTML": createElementFromHTML, 819 "remove": remove, 820 // "filter": filter, 821 "untilAll": untilAll, 822 "nextAll": nextAll, 823 "prevAll": prevAll, 824 "showError": showError 825 }; 826 827 var utils = /*#__PURE__*/Object.freeze({ 828 __proto__: null, 829 showError: showError, 830 isVisible: isVisible, 831 getVisible: getVisible, 832 $: $, 833 deepExtend: deepExtend, 834 hasClass: hasClass, 835 getWindowHeight: getWindowHeight, 836 getWindowWidth: getWindowWidth, 837 css: css, 838 prev: prev, 839 next: next, 840 last: last, 841 index: index, 842 getList: getList, 843 hide: hide, 844 show: show, 845 isArrayOrList: isArrayOrList, 846 addClass: addClass, 847 removeClass: removeClass, 848 appendTo: appendTo, 849 wrap: wrap, 850 wrapAll: wrapAll, 851 wrapInner: wrapInner, 852 unwrap: unwrap, 853 closest: closest, 854 after: after, 855 before: before, 856 insertBefore: insertBefore, 857 getScrollTop: getScrollTop, 858 siblings: siblings, 859 preventDefault: preventDefault, 860 getAttr: getAttr, 861 docAddEvent: docAddEvent, 862 windowAddEvent: windowAddEvent, 863 docRemoveEvent: docRemoveEvent, 864 windowRemoveEvent: windowRemoveEvent, 865 isFunction: isFunction, 866 trigger: trigger, 867 matches: matches, 868 toggle: toggle, 869 createElementFromHTML: createElementFromHTML, 870 remove: remove, 871 untilAll: untilAll, 872 nextAll: nextAll, 873 prevAll: prevAll, 874 toArray: toArray, 875 getLast: getLast, 876 getAverage: getAverage, 877 setSrc: setSrc, 878 getParentsUntil: getParentsUntil, 879 isInsideInput: isInsideInput 880 }); 881 882 function _typeof(obj) { 883 "@babel/helpers - typeof"; 884 885 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 886 _typeof = function (obj) { 887 return typeof obj; 888 }; 889 } else { 890 _typeof = function (obj) { 891 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 892 }; 893 } 894 895 return _typeof(obj); 896 } 897 898 var EventEmitter = { 899 events: {}, 900 on: function on(event, listener) { 901 var _this = this; 902 903 if (_typeof(this.events[event]) !== 'object') { 904 this.events[event] = []; 905 } 906 907 this.events[event].push(listener); 908 return function () { 909 return _this.removeListener(event, listener); 910 }; 911 }, 912 removeListener: function removeListener(event, listener) { 913 if (_typeof(this.events[event]) === 'object') { 914 var idx = this.events[event].indexOf(listener); 915 916 if (idx > -1) { 917 this.events[event].splice(idx, 1); 918 } 919 } 920 }, 921 emit: function emit(event) { 922 var _this2 = this; 923 924 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 925 args[_key - 1] = arguments[_key]; 926 } 927 928 if (_typeof(this.events[event]) === 'object') { 929 this.events[event].forEach(function (listener) { 930 return listener.apply(_this2, args); 931 }); 932 } 933 }, 934 once: function once(event, listener) { 935 var _this3 = this; 936 937 var remove = this.on(event, function () { 938 remove(); 939 940 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 941 args[_key2] = arguments[_key2]; 942 } 943 944 listener.apply(_this3, args); 945 }); 946 } 947 }; 948 949 var
vendor: 7,711 bytes, lines 949-1198
949state = { 950 numSections: 0, 951 numSlides: 0, 952 slides: [], 953 sections: [], 954 activeSection: null, 955 scrollTrigger: null, 956 isBeyondFullpage: false, 957 aboutToScrollToFullPage: false, 958 slideMoving: false, 959 isResizing: false, 960 isScrolling: false, 961 lastScrolledDestiny: undefined, 962 lastScrolledSlide: undefined, 963 activeAnimation: false, 964 canScroll: true, 965 touchDirection: 'none', 966 wheelDirection: 'none', 967 isGrabbing: false, 968 isUsingWheel: false, 969 isWindowFocused: true, 970 previousDestTop: 0, 971 windowsHeight: getWindowHeight(), 972 isDoingContinousVertical: false, 973 timeouts: {}, 974 scrollY: 0, 975 scrollX: 0 976 }; // @ts-ignore 977 978 win.state = state; 979 function setState(props) { 980 Object.assign(state, props); 981 } 982 function getState() { 983 return state; 984 } 985 function getActivePanel() { 986 return state.activeSection && state.activeSection.activeSlide ? state.activeSection.activeSlide : state.activeSection; 987 } 988 989 var events = { 990 onAfterRenderNoAnchor: 'onAfterRenderNoAnchor', 991 onClickOrTouch: 'onClickOrTouch', 992 moveSlideLeft: 'moveSlideLeft', 993 moveSlideRight: 'moveSlideRight', 994 onInitialise: 'onInitialise', 995 beforeInit: 'beforeInit', 996 bindEvents: 'bindEvents', 997 onDestroy: 'onDestroy', 998 contentChanged: 'contentChanged', 999 onScrollOverflowScrolled: 'onScrollOverflowScrolled', 1000 onScrollPageAndSlide: 'onScrollPageAndSlide', 1001 onKeyDown: 'onKeyDown', 1002 onMenuClick: 'onMenuClick', 1003 scrollPage: 'scrollPage', 1004 landscapeScroll: 'landscapeScroll', 1005 scrollBeyondFullpage: 'scrollBeyondFullpage', 1006 onPerformMovement: 'onPerformMovement', 1007 onSlideLeave: 'onSlideLeave', 1008 onLeave: 'onLeave', 1009 afterSectionLoads: 'afterSectionLoads', 1010 afterSlideLoads: 'afterSlideLoads' 1011 }; 1012 1013 EventEmitter.on(events.bindEvents, bindEvents$c); 1014 1015 function bindEvents$c() { 1016 //Scrolls to the section when clicking the navigation bullet 1017 //simulating the jQuery .on('click') event using delegation 1018 ['click', 'touchstart'].forEach(function (eventName) { 1019 docAddEvent(eventName, delegatedEvents); 1020 }); 1021 windowAddEvent('focus', focusHandler); 1022 internalEvents(); 1023 } 1024 1025 function internalEvents() { 1026 EventEmitter.on(events.onDestroy, onDestroy$9); 1027 } 1028 1029 function delegatedEvents(e) { 1030 EventEmitter.emit(events.onClickOrTouch, { 1031 e: e, 1032 target: e.target 1033 }); 1034 } 1035 1036 function onDestroy$9() { 1037 ['click', 'touchstart'].forEach(function (eventName) { 1038 docRemoveEvent(eventName, delegatedEvents); 1039 }); 1040 } // changing isWindowFocused to true on focus event 1041 1042 1043 function focusHandler() { 1044 setState({ 1045 isWindowFocused: true 1046 }); 1047 } 1048 1049 // keeping central set of classnames and selectors 1050 var WRAPPER = 'fullpage-wrapper'; 1051 var WRAPPER_SEL = '.' + WRAPPER; // slimscroll 1052 1053 var RESPONSIVE = 'fp-responsive'; 1054 var NO_TRANSITION = 'fp-notransition'; 1055 var DESTROYED = 'fp-destroyed'; 1056 var ENABLED = 'fp-enabled'; 1057 var VIEWING_PREFIX = 'fp-viewing'; 1058 var ACTIVE = 'active'; 1059 var ACTIVE_SEL = '.' + ACTIVE; 1060 var COMPLETELY = 'fp-completely'; 1061 var COMPLETELY_SEL = '.' + COMPLETELY; // section 1062 1063 var SECTION_DEFAULT_SEL = '.section'; 1064 var SECTION = 'fp-section'; 1065 var SECTION_SEL = '.' + SECTION; 1066 var SECTION_ACTIVE_SEL = SECTION_SEL + ACTIVE_SEL; 1067 var TABLE_CELL = 'fp-tableCell'; 1068 var TABLE_CELL_SEL = '.' + TABLE_CELL; 1069 var AUTO_HEIGHT = 'fp-auto-height'; 1070 var AUTO_HEIGHT_SEL = '.' + AUTO_HEIGHT; 1071 var AUTO_HEIGHT_RESPONSIVE = 'fp-auto-height-responsive'; 1072 var AUTO_HEIGHT_RESPONSIVE_SEL = '.' + AUTO_HEIGHT_RESPONSIVE; 1073 var NORMAL_SCROLL = 'fp-normal-scroll'; 1074 1075 var SECTION_NAV = 'fp-nav'; 1076 var SECTION_NAV_SEL = '#' + SECTION_NAV; 1077 var SECTION_NAV_TOOLTIP = 'fp-tooltip'; 1078 var SECTION_NAV_TOOLTIP_SEL = '.' + SECTION_NAV_TOOLTIP; 1079 var SHOW_ACTIVE_TOOLTIP = 'fp-show-active'; // slide 1080 1081 var SLIDE_DEFAULT_SEL = '.slide'; 1082 var SLIDE = 'fp-slide'; 1083 var SLIDE_SEL = '.' + SLIDE; 1084 var SLIDE_ACTIVE_SEL = SLIDE_SEL + ACTIVE_SEL; 1085 var SLIDES_WRAPPER = 'fp-slides'; 1086 var SLIDES_WRAPPER_SEL = '.' + SLIDES_WRAPPER; 1087 var SLIDES_CONTAINER = 'fp-slidesContainer'; 1088 var SLIDES_CONTAINER_SEL = '.' + SLIDES_CONTAINER; 1089 var TABLE = 'fp-table'; 1090 var OVERFLOW = 'fp-overflow'; 1091 var OVERFLOW_SEL = '.' + OVERFLOW; 1092 var IS_OVERFLOW = 'fp-is-overflow'; // slide nav 1093 1094 var SLIDES_NAV = 'fp-slidesNav'; 1095 var SLIDES_NAV_SEL = '.' + SLIDES_NAV; 1096 var SLIDES_NAV_LINK_SEL = SLIDES_NAV_SEL + ' a'; 1097 var SLIDES_STYLED_ARROW = 'fp-arrow'; 1098 var SLIDES_ARROW = 'fp-controlArrow'; 1099 var SLIDES_ARROW_SEL = '.' + SLIDES_ARROW; 1100 var SLIDES_PREV = 'fp-prev'; 1101 var SLIDES_PREV_SEL = '.' + SLIDES_PREV; 1102 var SLIDES_ARROW_PREV_SEL = SLIDES_ARROW_SEL + SLIDES_PREV_SEL; 1103 var SLIDES_NEXT = 'fp-next'; 1104 var SLIDES_NEXT_SEL = '.' + SLIDES_NEXT; 1105 var SLIDES_ARROW_NEXT_SEL = SLIDES_ARROW_SEL + SLIDES_NEXT_SEL; 1106 1107 var defaultOptions = { 1108 //navigation 1109 menu: false, 1110 anchors: [], 1111 lockAnchors: false, 1112 navigation: false, 1113 navigationPosition: 'right', 1114 navigationTooltips: [], 1115 showActiveTooltip: false, 1116 slidesNavigation: false, 1117 slidesNavPosition: 'bottom', 1118 scrollBar: false, 1119 hybrid: false, 1120 licenseKey: '', 1121 credits: { 1122 "enabled": true, 1123 "label": 'Made with fullPage.js', 1124 "position": 'right' 1125 }, 1126 //scrolling 1127 css3: true, 1128 scrollingSpeed: 700, 1129 autoScrolling: true, 1130 fitToSection: true, 1131 fitToSectionDelay: 600, 1132 easing: 'easeInOutCubic', 1133 easingcss3: 'ease', 1134 loopBottom: false, 1135 loopTop: false, 1136 loopHorizontal: true, 1137 continuousVertical: false, 1138 continuousHorizontal: false, 1139 scrollHorizontally: false, 1140 interlockedSlides: false, 1141 dragAndMove: false, 1142 offsetSections: false, 1143 resetSliders: false, 1144 fadingEffect: false, 1145 normalScrollElements: null, 1146 scrollOverflow: true, 1147 scrollOverflowReset: false, 1148 touchSensitivity: 5, 1149 touchWrapper: null, 1150 bigSectionsDestination: null, 1151 //Accessibility 1152 keyboardScrolling: true, 1153 animateAnchor: true, 1154 recordHistory: true, 1155 allowCorrectDirection: false, 1156 //design 1157 scrollOverflowMacStyle: true, 1158 controlArrows: true, 1159 controlArrowsHTML: ['<div class="' + SLIDES_STYLED_ARROW + '"></div>', '<div class="' + SLIDES_STYLED_ARROW + '"></div>'], 1160 controlArrowColor: '#fff', 1161 verticalCentered: true, 1162 sectionsColor: [], 1163 paddingTop: 0, 1164 paddingBottom: 0, 1165 fixedElements: null, 1166 responsive: 0, 1167 //backwards compabitility with responsiveWiddth 1168 responsiveWidth: 0, 1169 responsiveHeight: 0, 1170 responsiveSlides: false, 1171 parallax: false, 1172 parallaxOptions: { 1173 type: 'reveal', 1174 percentage: 62, 1175 property: 'translate' 1176 }, 1177 cards: false, 1178 cardsOptions: { 1179 perspective: 100, 1180 fadeContent: true, 1181 fadeBackground: true 1182 }, 1183 //Custom selectors 1184 sectionSelector: SECTION_DEFAULT_SEL, 1185 slideSelector: SLIDE_DEFAULT_SEL, 1186 //events 1187 afterLoad: null, 1188 beforeLeave: null, 1189 onLeave: null, 1190 afterRender: null, 1191 afterResize: null, 1192 afterReBuild: null, 1193 afterSlideLoad: null, 1194 onSlideLeave: null, 1195 afterResponsive: null, 1196 onScrollOverflow: null, 1197 lazyLoading: true, 1198 observer: tru
vendor: 11,786 bytes, lines 1198-1594
1198e 1199 }; 1200 1201 var container = null; 1202 var g_initialAnchorsInDom = false; 1203 var originals = deepExtend({}, defaultOptions); //deep copy 1204 1205 var g_options = null; 1206 function getInitialAnchorsInDom() { 1207 return g_initialAnchorsInDom; 1208 } 1209 function setContainer(value) { 1210 container = value; 1211 } 1212 function getContainer(value) { 1213 return container; 1214 } 1215 function getOptions() { 1216 return g_options || defaultOptions; 1217 } 1218 function setOptions(options) { 1219 g_options = deepExtend({}, defaultOptions, options); 1220 originals = Object.assign({}, g_options); 1221 } 1222 function getOriginals() { 1223 return originals; 1224 } 1225 function setOption(name, value) { 1226 defaultOptions[name] = value; 1227 } 1228 /* 1229 * Sets the state for a variable with multiple states (original, and temporal) 1230 * Some variables such as `autoScrolling` or `recordHistory` might change automatically its state when using `responsive` or `autoScrolling:false`. 1231 * This function is used to keep track of both states, the original and the temporal one. 1232 * If type is not 'internal', then we assume the user is globally changing the variable. 1233 */ 1234 1235 function setVariableState(variable, value, type) { 1236 g_options[variable] = value; 1237 1238 if (type !== 'internal') { 1239 originals[variable] = value; 1240 } 1241 } 1242 /** 1243 * Setting options from DOM elements if they are not provided. 1244 */ 1245 1246 function setOptionsFromDOM() { 1247 //no anchors option? Checking for them in the DOM attributes 1248 if (!getOptions().anchors.length) { 1249 var anchorsAttribute = '[data-anchor]'; 1250 var anchors = $(getOptions().sectionSelector.split(',').join(anchorsAttribute + ',') + anchorsAttribute, container); 1251 1252 if (anchors.length && anchors.length === $(getOptions().sectionSelector, container).length) { 1253 g_initialAnchorsInDom = true; 1254 anchors.forEach(function (item) { 1255 getOptions().anchors.push(getAttr(item, 'data-anchor').toString()); 1256 }); 1257 } 1258 } //no tooltips option? Checking for them in the DOM attributes 1259 1260 1261 if (!getOptions().navigationTooltips.length) { 1262 var tooltipsAttribute = '[data-tooltip]'; 1263 var tooltips = $(getOptions().sectionSelector.split(',').join(tooltipsAttribute + ',') + tooltipsAttribute, container); 1264 1265 if (tooltips.length) { 1266 tooltips.forEach(function (item) { 1267 getOptions().navigationTooltips.push(getAttr(item, 'data-tooltip').toString()); 1268 }); 1269 } 1270 } 1271 } 1272 1273 var plainItem = function plainItem(panel) { 1274 this.anchor = panel.anchor; 1275 this.item = panel.item; 1276 this.index = panel.index(); 1277 this.isLast = this.index === panel.item.parentElement.querySelectorAll(panel.selector).length - 1; 1278 this.isFirst = !this.index; 1279 this.isActive = panel.isActive; 1280 }; 1281 /** 1282 * Item. Slide or Section objects share the same properties. 1283 */ 1284 1285 var Item = function Item(el, selector) { 1286 this.parent = this.parent || null; 1287 this.selector = selector; 1288 this.anchor = getAttr(el, 'data-anchor') || getOptions().anchors[index(el, getOptions().sectionSelector)]; 1289 this.item = el; 1290 this.isVisible = isVisible(el); 1291 this.isActive = hasClass(el, ACTIVE); 1292 this.hasScroll = hasClass(el, OVERFLOW) || $(OVERFLOW_SEL, el)[0] != null; 1293 this.isSection = selector === getOptions().sectionSelector; 1294 this.container = closest(el, SLIDES_CONTAINER_SEL) || closest(el, WRAPPER_SEL); 1295 1296 this.index = function () { 1297 return this.siblings().indexOf(this); 1298 }; 1299 }; 1300 1301 Item.prototype.siblings = function () { 1302 if (this.isSection) { 1303 if (this.isVisible) { 1304 return state.sections; 1305 } else { 1306 return state.sectionsIncludingHidden; 1307 } 1308 } 1309 1310 return this.parent ? this.parent.slides : 0; 1311 }; 1312 1313 Item.prototype.prev = function () { 1314 var siblings = this.siblings(); 1315 var currentIndex = this.isSection ? siblings.indexOf(this) : this.parent.slides.indexOf(this); 1316 var prevIndex = currentIndex - 1; 1317 1318 if (prevIndex >= 0) { 1319 return siblings[prevIndex]; 1320 } 1321 1322 return null; 1323 }; 1324 1325 Item.prototype.next = function () { 1326 var siblings = this.siblings(); 1327 var currentIndex = this.isSection ? siblings.indexOf(this) : this.parent.slides.indexOf(this); 1328 var nextIndex = currentIndex + 1; 1329 1330 if (nextIndex < siblings.length) { 1331 return siblings[nextIndex]; 1332 } 1333 1334 return null; 1335 }; 1336 1337 Item.prototype["prevPanel"] = function () { 1338 return this.prev() || (this.parent ? this.parent.prev() : null); 1339 }; 1340 1341 Item.prototype["nextPanel"] = function () { 1342 return this.next() || (this.parent ? this.parent.next() : null); 1343 }; 1344 1345 Item.prototype.getSiblings = function () { 1346 if (this.isSection) { 1347 return state.sections; 1348 } 1349 1350 return state.panels; 1351 }; 1352 1353 function getNodes(panels) { 1354 return panels.map(function (panel) { 1355 return panel.item; 1356 }); 1357 } 1358 function getPanelByElement(panels, el) { 1359 return panels.find(function (panel) { 1360 return panel.item === el; 1361 }); 1362 } 1363 var Section = function Section(el) { 1364 plainItem.call(this, el); 1365 }; 1366 var Slide = function Slide(el) { 1367 plainItem.call(this, el); 1368 }; 1369 1370 /** 1371 * Gets the active slide (or section) for the given section 1372 */ 1373 1374 function getSlideOrSection(destiny) { 1375 var slide = $(SLIDE_ACTIVE_SEL, destiny); 1376 1377 if (slide.length) { 1378 destiny = slide[0]; 1379 } 1380 1381 return destiny; 1382 } 1383 function getSlideOrSectionPanel(panel) { 1384 if (!panel) { 1385 return null; 1386 } 1387 1388 return panel.activeSlide ? panel.activeSlide : panel; 1389 } 1390 function isFullPageAbove() { 1391 return getContainer().getBoundingClientRect().bottom >= 0; 1392 } 1393 /** 1394 * Gets the scrolling settings depending on the plugin autoScrolling option 1395 */ 1396 1397 function getScrollSettings(top) { 1398 var options = getOptions(); 1399 var position; 1400 var element; //top property animation 1401 1402 if (options.autoScrolling && !options.scrollBar) { 1403 position = -top; 1404 element = $(WRAPPER_SEL)[0]; 1405 } //window real scrolling 1406 else { 1407 position = top; 1408 element = window; 1409 } 1410 1411 return { 1412 options: position, 1413 element: element 1414 }; 1415 } 1416 /** 1417 * Scrolls the page / slider the given number of pixels. 1418 * It will do it one or another way dependiong on the library's config. 1419 */ 1420 1421 function setScrolling(element, val) { 1422 if (!getOptions().autoScrolling || getOptions().scrollBar || element.self != window && hasClass(element, SLIDES_WRAPPER)) { 1423 //scrolling horizontally through the slides? 1424 if (element.self != window && hasClass(element, SLIDES_WRAPPER)) { 1425 element.scrollLeft = val; 1426 } //vertical scroll 1427 else { 1428 element.scrollTo(0, val); 1429 } 1430 } else { 1431 element.style.top = val + 'px'; 1432 } 1433 } 1434 /** 1435 * Adds transition animations for the given element 1436 */ 1437 1438 function addAnimation(element) { 1439 var transition = 'transform ' + getOptions().scrollingSpeed + 'ms ' + getOptions().easingcss3; 1440 removeClass(element, NO_TRANSITION); 1441 return css(element, { 1442 '-webkit-transition': transition, 1443 'transition': transition 1444 }); 1445 } 1446 /** 1447 * Retuns `up` or `down` depending on the scrolling movement to reach its destination 1448 * from the current section. 1449 */ 1450 1451 function getYmovement(activeSection, destiny) { 1452 var fromIndex = activeSection.index(); 1453 var toIndex = index(destiny, SECTION_SEL); 1454 1455 if (fromIndex == toIndex) { 1456 return 'none'; 1457 } 1458 1459 if (fromIndex > toIndex) { 1460 return 'up'; 1461 } 1462 1463 return 'down'; 1464 } 1465 /** 1466 * Remove transition animations for the given element 1467 */ 1468 1469 function removeAnimation(element) { 1470 return addClass(element, NO_TRANSITION); 1471 } 1472 /** 1473 * Returns the cross-browser transform string. 1474 */ 1475 1476 function getTransforms(translate3d) { 1477 return { 1478 '-webkit-transform': translate3d, 1479 '-moz-transform': translate3d, 1480 '-ms-transform': translate3d, 1481 'transform': translate3d 1482 }; 1483 } 1484 1485 var silentScrollId; 1486 /** 1487 * Adds a css3 transform property to the container class with or without animation depending on the animated param. 1488 */ 1489 1490 function transformContainer(translate3d, animated) { 1491 if (animated) { 1492 addAnimation(getContainer()); 1493 } else { 1494 removeAnimation(getContainer()); 1495 } 1496 1497 clearTimeout(silentScrollId); 1498 css(getContainer(), getTransforms(translate3d)); 1499 FP.test.translate3d = translate3d; //syncronously removing the class after the animation has been applied. 1500 1501 silentScrollId = setTimeout(function () { 1502 removeClass(getContainer(), NO_TRANSITION); 1503 }, 10); 1504 } 1505 1506 /** 1507 * Scrolls silently (with no animation) the page to the given Y position. 1508 */ 1509 1510 function silentScroll(top) { 1511 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 1512 // that's why we round it to 0. 1513 var roundedTop = Math.round(top); 1514 1515 if (getOptions().css3 && getOptions().autoScrolling && !getOptions().scrollBar) { 1516 var translate3d = 'translate3d(0px, -' + roundedTop + 'px, 0px)'; 1517 transformContainer(translate3d, false); 1518 } else if (getOptions().autoScrolling && !getOptions().scrollBar) { 1519 css(getContainer(), { 1520 'top': -roundedTop + 'px' 1521 }); 1522 FP.test.top = -roundedTop + 'px'; 1523 } else { 1524 var scrollSettings = getScrollSettings(roundedTop); 1525 setScrolling(scrollSettings.element, scrollSettings.options); 1526 } 1527 } 1528 1529 FP.setScrollingSpeed = setScrollingSpeed; 1530 /** 1531 * Defines the scrolling speed 1532 */ 1533 1534 function setScrollingSpeed(value, type) { 1535 setVariableState('scrollingSpeed', value, type); 1536 } 1537 1538 var $body = null; 1539 var $html = null; 1540 var $htmlBody = null; // caching common elements 1541 1542 function setCache() { 1543 $body = $('body')[0]; 1544 $html = $('html')[0]; 1545 $htmlBody = $('html, body'); 1546 } 1547 1548 //@ts-check 1549 1550 var _g_animateScroll; 1551 /** 1552 * Simulates the animated scrollTop of jQuery. Used when css3:false or scrollBar:true or autoScrolling:false 1553 * http://stackoverflow.com/a/16136789/1081396 1554 */ 1555 1556 1557 function scrollTo(element, to, duration, callback) { 1558 var start = getScrolledPosition(element); 1559 var change = to - start; 1560 var isCallbackFired = false; 1561 var startTime; 1562 var wasAnimationActive = state.activeAnimation; 1563 setState({ 1564 activeAnimation: true 1565 }); // Cancelling any possible previous animations (io: clicking on nav dots very fast) 1566 1567 if (_g_animateScroll) { 1568 window.cancelAnimationFrame(_g_animateScroll); 1569 } 1570 1571 _g_animateScroll = function g_animateScroll(timestamp) { 1572 if (!startTime) { 1573 startTime = timestamp; 1574 } 1575 1576 var currentTime = Math.floor(timestamp - startTime); 1577 1578 if (state.activeAnimation) { 1579 //in order to stope it from other function whenever we want 1580 var val = to; 1581 1582 if (duration) { 1583 // @ts-ignore 1584 val = win.fp_easings[getOptions().easing](currentTime, start, change, duration); 1585 } 1586 1587 if (currentTime <= duration) { 1588 setScrolling(element, val); 1589 } 1590 1591 if (currentTime < duration) { 1592 window.requestAnimationFrame(_g_animateScroll); 1593 } else if (typeof callback !== 'undefined' && !isCallbackFired) { 1594
vendor: 5,400 bytes, lines 1594-1773
1594callback(); 1595 setState({ 1596 activeAnimation: false 1597 }); 1598 isCallbackFired = true; 1599 } 1600 } else if (!isCallbackFired && !wasAnimationActive) { 1601 callback(); 1602 setState({ 1603 activeAnimation: false 1604 }); 1605 isCallbackFired = true; 1606 } 1607 }; 1608 1609 window.requestAnimationFrame(_g_animateScroll); 1610 } 1611 /** 1612 * Getting the position of the element to scroll when using jQuery animations 1613 */ 1614 1615 function getScrolledPosition(element) { 1616 var position; //is not the window element and is a slide? 1617 1618 if (element.self != win && hasClass(element, SLIDES_WRAPPER)) { 1619 position = element.scrollLeft; 1620 } else if (!getOptions().autoScrolling || getOptions().scrollBar) { 1621 position = getScrollTop(); 1622 } else { 1623 position = element.offsetTop; 1624 } //gets the top property of the wrapper 1625 1626 1627 return position; 1628 } 1629 1630 /** 1631 * Makes sure to only create a Panel object if the element exist 1632 */ 1633 1634 function nullOrSection(el) { 1635 if (el && !el.item) { 1636 return new Section(new SectionPanel(el)); 1637 } 1638 1639 return el ? new Section(el) : null; 1640 } 1641 1642 function nullOrSlide(el) { 1643 return el ? new Slide(el) : null; 1644 } 1645 1646 /** 1647 * Dispatch events & callbacks 1648 */ 1649 1650 function fireCallback(eventName, v) { 1651 var eventData = getEventData(eventName, v); 1652 trigger(getContainer(), eventName, eventData); 1653 1654 if (getOptions()[eventName].apply(eventData[Object.keys(eventData)[0]], toArray(eventData)) === false) { 1655 return false; 1656 } 1657 1658 return true; 1659 } 1660 /** 1661 * Gets the event's data for the given event on the right format. 1662 */ 1663 1664 function getEventData(eventName, v) { 1665 //using functions to run only the necessary bits within the object 1666 var paramsPerEvent = { 1667 afterRender: function afterRender() { 1668 return { 1669 section: nullOrSection(getState().activeSection), 1670 slide: nullOrSlide(getState().activeSection.activeSlide) 1671 }; 1672 }, 1673 onLeave: function onLeave() { 1674 return { 1675 origin: nullOrSection(v.items.origin), 1676 destination: nullOrSection(v.items.destination), 1677 direction: v.direction, 1678 trigger: getState().scrollTrigger 1679 }; 1680 }, 1681 afterLoad: function afterLoad() { 1682 return paramsPerEvent.onLeave(); 1683 }, 1684 afterSlideLoad: function afterSlideLoad() { 1685 return { 1686 section: nullOrSection(v.items.section), 1687 origin: nullOrSection(v.items.origin), 1688 destination: nullOrSection(v.items.destination), 1689 direction: v.direction, 1690 trigger: getState().scrollTrigger 1691 }; 1692 }, 1693 onSlideLeave: function onSlideLeave() { 1694 return paramsPerEvent.afterSlideLoad(); 1695 }, 1696 beforeLeave: function beforeLeave() { 1697 return paramsPerEvent.onLeave(); 1698 }, 1699 onScrollOverflow: function onScrollOverflow() { 1700 return { 1701 section: nullOrSection(getState().activeSection), 1702 slide: nullOrSlide(getState().activeSection.activeSlide), 1703 position: v.position, 1704 direction: v.direction 1705 }; 1706 } 1707 }; 1708 return paramsPerEvent[eventName](); 1709 } 1710 1711 /** 1712 * Plays video and audio elements. 1713 */ 1714 1715 function playMedia(destiny) { 1716 var panel = getSlideOrSection(destiny); //playing HTML5 media elements 1717 1718 $('video, audio', panel).forEach(function (element) { 1719 if (element.hasAttribute('data-autoplay') && typeof element.play === 'function') { 1720 element.play(); 1721 } 1722 }); //youtube videos 1723 1724 $('iframe[src*="youtube.com/embed/"]', panel).forEach(function (element) { 1725 if (element.hasAttribute('data-autoplay')) { 1726 playYoutube(element); 1727 } //in case the URL was not loaded yet. On page load we need time for the new URL (with the API string) to load. 1728 1729 1730 element.onload = function () { 1731 if (element.hasAttribute('data-autoplay')) { 1732 playYoutube(element); 1733 } 1734 }; 1735 }); 1736 } 1737 /** 1738 * Plays a youtube video 1739 */ 1740 1741 function playYoutube(element) { 1742 element.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}', '*'); 1743 } 1744 /** 1745 * Stops video and audio elements. 1746 */ 1747 1748 1749 function stopMedia(destiny) { 1750 var panel = getSlideOrSection(destiny); //stopping HTML5 media elements 1751 1752 $('video, audio', panel).forEach(function (element) { 1753 if (!element.hasAttribute('data-keepplaying') && typeof element.pause === 'function') { 1754 element.pause(); 1755 } 1756 }); //youtube videos 1757 1758 $('iframe[src*="youtube.com/embed/"]', panel).forEach(function (element) { 1759 if (/youtube\.com\/embed\//.test(getAttr(element, 'src')) && !element.hasAttribute('data-keepplaying')) { 1760 element.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}', '*'); 1761 } 1762 }); 1763 } 1764 /* 1765 * Enables the Youtube videos API so we can control their flow if necessary. 1766 */ 1767 1768 function enableYoutubeAPI() { 1769 $('iframe[src*="youtube.com/embed/"]', getContainer()).forEach(function (item) { 1770 addURLParam(item, 'enablejsapi=1'); 1771 }); 1772 } 1773 /**
1774 * Adds a new parameter and its value to the `src` of a given element 1775 */ 1776 1777 function addURLParam(element, newParam) { 1778 var originalSrc = getAttr(element, 'src'); 1779 element.setAttribute('src', originalSrc + getUrlParamSign(originalSrc) + newParam); 1780 } 1781 /* 1782 * Returns the prefix sign to use for a new parameter in an existen URL. 1783 * 1784 * @return {String} ? | & 1785 */ 1786 1787 1788 function getUrlParamSign(url) { 1789 return !/\?/.test(url) ? '?' : '&'; 1790 } 1791 1792 /** 1793 * Lazy loads image, video and audio elements. 1794 */ 1795 1796 function lazyLoad(destiny) { 1797 if (!getOptions().lazyLoading) { 1798 return; 1799 } 1800 1801 var panel = getSlideOrSection(destiny); 1802 $('img[data-src], img[data-srcset], source[data-src], source[data-srcset], video[data-src], audio[data-src], iframe[data-src]', panel).forEach(function (element) { 1803 ['src', 'srcset'].forEach(function (type) { 1804 var attribute = getAttr(element, 'data-' + type); 1805 1806 if (attribute != null && attribute) { 1807 setSrc(element, type); 1808 element.addEventListener('load', function () { 1809 }); 1810 } 1811 }); 1812 1813 if (matches(element, 'source')) { 1814 var elementToPlay = closest(element, 'video, audio'); 1815 1816 if (elementToPlay) { 1817 elementToPlay.load(); 1818 1819 elementToPlay.onloadeddata = function () { 1820 }; 1821 } 1822 } 1823 }); 1824 } 1825 1826 /** 1827 * Sets a class for the body of the page depending on the active section / slide 1828 */ 1829 1830 function setBodyClass() { 1831 var section = getState().activeSection.item; 1832 var slide = getState().activeSection.activeSlide; 1833 var sectionAnchor = getAnchor(section); 1834 var text = String(sectionAnchor); 1835 1836 if (slide) { 1837 var slideAnchor = getAnchor(slide.item); 1838 text = text + '-' + slideAnchor; 1839 } //changing slash for dash to make it a valid CSS style 1840 1841 1842 text = text.replace('/', '-').replace('#', ''); //removing previous anchor classes 1843 1844 var classRe = new RegExp('\\b\\s?' + VIEWING_PREFIX + '-[^\\s]+\\b', "g"); 1845 $body.className = $body.className.replace(classRe, ''); //adding the current anchor 1846 1847 addClass($body, VIEWING_PREFIX + '-' + text); 1848 } 1849 /** 1850 * Gets the anchor for the given slide / section. Its index will be used if there's none. 1851 */ 1852 1853 function getAnchor(element) { 1854 if (!element) { 1855 return null; 1856 } 1857 1858 var anchor = getAttr(element, 'data-anchor'); 1859 var elementIndex = index(element); //Slide without anchor link? We take the index instead. 1860 1861 if (anchor == null) { 1862 anchor = elementIndex; 1863 } 1864 1865 return anchor; 1866 } 1867 1868 /** 1869 * Sets the state of the website depending on the active section/slide. 1870 * It changes the URL hash when needed and updates the body class. 1871 */ 1872 1873 function setPageStatus(slideIndex, slideAnchor, anchorLink) { 1874 var sectionHash = ''; 1875 1876 if (getOptions().anchors.length && !getOptions().lockAnchors) { 1877 //isn't it the first slide? 1878 if (slideIndex) { 1879 if (anchorLink != null) { 1880 sectionHash = anchorLink; 1881 } //slide without anchor link? We take the index instead. 1882 1883 1884 if (slideAnchor == null) { 1885 slideAnchor = slideIndex; 1886 } 1887 1888 setState({ 1889 lastScrolledSlide: slideAnchor 1890 }); 1891 setUrlHash(sectionHash + '/' + slideAnchor); //first slide won't have slide anchor, just the section one 1892 } else if (slideIndex != null) { 1893 setState({ 1894 lastScrolledSlide: slideAnchor 1895 }); 1896 setUrlHash(anchorLink); 1897 } //section without slides 1898 else { 1899 setUrlHash(anchorLink); 1900 } 1901 } 1902 1903 setBodyClass(); 1904 } 1905 /** 1906 * Sets the URL hash. 1907 */ 1908 1909 function setUrlHash(url) { 1910 if (getOptions().recordHistory) { 1911 location.hash = url; 1912 } else { 1913 //Mobile Chrome doesn't work the normal way, so... lets use HTML5 for phones :) 1914 if (isTouchDevice || isTouch) { 1915 win.history.replaceState(undefined, undefined, '#' + url); 1916 } else { 1917 var baseUrl = win.location.href.split('#')[0]; 1918 win.location.replace(baseUrl + '#' + url); 1919 } 1920 } 1921 } 1922 1923 /**
vendor: 55,347 bytes, lines 1924-3561
1924 * Gets the name for screen readers for a section/slide navigation bullet. 1925 */ 1926 1927 function getBulletLinkName(i, defaultName, item) { 1928 var anchor = defaultName === 'Section' ? getOptions().anchors[i] : getAttr(item, 'data-anchor'); 1929 return encodeURI(getOptions().navigationTooltips[i] || anchor || defaultName + ' ' + (i + 1)); 1930 } 1931 1932 function slideBulletHandler(e) { 1933 preventDefault(e); 1934 setState({ 1935 scrollTrigger: 'horizontalNav' 1936 }); 1937 /*jshint validthis:true */ 1938 1939 var sectionElem = closest(this, SECTION_SEL); 1940 var slides = $(SLIDES_WRAPPER_SEL, closest(this, SECTION_SEL))[0]; 1941 var section = getPanelByElement(getState().sections, sectionElem); 1942 var destiny = section.slides[index(closest(this, 'li'))]; 1943 EventEmitter.emit(events.landscapeScroll, { 1944 slides: slides, 1945 destination: destiny.item 1946 }); 1947 } 1948 /** 1949 * Sets the state for the horizontal bullet navigations. 1950 */ 1951 1952 function activeSlidesNavigation(slidesNav, slideIndex) { 1953 if (getOptions().slidesNavigation && slidesNav != null) { 1954 removeClass($(ACTIVE_SEL, slidesNav), ACTIVE); 1955 addClass($('a', $('li', slidesNav)[slideIndex]), ACTIVE); 1956 } 1957 } 1958 /** 1959 * Creates a landscape navigation bar with dots for horizontal sliders. 1960 */ 1961 1962 function addSlidesNavigation(section) { 1963 var sectionElem = section.item; 1964 var numSlides = section.slides.length; 1965 appendTo(createElementFromHTML('<div class="' + SLIDES_NAV + '"><ul></ul></div>'), sectionElem); 1966 var nav = $(SLIDES_NAV_SEL, sectionElem)[0]; //top or bottom 1967 1968 addClass(nav, 'fp-' + getOptions().slidesNavPosition); 1969 1970 for (var i = 0; i < numSlides; i++) { 1971 var slide = $(SLIDE_SEL, sectionElem)[i]; 1972 appendTo(createElementFromHTML('<li><a href="#"><span class="fp-sr-only">' + getBulletLinkName(i, 'Slide', slide) + '</span><span></span></a></li>'), $('ul', nav)[0]); 1973 } //centering it 1974 1975 1976 css(nav, { 1977 'margin-left': '-' + nav.innerWidth / 2 + 'px' 1978 }); 1979 var activeSlideIndex = section.activeSlide ? section.activeSlide.index() : 0; 1980 addClass($('a', $('li', nav)[activeSlideIndex]), ACTIVE); 1981 } 1982 1983 var isScrollAllowed = {}; 1984 isScrollAllowed.m = { 1985 'up': true, 1986 'down': true, 1987 'left': true, 1988 'right': true 1989 }; 1990 isScrollAllowed.k = deepExtend({}, isScrollAllowed.m); 1991 /** 1992 * Allowing or disallowing the mouse/swipe scroll in a given direction. (not for keyboard) 1993 * @param type m (mouse) or k (keyboard) 1994 */ 1995 1996 function setIsScrollAllowed(value, direction, type) { 1997 //up, down, left, right 1998 if (direction !== 'all') { 1999 isScrollAllowed[type][direction] = value; 2000 } //all directions? 2001 else { 2002 Object.keys(isScrollAllowed[type]).forEach(function (key) { 2003 isScrollAllowed[type][key] = value; 2004 }); 2005 } 2006 } 2007 function getIsScrollAllowed() { 2008 return isScrollAllowed; 2009 } 2010 2011 EventEmitter.on(events.onClickOrTouch, onClickOrTouch$2); 2012 2013 function onClickOrTouch$2(params) { 2014 var target = params.target; 2015 2016 if (matches(target, SLIDES_ARROW_SEL) || closest(target, SLIDES_ARROW_SEL)) { 2017 slideArrowHandler.call(target, params); 2018 } 2019 } //Scrolling horizontally when clicking on the slider controls. 2020 2021 2022 function slideArrowHandler() { 2023 /*jshint validthis:true */ 2024 var section = closest(this, SECTION_SEL); 2025 /*jshint validthis:true */ 2026 2027 if (hasClass(this, SLIDES_PREV)) { 2028 if (getIsScrollAllowed().m.left) { 2029 setState({ 2030 scrollTrigger: 'slideArrow' 2031 }); 2032 EventEmitter.emit(events.moveSlideLeft, { 2033 section: section 2034 }); 2035 } 2036 } else { 2037 if (getIsScrollAllowed().m.right) { 2038 setState({ 2039 scrollTrigger: 'slideArrow' 2040 }); 2041 EventEmitter.emit(events.moveSlideRight, { 2042 section: section 2043 }); 2044 } 2045 } 2046 } 2047 /** 2048 * Creates the control arrows for the given section 2049 */ 2050 2051 2052 function createSlideArrows(section) { 2053 var sectionElem = section.item; 2054 var arrows = [createElementFromHTML(getOptions().controlArrowsHTML[0]), createElementFromHTML(getOptions().controlArrowsHTML[1])]; 2055 after($(SLIDES_WRAPPER_SEL, sectionElem)[0], arrows); 2056 addClass(arrows, SLIDES_ARROW); 2057 addClass(arrows[0], SLIDES_PREV); 2058 addClass(arrows[1], SLIDES_NEXT); 2059 2060 if (getOptions().controlArrowColor !== '#fff') { 2061 css($(SLIDES_ARROW_NEXT_SEL, sectionElem), { 2062 'border-color': 'transparent transparent transparent ' + getOptions().controlArrowColor 2063 }); 2064 css($(SLIDES_ARROW_PREV_SEL, sectionElem), { 2065 'border-color': 'transparent ' + getOptions().controlArrowColor + ' transparent transparent' 2066 }); 2067 } 2068 2069 if (!getOptions().loopHorizontal) { 2070 hide($(SLIDES_ARROW_PREV_SEL, sectionElem)); 2071 } 2072 } 2073 function toggleControlArrows(v) { 2074 if (!getOptions().loopHorizontal && getOptions().controlArrows) { 2075 //hidding it for the fist slide, showing for the rest 2076 toggle($(SLIDES_ARROW_PREV_SEL, v.section), v.slideIndex !== 0); //hidding it for the last slide, showing for the rest 2077 2078 toggle($(SLIDES_ARROW_NEXT_SEL, v.section), next(v.destiny) != null); 2079 } 2080 } 2081 2082 FP.setRecordHistory = setRecordHistory; 2083 /** 2084 * Defines wheter to record the history for each hash change in the URL. 2085 */ 2086 2087 function setRecordHistory(value, type) { 2088 setVariableState('recordHistory', value, type); 2089 } 2090 2091 FP.setAutoScrolling = setAutoScrolling; 2092 FP.test.setAutoScrolling = setAutoScrolling; 2093 /** 2094 * Sets the autoScroll option. 2095 * It changes the scroll bar visibility and the history of the site as a result. 2096 */ 2097 2098 function setAutoScrolling(value, type) { 2099 //removing the transformation 2100 if (!value) { 2101 silentScroll(0); 2102 } 2103 2104 setVariableState('autoScrolling', value, type); 2105 var element = getState().activeSection.item; 2106 2107 if (getOptions().autoScrolling && !getOptions().scrollBar) { 2108 css($htmlBody, { 2109 'overflow': 'hidden', 2110 'height': '100%' 2111 }); 2112 removeClass($body, 'fp-scrollable'); 2113 setRecordHistory(getOriginals().recordHistory, 'internal'); //for IE touch devices 2114 2115 css(getContainer(), { 2116 '-ms-touch-action': 'none', 2117 'touch-action': 'none' 2118 }); 2119 2120 if (element != null) { 2121 //moving the container up 2122 silentScroll(element.offsetTop); 2123 } 2124 } else { 2125 css($htmlBody, { 2126 'overflow': 'visible', 2127 'height': 'initial' 2128 }); 2129 addClass($body, 'fp-scrollable'); 2130 var recordHistory = !getOptions().autoScrolling ? false : getOriginals().recordHistory; 2131 setRecordHistory(recordHistory, 'internal'); //for IE touch devices 2132 2133 css(getContainer(), { 2134 '-ms-touch-action': '', 2135 'touch-action': '' 2136 }); //scrolling the page to the section with no animation 2137 2138 if (element != null) { 2139 var scrollSettings = getScrollSettings(element.offsetTop); 2140 scrollSettings.element.scrollTo(0, scrollSettings.options); 2141 } 2142 } 2143 } 2144 2145 //@ts-check 2146 /** 2147 * Adds sections before or after the current one to create the infinite effect. 2148 */ 2149 2150 function createInfiniteSections(v) { 2151 setState({ 2152 isDoingContinousVertical: true 2153 }); 2154 var activeSectionItem = getState().activeSection.item; // Scrolling down 2155 2156 if (!v.isMovementUp) { 2157 // Move all previous sections to after the active section 2158 after(activeSectionItem, prevAll(activeSectionItem, SECTION_SEL).reverse()); 2159 } else { 2160 // Scrolling up 2161 // Move all next sections to before the active section 2162 before(activeSectionItem, nextAll(activeSectionItem, SECTION_SEL)); 2163 } // Maintain the displayed position (now that we changed the element order) 2164 2165 2166 silentScroll(getState().activeSection.item.offsetTop); // Maintain the active slides visible in the viewport 2167 2168 keepSlidesPosition$1(); // save for later the elements that still need to be reordered 2169 2170 v.wrapAroundElements = activeSectionItem; // Recalculate animation variables 2171 2172 v.dtop = v.element.offsetTop; 2173 v.yMovement = getYmovement(getState().activeSection, v.element); 2174 return v; 2175 } 2176 /** 2177 * Maintains the active slides in the viewport 2178 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 2179 */ 2180 2181 function keepSlidesPosition$1() { 2182 var activeSlides = $(SLIDE_ACTIVE_SEL); 2183 2184 for (var i = 0; i < activeSlides.length; i++) { 2185 silentLandscapeScroll(activeSlides[i], 'internal'); 2186 } 2187 } 2188 2189 //@ts-check 2190 /** 2191 * Maintains the active slides in the viewport 2192 * (Because the `scroll` animation might get lost with some actions, such as when using continuousVertical) 2193 */ 2194 2195 function keepSlidesPosition() { 2196 var activeSlides = $(SLIDE_ACTIVE_SEL); 2197 2198 for (var i = 0; i < activeSlides.length; i++) { 2199 silentLandscapeScroll(activeSlides[i], 'internal'); 2200 } 2201 } 2202 /** 2203 * Fix section order after continuousVertical changes have been animated 2204 */ 2205 2206 2207 function continuousVerticalFixSectionOrder(v) { 2208 // If continuousVertical is in effect (and autoScrolling would also be in effect then), 2209 // finish moving the elements around so the direct navigation will function more simply 2210 if (v.wrapAroundElements == null) { 2211 return; 2212 } 2213 2214 if (v.isMovementUp) { 2215 before($(SECTION_SEL)[0], v.wrapAroundElements); 2216 } else { 2217 after($(SECTION_SEL)[getState().sections.length - 1], v.wrapAroundElements); 2218 } 2219 2220 silentScroll(getState().activeSection.item.offsetTop); // Maintain the active slides visible in the viewport 2221 2222 keepSlidesPosition(); 2223 setState({ 2224 isDoingContinousVertical: false 2225 }); 2226 } 2227 2228 /** 2229 * Makes sure lazyload is done for other sections in the viewport that are not the 2230 * active one. 2231 */ 2232 2233 function lazyLoadOthers() { 2234 var hasAutoHeightSections = $(AUTO_HEIGHT_SEL)[0] || isResponsiveMode() && $(AUTO_HEIGHT_RESPONSIVE_SEL)[0]; //quitting when it doesn't apply 2235 2236 if (!getOptions().lazyLoading || !hasAutoHeightSections) { 2237 return; 2238 } //making sure to lazy load auto-height sections that are in the viewport 2239 2240 2241 $(SECTION_SEL + ':not(' + ACTIVE_SEL + ')').forEach(function (section) { 2242 if (isSectionInViewport(section)) { 2243 lazyLoad(section); 2244 } 2245 }); 2246 } 2247 /** 2248 * Determines whether a section is in the viewport or not. 2249 */ 2250 2251 function isSectionInViewport(el) { 2252 var rect = el.getBoundingClientRect(); 2253 var top = rect.top; 2254 var bottom = rect.bottom; //sometimes there's a 1px offset on the bottom of the screen even when the 2255 //section's height is the window.innerHeight one. I guess because pixels won't allow decimals. 2256 //using this prevents from lazyLoading the section that is not yet visible 2257 //(only 1 pixel offset is) 2258 2259 var pixelOffset = 2; 2260 var isTopInView = top + pixelOffset < state.windowsHeight && top > 0; 2261 var isBottomInView = bottom > pixelOffset && bottom < state.windowsHeight; 2262 return isTopInView || isBottomInView; 2263 } 2264 2265 function tooltipTextHandler() { 2266 /*jshint validthis:true */ 2267 trigger(prev(this), 'click'); 2268 } 2269 /** 2270 * Activating the vertical navigation bullets according to the given slide name. 2271 */ 2272 2273 function activateNavDots(name, sectionIndex) { 2274 var nav = $(SECTION_NAV_SEL)[0]; 2275 2276 if (getOptions().navigation && nav != null && nav.style.display !== 'none') { 2277 removeClass($(ACTIVE_SEL, nav), ACTIVE); 2278 2279 if (name) { 2280 addClass($('a[href="#' + name + '"]', nav), ACTIVE); 2281 } else { 2282 addClass($('a', $('li', nav)[sectionIndex]), ACTIVE); 2283 } 2284 } 2285 } 2286 /** 2287 * Creates a vertical navigation bar. 2288 */ 2289 2290 function addVerticalNavigation() { 2291 remove($(SECTION_NAV_SEL)); 2292 var navigation = doc.createElement('div'); 2293 navigation.setAttribute('id', SECTION_NAV); 2294 var divUl = doc.createElement('ul'); 2295 navigation.appendChild(divUl); 2296 appendTo(navigation, $body); 2297 var nav = $(SECTION_NAV_SEL)[0]; 2298 addClass(nav, 'fp-' + getOptions().navigationPosition); 2299 2300 if (getOptions().showActiveTooltip) { 2301 addClass(nav, SHOW_ACTIVE_TOOLTIP); 2302 } 2303 2304 var li = ''; 2305 2306 for (var i = 0; i < getState().sections.length; i++) { 2307 var section = getState().sections[i]; 2308 var link = ''; 2309 2310 if (getOptions().anchors.length) { 2311 link = section.anchor; 2312 } 2313 2314 li += '<li><a href="#' + encodeURI(link) + '"><span class="fp-sr-only">' + getBulletLinkName(section.index(), 'Section') + '</span><span></span></a>'; // Only add tooltip if needed (defined by user) 2315 2316 var tooltip = getOptions().navigationTooltips[section.index()]; 2317 2318 if (typeof tooltip !== 'undefined' && tooltip !== '') { 2319 li += '<div class="' + SECTION_NAV_TOOLTIP + ' fp-' + getOptions().navigationPosition + '">' + tooltip + '</div>'; 2320 } 2321 2322 li += '</li>'; 2323 } 2324 2325 $('ul', nav)[0].innerHTML = li; //activating the current active section 2326 2327 var bullet = $('li', $(SECTION_NAV_SEL)[0])[getState().activeSection.index()]; 2328 addClass($('a', bullet), ACTIVE); 2329 } //Scrolls to the section when clicking the navigation bullet 2330 2331 function sectionBulletHandler(e) { 2332 if (e.preventDefault) { 2333 preventDefault(e); 2334 } 2335 2336 setState({ 2337 scrollTrigger: 'verticalNav' 2338 }); 2339 /*jshint validthis:true */ 2340 // @ts-ignore 2341 2342 var indexBullet = index(closest(this, SECTION_NAV_SEL + ' li')); 2343 EventEmitter.emit(events.scrollPage, { 2344 destination: getState().sections[indexBullet] 2345 }); 2346 } 2347 2348 /** 2349 * Sets to active the current menu and vertical nav items. 2350 */ 2351 2352 function activateMenuAndNav(anchor, index) { 2353 activateMenuElement(anchor); 2354 activateNavDots(anchor, index); 2355 } 2356 /** 2357 * Activating the website main menu elements according to the given slide name. 2358 */ 2359 2360 function activateMenuElement(name) { 2361 if (getOptions().menu && getOptions().menu.length) { 2362 $(getOptions().menu).forEach(function (menu) { 2363 if (menu != null) { 2364 removeClass($(ACTIVE_SEL, menu), ACTIVE); 2365 addClass($('[data-menuanchor="' + name + '"]', menu), ACTIVE); 2366 } 2367 }); 2368 } 2369 } 2370 2371 new Date().getTime(); 2372 /** 2373 * Triggers the callback once per scroll wheel action. 2374 * Based on scrolling speed delay. 2375 */ 2376 2377 var oncePerScroll = function () { 2378 var canTriggerEvent = true; 2379 var prevWheelTime = new Date().getTime(); 2380 var result; 2381 var isScrollingOnInit = !win.fullpage_api; 2382 return function (scrollTrigger, callback) { 2383 var currentTime = new Date().getTime(); 2384 var timeThreshold = scrollTrigger === 'wheel' ? getOptions().scrollingSpeed : 100; 2385 canTriggerEvent = isScrollingOnInit || currentTime - prevWheelTime >= timeThreshold; 2386 isScrollingOnInit = !win.fullpage_api; 2387 2388 if (canTriggerEvent) { 2389 result = callback(); 2390 prevWheelTime = currentTime; 2391 } 2392 2393 return typeof result !== 'undefined' ? result : true; 2394 }; 2395 }(); 2396 2397 /** 2398 * Fires the wheel event once per mouse wheel trigger. 2399 */ 2400 2401 function fireCallbackOncePerScroll(callbackName, params) { 2402 if (!isFunction(getOptions().beforeLeave)) { 2403 return; 2404 } 2405 2406 var result = oncePerScroll(getState().scrollTrigger, function () { 2407 return fireCallback(callbackName, params); 2408 }); 2409 return result; 2410 } 2411 2412 FP.moveTo = moveTo; 2413 2414 FP.getScrollY = function () { 2415 return state.scrollY; 2416 }; 2417 2418 var g_afterSectionLoadsId; 2419 var g_transitionLapseId; 2420 EventEmitter.on(events.onDestroy, onDestroy$8); 2421 /** 2422 * Scrolls the site to the given element and scrolls to the slide if a callback is given. 2423 */ 2424 2425 function scrollPage(section, callback, isMovementUp) { 2426 var element = section.item; 2427 2428 if (element == null) { 2429 return; 2430 } //there's no element to scroll, leaving the function 2431 2432 2433 var dtop = getDestinationPosition(element); 2434 var slideAnchorLink; 2435 var slideIndex; //local variables 2436 2437 var v = { 2438 "element": element, 2439 "callback": callback, 2440 "isMovementUp": isMovementUp, 2441 "dtop": dtop, 2442 "yMovement": getYmovement(getState().activeSection, element), 2443 "anchorLink": section.anchor, 2444 "sectionIndex": section.index(), 2445 "activeSlide": section.activeSlide ? section.activeSlide.item : null, 2446 "leavingSection": getState().activeSection.index() + 1, 2447 //caching the value of isResizing at the momment the function is called 2448 //because it will be checked later inside a setTimeout and the value might change 2449 "localIsResizing": state.isResizing, 2450 "items": { 2451 "origin": getState().activeSection, 2452 "destination": section 2453 }, 2454 "direction": null 2455 }; //quiting when destination scroll is the same as the current one 2456 2457 if (getState().activeSection.item == element && !state.isResizing || getOptions().scrollBar && getScrollTop() === v.dtop && !hasClass(element, AUTO_HEIGHT)) { 2458 return; 2459 } 2460 2461 if (v.activeSlide != null) { 2462 slideAnchorLink = getAttr(v.activeSlide, 'data-anchor'); 2463 slideIndex = index(v.activeSlide, null); 2464 } //callback (onLeave) if the site is not just resizing and readjusting the slides 2465 2466 2467 if (!v.localIsResizing) { 2468 var direction = v.yMovement; //required for continousVertical 2469 2470 if (typeof isMovementUp !== 'undefined') { 2471 direction = isMovementUp ? 'up' : 'down'; 2472 } //for the callback 2473 2474 2475 v.direction = direction; 2476 2477 if (isFunction(getOptions().beforeLeave)) { 2478 if (fireCallbackOncePerScroll('beforeLeave', v) === false) { 2479 return; 2480 } 2481 } 2482 2483 if (isFunction(getOptions().onLeave)) { 2484 if (!fireCallback('onLeave', v)) { 2485 return; 2486 } 2487 } 2488 } // If continuousVertical && we need to wrap around 2489 2490 2491 if (getOptions().autoScrolling && getOptions().continuousVertical && typeof v.isMovementUp !== "undefined" && (!v.isMovementUp && v.yMovement == 'up' || // Intending to scroll down but about to go up or 2492 v.isMovementUp && v.yMovement == 'down')) { 2493 // intending to scroll up but about to go down 2494 v = createInfiniteSections(v); 2495 } //pausing media of the leaving section (if we are not just resizing, as destinatino will be the same one) 2496 2497 2498 if (!v.localIsResizing) { 2499 stopMedia(getState().activeSection.item); 2500 } 2501 2502 addClass(element, ACTIVE); 2503 removeClass(siblings(element), ACTIVE); 2504 updateState(); 2505 lazyLoad(element); //preventing from activating the MouseWheelHandler event 2506 //more than once if the page is scrolling 2507 2508 setState({ 2509 canScroll: FP.test.isTesting 2510 }); 2511 setPageStatus(slideIndex, slideAnchorLink, v.anchorLink); 2512 EventEmitter.emit(events.onLeave, v); 2513 performMovement(v); //flag to avoid callingn `scrollPage()` twice in case of using anchor links 2514 2515 setState({ 2516 lastScrolledDestiny: v.anchorLink 2517 }); //avoid firing it twice (as it does also on scroll) 2518 2519 activateMenuAndNav(v.anchorLink, v.sectionIndex); 2520 } 2521 2522 function onDestroy$8() { 2523 clearTimeout(g_afterSectionLoadsId); 2524 clearTimeout(g_transitionLapseId); 2525 } 2526 /** 2527 * Returns the destination Y position based on the scrolling direction and 2528 * the height of the section. 2529 */ 2530 2531 2532 function getDestinationPosition(element) { 2533 var elementHeight = element.offsetHeight; 2534 var elementTop = element.offsetTop; //top of the desination will be at the top of the viewport 2535 2536 var position = elementTop; 2537 var isScrollingDown = elementTop > state.previousDestTop; 2538 var sectionBottom = position - getWindowHeight() + elementHeight; 2539 var bigSectionsDestination = getOptions().bigSectionsDestination; //is the destination element bigger than the viewport? 2540 2541 if (elementHeight > getWindowHeight()) { 2542 //scrolling up? 2543 if (!isScrollingDown && !bigSectionsDestination || bigSectionsDestination === 'bottom') { 2544 position = sectionBottom; 2545 } 2546 } //sections equal or smaller than the viewport height && scrolling down? || is resizing and its in the last section 2547 else if (isScrollingDown || state.isResizing && next(element) == null) { 2548 //The bottom of the destination will be at the bottom of the viewport 2549 position = sectionBottom; 2550 } 2551 /* 2552 Keeping record of the last scrolled position to determine the scrolling direction. 2553 No conventional methods can be used as the scroll bar might not be present 2554 AND the section might not be active if it is auto-height and didnt reach the middle 2555 of the viewport. 2556 */ 2557 2558 2559 setState({ 2560 previousDestTop: position 2561 }); 2562 return position; 2563 } 2564 /** 2565 * Performs the vertical movement (by CSS3 or by jQuery) 2566 */ 2567 2568 2569 function performMovement(v) { 2570 var isFastSpeed = getOptions().scrollingSpeed < 700; 2571 var transitionLapse = isFastSpeed ? 700 : getOptions().scrollingSpeed; 2572 setState({ 2573 touchDirection: 'none', 2574 scrollY: Math.round(v.dtop) 2575 }); 2576 EventEmitter.emit(events.onPerformMovement); // using CSS3 translate functionality 2577 2578 if (getOptions().css3 && getOptions().autoScrolling && !getOptions().scrollBar) { 2579 // The first section can have a negative value in iOS 10. Not quite sure why: -0.0142822265625 2580 // that's why we round it to 0. 2581 var translate3d = 'translate3d(0px, -' + Math.round(v.dtop) + 'px, 0px)'; 2582 transformContainer(translate3d, true); //even when the scrollingSpeed is 0 there's a little delay, which might cause the 2583 //scrollingSpeed to change in case of using silentMoveTo();ç 2584 2585 if (getOptions().scrollingSpeed) { 2586 clearTimeout(g_afterSectionLoadsId); 2587 g_afterSectionLoadsId = setTimeout(function () { 2588 afterSectionLoads$1(v); //disabling canScroll when using fastSpeed 2589 2590 setState({ 2591 canScroll: !isFastSpeed || FP.test.isTesting 2592 }); 2593 }, getOptions().scrollingSpeed); 2594 } else { 2595 afterSectionLoads$1(v); 2596 } 2597 } // using JS to animate 2598 else { 2599 var scrollSettings = getScrollSettings(v.dtop); 2600 FP.test.top = -v.dtop + 'px'; 2601 clearTimeout(g_afterSectionLoadsId); 2602 scrollTo(scrollSettings.element, scrollSettings.options, getOptions().scrollingSpeed, function () { 2603 if (getOptions().scrollBar) { 2604 /* Hack! 2605 The timeout prevents setting the most dominant section in the viewport as "active" when the user 2606 scrolled to a smaller section by using the mousewheel (auto scrolling) rather than draging the scroll bar. 2607 When using scrollBar:true It seems like the scroll events still getting propagated even after the scrolling animation has finished. 2608 */ 2609 g_afterSectionLoadsId = setTimeout(function () { 2610 afterSectionLoads$1(v); 2611 }, 30); 2612 } else { 2613 afterSectionLoads$1(v); //disabling canScroll when using fastSpeed 2614 2615 setState({ 2616 canScroll: !isFastSpeed || FP.test.isTesting 2617 }); 2618 } 2619 }); 2620 } // enabling canScroll after the minimum transition laps 2621 2622 2623 if (isFastSpeed) { 2624 clearTimeout(g_transitionLapseId); 2625 g_transitionLapseId = setTimeout(function () { 2626 setState({ 2627 canScroll: true 2628 }); 2629 }, transitionLapse); 2630 } 2631 } 2632 /** 2633 * Actions to do once the section is loaded. 2634 */ 2635 2636 2637 function afterSectionLoads$1(v) { 2638 setState({ 2639 isBeyondFullpage: false 2640 }); 2641 continuousVerticalFixSectionOrder(v); //callback (afterLoad) if the site is not just resizing and readjusting the slides 2642 2643 if (isFunction(getOptions().afterLoad) && !v.localIsResizing) { 2644 fireCallback('afterLoad', v); 2645 } 2646 2647 updateState(); 2648 2649 if (!v.localIsResizing) { 2650 playMedia(v.element); 2651 } 2652 2653 addClass(v.element, COMPLETELY); 2654 removeClass(siblings(v.element), COMPLETELY); 2655 lazyLoadOthers(); 2656 setState({ 2657 canScroll: true 2658 }); 2659 EventEmitter.emit(events.afterSectionLoads, v); 2660 2661 if (isFunction(v.callback)) { 2662 v.callback(); 2663 } 2664 } 2665 2666 FP.setFitToSection = setFitToSection; 2667 FP.fitToSection = fitToSection; 2668 /** 2669 * Sets fitToSection 2670 */ 2671 2672 function setFitToSection(value, type) { 2673 setVariableState('fitToSection', value, type); 2674 } 2675 /** 2676 * Fits the site to the nearest active section 2677 */ 2678 2679 function fitToSection() { 2680 //checking fitToSection again in case it was set to false before the timeout delay 2681 if (state.canScroll) { 2682 //allows to scroll to an active section and 2683 //if the section is already active, we prevent firing callbacks 2684 setState({ 2685 isResizing: true 2686 }); 2687 scrollPage(state.activeSection); 2688 setState({ 2689 isResizing: false 2690 }); 2691 } 2692 } 2693 2694 FP.setResponsive = setResponsive; 2695 /** 2696 * Checks if the site needs to get responsive and disables autoScrolling if so. 2697 * A class `fp-responsive` is added to the plugin's container in case the user wants to use it for his own responsive CSS. 2698 */ 2699 2700 function responsive() { 2701 var widthLimit = getOptions().responsive || getOptions().responsiveWidth; //backwards compatiblity 2702 2703 var heightLimit = getOptions().responsiveHeight; //only calculating what we need. Remember its called on the resize event. 2704 2705 var isBreakingPointWidth = widthLimit && win.innerWidth < widthLimit; 2706 var isBreakingPointHeight = heightLimit && win.innerHeight < heightLimit; 2707 2708 if (widthLimit && heightLimit) { 2709 setResponsive(isBreakingPointWidth || isBreakingPointHeight); 2710 } else if (widthLimit) { 2711 setResponsive(isBreakingPointWidth); 2712 } else if (heightLimit) { 2713 setResponsive(isBreakingPointHeight); 2714 } 2715 } 2716 /** 2717 * Turns fullPage.js to normal scrolling mode when the viewport `width` or `height` 2718 * are smaller than the set limit values. 2719 */ 2720 2721 function setResponsive(active) { 2722 var isResponsive = isResponsiveMode(); 2723 2724 if (active) { 2725 if (!isResponsive) { 2726 setAutoScrolling(false, 'internal'); 2727 setFitToSection(false, 'internal'); 2728 hide($(SECTION_NAV_SEL)); 2729 addClass($body, RESPONSIVE); 2730 2731 if (isFunction(getOptions().afterResponsive)) { 2732 getOptions().afterResponsive.call(getContainer(), active); 2733 } 2734 } 2735 } else if (isResponsive) { 2736 setAutoScrolling(getOriginals().autoScrolling, 'internal'); 2737 setFitToSection(getOriginals().autoScrolling, 'internal'); 2738 show($(SECTION_NAV_SEL)); 2739 removeClass($body, RESPONSIVE); 2740 2741 if (isFunction(getOptions().afterResponsive)) { 2742 getOptions().afterResponsive.call(getContainer(), active); 2743 } 2744 } 2745 } 2746 /** 2747 * Determines whether fullpage.js is in responsive mode or not. 2748 */ 2749 2750 2751 function isResponsiveMode() { 2752 return hasClass($body, RESPONSIVE); 2753 } 2754 2755 function addTableClass(element) { 2756 if (!getOptions().verticalCentered) { 2757 return; 2758 } // Overflowing sections when scrollOverflow is disabled will be autoHeight 2759 // and won't require vertical aligment 2760 2761 2762 if (!getOptions().scrollOverflow && scrollOverflowHandler.shouldBeScrollable(element.item)) { 2763 return; 2764 } 2765 2766 if (!scrollOverflowHandler.isScrollable(element)) { 2767 //In case we are styling for the 2nd time as in with reponsiveSlides 2768 if (!hasClass(element.item, TABLE)) { 2769 addClass(element.item, TABLE); 2770 } 2771 } 2772 } 2773 2774 var startingSection = null; 2775 FP.getActiveSection = getActiveSection; 2776 function getStartingSection() { 2777 return startingSection; 2778 } 2779 /** 2780 * Styling vertical sections 2781 */ 2782 2783 function styleSection(section) { 2784 var sectionElem = section.item; 2785 var hasSlides = section.allSlidesItems.length; 2786 var index = section.index(); //if no active section is defined, the 1st one will be the default one 2787 2788 if (!getState().activeSection && section.isVisible) { 2789 addClass(sectionElem, ACTIVE); 2790 updateState(); 2791 startingSection = getState().activeSection.item; 2792 } 2793 2794 if (getOptions().paddingTop) { 2795 css(sectionElem, { 2796 'padding-top': getOptions().paddingTop 2797 }); 2798 } 2799 2800 if (getOptions().paddingBottom) { 2801 css(sectionElem, { 2802 'padding-bottom': getOptions().paddingBottom 2803 }); 2804 } 2805 2806 if (typeof getOptions().sectionsColor[index] !== 'undefined') { 2807 css(sectionElem, { 2808 'background-color': getOptions().sectionsColor[index] 2809 }); 2810 } 2811 2812 if (typeof getOptions().anchors[index] !== 'undefined') { 2813 sectionElem.setAttribute('data-anchor', section.anchor); 2814 } 2815 2816 if (!hasSlides) { 2817 addTableClass(section); 2818 } 2819 } 2820 /** 2821 * Gets the active section. 2822 */ 2823 2824 function getActiveSection() { 2825 return getState().activeSection; 2826 } 2827 2828 function getSectionFromPanel(panel) { 2829 return panel.isSection ? panel : panel.parent; 2830 } 2831 2832 var g_focusScrollableId; 2833 EventEmitter.on(events.bindEvents, bindEvents$b); 2834 2835 function bindEvents$b() { 2836 // We can't focus scrollOverflow before scrolling 2837 // to the anchor (if we need to) 2838 EventEmitter.on(events.onAfterRenderNoAnchor, afterRender); 2839 EventEmitter.on(events.onLeave, scrollOverflowHandler.onLeave); 2840 EventEmitter.on(events.onSlideLeave, scrollOverflowHandler.onLeave); 2841 EventEmitter.on(events.afterSlideLoads, scrollOverflowHandler.afterLoad); 2842 EventEmitter.on(events.afterSectionLoads, scrollOverflowHandler.afterLoad); 2843 EventEmitter.on(events.onDestroy, onDestroy$7); 2844 docAddEvent('keyup', scrollOverflowHandler.keyUpHandler); 2845 } 2846 2847 function afterRender() { 2848 if (getOptions().scrollOverflow && !getOptions().scrollBar) { 2849 scrollOverflowHandler.makeScrollable(); 2850 scrollOverflowHandler.focusScrollable(); 2851 } 2852 } 2853 2854 function onDestroy$7() { 2855 docRemoveEvent('keyup', scrollOverflowHandler.keyUpHandler); 2856 } 2857 2858 var scrollOverflowHandler = { 2859 focusedElem: null, 2860 shouldFocusScrollable: true, 2861 isInnerScrollAllowed: true, 2862 timeBeforeReachingLimit: null, 2863 timeLastScroll: null, 2864 preventScrollWithMouseWheel: function preventScrollWithMouseWheel(e) { 2865 if (!state.canScroll) { 2866 preventDefault(e); 2867 return false; 2868 } 2869 }, 2870 preventScrollWithKeyboard: function preventScrollWithKeyboard(e) { 2871 if (!isInsideInput() && getOptions().keyboardScrolling) { 2872 var directionKeys = [38, 33, 32, 40, 34, 36, 35]; 2873 2874 if (directionKeys.indexOf(e.keyCode) > -1 && !scrollOverflowHandler.isInnerScrollAllowed) { 2875 preventDefault(e); 2876 return false; 2877 } 2878 } 2879 }, 2880 keyUpHandler: function keyUpHandler() { 2881 scrollOverflowHandler.shouldFocusScrollable = state.canScroll; 2882 }, 2883 // Leaving sections or slides 2884 onLeave: function onLeave() { 2885 clearTimeout(g_focusScrollableId); 2886 scrollOverflowHandler.isInnerScrollAllowed = false; 2887 }, 2888 // Loading sections or slides 2889 afterLoad: function afterLoad() { 2890 scrollOverflowHandler.isInnerScrollAllowed = false; // Delaying it to avoid issues on Safari when focusing elements #4484 & #4493 2891 2892 clearTimeout(g_focusScrollableId); 2893 g_focusScrollableId = setTimeout(function () { 2894 scrollOverflowHandler.shouldFocusScrollable = state.canScroll; 2895 }, 200); 2896 }, 2897 // Unfocusing the scrollable element from the orgin section/slide 2898 unfocusScrollable: function unfocusScrollable() { 2899 if (doc.activeElement === this.focusedElem) { 2900 // @ts-ignore 2901 this.focusedElem.blur(); 2902 scrollOverflowHandler.isInnerScrollAllowed = false; 2903 } 2904 }, 2905 focusScrollable: function focusScrollable() { 2906 if (!getOptions().scrollOverflow || !scrollOverflowHandler.shouldFocusScrollable) { 2907 return; 2908 } 2909 2910 scrollOverflowHandler.unfocusScrollable(); 2911 var scrollableItem = scrollOverflowHandler.getScrollableItem(getState().activeSection.item); // On desktop we focus the scrollable to be able to use the mouse wheel 2912 // We avoid it on mobile due to a bug in iOS Safari 2913 2914 if (scrollableItem && !isTouchDevice && !isTouch) { 2915 this.focusedElem = scrollableItem; // Forcing the focus on the next paint 2916 // to avoid issue #4484 & #4493 on Safari 2917 2918 requestAnimationFrame(function () { 2919 scrollableItem.focus(); 2920 scrollOverflowHandler.isInnerScrollAllowed = true; 2921 }); 2922 } 2923 2924 scrollOverflowHandler.shouldFocusScrollable = false; 2925 }, 2926 makeScrollable: function makeScrollable() { 2927 if (getOptions().scrollOverflowMacStyle && !isMacDevice) { 2928 addClass($body, 'fp-scroll-mac'); 2929 } 2930 2931 getState().panels.forEach(function (el) { 2932 if (el.slides && el.slides.length) { 2933 return; 2934 } 2935 2936 if (hasClass(el.item, AUTO_HEIGHT_RESPONSIVE) && isResponsiveMode()) { 2937 return; 2938 } else { 2939 var item = getSlideOrSection(el.item); 2940 var shouldBeScrollable = scrollOverflowHandler.shouldBeScrollable(el.item); 2941 var section = getSectionFromPanel(el); 2942 2943 if (isIE11) { 2944 var toggleAction = shouldBeScrollable ? 'addClass' : 'removeClass'; 2945 utils[toggleAction](section.item, IS_OVERFLOW); 2946 utils[toggleAction](el.item, IS_OVERFLOW); 2947 } else { 2948 addClass(section.item, IS_OVERFLOW); 2949 addClass(el.item, IS_OVERFLOW); 2950 } 2951 2952 if (!el.hasScroll) { 2953 scrollOverflowHandler.createWrapper(item); 2954 scrollOverflowHandler.bindEvents(item); 2955 } // updating the state now in case 2956 // this is executed on page load (after images load) 2957 2958 2959 el.hasScroll = true; 2960 } 2961 }); 2962 }, 2963 bindEvents: function bindEvents(item) { 2964 scrollOverflowHandler.getScrollableItem(item).addEventListener('scroll', scrollOverflowHandler.onPanelScroll); 2965 item.addEventListener('wheel', scrollOverflowHandler.preventScrollWithMouseWheel, { 2966 passive: false 2967 }); 2968 item.addEventListener('keydown', scrollOverflowHandler.preventScrollWithKeyboard, { 2969 passive: false 2970 }); 2971 }, 2972 createWrapper: function createWrapper(item) { 2973 var overflowWrapper = document.createElement('div'); 2974 overflowWrapper.className = OVERFLOW; 2975 wrapInner(item, overflowWrapper); 2976 overflowWrapper.setAttribute('tabindex', '-1'); 2977 }, 2978 destroyWrapper: function destroyWrapper(item) { 2979 var overflowWrapper = $(OVERFLOW_SEL, item)[0]; 2980 2981 if (overflowWrapper) { 2982 unwrap(overflowWrapper); 2983 item.removeAttribute('tabindex'); 2984 } 2985 }, 2986 getScrollableItem: function getScrollableItem(sectionItem) { 2987 var panel = getSlideOrSection(sectionItem); 2988 return $(OVERFLOW_SEL, panel)[0] || panel; 2989 }, 2990 hasScroll: function hasScroll(panelItem) { 2991 return hasClass(panelItem, OVERFLOW) || $(OVERFLOW_SEL, panelItem)[0] != null; 2992 }, 2993 isScrollable: function isScrollable(panel) { 2994 return panel.isSection && panel.activeSlide ? panel.activeSlide.hasScroll : panel.hasScroll; 2995 }, 2996 shouldBeScrollable: function shouldBeScrollable(item) { 2997 var scrollable = scrollOverflowHandler.getScrollableItem(item); 2998 return scrollable.scrollHeight > win.innerHeight; 2999 }, 3000 isScrolled: function isScrolled(direction, el) { 3001 if (!state.canScroll) { 3002 return false; 3003 } // we won't allow scrolloverflow on scrollBar:true 3004 3005 3006 if (getOptions().scrollBar) { 3007 return true; 3008 } 3009 3010 var scrollableItem = scrollOverflowHandler.getScrollableItem(el); 3011 3012 if (!getOptions().scrollOverflow || !hasClass(scrollableItem, OVERFLOW) || // Checking the section first 3013 // In case they apply to both section + slide #4505 3014 hasClass(el, 'fp-noscroll') || // Checking the slide (in case it has) 3015 hasClass(getSlideOrSection(el), 'fp-noscroll')) { 3016 return true; 3017 } // ie11 wrongly calculates scrollHeight when using the CSS style 3018 // overflow: auto It adds 1 more pixel compared to offsetHeight 3019 3020 3021 var ie11offset = isIE11 ? 1 : 0; 3022 var positionY = scrollableItem.scrollTop; 3023 var isTopReached = direction === 'up' && positionY <= 0; 3024 var isBottomReached = direction === 'down' && scrollableItem.scrollHeight <= Math.ceil(scrollableItem.offsetHeight + positionY) + ie11offset; 3025 var isScrolled = isTopReached || isBottomReached; 3026 3027 if (!isScrolled) { 3028 this.timeBeforeReachingLimit = new Date().getTime(); 3029 } 3030 3031 return isScrolled; 3032 }, 3033 shouldMovePage: function shouldMovePage() { 3034 this.timeLastScroll = new Date().getTime(); 3035 var timeDiff = this.timeLastScroll - scrollOverflowHandler.timeBeforeReachingLimit; 3036 var isUsingTouch = isTouchDevice || isTouch; 3037 var isGrabbing = isUsingTouch && state.isGrabbing; 3038 var isNotFirstTimeReachingLimit = state.isUsingWheel && timeDiff > 600; 3039 return isGrabbing && timeDiff > 400 || isNotFirstTimeReachingLimit; 3040 }, 3041 onPanelScroll: function () { 3042 var prevPosition = 0; 3043 return function (e) { 3044 var currentPosition = e.target.scrollTop; 3045 var direction = state.touchDirection !== 'none' ? state.touchDirection : prevPosition < currentPosition ? 'down' : 'up'; 3046 prevPosition = currentPosition; 3047 3048 if (isFunction(getOptions().onScrollOverflow)) { 3049 fireCallback('onScrollOverflow', { 3050 position: currentPosition, 3051 direction: direction 3052 }); 3053 } 3054 3055 if (hasClass(e.target, OVERFLOW) && state.canScroll) { 3056 if (scrollOverflowHandler.isScrolled(direction, e.target) && scrollOverflowHandler.shouldMovePage()) { 3057 // Checking again if we have a scrollable content 3058 // To avoid issues like #4479 where the scroll event gets 3059 // triggered after removing/hidding content if this was scrolled 3060 if (scrollOverflowHandler.shouldBeScrollable(getState().activeSection.item)) { 3061 EventEmitter.emit(events.onScrollOverflowScrolled, { 3062 direction: direction 3063 }); 3064 } 3065 } 3066 } 3067 }; 3068 }() 3069 }; 3070 3071 var g_afterSlideLoadsId; 3072 FP.landscapeScroll = landscapeScroll; 3073 EventEmitter.on(events.bindEvents, bindEvents$a); 3074 3075 function bindEvents$a() { 3076 EventEmitter.on(events.onPerformMovement, onPerformMovement); 3077 } 3078 3079 function onPerformMovement() { 3080 clearTimeout(g_afterSlideLoadsId); 3081 setState({ 3082 slideMoving: false 3083 }); 3084 } 3085 /** 3086 * Scrolls horizontal sliders. 3087 */ 3088 3089 3090 function landscapeScroll(slides, destiny, direction) { 3091 var sectionElem = closest(slides, SECTION_SEL); 3092 var section = getState().sections.filter(function (section) { 3093 return section.item == sectionElem; 3094 })[0]; 3095 var slide = section.slides.filter(function (slide) { 3096 return slide.item == destiny; 3097 })[0]; 3098 var v = { 3099 "slides": slides, 3100 "destiny": destiny, 3101 "direction": direction, 3102 "destinyPos": { 3103 "left": destiny.offsetLeft 3104 }, 3105 "slideIndex": slide.index(), 3106 "section": sectionElem, 3107 "sectionIndex": section.index(), 3108 "anchorLink": section.anchor, 3109 "slidesNav": $(SLIDES_NAV_SEL, sectionElem)[0], 3110 "slideAnchor": slide.anchor, 3111 "prevSlide": section.activeSlide.item, 3112 "prevSlideIndex": section.activeSlide.index(), 3113 "items": { 3114 "section": section, 3115 "origin": section.activeSlide, 3116 "destination": slide 3117 }, 3118 //caching the value of isResizing at the momment the function is called 3119 //because it will be checked later inside a setTimeout and the value might change 3120 "localIsResizing": state.isResizing 3121 }; 3122 v.xMovement = getXmovement(v.prevSlideIndex, v.slideIndex); 3123 v.direction = v.direction ? v.direction : v.xMovement; //important!! Only do it when not resizing 3124 3125 if (!v.localIsResizing) { 3126 //preventing from scrolling to the next/prev section when using scrollHorizontally 3127 setState({ 3128 canScroll: false 3129 }); 3130 } 3131 3132 if (getOptions().onSlideLeave) { 3133 //if the site is not just resizing and readjusting the slides 3134 if (!v.localIsResizing && v.xMovement !== 'none') { 3135 if (isFunction(getOptions().onSlideLeave)) { 3136 if (fireCallback('onSlideLeave', v) === false) { 3137 setState({ 3138 slideMoving: false 3139 }); 3140 return; 3141 } 3142 } 3143 } 3144 } 3145 3146 addClass(destiny, ACTIVE); 3147 removeClass(siblings(destiny), ACTIVE); 3148 updateState(); 3149 3150 if (!v.localIsResizing) { 3151 stopMedia(v.prevSlide); 3152 lazyLoad(destiny); 3153 } 3154 3155 toggleControlArrows(v); //only changing the URL if the slides are in the current section (not for resize re-adjusting) 3156 3157 if (section.isActive && !v.localIsResizing) { 3158 setPageStatus(v.slideIndex, v.slideAnchor, v.anchorLink); 3159 } 3160 3161 EventEmitter.emit(events.onSlideLeave, v); 3162 performHorizontalMove(slides, v, true); 3163 } 3164 /** 3165 * Performs the horizontal movement. (CSS3 or jQuery) 3166 * 3167 * @param fireCallback {Boolean} - determines whether or not to fire the callback 3168 */ 3169 3170 function performHorizontalMove(slides, v, fireCallback) { 3171 var destinyPos = v.destinyPos; 3172 activeSlidesNavigation(v.slidesNav, v.slideIndex); 3173 setState({ 3174 scrollX: Math.round(destinyPos.left) 3175 }); 3176 3177 if (getOptions().css3) { 3178 var translate3d = 'translate3d(-' + Math.round(destinyPos.left) + 'px, 0px, 0px)'; 3179 FP.test.translate3dH[v.sectionIndex] = translate3d; 3180 css(addAnimation($(SLIDES_CONTAINER_SEL, slides)), getTransforms(translate3d)); 3181 clearTimeout(g_afterSlideLoadsId); 3182 g_afterSlideLoadsId = setTimeout(function () { 3183 if (fireCallback) { 3184 afterSlideLoads(v); 3185 } 3186 }, getOptions().scrollingSpeed); 3187 } else { 3188 FP.test.left[v.sectionIndex] = Math.round(destinyPos.left); 3189 scrollTo(slides, Math.round(destinyPos.left), getOptions().scrollingSpeed, function () { 3190 if (fireCallback) { 3191 afterSlideLoads(v); 3192 } 3193 }); 3194 } 3195 } 3196 /** 3197 * Retuns `right` or `left` depending on the scrolling movement to reach its destination 3198 * from the current slide. 3199 */ 3200 3201 3202 function getXmovement(fromIndex, toIndex) { 3203 if (fromIndex == toIndex) { 3204 return 'none'; 3205 } 3206 3207 if (fromIndex > toIndex) { 3208 return 'left'; 3209 } 3210 3211 return 'right'; 3212 } 3213 3214 function onDestroy$6() { 3215 clearTimeout(g_afterSlideLoadsId); 3216 } 3217 3218 function afterSlideLoads(v) { 3219 //if the site is not just resizing and readjusting the slides 3220 if (!v.localIsResizing) { 3221 if (isFunction(getOptions().afterSlideLoad)) { 3222 fireCallback('afterSlideLoad', v); 3223 } //needs to be inside the condition to prevent problems with continuousVertical and scrollHorizontally 3224 //and to prevent double scroll right after a windows resize 3225 3226 3227 setState({ 3228 canScroll: true 3229 }); 3230 playMedia(v.destiny); 3231 EventEmitter.emit(events.afterSlideLoads, v); 3232 } //letting them slide again 3233 3234 3235 setState({ 3236 slideMoving: false 3237 }); 3238 } 3239 3240 /** 3241 * Slides silently (with no animation) the active slider to the given slide. 3242 * @param noCallback {bool} true or defined -> no callbacks 3243 */ 3244 3245 function silentLandscapeScroll(activeSlide, noCallbacks) { 3246 setScrollingSpeed(0, 'internal'); 3247 3248 if (typeof noCallbacks !== 'undefined') { 3249 //preventing firing callbacks afterSlideLoad etc. 3250 setState({ 3251 isResizing: true 3252 }); 3253 } 3254 3255 landscapeScroll(closest(activeSlide, SLIDES_WRAPPER_SEL), activeSlide); 3256 3257 if (typeof noCallbacks !== 'undefined') { 3258 setState({ 3259 isResizing: false 3260 }); 3261 } 3262 3263 setScrollingSpeed(getOriginals().scrollingSpeed, 'internal'); 3264 } 3265 3266 var g_prevActiveSectionIndex = null; 3267 var g_prevActiveSlideIndex = null; 3268 /** 3269 * Updates the state of the app. 3270 */ 3271 3272 function updateState() { 3273 state.activeSection = null; 3274 state.sections.map(function (section) { 3275 var isActive = hasClass(section.item, ACTIVE); 3276 section.isActive = isActive; 3277 section.hasScroll = scrollOverflowHandler.hasScroll(section.item); 3278 3279 if (isActive) { 3280 state.activeSection = section; 3281 } 3282 3283 if (section.slides.length) { 3284 section.activeSlide = null; 3285 section.slides.map(function (slide) { 3286 var isActiveSlide = hasClass(slide.item, ACTIVE); 3287 slide.hasScroll = scrollOverflowHandler.hasScroll(section.item); 3288 slide.isActive = isActiveSlide; 3289 3290 if (isActiveSlide) { 3291 section.activeSlide = slide; 3292 } 3293 }); 3294 } 3295 }); 3296 scrollToNewActivePanel(); 3297 } 3298 function updateStructuralState() { 3299 var allSectionItems = $(getOptions().sectionSelector, getContainer()); 3300 var sectionsItems = getVisible(allSectionItems); 3301 var allSections = Array.from(allSectionItems).map(function (item) { 3302 return new SectionPanel(item); 3303 }); 3304 var sections = allSections.filter(function (item) { 3305 return item.isVisible; 3306 }); 3307 var slides = sections.reduce(function (acc, section) { 3308 return acc.concat(section.slides); 3309 }, []); // keeping track of the previously active section 3310 3311 g_prevActiveSectionIndex = getPrevActivePanelIndex(state.activeSection); 3312 g_prevActiveSlideIndex = getPrevActivePanelIndex(state.activeSection ? state.activeSection.activeSlide : null); 3313 state.numSections = sectionsItems.length; 3314 state.numSlides = sections.reduce(function (acc, section) { 3315 return acc + section.slides.length; 3316 }, 0); 3317 state.sections = sections; 3318 state.sectionsIncludingHidden = allSections; 3319 state.slides = slides; 3320 state.panels = state.sections.concat(state.slides); 3321 } 3322 3323 function getPrevActivePanelIndex(activePanel) { 3324 if (!activePanel) { 3325 return null; 3326 } 3327 3328 var prevActivePanelItem = activePanel ? activePanel.item : null; 3329 var hiddenPanels = activePanel.isSection ? state.sectionsIncludingHidden : state.activeSection.slidesIncludingHidden; 3330 3331 if (prevActivePanelItem) { 3332 var panel = getPanelByElement(hiddenPanels, prevActivePanelItem); 3333 return panel ? panel.index() : null; 3334 } 3335 3336 return null; 3337 } 3338 /** 3339 * When changes in the DOM take place there's a change 3340 * the active section is now hidden or removed. 3341 * fullPage.js will scroll to the closest section nearby. 3342 */ 3343 3344 3345 function scrollToNewActivePanel() { 3346 var activeSection = state.activeSection; 3347 var activeSectionHasSlides = state.activeSection ? state.activeSection.slides.length : false; 3348 var activeSlide = state.activeSection ? state.activeSection.activeSlide : null; // Hidding / removing the active section ? 3349 3350 if (!activeSection && state.sections.length && !getState().isBeyondFullpage && g_prevActiveSectionIndex) { 3351 var newActiveSection = getNewActivePanel(g_prevActiveSectionIndex, state.sections); 3352 3353 if (newActiveSection) { 3354 state.activeSection = newActiveSection; 3355 state.activeSection.isActive = true; 3356 addClass(state.activeSection.item, ACTIVE); 3357 } 3358 3359 if (state.activeSection) { 3360 silentScroll(state.activeSection.item.offsetTop); 3361 } 3362 } 3363 3364 if (activeSectionHasSlides && !activeSlide && g_prevActiveSlideIndex) { 3365 var newActiveSlide = getNewActivePanel(g_prevActiveSlideIndex, state.activeSection.slides); 3366 3367 if (newActiveSlide) { 3368 state.activeSection.activeSlide = newActiveSlide; 3369 state.activeSection.activeSlide.isActive = true; 3370 addClass(state.activeSection.activeSlide.item, ACTIVE); 3371 } 3372 3373 if (state.activeSection.activeSlide) { 3374 silentLandscapeScroll(state.activeSection.activeSlide.item, 'internal'); 3375 } 3376 } 3377 } 3378 3379 function getNewActivePanel(prevActivePanelIndex, siblings) { 3380 var newActiveSection; 3381 var prevIndex = prevActivePanelIndex - 1; 3382 var nextIndex = prevActivePanelIndex; 3383 3384 do { 3385 newActiveSection = siblings[prevIndex] || siblings[nextIndex]; 3386 3387 if (newActiveSection) { 3388 break; 3389 } 3390 3391 prevIndex = prevIndex - 1; 3392 nextIndex = nextIndex + 1; 3393 } while (prevIndex >= 0 || nextIndex < siblings.length); 3394 3395 return newActiveSection; 3396 } 3397 /** 3398 * Section object 3399 */ 3400 3401 3402 var SectionPanel = function SectionPanel(el) { 3403 var _this = this; 3404 3405 [].push.call(arguments, getOptions().sectionSelector); 3406 Item.apply(this, arguments); 3407 this.allSlidesItems = $(getOptions().slideSelector, el); 3408 this.slidesIncludingHidden = Array.from(this.allSlidesItems).map(function (item) { 3409 return new SlidePanel(item, _this); 3410 }); 3411 this.slides = this.slidesIncludingHidden.filter(function (slidePanel) { 3412 return slidePanel.isVisible; 3413 }); 3414 this.activeSlide = this.slides.length ? this.slides.filter(function (slide) { 3415 return slide.isActive; 3416 })[0] || this.slides[0] : null; 3417 }; 3418 SectionPanel.prototype = Item.prototype; 3419 SectionPanel.prototype.constructor = SectionPanel; 3420 /** 3421 * Slide object 3422 */ 3423 3424 var SlidePanel = function SlidePanel(el, section) { 3425 this.parent = section; 3426 Item.call(this, el, getOptions().slideSelector); 3427 }; 3428 3429 SlidePanel.prototype = Item.prototype; 3430 SlidePanel.prototype.constructor = SectionPanel; 3431 3432 /** 3433 * Adds internal classes to be able to provide customizable selectors 3434 * keeping the link with the style sheet. 3435 */ 3436 3437 function addInternalSelectors() { 3438 addClass($(getOptions().sectionSelector, getContainer()), SECTION); 3439 addClass($(getOptions().slideSelector, getContainer()), SLIDE); 3440 } 3441 3442 /** 3443 * Styles the horizontal slides for a section. 3444 */ 3445 3446 function styleSlides(section) { 3447 var numSlides = section.slides.length; 3448 var slidesElems = section.allSlidesItems; 3449 var slides = section.slides; 3450 var sliderWidth = numSlides * 100; 3451 var slideWidth = 100 / numSlides; 3452 3453 if (!$(SLIDES_WRAPPER_SEL, section.item)[0]) { 3454 var slidesWrapper = doc.createElement('div'); 3455 slidesWrapper.className = SLIDES_WRAPPER; //fp-slides 3456 3457 wrapAll(slidesElems, slidesWrapper); 3458 var slidesContainer = doc.createElement('div'); 3459 slidesContainer.className = SLIDES_CONTAINER; //fp-slidesContainer 3460 3461 wrapAll(slidesElems, slidesContainer); 3462 } 3463 3464 css($(SLIDES_CONTAINER_SEL, section.item), { 3465 'width': sliderWidth + '%' 3466 }); 3467 3468 if (numSlides > 1) { 3469 if (getOptions().controlArrows) { 3470 createSlideArrows(section); 3471 } 3472 3473 if (getOptions().slidesNavigation) { 3474 addSlidesNavigation(section); 3475 } 3476 } 3477 3478 slides.forEach(function (slide) { 3479 css(slide.item, { 3480 'width': slideWidth + '%' 3481 }); 3482 3483 if (getOptions().verticalCentered) { 3484 addTableClass(slide); 3485 } 3486 }); 3487 var startingSlide = section.activeSlide || null; //if the slide won't be an starting point, the default will be the first one 3488 //the active section isn't the first one? Is not the first slide of the first section? Then we load that section/slide by default. 3489 3490 if (startingSlide != null && state.activeSection && (state.activeSection.index() !== 0 || state.activeSection.index() === 0 && startingSlide.index() !== 0)) { 3491 silentLandscapeScroll(startingSlide.item, 'internal'); 3492 } else { 3493 addClass(slidesElems[0], ACTIVE); 3494 } 3495 } 3496 3497 var g_wrapperObserver; 3498 var g_wrapperObserveConfig = { 3499 attributes: false, 3500 subtree: true, 3501 childList: true, 3502 characterData: true 3503 }; 3504 EventEmitter.on(events.bindEvents, bindEvents$9); 3505 FP["render"] = onContentChange; 3506 3507 function bindEvents$9() { 3508 if (getOptions().observer && "MutationObserver" in window && $(WRAPPER_SEL)[0]) { 3509 g_wrapperObserver = createObserver($(WRAPPER_SEL)[0], onContentChange, g_wrapperObserveConfig); 3510 } 3511 3512 EventEmitter.on(events.contentChanged, onContentChange); 3513 } 3514 /** 3515 * Creates a Mutation observer. 3516 */ 3517 3518 3519 function createObserver(target, callback, config) { 3520 var observer = new MutationObserver(callback); 3521 observer.observe(target, config); 3522 return observer; 3523 } 3524 3525 function didSlidesChange() { 3526 return getVisible($(getOptions().slideSelector, getContainer())).length !== getState().numSlides; 3527 } 3528 3529 function didSectionsChange() { 3530 return getVisible($(getOptions().sectionSelector, getContainer())).length !== getState().numSections; 3531 } 3532 3533 function didSectionsOrSlidesChange() { 3534 return didSlidesChange() || didSectionsChange(); 3535 } 3536 /** 3537 * Listen to changes on sections and fires reBuild 3538 * when those changes affect the section height. 3539 */ 3540 3541 3542 function onContentChange(mutations) { 3543 var _didSlidesChange = didSlidesChange(); 3544 3545 if (didSectionsOrSlidesChange() && !state.isDoingContinousVertical) { 3546 if (getOptions().observer && g_wrapperObserver) { 3547 // Temporally disabling the observer while 3548 // we modidy the DOM again 3549 g_wrapperObserver.disconnect(); 3550 } 3551 3552 updateStructuralState(); 3553 updateState(); // Removing navs and anchors options 3554 3555 getOptions().anchors = []; 3556 remove($(SECTION_NAV_SEL)); 3557 addInternalSelectors(); 3558 setOptionsFromDOM(); 3559 3560 if (getOptions().navigation) { 3561 addVerticalNavigation
vendor: 19,113 bytes, lines 3561-4169
3561(); 3562 } 3563 3564 if (_didSlidesChange) { 3565 remove($(SLIDES_NAV_SEL)); 3566 remove($(SLIDES_ARROW_SEL)); 3567 } 3568 3569 getState().sections.forEach(function (section) { 3570 if (section.slides.length) { 3571 if (_didSlidesChange) { 3572 styleSlides(section); 3573 } 3574 } else { 3575 styleSection(section); 3576 } 3577 }); 3578 } 3579 3580 if (getOptions().observer && g_wrapperObserver && $(WRAPPER_SEL)[0]) { 3581 g_wrapperObserver.observe($(WRAPPER_SEL)[0], g_wrapperObserveConfig); 3582 } 3583 } 3584 3585 var supportsPassiveEvents = function () { 3586 //cheks for passive event support 3587 var g_supportsPassive = false; 3588 3589 try { 3590 var opts = Object.defineProperty({}, 'passive', { 3591 get: function get() { 3592 g_supportsPassive = true; 3593 } 3594 }); 3595 windowAddEvent("testPassive", null, opts); 3596 windowRemoveEvent("testPassive", null, opts); 3597 } catch (e) {} 3598 3599 return function () { 3600 return g_supportsPassive; 3601 }; 3602 }(); 3603 3604 function getPassiveOptionsIfPossible() { 3605 return supportsPassiveEvents() ? { 3606 passive: false 3607 } : false; 3608 } 3609 3610 var wheelDataHandler = function () { 3611 var _prevTime = new Date().getTime(); 3612 3613 var _scrollings = []; 3614 var isScrollingVertically; 3615 var direction; 3616 return { 3617 registerEvent: function registerEvent(e) { 3618 e = e || win.event; 3619 var value = e.wheelDelta || -e.deltaY || -e.detail; 3620 var delta = Math.max(-1, Math.min(1, value)); 3621 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 3622 isScrollingVertically = Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta) || Math.abs(e.deltaX) < Math.abs(e.deltaY) || !horizontalDetection; 3623 var curTime = new Date().getTime(); 3624 direction = delta < 0 ? 'down' : 'up'; //Limiting the array to 150 (lets not waste memory!) 3625 3626 if (_scrollings.length > 149) { 3627 _scrollings.shift(); 3628 } //keeping record of the previous scrollings 3629 3630 3631 _scrollings.push(Math.abs(value)); //time difference between the last scroll and the current one 3632 3633 3634 var timeDiff = curTime - _prevTime; 3635 _prevTime = curTime; //haven't they scrolled in a while? 3636 //(enough to be consider a different scrolling action to scroll another section) 3637 3638 if (timeDiff > 200) { 3639 //emptying the array, we dont care about old scrollings for our averages 3640 _scrollings = []; 3641 } 3642 }, 3643 isAccelerating: function isAccelerating() { 3644 var averageEnd = getAverage(_scrollings, 10); 3645 var averageMiddle = getAverage(_scrollings, 70); 3646 var isAccelerating = averageEnd >= averageMiddle; 3647 return _scrollings.length ? isAccelerating && isScrollingVertically : false; 3648 }, 3649 getDirection: function getDirection() { 3650 return direction; 3651 } 3652 }; 3653 }(); 3654 3655 function scrollBeyondFullPage() { 3656 var dtop = getDestinationOffset(); 3657 var scrollSettings = getScrollSettings(dtop); 3658 FP.test.top = -dtop + 'px'; 3659 setState({ 3660 canScroll: false 3661 }); 3662 scrollTo(scrollSettings.element, scrollSettings.options, getOptions().scrollingSpeed, function () { 3663 setTimeout(function () { 3664 setState({ 3665 isBeyondFullpage: true 3666 }); 3667 setState({ 3668 canScroll: true 3669 }); 3670 }, 30); 3671 }); 3672 } 3673 function onKeyDown() { 3674 if (!isFullPageAbove()) { 3675 return; 3676 } else { 3677 scrollUpToFullpage(); 3678 } 3679 } 3680 function scrollUpToFullpage() { 3681 var scrollSettings = getScrollSettings(getLast(getState().sections).item.offsetTop); 3682 setState({ 3683 canScroll: false 3684 }); 3685 scrollTo(scrollSettings.element, scrollSettings.options, getOptions().scrollingSpeed, function () { 3686 setState({ 3687 canScroll: true 3688 }); 3689 setState({ 3690 isBeyondFullpage: false 3691 }); 3692 setState({ 3693 isAboutToScrollToFullPage: false 3694 }); 3695 }); 3696 } 3697 3698 function getDestinationOffset() { 3699 if (!getOptions().css3) { 3700 return getLast(getState().sections).item.offsetTop + getLast(getState().sections).item.offsetHeight; 3701 } 3702 3703 return getScrollTop() + getWindowHeight(); 3704 } 3705 3706 function beyondFullPageHandler(container, e) { 3707 new Date().getTime(); 3708 var pauseScroll = getState().isBeyondFullpage && container.getBoundingClientRect().bottom >= 0 && wheelDataHandler.getDirection() === 'up'; 3709 var g_isAboutToScrollToFullPage = getState().isAboutToScrollToFullPage; 3710 3711 if (g_isAboutToScrollToFullPage) { 3712 preventDefault(e); 3713 return false; 3714 } 3715 3716 if (getState().isBeyondFullpage) { 3717 if (!pauseScroll) { 3718 keyframeTime('set', 'beyondFullpage', 1000); 3719 } else { 3720 var shouldSetFixedPosition = !g_isAboutToScrollToFullPage && (!keyframeTime('isNewKeyframe', 'beyondFullpage') || !wheelDataHandler.isAccelerating()); 3721 var scrollSettings; 3722 3723 if (shouldSetFixedPosition) { 3724 scrollSettings = getScrollSettings(getLast(getState().sections).item.offsetTop + getLast(getState().sections).item.offsetHeight); 3725 scrollSettings.element.scrollTo(0, scrollSettings.options); 3726 setState({ 3727 isAboutToScrollToFullPage: false 3728 }); 3729 preventDefault(e); 3730 return false; 3731 } else if (wheelDataHandler.isAccelerating()) { 3732 pauseScroll = false; 3733 setState({ 3734 isAboutToScrollToFullPage: true 3735 }); 3736 setState({ 3737 scrollTrigger: 'wheel' 3738 }); 3739 scrollUpToFullpage(); 3740 preventDefault(e); 3741 return false; 3742 } 3743 } 3744 3745 if (!g_isAboutToScrollToFullPage) { 3746 // allow normal scrolling, but quitting 3747 if (!pauseScroll) { 3748 return true; 3749 } 3750 } 3751 } 3752 } 3753 3754 var keyframeTime = function () { 3755 var isNew = false; 3756 var frames = {}; 3757 var timeframes = {}; 3758 return function (action, name, timeframe) { 3759 switch (action) { 3760 case 'set': 3761 frames[name] = new Date().getTime(); 3762 timeframes[name] = timeframe; 3763 break; 3764 3765 case 'isNewKeyframe': 3766 var current = new Date().getTime(); 3767 isNew = current - frames[name] > timeframes[name]; 3768 break; 3769 } 3770 3771 return isNew; 3772 }; 3773 }(); 3774 3775 FP.moveSectionDown = moveSectionDown; 3776 /** 3777 * Moves the page down one section. 3778 */ 3779 3780 function moveSectionDown() { 3781 var next = getState().activeSection.next(); //looping to the top if there's no more sections below 3782 3783 if (!next && (getOptions().loopBottom || getOptions().continuousVertical)) { 3784 next = getState().sections[0]; 3785 } 3786 3787 if (next != null) { 3788 scrollPage(next, null, false); 3789 } else if (hasContentBeyondFullPage()) { 3790 EventEmitter.emit(events.scrollBeyondFullpage); 3791 } 3792 } 3793 3794 function hasContentBeyondFullPage() { 3795 return getContainer().scrollHeight < $body.scrollHeight; 3796 } 3797 3798 FP.moveSectionUp = moveSectionUp; 3799 /** 3800 * Moves the page up one section. 3801 */ 3802 3803 function moveSectionUp() { 3804 var prev = getState().activeSection.prev(); //looping to the bottom if there's no more sections above 3805 3806 if (!prev && (getOptions().loopTop || getOptions().continuousVertical)) { 3807 prev = getLast(getState().sections); 3808 } 3809 3810 if (prev != null) { 3811 scrollPage(prev, null, true); 3812 } 3813 } 3814 3815 var oldPageY = 0; 3816 /** 3817 * Detecting the direction of the mouse movement. 3818 * Used only for the middle button of the mouse. 3819 */ 3820 3821 function mouseMoveHandler(e) { 3822 if (!getOptions().autoScrolling) { 3823 return; 3824 } 3825 3826 if (state.canScroll) { 3827 // moving up 3828 if (e.pageY < oldPageY && getIsScrollAllowed().m.up) { 3829 moveSectionUp(); 3830 } // moving down 3831 else if (e.pageY > oldPageY && getIsScrollAllowed().m.down) { 3832 moveSectionDown(); 3833 } 3834 } 3835 3836 oldPageY = e.pageY; 3837 } 3838 function setOldPageY(value) { 3839 oldPageY = value; 3840 } 3841 3842 /** 3843 * Determines the way of scrolling up or down: 3844 * by 'automatically' scrolling a section or by using the default and normal scrolling. 3845 */ 3846 3847 function scrolling(type) { 3848 if (!getIsScrollAllowed().m[type]) { 3849 return; 3850 } 3851 3852 var scrollSection = type === 'down' ? moveSectionDown : moveSectionUp; 3853 3854 if (getOptions().scrollOverflow && scrollOverflowHandler.isScrollable(getState().activeSection)) { 3855 //is the scrollbar at the start/end of the scroll? 3856 if (scrollOverflowHandler.isScrolled(type, getState().activeSection.item) && scrollOverflowHandler.shouldMovePage()) { 3857 scrollSection(); 3858 } 3859 } else { 3860 scrollSection(); 3861 } 3862 } 3863 3864 var touchStartY = 0; 3865 var touchStartX = 0; 3866 var touchEndY = 0; 3867 var touchEndX = 0; 3868 var MSPointer = getMSPointer(); 3869 var pointers = { 3870 touchmove: 'ontouchmove' in window ? 'touchmove' : MSPointer ? MSPointer.move : null, 3871 touchstart: 'ontouchstart' in window ? 'touchstart' : MSPointer ? MSPointer.down : null 3872 }; 3873 /** 3874 * Adds the possibility to auto scroll through sections on touch devices. 3875 */ 3876 3877 function addTouchHandler() { 3878 if (!pointers.touchmove) { 3879 return; 3880 } 3881 3882 if (isTouchDevice || isTouch) { 3883 if (getOptions().autoScrolling) { 3884 $body.removeEventListener(pointers.touchmove, preventBouncing, { 3885 passive: false 3886 }); 3887 $body.addEventListener(pointers.touchmove, preventBouncing, { 3888 passive: false 3889 }); 3890 } 3891 3892 var touchWrapper = getOptions().touchWrapper; 3893 touchWrapper.removeEventListener(pointers.touchstart, touchStartHandler); 3894 touchWrapper.removeEventListener(pointers.touchmove, touchMoveHandler, { 3895 passive: false 3896 }); 3897 touchWrapper.addEventListener(pointers.touchstart, touchStartHandler); 3898 touchWrapper.addEventListener(pointers.touchmove, touchMoveHandler, { 3899 passive: false 3900 }); 3901 } 3902 } 3903 /** 3904 * Removes the auto scrolling for touch devices. 3905 */ 3906 3907 function removeTouchHandler() { 3908 if (!pointers.touchmove) { 3909 return; 3910 } 3911 3912 if (isTouchDevice || isTouch) { 3913 // normalScrollElements requires it off #2691 3914 if (getOptions().autoScrolling) { 3915 $body.removeEventListener(pointers.touchmove, touchMoveHandler, { 3916 passive: false 3917 }); 3918 $body.removeEventListener(pointers.touchmove, preventBouncing, { 3919 passive: false 3920 }); 3921 } 3922 3923 var touchWrapper = getOptions().touchWrapper; 3924 touchWrapper.removeEventListener(pointers.touchstart, touchStartHandler); 3925 touchWrapper.removeEventListener(pointers.touchmove, touchMoveHandler, { 3926 passive: false 3927 }); 3928 } 3929 } 3930 /* Detecting touch events 3931 3932 * As we are changing the top property of the page on scrolling, we can not use the traditional way to detect it. 3933 * This way, the touchstart and the touch moves shows an small difference between them which is the 3934 * used one to determine the direction. 3935 */ 3936 3937 function touchMoveHandler(e) { 3938 var activeSection = closest(e.target, SECTION_SEL) || getState().activeSection.item; 3939 var hasActiveSectionOverflow = scrollOverflowHandler.isScrollable(getState().activeSection); 3940 3941 if (isReallyTouch(e)) { 3942 setState({ 3943 isGrabbing: true, 3944 isUsingWheel: false 3945 }); 3946 3947 if (getOptions().autoScrolling) { 3948 if (hasActiveSectionOverflow && !state.canScroll || getOptions().scrollBar) { 3949 //preventing the easing on iOS devices 3950 preventDefault(e); 3951 } 3952 } 3953 3954 var touchEvents = getEventsPage(e); 3955 touchEndY = touchEvents.y; 3956 touchEndX = touchEvents.x; 3957 var isVerticalMovementEnough = Math.abs(touchStartY - touchEndY) > win.innerHeight / 100 * getOptions().touchSensitivity; 3958 var isHorizontalMovementEnough = Math.abs(touchStartX - touchEndX) > getWindowWidth() / 100 * getOptions().touchSensitivity; 3959 var isHorizontalPredominantMove = $(SLIDES_WRAPPER_SEL, activeSection).length && Math.abs(touchStartX - touchEndX) > Math.abs(touchStartY - touchEndY); 3960 var directionH = touchStartX > touchEndX ? 'right' : 'left'; 3961 var directionV = touchStartY > touchEndY ? 'down' : 'up'; 3962 var direction = isHorizontalPredominantMove ? directionH : directionV; 3963 setState({ 3964 touchDirection: direction 3965 }); //if movement in the X axys is greater than in the Y and the currect section has slides... 3966 3967 if (isHorizontalPredominantMove) { 3968 //is the movement greater than the minimum resistance to scroll? 3969 if (!state.slideMoving && isHorizontalMovementEnough) { 3970 if (touchStartX > touchEndX) { 3971 if (getIsScrollAllowed().m.right) { 3972 EventEmitter.emit(events.moveSlideRight, { 3973 section: activeSection 3974 }); 3975 } 3976 } else { 3977 if (getIsScrollAllowed().m.left) { 3978 EventEmitter.emit(events.moveSlideLeft, { 3979 section: activeSection 3980 }); 3981 } 3982 } 3983 } 3984 } //vertical scrolling (only when autoScrolling is enabled) 3985 else if (getOptions().autoScrolling && state.canScroll) { 3986 //is the movement greater than the minimum resistance to scroll? 3987 if (isVerticalMovementEnough) { 3988 scrolling(directionV); 3989 } 3990 } 3991 } 3992 } 3993 /** 3994 * As IE >= 10 fires both touch and mouse events when using a mouse in a touchscreen 3995 * this way we make sure that is really a touch event what IE is detecting. 3996 */ 3997 3998 3999 function isReallyTouch(e) { 4000 //if is not IE || IE is detecting `touch` or `pen` 4001 return typeof e.pointerType === 'undefined' || e.pointerType != 'mouse'; 4002 } 4003 /** 4004 * Handler for the touch start event. 4005 */ 4006 4007 4008 function touchStartHandler(e) { 4009 //stopping the auto scroll to adjust to a section 4010 if (getOptions().fitToSection) { 4011 setState({ 4012 activeAnimation: false 4013 }); 4014 } 4015 4016 if (isReallyTouch(e)) { 4017 var touchEvents = getEventsPage(e); 4018 touchStartY = touchEvents.y; 4019 touchStartX = touchEvents.x; 4020 } 4021 4022 windowAddEvent('touchend', touchEndHandler); 4023 } 4024 /** 4025 * Handler for the touch end event. 4026 */ 4027 4028 4029 function touchEndHandler() { 4030 windowRemoveEvent('touchend', touchEndHandler); 4031 setState({ 4032 isGrabbing: false 4033 }); 4034 } 4035 /** 4036 * Gets the pageX and pageY properties depending on the browser. 4037 * https://github.com/alvarotrigo/fullPage.js/issues/194#issuecomment-34069854 4038 */ 4039 4040 4041 function getEventsPage(e) { 4042 var events = {}; 4043 events.y = typeof e.pageY !== 'undefined' && (e.pageY || e.pageX) ? e.pageY : e.touches[0].pageY; 4044 events.x = typeof e.pageX !== 'undefined' && (e.pageY || e.pageX) ? e.pageX : e.touches[0].pageX; //in touch devices with scrollBar:true, e.pageY is detected, but we have to deal with touch events. #1008 4045 4046 if (isTouch && isReallyTouch(e) && getOptions().scrollBar && typeof e.touches !== 'undefined') { 4047 events.y = e.touches[0].pageY; 4048 events.x = e.touches[0].pageX; 4049 } 4050 4051 return events; 4052 } 4053 /* 4054 * Returns and object with Microsoft pointers (for IE<11 and for IE >= 11) 4055 * http://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx 4056 */ 4057 4058 4059 function getMSPointer() { 4060 var pointer; //IE >= 11 & rest of browsers 4061 4062 if (win.PointerEvent) { 4063 pointer = { 4064 down: 'pointerdown', 4065 move: 'pointermove' 4066 }; 4067 } 4068 4069 return pointer; 4070 } 4071 /* 4072 * Preventing bouncing in iOS #2285 4073 */ 4074 4075 4076 function preventBouncing(e) { 4077 if (getOptions().autoScrolling && isReallyTouch(e) && getIsScrollAllowed().m.up) { 4078 //preventing the easing on iOS devices 4079 if (!state.canScroll) { 4080 preventDefault(e); 4081 } 4082 } 4083 } 4084 4085 FP.moveSlideLeft = moveSlideLeft; 4086 FP.moveSlideRight = moveSlideRight; 4087 /** 4088 * Slides a slider to the given direction. 4089 * Optional `section` param. 4090 */ 4091 4092 function moveSlide(direction, section) { 4093 var activeSectionItem = section == null ? getState().activeSection.item : section; 4094 var activeSection = getPanelByElement(state.sections, activeSectionItem); 4095 var slides = $(SLIDES_WRAPPER_SEL, activeSectionItem)[0]; // more than one slide needed and nothing should be sliding 4096 4097 if (slides == null || state.slideMoving || activeSection.slides.length < 2) { 4098 return; 4099 } 4100 4101 var currentSlide = activeSection.activeSlide; 4102 var destiny = direction === 'left' ? currentSlide.prev() : currentSlide.next(); //isn't there a next slide in the secuence? 4103 4104 if (!destiny) { 4105 //respect loopHorizontal setting 4106 if (!getOptions().loopHorizontal) return; 4107 destiny = direction === 'left' ? getLast(activeSection.slides) : activeSection.slides[0]; 4108 } 4109 4110 setState({ 4111 slideMoving: !FP.test.isTesting 4112 }); 4113 landscapeScroll(slides, destiny.item, direction); 4114 } 4115 /** 4116 * Slides left the slider of the active section. 4117 * Optional `section` param. 4118 */ 4119 4120 function moveSlideLeft(section) { 4121 moveSlide('left', section); 4122 } 4123 /** 4124 * Slides right the slider of the active section. 4125 * Optional `section` param. 4126 */ 4127 4128 function moveSlideRight(section) { 4129 moveSlide('right', section); 4130 } 4131 4132 /** 4133 * Gets a section by its anchor / index 4134 */ 4135 4136 function getSectionByAnchor(sectionAnchor) { 4137 var section = getState().sections.filter(function (section) { 4138 return section.anchor === sectionAnchor; 4139 })[0]; 4140 4141 if (!section) { 4142 var sectionIndex = typeof sectionAnchor !== 'undefined' ? sectionAnchor - 1 : 0; 4143 section = getState().sections[sectionIndex]; 4144 } 4145 4146 return section; 4147 } 4148 4149 /** 4150 * Scrolls the slider to the given slide destination for the given section 4151 */ 4152 4153 function scrollSlider(slideElem) { 4154 if (slideElem != null) { 4155 landscapeScroll(closest(slideElem, SLIDES_WRAPPER_SEL), slideElem); 4156 } 4157 } 4158 4159 /** 4160 * Scrolls to the given section and slide anchors 4161 */ 4162 4163 function scrollPageAndSlide(sectionAnchor, slideAnchor) { 4164 var section = getSectionByAnchor(sectionAnchor); //do nothing if there's no section with the given anchor name 4165 4166 if (section == null) return; 4167 var slideElem = getSlideByAnchor(slideAnchor, section); //we need to scroll to the section and then to the slide 4168 4169 if (
vendor: 59,658 bytes, lines 4169-5970
4169section.anchor !== state.lastScrolledDestiny && !hasClass(section.item, ACTIVE)) { 4170 scrollPage(section, function () { 4171 scrollSlider(slideElem); 4172 }); 4173 } //if we were already in the section 4174 else { 4175 scrollSlider(slideElem); 4176 } 4177 } 4178 /** 4179 * Gets a slide inside a given section by its anchor / index 4180 */ 4181 4182 function getSlideByAnchor(slideAnchor, section) { 4183 var slide = section.slides.filter(function (slide) { 4184 return slide.anchor === slideAnchor; 4185 })[0]; 4186 4187 if (slide == null) { 4188 slideAnchor = typeof slideAnchor !== 'undefined' ? slideAnchor : 0; 4189 slide = section.slides[slideAnchor]; 4190 } 4191 4192 return slide ? slide.item : null; 4193 } 4194 4195 FP.moveTo = moveTo$1; 4196 /** 4197 * Moves the page to the given section and slide. 4198 * Anchors or index positions can be used as params. 4199 */ 4200 4201 function moveTo$1(sectionAnchor, slideAnchor) { 4202 var destiny = getSectionByAnchor(sectionAnchor); 4203 4204 if (typeof slideAnchor !== 'undefined') { 4205 scrollPageAndSlide(sectionAnchor, slideAnchor); 4206 } else if (destiny != null) { 4207 scrollPage(destiny); 4208 } 4209 } 4210 4211 //@ts-check 4212 var g_controlPressed; 4213 var g_keydownId; 4214 var g_elToFocus; 4215 EventEmitter.on(events.bindEvents, bindEvents$8); 4216 4217 function bindEvents$8() { 4218 //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 4219 windowAddEvent('blur', blurHandler); //Sliding with arrow keys, both, vertical and horizontal 4220 4221 docAddEvent('keydown', keydownHandler); //to prevent scrolling while zooming 4222 4223 docAddEvent('keyup', keyUpHandler); 4224 EventEmitter.on(events.onDestroy, onDestroy$5); 4225 EventEmitter.on(events.afterSlideLoads, onAfterSlideLoads); 4226 EventEmitter.on(events.afterSectionLoads, afterSectionLoads); 4227 } 4228 4229 function onDestroy$5() { 4230 clearTimeout(g_keydownId); 4231 docRemoveEvent('keydown', keydownHandler); 4232 docRemoveEvent('keyup', keyUpHandler); 4233 } //Sliding with arrow keys, both, vertical and horizontal 4234 4235 4236 function keydownHandler(e) { 4237 clearTimeout(g_keydownId); 4238 var keyCode = e.keyCode; 4239 var isPressingHorizontalArrows = [37, 39].indexOf(keyCode) > -1; 4240 var canScrollWithKeyboard = getOptions().autoScrolling || getOptions().fitToSection || isPressingHorizontalArrows; //tab? 4241 4242 if (keyCode === 9) { 4243 onTab(e); 4244 } else if (!isInsideInput() && getOptions().keyboardScrolling && canScrollWithKeyboard) { 4245 g_controlPressed = e.ctrlKey; 4246 g_keydownId = setTimeout(function () { 4247 onkeydown(e); 4248 }, 0); 4249 } 4250 } 4251 /** 4252 * Keydown event 4253 */ 4254 4255 4256 function onkeydown(e) { 4257 var shiftPressed = e.shiftKey; 4258 var activeElement = doc.activeElement; 4259 var isMediaFocused = matches(activeElement, 'video') || matches(activeElement, 'audio'); 4260 var isScrolled = { 4261 up: scrollOverflowHandler.isScrolled('up', getState().activeSection.item), 4262 down: scrollOverflowHandler.isScrolled('down', getState().activeSection.item) 4263 }; 4264 var isUsingHorizontalArrowKeys = [37, 39].indexOf(e.keyCode) > -1; 4265 cancelDirectionKeyEvents(e); //do nothing if we can not scroll or we are not using horizotnal key arrows. 4266 4267 if (!state.canScroll && !isUsingHorizontalArrowKeys) { 4268 return; 4269 } 4270 4271 setState({ 4272 scrollTrigger: 'keydown' 4273 }); 4274 4275 switch (e.keyCode) { 4276 //up 4277 case 38: 4278 case 33: 4279 if (getIsScrollAllowed().k.up && isScrolled.up) { 4280 if (state.isBeyondFullpage) { 4281 EventEmitter.emit(events.onKeyDown, { 4282 e: e 4283 }); 4284 } else { 4285 moveSectionUp(); 4286 } 4287 } else { 4288 scrollOverflowHandler.focusScrollable(); 4289 } 4290 4291 break; 4292 //down 4293 4294 case 32: 4295 //spacebar 4296 if (shiftPressed && getIsScrollAllowed().k.up && !isMediaFocused && isScrolled.up) { 4297 moveSectionUp(); 4298 break; 4299 } 4300 4301 /* falls through */ 4302 4303 case 40: 4304 case 34: 4305 if (getIsScrollAllowed().k.down && isScrolled.down) { 4306 if (state.isBeyondFullpage) { 4307 return; 4308 } // space bar? 4309 4310 4311 if (e.keyCode !== 32 || !isMediaFocused) { 4312 moveSectionDown(); 4313 } 4314 } else { 4315 scrollOverflowHandler.focusScrollable(); 4316 } 4317 4318 break; 4319 //Home 4320 4321 case 36: 4322 if (getIsScrollAllowed().k.up) { 4323 moveTo$1(1); 4324 } 4325 4326 break; 4327 //End 4328 4329 case 35: 4330 if (getIsScrollAllowed().k.down) { 4331 moveTo$1(getState().sections.length); 4332 } 4333 4334 break; 4335 //left 4336 4337 case 37: 4338 if (getIsScrollAllowed().k.left) { 4339 moveSlideLeft(); 4340 } 4341 4342 break; 4343 //right 4344 4345 case 39: 4346 if (getIsScrollAllowed().k.right) { 4347 moveSlideRight(); 4348 } 4349 4350 break; 4351 4352 default: 4353 return; 4354 // exit this handler for other keys 4355 } 4356 } //to prevent scrolling while zooming 4357 4358 4359 function keyUpHandler(e) { 4360 if (state.isWindowFocused) { 4361 //the keyup gets fired on new tab ctrl + t in Firefox 4362 g_controlPressed = e.ctrlKey; 4363 } 4364 } //when opening a new tab (ctrl + t), `control` won't be pressed when coming back. 4365 4366 4367 function blurHandler() { 4368 setState({ 4369 isWindowFocused: false 4370 }); 4371 g_controlPressed = false; 4372 } 4373 /** 4374 * Makes sure the tab key will only focus elements within the current section/slide 4375 * preventing this way from breaking the page. 4376 * Based on "Modals and keyboard traps" 4377 * from https://developers.google.com/web/fundamentals/accessibility/focus/using-tabindex 4378 */ 4379 4380 4381 function onTab(e) { 4382 var isShiftPressed = e.shiftKey; 4383 var activeElement = doc.activeElement; 4384 var focusableElements = getFocusables(getSlideOrSection(getState().activeSection.item)); 4385 4386 function preventAndFocusFirst(e) { 4387 preventDefault(e); 4388 return focusableElements[0] ? focusableElements[0].focus() : null; 4389 } //outside any section or slide? Let's not hijack the tab! 4390 4391 4392 if (isFocusOutside(e)) { 4393 return; 4394 } //is there an element with focus? 4395 4396 4397 if (activeElement) { 4398 if (closest(activeElement, SECTION_ACTIVE_SEL + ',' + SECTION_ACTIVE_SEL + ' ' + SLIDE_ACTIVE_SEL) == null) { 4399 activeElement = preventAndFocusFirst(e); 4400 } 4401 } //no element if focused? Let's focus the first one of the section/slide 4402 else { 4403 preventAndFocusFirst(e); 4404 } //when reached the first or last focusable element of the section/slide 4405 //we prevent the tab action to keep it in the last focusable element 4406 4407 4408 var isFirstFocusableInSection = activeElement == focusableElements[0]; 4409 var isLastFocusableInSection = activeElement == focusableElements[focusableElements.length - 1]; 4410 var isNextItem = !isShiftPressed && isLastFocusableInSection; 4411 var isPrevItem = isShiftPressed && isFirstFocusableInSection; 4412 4413 if (isPrevItem || isNextItem) { 4414 preventDefault(e); 4415 var focusInfo = getPanelWithFocusable(isPrevItem); 4416 var destinationPanel = focusInfo ? focusInfo.panel : null; 4417 4418 if (destinationPanel) { 4419 var destinationSection = destinationPanel.isSection ? destinationPanel : destinationPanel.parent; 4420 EventEmitter.emit(events.onScrollPageAndSlide, { 4421 sectionAnchor: destinationSection.index() + 1, 4422 slideAnchor: destinationPanel.isSection ? 0 : destinationPanel.index() 4423 }); 4424 g_elToFocus = focusInfo.itemToFocus; 4425 preventDefault(e); 4426 } 4427 } 4428 } 4429 4430 function onAfterSlideLoads(v) { 4431 focusItem(); 4432 } 4433 4434 function afterSectionLoads(v) { 4435 if (!closest(g_elToFocus, SLIDE_SEL) || closest(g_elToFocus, SLIDE_ACTIVE_SEL)) { 4436 focusItem(); 4437 } 4438 } 4439 4440 function focusItem() { 4441 if (g_elToFocus) { 4442 g_elToFocus.focus(); 4443 g_elToFocus = null; 4444 } 4445 } 4446 /** 4447 * Get's the panel containing the element to focus. 4448 * 4449 */ 4450 4451 4452 function getPanelWithFocusable(isPrevItem) { 4453 var action = isPrevItem ? 'prevPanel' : 'nextPanel'; 4454 var focusableElements = []; 4455 var panelWithFocusables; 4456 var currentPanel = getSlideOrSectionPanel(getActivePanel()[action]()); 4457 4458 do { 4459 focusableElements = getFocusables(currentPanel.item); 4460 4461 if (focusableElements.length) { 4462 panelWithFocusables = { 4463 panel: currentPanel, 4464 itemToFocus: focusableElements[isPrevItem ? focusableElements.length - 1 : 0] 4465 }; 4466 } 4467 4468 currentPanel = getSlideOrSectionPanel(currentPanel[action]()); 4469 } while (currentPanel && focusableElements.length === 0); 4470 4471 return panelWithFocusables; 4472 } 4473 /** 4474 * Gets all the focusable elements inside the passed element. 4475 */ 4476 4477 4478 function getFocusables(el) { 4479 return [].slice.call($(focusableElementsString, el)).filter(function (item) { 4480 return getAttr(item, 'tabindex') !== '-1' && //are also not hidden elements (or with hidden parents) 4481 item.offsetParent !== null; 4482 }); 4483 } 4484 /** 4485 * Determines whether the focus is outside fullpage.js sections/slides or not. 4486 */ 4487 4488 4489 function isFocusOutside(e) { 4490 var allFocusables = getFocusables(doc); 4491 var currentFocusIndex = allFocusables.indexOf(doc.activeElement); 4492 var focusDestinationIndex = e.shiftKey ? currentFocusIndex - 1 : currentFocusIndex + 1; 4493 var focusDestination = allFocusables[focusDestinationIndex]; 4494 var destinationItemSlide = closest(focusDestination, SLIDE_SEL); 4495 var destinationItemSection = closest(focusDestination, SECTION_SEL); 4496 return !destinationItemSlide && !destinationItemSection; 4497 } 4498 4499 function shouldCancelKeyboardNavigation(e) { 4500 // https://keycode.info/for/34 4501 // 40 = arrow down 4502 // 38 = arrow up 4503 // 32 = spacebar 4504 // 33 = PageUp 4505 // 34 = PageDown 4506 var keyControls = [40, 38, 32, 33, 34]; 4507 return keyControls.indexOf(e.keyCode) > -1 && !state.isBeyondFullpage; 4508 } //preventing the scroll with arrow keys & spacebar & Page Up & Down keys 4509 4510 4511 function cancelDirectionKeyEvents(e) { 4512 if (shouldCancelKeyboardNavigation(e) && !closest(e.target, OVERFLOW_SEL)) { 4513 e.preventDefault(); 4514 } 4515 } 4516 4517 function getControlPressed() { 4518 return g_controlPressed; 4519 } 4520 4521 var prevTime = new Date().getTime(); 4522 var scrollings = []; 4523 FP.setMouseWheelScrolling = setMouseWheelScrolling; 4524 /** 4525 * Adds or remove the possibility of scrolling through sections by using the mouse wheel or the trackpad. 4526 */ 4527 4528 function setMouseWheelScrolling(value) { 4529 if (value) { 4530 addMouseWheelHandler(); 4531 addMiddleWheelHandler(); 4532 } else { 4533 removeMouseWheelHandler(); 4534 removeMiddleWheelHandler(); 4535 } 4536 } 4537 /** 4538 * Adds the auto scrolling action for the mouse wheel and trackpad. 4539 * After this function is called, the mousewheel and trackpad movements will scroll through sections 4540 * https://developer.mozilla.org/en-US/docs/Web/Events/wheel 4541 */ 4542 4543 4544 function addMouseWheelHandler() { 4545 var prefix = ''; 4546 4547 var _addEventListener; 4548 4549 if (win.addEventListener) { 4550 _addEventListener = "addEventListener"; 4551 } else { 4552 _addEventListener = "attachEvent"; 4553 prefix = 'on'; 4554 } // detect available wheel event 4555 4556 4557 var support = 'onwheel' in doc.createElement('div') ? 'wheel' : // Modern browsers support "wheel" 4558 // @ts-ignore 4559 doc.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel" 4560 'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox 4561 4562 var passiveEvent = getPassiveOptionsIfPossible(); 4563 4564 if (support == 'DOMMouseScroll') { 4565 doc[_addEventListener](prefix + 'MozMousePixelScroll', MouseWheelHandler, passiveEvent); 4566 } //handle MozMousePixelScroll in older Firefox 4567 else { 4568 doc[_addEventListener](prefix + support, MouseWheelHandler, passiveEvent); 4569 } 4570 } 4571 /** 4572 * Binding the mousemove when the mouse's middle button is pressed 4573 */ 4574 4575 4576 function addMiddleWheelHandler() { 4577 getContainer().addEventListener('mousedown', mouseDownHandler); 4578 getContainer().addEventListener('mouseup', mouseUpHandler); 4579 } 4580 /** 4581 * Removes the auto scrolling action fired by the mouse wheel and trackpad. 4582 * After this function is called, the mousewheel and trackpad movements won't scroll through sections. 4583 */ 4584 4585 4586 function removeMouseWheelHandler() { 4587 if (doc.addEventListener) { 4588 docRemoveEvent('mousewheel', MouseWheelHandler, false); //IE9, Chrome, Safari, Oper 4589 4590 docRemoveEvent('wheel', MouseWheelHandler, false); //Firefox 4591 4592 docRemoveEvent('MozMousePixelScroll', MouseWheelHandler, false); //old Firefox 4593 } else { 4594 // @ts-ignore 4595 doc.detachEvent('onmousewheel', MouseWheelHandler); //IE 6/7/8 4596 } 4597 } 4598 /** 4599 * Unbinding the mousemove when the mouse's middle button is released 4600 */ 4601 4602 4603 function removeMiddleWheelHandler() { 4604 getContainer().removeEventListener('mousedown', mouseDownHandler); 4605 getContainer().removeEventListener('mouseup', mouseUpHandler); 4606 } 4607 /** 4608 * Detecting mousewheel scrolling 4609 * 4610 * http://blogs.sitepointstatic.com/examples/tech/mouse-wheel/index.html 4611 * http://www.sitepoint.com/html5-javascript-mouse-wheel/ 4612 */ 4613 4614 4615 function MouseWheelHandler(e) { 4616 var curTime = new Date().getTime(); 4617 var isNormalScroll = hasClass($(COMPLETELY_SEL)[0], NORMAL_SCROLL); 4618 var isScrollAllowedBeyondFullPage = beyondFullPageHandler(getContainer(), e); 4619 4620 if (!state.isUsingWheel) { 4621 setState({ 4622 isGrabbing: false, 4623 isUsingWheel: true, 4624 touchDirection: 'none' 4625 }); 4626 } //is scroll allowed? 4627 4628 4629 if (!getIsScrollAllowed().m.down && !getIsScrollAllowed().m.up) { 4630 preventDefault(e); 4631 return false; 4632 } 4633 4634 if (isScrollAllowedBeyondFullPage) { 4635 return true; 4636 } else if (isScrollAllowedBeyondFullPage === false) { 4637 preventDefault(e); 4638 return false; 4639 } //autoscrolling and not zooming? 4640 4641 4642 if (getOptions().autoScrolling && !getControlPressed() && !isNormalScroll) { 4643 // cross-browser wheel delta 4644 e = e || win.event; 4645 var value = e.wheelDelta || -e.deltaY || -e.detail; 4646 var delta = Math.max(-1, Math.min(1, value)); 4647 var horizontalDetection = typeof e.wheelDeltaX !== 'undefined' || typeof e.deltaX !== 'undefined'; 4648 var isScrollingVertically = Math.abs(e.wheelDeltaX) < Math.abs(e.wheelDelta) || Math.abs(e.deltaX) < Math.abs(e.deltaY) || !horizontalDetection; 4649 var direction = delta < 0 ? 'down' : delta > 0 ? 'up' : 'none'; //Limiting the array to 150 (lets not waste memory!) 4650 4651 if (scrollings.length > 149) { 4652 scrollings.shift(); 4653 } //keeping record of the previous scrollings 4654 4655 4656 scrollings.push(Math.abs(value)); //preventing to scroll the site on mouse wheel when scrollbar is present 4657 4658 if (getOptions().scrollBar) { 4659 preventDefault(e); 4660 } //time difference between the last scroll and the current one 4661 4662 4663 var timeDiff = curTime - prevTime; 4664 prevTime = curTime; //haven't they scrolled in a while? 4665 //(enough to be consider a different scrolling action to scroll another section) 4666 4667 if (timeDiff > 200) { 4668 //emptying the array, we dont care about old scrollings for our averages 4669 scrollings = []; 4670 } 4671 4672 setState({ 4673 wheelDirection: direction 4674 }); 4675 4676 if (state.canScroll) { 4677 var averageEnd = getAverage(scrollings, 10); 4678 var averageMiddle = getAverage(scrollings, 70); 4679 var isAccelerating = averageEnd >= averageMiddle; //to avoid double swipes... 4680 4681 if (isAccelerating && isScrollingVertically) { 4682 setState({ 4683 scrollTrigger: 'wheel' 4684 }); //scrolling down? 4685 4686 if (delta < 0) { 4687 scrolling('down'); 4688 } //scrolling up? 4689 else { 4690 scrolling('up'); 4691 } 4692 } 4693 } 4694 4695 return false; 4696 } 4697 4698 if (getOptions().fitToSection) { 4699 //stopping the auto scroll to adjust to a section 4700 setState({ 4701 activeAnimation: false 4702 }); 4703 } 4704 } //binding the mousemove when the mouse's middle button is released 4705 4706 4707 function mouseDownHandler(e) { 4708 //middle button 4709 if (e.which == 2) { 4710 setOldPageY(e.pageY); 4711 getContainer().addEventListener('mousemove', mouseMoveHandler); 4712 } 4713 } //unbinding the mousemove when the mouse's middle button is released 4714 4715 4716 function mouseUpHandler(e) { 4717 //middle button 4718 if (e.which == 2) { 4719 getContainer().removeEventListener('mousemove', mouseMoveHandler); 4720 } 4721 } 4722 /** 4723 * Adds or remove the mouse wheel hijacking 4724 */ 4725 4726 4727 function setMouseHijack(value) { 4728 if (value) { 4729 setMouseWheelScrolling(true); 4730 addTouchHandler(); 4731 } else { 4732 setMouseWheelScrolling(false); 4733 removeTouchHandler(); 4734 } 4735 } 4736 4737 var g_canFireMouseEnterNormalScroll = true; 4738 EventEmitter.on(events.bindEvents, bindEvents$7); 4739 4740 function bindEvents$7() { 4741 /** 4742 * Applying normalScroll elements. 4743 * Ignoring the scrolls over the specified selectors. 4744 */ 4745 if (getOptions().normalScrollElements) { 4746 ['mouseenter', 'touchstart'].forEach(function (eventName) { 4747 forMouseLeaveOrTouch(eventName, false); 4748 }); 4749 ['mouseleave', 'touchend'].forEach(function (eventName) { 4750 forMouseLeaveOrTouch(eventName, true); 4751 }); 4752 } 4753 4754 EventEmitter.on(events.onDestroy, onDestroy$4); 4755 } 4756 4757 function onDestroy$4() { 4758 ['mouseenter', 'touchstart', 'mouseleave', 'touchend'].forEach(function (eventName) { 4759 docRemoveEvent(eventName, onMouseEnterOrLeave, true); //true is required! 4760 }); 4761 } 4762 4763 function forMouseLeaveOrTouch(eventName, allowScrolling) { 4764 //a way to pass arguments to the onMouseEnterOrLeave function 4765 document['fp_' + eventName] = allowScrolling; 4766 docAddEvent(eventName, onMouseEnterOrLeave, true); //capturing phase 4767 } 4768 4769 function onMouseEnterOrLeave(e) { 4770 var type = e.type; 4771 var isInsideOneNormalScroll = false; //onMouseLeave will use the destination target, not the one we are moving away from 4772 4773 var target = type === 'mouseleave' ? e.toElement || e.relatedTarget : e.target; //coming from closing a normalScrollElements modal or moving outside viewport? 4774 4775 if (target == document || !target) { 4776 setMouseHijack(true); 4777 return; 4778 } 4779 4780 if (type === 'touchend') { 4781 g_canFireMouseEnterNormalScroll = false; 4782 setTimeout(function () { 4783 g_canFireMouseEnterNormalScroll = true; 4784 }, 800); 4785 } //preventing mouseenter event to do anything when coming from a touchEnd event 4786 //fixing issue #3576 4787 4788 4789 if (type === 'mouseenter' && !g_canFireMouseEnterNormalScroll) { 4790 return; 4791 } 4792 4793 var normalSelectors = getOptions().normalScrollElements.split(','); 4794 normalSelectors.forEach(function (normalSelector) { 4795 if (!isInsideOneNormalScroll) { 4796 var isNormalScrollTarget = matches(target, normalSelector); //leaving a child inside the normalScoll element is not leaving the normalScroll #3661 4797 4798 var isNormalScrollChildFocused = closest(target, normalSelector); 4799 4800 if (isNormalScrollTarget || isNormalScrollChildFocused) { 4801 if (!FP.shared.isNormalScrollElement) { 4802 setMouseHijack(false); 4803 } 4804 4805 FP.shared.isNormalScrollElement = true; 4806 isInsideOneNormalScroll = true; 4807 } 4808 } 4809 }); //not inside a single normal scroll element anymore? 4810 4811 if (!isInsideOneNormalScroll && FP.shared.isNormalScrollElement) { 4812 setMouseHijack(true); 4813 FP.shared.isNormalScrollElement = false; 4814 } 4815 } 4816 4817 FP.silentMoveTo = silentMoveTo; 4818 /** 4819 * Moves the page to the given section and slide with no animation. 4820 * Anchors or index positions can be used as params. 4821 */ 4822 4823 function silentMoveTo(sectionAnchor, slideAnchor) { 4824 setScrollingSpeed(0, 'internal'); 4825 moveTo$1(sectionAnchor, slideAnchor); 4826 setScrollingSpeed(getOriginals().scrollingSpeed, 'internal'); 4827 } 4828 4829 var previousHeight = getWindowHeight(); 4830 var windowsWidth = getWindowWidth(); 4831 var g_resizeId; 4832 var g_isConsecutiveResize = false; 4833 var g_resizeMobileHandlerId; 4834 FP.reBuild = reBuild; 4835 EventEmitter.on(events.bindEvents, bindEvents$6); 4836 4837 function bindEvents$6() { 4838 // Setting VH correctly in mobile devices 4839 resizeHandler(); //when resizing the site, we adjust the heights of the sections, slimScroll... 4840 4841 windowAddEvent('resize', resizeHandler); 4842 EventEmitter.on(events.onDestroy, onDestroy$3); 4843 } 4844 4845 function onDestroy$3() { 4846 clearTimeout(g_resizeId); 4847 clearTimeout(g_resizeMobileHandlerId); 4848 windowRemoveEvent('resize', resizeHandler); 4849 } 4850 /* 4851 * Resize event handler. 4852 */ 4853 4854 4855 function resizeHandler() { 4856 if (!g_isConsecutiveResize) { 4857 if (getOptions().autoScrolling && !getOptions().scrollBar || !getOptions().fitToSection) { 4858 setSectionsHeight(getWindowHeight()); 4859 } 4860 } 4861 4862 fitToActiveSection(); 4863 g_isConsecutiveResize = true; //in order to call the functions only when the resize is finished 4864 //http://stackoverflow.com/questions/4298612/jquery-how-to-call-resize-event-only-once-its-finished-resizing 4865 4866 clearTimeout(g_resizeId); 4867 g_resizeId = setTimeout(function () { 4868 //issue #3336 4869 //(some apps or browsers, like Chrome/Firefox for Mobile take time to report the real height) 4870 //so we check it 3 times with intervals in that case 4871 // for(var i = 0; i< 4; i++){ 4872 resizeActions(); 4873 g_isConsecutiveResize = false; // } 4874 }, 400); 4875 } 4876 4877 function fitToActiveSection() { 4878 if (isTouchDevice) { 4879 // Issue #4393 and previously in v3, #3336 4880 // (some apps or browsers, like Chrome/Firefox will delay a bit to scroll 4881 // to the focused input 4882 for (var i = 0; i < 4; i++) { 4883 g_resizeMobileHandlerId = setTimeout(function () { 4884 window.requestAnimationFrame(function () { 4885 // on Android devices the browser scrolls to the focused element 4886 // messing up the whole page structure. So we need to update the 4887 // translate3d value when the keyboard shows/hides 4888 if (getOptions().autoScrolling && !getOptions().scrollBar) { 4889 setState({ 4890 isResizing: true 4891 }); 4892 silentMoveTo(state.activeSection.index() + 1); 4893 setState({ 4894 isResizing: false 4895 }); 4896 } 4897 }); 4898 }, 200 * i); 4899 } 4900 } 4901 } 4902 /** 4903 * When resizing the site, we adjust the heights of the sections, slimScroll... 4904 */ 4905 4906 4907 function resizeActions() { 4908 setState({ 4909 isResizing: true 4910 }); 4911 setSectionsHeight(''); 4912 4913 if (!getOptions().autoScrolling && !state.isBeyondFullpage) { 4914 setVhUnits(); 4915 } 4916 4917 EventEmitter.emit(events.contentChanged); 4918 updateState(); //checking if it needs to get responsive 4919 4920 responsive(); // rebuild immediately on touch devices 4921 4922 if (isTouchDevice) { 4923 var activeElement = doc.activeElement; //if the keyboard is NOT visible 4924 4925 if (!matches(activeElement, 'textarea') && !matches(activeElement, 'input') && !matches(activeElement, 'select')) { 4926 var currentHeight = getWindowHeight(); //making sure the change in the viewport size is enough to force a rebuild. (20 % of the window to avoid problems when hidding scroll bars) 4927 4928 if (Math.abs(currentHeight - previousHeight) > 20 * Math.max(previousHeight, currentHeight) / 100) { 4929 reBuild(true); 4930 previousHeight = currentHeight; 4931 } 4932 } 4933 } else { 4934 adjustToNewViewport(); 4935 } 4936 4937 setState({ 4938 isResizing: false 4939 }); 4940 } 4941 /** 4942 * When resizing is finished, we adjust the slides sizes and positions 4943 */ 4944 4945 4946 function reBuild(resizing) { 4947 if (hasClass(getContainer(), DESTROYED)) { 4948 return; 4949 } //nothing to do if the plugin was destroyed 4950 //updating global vars 4951 4952 4953 setState({ 4954 isResizing: true, 4955 windowsHeight: getWindowHeight(), 4956 windowsWidth: getWindowWidth() 4957 }); 4958 var sections = getState().sections; 4959 4960 for (var i = 0; i < sections.length; ++i) { 4961 var section = sections[i]; 4962 var slidesWrap = $(SLIDES_WRAPPER_SEL, section.item)[0]; 4963 var slides = section.slides; //adjusting the position fo the FULL WIDTH slides... 4964 4965 if (slides.length > 1) { 4966 landscapeScroll(slidesWrap, section.activeSlide.item); 4967 } 4968 } 4969 4970 if (getOptions().scrollOverflow) { 4971 scrollOverflowHandler.makeScrollable(); 4972 } 4973 4974 var sectionIndex = getState().activeSection.index(); 4975 4976 if (!state.isBeyondFullpage) { 4977 //isn't it the first section? 4978 if (sectionIndex) { 4979 //adjusting the position for the current section 4980 silentMoveTo(sectionIndex + 1); 4981 } 4982 } 4983 4984 setState({ 4985 isResizing: false 4986 }); 4987 4988 if (isFunction(getOptions().afterResize) && resizing) { 4989 getOptions().afterResize.call(getContainer(), win.innerWidth, win.innerHeight); 4990 } 4991 4992 if (isFunction(getOptions().afterReBuild) && !resizing) { 4993 getOptions().afterReBuild.call(getContainer()); 4994 } 4995 4996 trigger(getContainer(), 'afterRebuild'); 4997 } 4998 /** 4999 * Adjusts a section to the viewport if it has changed. 5000 */ 5001 5002 5003 function adjustToNewViewport() { 5004 var newWindowHeight = getWindowHeight(); 5005 var newWindowWidth = getWindowWidth(); 5006 5007 if (state.windowsHeight !== newWindowHeight || windowsWidth !== newWindowWidth) { 5008 setState({ 5009 windowsHeight: newWindowHeight 5010 }); 5011 windowsWidth = newWindowWidth; 5012 reBuild(true); 5013 } 5014 } 5015 5016 function setSectionsHeight(value) { 5017 var propertyValue = value === '' ? '' : value + 'px'; 5018 getState().sections.forEach(function (section) { 5019 css(section.item, { 5020 'height': propertyValue 5021 }); 5022 }); 5023 } 5024 /** 5025 * Defining the value in px of a VH unit. (Used for autoScrolling: false) 5026 * To fix the height issue on mobile devices when using VH units. 5027 * https://css-tricks.com/the-trick-to-viewport-units-on-mobile/ 5028 */ 5029 5030 5031 function setVhUnits() { 5032 if (!getOptions().autoScrolling || getOptions().scrollBar) { 5033 // First we get the viewport height and we multiple it by 1% to get a value for a vh unit 5034 var vh = win.innerHeight * 0.01; // Then we set the value in the --vh custom property to the root of the document 5035 5036 doc.documentElement.style.setProperty('--vh', "".concat(vh, "px")); 5037 } 5038 } 5039 5040 function getAnchorsURL() { 5041 var section; 5042 var slide; 5043 var hash = win.location.hash; 5044 5045 if (hash.length) { 5046 //getting the anchor link in the URL and deleting the `#` 5047 var anchorsParts = hash.replace('#', '').split('/'); //using / for visual reasons and not as a section/slide separator #2803 5048 5049 var isFunkyAnchor = hash.indexOf('#/') > -1; 5050 section = isFunkyAnchor ? '/' + anchorsParts[1] : decodeURIComponent(anchorsParts[0]); 5051 var slideAnchor = isFunkyAnchor ? anchorsParts[2] : anchorsParts[1]; 5052 5053 if (slideAnchor && slideAnchor.length) { 5054 slide = decodeURIComponent(slideAnchor); 5055 } 5056 } 5057 5058 return { 5059 section: section, 5060 slide: slide 5061 }; 5062 } 5063 5064 FP.setLockAnchors = setLockAnchors; 5065 EventEmitter.on(events.bindEvents, bindEvents$5); 5066 5067 function bindEvents$5() { 5068 //detecting any change on the URL to scroll to the given anchor link 5069 //(a way to detect back history button as we play with the hashes on the URL) 5070 windowAddEvent('hashchange', hashChangeHandler); 5071 EventEmitter.on(events.onDestroy, onDestroy$2); 5072 } 5073 5074 function onDestroy$2() { 5075 windowRemoveEvent('hashchange', hashChangeHandler); 5076 } 5077 /** 5078 * Sets lockAnchors 5079 */ 5080 5081 5082 function setLockAnchors(value) { 5083 getOptions().lockAnchors = value; 5084 } 5085 /** 5086 * Detecting any change on the URL to scroll to the given anchor link 5087 * (a way to detect back history button as we play with the hashes on the URL) 5088 */ 5089 5090 5091 function hashChangeHandler() { 5092 if (!state.isScrolling && !getOptions().lockAnchors) { 5093 var anchors = getAnchorsURL(); 5094 var sectionAnchor = anchors.section; 5095 var slideAnchor = anchors.slide; //when moving to a slide in the first section for the first time (first time to add an anchor to the URL) 5096 5097 var isFirstSlideMove = typeof state.lastScrolledDestiny === 'undefined'; 5098 var isFirstScrollMove = typeof state.lastScrolledDestiny === 'undefined' && typeof slideAnchor === 'undefined' && !state.slideMoving; 5099 5100 if (sectionAnchor && sectionAnchor.length) { 5101 /*in order to call scrollpage() only once for each destination at a time 5102 It is called twice for each scroll otherwise, as in case of using anchorlinks `hashChange` 5103 event is fired on every scroll too.*/ 5104 if (sectionAnchor && sectionAnchor !== state.lastScrolledDestiny && !isFirstSlideMove || isFirstScrollMove || !state.slideMoving && state.lastScrolledSlide != slideAnchor) { 5105 EventEmitter.emit(events.onScrollPageAndSlide, { 5106 sectionAnchor: sectionAnchor, 5107 slideAnchor: slideAnchor 5108 }); 5109 } 5110 } 5111 } 5112 } 5113 5114 EventEmitter.on(events.bindEvents, bindEvents$4); 5115 5116 function bindEvents$4() { 5117 docAddEvent('wheel', wheelDataHandler.registerEvent, getPassiveOptionsIfPossible()); 5118 EventEmitter.on(events.scrollBeyondFullpage, scrollBeyondFullPage); 5119 EventEmitter.on(events.onKeyDown, onKeyDown); 5120 } 5121 5122 EventEmitter.on(events.bindEvents, bindEvents$3); 5123 5124 function bindEvents$3() { 5125 EventEmitter.on(events.onClickOrTouch, onClickOrTouch$1); 5126 } 5127 5128 function onClickOrTouch$1(params) { 5129 var target = params.target; 5130 5131 if (closest(target, getOptions().menu + ' [data-menuanchor]')) { 5132 menuItemsHandler.call(target, params); 5133 } 5134 } //Menu item handler when not using anchors or using lockAnchors:true 5135 5136 5137 function menuItemsHandler(e) { 5138 setState({ 5139 scrollTrigger: 'menu' 5140 }); 5141 5142 if ($(getOptions().menu)[0] && (getOptions().lockAnchors || !getOptions().anchors.length)) { 5143 preventDefault(e); 5144 /*jshint validthis:true */ 5145 5146 EventEmitter.emit(events.onMenuClick, { 5147 anchor: getAttr(this, 'data-menuanchor') 5148 }); 5149 } 5150 } 5151 5152 EventEmitter.on(events.bindEvents, bindEvents$2); 5153 5154 function bindEvents$2() { 5155 EventEmitter.on(events.onClickOrTouch, onClickOrTouch); 5156 } 5157 5158 function onClickOrTouch(params) { 5159 var target = params.target; 5160 5161 if (target && closest(target, SECTION_NAV_SEL + ' a')) { 5162 sectionBulletHandler.call(target, params.e); 5163 } else if (matches(target, SECTION_NAV_TOOLTIP_SEL)) { 5164 tooltipTextHandler.call(target); 5165 } else if (matches(target, SLIDES_NAV_LINK_SEL) || closest(target, SLIDES_NAV_LINK_SEL) != null) { 5166 slideBulletHandler.call(target, params.e); 5167 } 5168 } 5169 5170 var lastScroll = 0; 5171 var g_scrollId; 5172 var g_scrollId2; 5173 EventEmitter.on(events.onDestroy, onDestroy$1); //when scrolling... 5174 5175 function scrollHandler(e) { 5176 var currentSection; 5177 var currentSectionElem; 5178 5179 if (state.isResizing || !getState().activeSection) { 5180 return; 5181 } 5182 5183 getLast(getState().sections); 5184 5185 if (getState().isBeyondFullpage || getState().isAboutToScrollToFullPage) { 5186 return; 5187 } 5188 5189 if (!getOptions().autoScrolling || getOptions().scrollBar) { 5190 var currentScroll = getScrollTop(); 5191 var scrollDirection = getScrollDirection(currentScroll); 5192 var visibleSectionIndex = 0; 5193 var screen_mid = currentScroll + getWindowHeight() / 2.0; 5194 var isAtBottom = $body.scrollHeight - getWindowHeight() === currentScroll; 5195 var sections = getState().sections; 5196 setState({ 5197 scrollY: currentScroll 5198 }); //when using `auto-height` for a small last section it won't be centered in the viewport 5199 5200 if (isAtBottom) { 5201 visibleSectionIndex = sections.length - 1; 5202 } //is at top? when using `auto-height` for a small first section it won't be centered in the viewport 5203 else if (!currentScroll) { 5204 visibleSectionIndex = 0; 5205 } //taking the section which is showing more content in the viewport 5206 else { 5207 for (var i = 0; i < sections.length; ++i) { 5208 var section = sections[i].item; // Pick the the last section which passes the middle line of the screen. 5209 5210 if (section.offsetTop <= screen_mid) { 5211 visibleSectionIndex = i; 5212 } 5213 } 5214 } 5215 5216 if (isCompletelyInViewPort(scrollDirection)) { 5217 if (!hasClass(getState().activeSection.item, COMPLETELY)) { 5218 addClass(getState().activeSection.item, COMPLETELY); 5219 removeClass(siblings(getState().activeSection.item), COMPLETELY); 5220 } 5221 } //geting the last one, the current one on the screen 5222 5223 5224 currentSection = sections[visibleSectionIndex]; 5225 currentSectionElem = currentSection.item; //setting the visible section as active when manually scrolling 5226 //executing only once the first time we reach the section 5227 5228 if (!currentSection.isActive) { 5229 setState({ 5230 isScrolling: true 5231 }); 5232 var leavingSection = getState().activeSection.item; 5233 var leavingSectionIndex = getState().activeSection.index() + 1; 5234 var yMovement = getYmovement(getState().activeSection, currentSectionElem); 5235 var anchorLink = currentSection.anchor; 5236 var sectionIndex = currentSection.index() + 1; 5237 var activeSlide = currentSection.activeSlide; 5238 var slideIndex; 5239 var slideAnchorLink; 5240 var callbacksParams = { 5241 activeSection: leavingSection, 5242 sectionIndex: sectionIndex - 1, 5243 anchorLink: anchorLink, 5244 element: currentSectionElem, 5245 leavingSection: leavingSectionIndex, 5246 direction: yMovement, 5247 items: { 5248 origin: getState().activeSection, 5249 destination: currentSection 5250 } 5251 }; 5252 5253 if (activeSlide) { 5254 slideAnchorLink = activeSlide.anchor; 5255 slideIndex = activeSlide.index(); 5256 } 5257 5258 if (state.canScroll) { 5259 addClass(currentSectionElem, ACTIVE); 5260 removeClass(siblings(currentSectionElem), ACTIVE); 5261 5262 if (isFunction(getOptions().beforeLeave)) { 5263 fireCallbackOncePerScroll('beforeLeave', callbacksParams); 5264 } 5265 5266 if (isFunction(getOptions().onLeave)) { 5267 fireCallback('onLeave', callbacksParams); 5268 } 5269 5270 if (isFunction(getOptions().afterLoad)) { 5271 fireCallback('afterLoad', callbacksParams); 5272 } 5273 5274 stopMedia(leavingSection); 5275 lazyLoad(currentSectionElem); 5276 playMedia(currentSectionElem); 5277 activateMenuAndNav(anchorLink, sectionIndex - 1); 5278 5279 if (getOptions().anchors.length) { 5280 //needed to enter in hashChange event when using the menu with anchor links 5281 setState({ 5282 lastScrolledDestiny: anchorLink 5283 }); 5284 } 5285 5286 setPageStatus(slideIndex, slideAnchorLink, anchorLink); 5287 updateState(); 5288 } //small timeout in order to avoid entering in hashChange event when scrolling is not finished yet 5289 5290 5291 clearTimeout(g_scrollId); 5292 g_scrollId = setTimeout(function () { 5293 setState({ 5294 isScrolling: false 5295 }); 5296 }, 100); 5297 } 5298 5299 if (getOptions().fitToSection && state.canScroll) { 5300 clearTimeout(g_scrollId2); 5301 g_scrollId2 = setTimeout(function () { 5302 var fixedSections = state.sections.filter(function (section) { 5303 var sectionValues = section.item.getBoundingClientRect(); 5304 return Math.round(sectionValues.bottom) === Math.round(getWindowHeight()) || Math.round(sectionValues.top) === 0; 5305 }); // No section is fitting the viewport? Let's fix that! 5306 5307 if (!fixedSections.length) { 5308 fitToSection(); 5309 } 5310 }, getOptions().fitToSectionDelay); 5311 } 5312 } 5313 } 5314 5315 function onDestroy$1() { 5316 clearTimeout(g_scrollId); 5317 clearTimeout(g_scrollId2); 5318 } 5319 /** 5320 * Gets the directon of the the scrolling fired by the scroll event. 5321 */ 5322 5323 5324 function getScrollDirection(currentScroll) { 5325 var direction = currentScroll > lastScroll ? 'down' : 'up'; 5326 lastScroll = currentScroll; //needed for auto-height sections to determine if we want to scroll to the top or bottom of the destination 5327 5328 setState({ 5329 previousDestTop: currentScroll 5330 }); 5331 return direction; 5332 } 5333 /** 5334 * Determines whether the active section has seen in its whole or not. 5335 */ 5336 5337 5338 function isCompletelyInViewPort(movement) { 5339 var top = getState().activeSection.item.offsetTop; 5340 var bottom = top + getWindowHeight(); 5341 5342 if (movement == 'up') { 5343 return bottom >= getScrollTop() + getWindowHeight(); 5344 } 5345 5346 return top <= getScrollTop(); 5347 } 5348 5349 EventEmitter.on(events.bindEvents, bindEvents$1); 5350 EventEmitter.on(events.onDestroy, onDestroy); 5351 5352 function onDestroy() { 5353 windowRemoveEvent('scroll', scrollHandler); 5354 } 5355 5356 function bindEvents$1() { 5357 windowAddEvent('scroll', scrollHandler); 5358 doc.body.addEventListener('scroll', scrollHandler); 5359 EventEmitter.on(events.onScrollPageAndSlide, function (params) { 5360 scrollPageAndSlide(params.sectionAnchor, params.slideAnchor); 5361 }); 5362 EventEmitter.on(events.onMenuClick, function (params) { 5363 moveTo$1(params.anchor, undefined); 5364 }); 5365 EventEmitter.on(events.onScrollOverflowScrolled, function (params) { 5366 var scrollSection = params.direction === 'down' ? moveSectionDown : moveSectionUp; 5367 scrollSection(); 5368 }); 5369 EventEmitter.on(events.scrollPage, function (params) { 5370 scrollPage(params.destination); 5371 }); 5372 } 5373 5374 FP.getActiveSlide = getActiveSlide; 5375 5376 FP.getScrollX = function () { 5377 return state.scrollX; 5378 }; 5379 5380 EventEmitter.on(events.bindEvents, bindEvents); 5381 5382 function bindEvents() { 5383 EventEmitter.on(events.onDestroy, onDestroy$6); 5384 EventEmitter.on(events.landscapeScroll, function (params) { 5385 landscapeScroll(params.slides, params.destination); 5386 }); 5387 EventEmitter.on(events.moveSlideRight, function (params) { 5388 moveSlideRight(params.section); 5389 }); 5390 EventEmitter.on(events.moveSlideLeft, function (params) { 5391 moveSlideLeft(params.section); 5392 }); 5393 } 5394 /** 5395 * Gets the active slide. 5396 */ 5397 5398 5399 function getActiveSlide() { 5400 return nullOrSlide(getState().activeSection.activeSlide); 5401 } 5402 5403 EventEmitter.on(events.bindEvents, init$1); 5404 5405 function init$1() { 5406 var position = getOptions().credits.position || 'right'; 5407 var positionStyle = ['left', 'right'].indexOf(position) > -1 ? "".concat(position, ": 0;") : ''; 5408 var waterMark = "\n <div class=\"fp-watermark\" style=\"".concat(positionStyle, "\">\n <a href=\"https://alvarotrigo.com/fullPage/\" \n rel=\"nofollow noopener\" \n target=\"_blank\" \n style=\"text-decoration:none; color: #000;\">\n ").concat(getOptions().credits.label || 'Made with fullPage.js', "\n </a>\n </div>\n "); 5409 var lastSection = getLast(state.sections); 5410 var shouldUseWaterMark = !state.isValid || getOptions().credits.enabled; 5411 5412 if (lastSection && lastSection.item && shouldUseWaterMark) { 5413 lastSection.item.insertAdjacentHTML('beforeend', waterMark); 5414 } 5415 } 5416 5417 !function () { 5418 EventEmitter.on(events.onInitialise, function () { 5419 var n, a, l; 5420 setState({ 5421 isValid: (getOptions().licenseKey, n = getOptions().licenseKey, a = function (n) { 5422 var e = parseInt("\x35\x31\x34").toString(16); 5423 if (!n || n.length < 29 || 4 === n.split(t[0]).length) return null; 5424 var r = ["\x45\x61\x63\x68", "\x66\x6f\x72"][i()]().join(""), 5425 a = n[["\x73\x70\x6c\x69\x74"]]("-"), 5426 l = []; 5427 a[r](function (t, n) { 5428 if (n < 4) { 5429 var r = function (t) { 5430 var n = t[t.length - 1], 5431 e = ["\x4e\x61\x4e", "\x69\x73"][i()]().join(""); 5432 return window[e](n) ? o(n) : function (t) { 5433 return t - ACTIVE.length; 5434 }(n); 5435 }(t); 5436 5437 l.push(r); 5438 var s = o(t[r]); 5439 5440 if (1 === n) { 5441 var a = ["\x70\x61", "\x64\x53", "\x74", "\x61\x72\x74"].join(""); 5442 s = s.toString()[a](2, "0"); 5443 } 5444 5445 e += s, 0 !== n && 1 !== n || (e += "-"); 5446 } 5447 }); 5448 var m = 0, 5449 f = ""; 5450 return n.split("-").forEach(function (t, n) { 5451 if (n < 4) { 5452 var _i = 0; 5453 5454 for (var e = 0; e < 4; e++) { 5455 e !== l[n] && (_i += Math.abs(o(t[e])), isNaN(t[e]) || m++); 5456 } 5457 5458 var r = s(_i); 5459 f += r; 5460 } 5461 }), f += s(m), { 5462 v: new Date(e + "T00:00"), 5463 o: e.split("-")[2] === 8 * (ACTIVE.length - 2) + "", 5464 l: f 5465 }; 5466 }(n), l = function (t) { 5467 var n = r[i()]().join(""); 5468 return t && 0 === n.indexOf(t) && t.length === n.length; 5469 }(n), (a || l) && (a && e <= a.v && a.l === n.split(t[0])[4] || l || a.o) || !1) 5470 }); 5471 }); 5472 var t = ["-"]; 5473 var n = "\x32\x30\x32\x33\x2d\x31\x2d\x31\x36".split("-"), 5474 e = new Date(n[0], n[1], n[2]), 5475 r = ["se", "licen", "-", "v3", "l", "gp"]; 5476 5477 function i() { 5478 return [["\x72\x65", "\x76\x65\x72\x73\x65"].join("")]["".length]; 5479 } 5480 5481 function o(t) { 5482 return t ? isNaN(t) ? t.charCodeAt(0) - 72 : t : ""; 5483 } 5484 5485 function s(t) { 5486 var n = 72 + t; 5487 return n > 90 && n < 97 && (n += 15), String.fromCharCode(n).toUpperCase(); 5488 } 5489 }(); 5490 5491 //@ts-check 5492 FP.setKeyboardScrolling = setKeyboardScrolling; 5493 /** 5494 * Adds or remove the possibility of scrolling through sections by using the keyboard arrow keys 5495 */ 5496 5497 function setKeyboardScrolling(value, directions) { 5498 if (typeof directions !== 'undefined') { 5499 directions = directions.replace(/ /g, '').split(','); 5500 directions.forEach(function (direction) { 5501 setIsScrollAllowed(value, direction, 'k'); 5502 }); 5503 } else { 5504 setIsScrollAllowed(value, 'all', 'k'); 5505 getOptions().keyboardScrolling = value; 5506 } 5507 } 5508 5509 /** 5510 * Sets the data-anchor attributes to the menu elements and activates the current one. 5511 */ 5512 5513 function styleMenu(section) { 5514 var index = section.index(); 5515 5516 if (typeof getOptions().anchors[index] !== 'undefined') { 5517 //activating the menu / nav element on load 5518 if (section.isActive) { 5519 activateMenuAndNav(getOptions().anchors[index], index); 5520 } 5521 } //moving the menu outside the main container if it is inside (avoid problems with fixed positions when using CSS3 tranforms) 5522 5523 5524 if (getOptions().menu && getOptions().css3 && closest($(getOptions().menu)[0], WRAPPER_SEL) != null) { 5525 $(getOptions().menu).forEach(function (menu) { 5526 $body.appendChild(menu); 5527 }); 5528 } 5529 } 5530 5531 /** 5532 * Works over the DOM structure to set it up for the current fullpage getOptions(). 5533 */ 5534 5535 function prepareDom() { 5536 css(getParentsUntil(getContainer(), 'body'), { 5537 'height': '100%', 5538 'position': 'relative' 5539 }); //adding a class to recognize the container internally in the code 5540 5541 addClass(getContainer(), WRAPPER); 5542 addClass($html, ENABLED); //due to https://github.com/alvarotrigo/fullPage.js/issues/1502 5543 5544 setState({ 5545 windowsHeight: getWindowHeight() 5546 }); 5547 removeClass(getContainer(), DESTROYED); //in case it was destroyed before initializing it again 5548 5549 addInternalSelectors(); 5550 var sections = getState().sectionsIncludingHidden; //styling the sections / slides / menu 5551 5552 for (var i = 0; i < sections.length; i++) { 5553 var section = sections[i]; 5554 var slides = section.allSlidesItems; //caching the original styles to add them back on destroy('all') 5555 5556 section.item.setAttribute('data-fp-styles', getAttr(section.item, 'style')); 5557 styleSection(section); 5558 styleMenu(section); // if there's any slide 5559 5560 if (slides.length > 0) { 5561 styleSlides(section); 5562 } 5563 } //fixed elements need to be moved out of the plugin container due to problems with CSS3. 5564 5565 5566 if (getOptions().fixedElements && getOptions().css3) { 5567 $(getOptions().fixedElements).forEach(function (item) { 5568 $body.appendChild(item); 5569 }); 5570 } //vertical centered of the navigation + active bullet 5571 5572 5573 if (getOptions().navigation) { 5574 addVerticalNavigation(); 5575 } 5576 5577 enableYoutubeAPI(); 5578 5579 if (getOptions().scrollOverflow) { 5580 scrollOverflowHandler.makeScrollable(); 5581 } 5582 } 5583 5584 FP.shared.afterRenderActions = afterRenderActions; 5585 /** 5586 * Actions and callbacks to fire afterRender 5587 */ 5588 5589 function afterRenderActions() { 5590 var section = getState().activeSection; 5591 var sectionElem = getState().activeSection.item; 5592 addClass(sectionElem, COMPLETELY); 5593 lazyLoad(sectionElem); 5594 lazyLoadOthers(); 5595 playMedia(sectionElem); 5596 5597 if (isDestinyTheStartingSection() && isFunction(getOptions().afterLoad)) { 5598 fireCallback('afterLoad', { 5599 activeSection: sectionElem, 5600 element: sectionElem, 5601 direction: null, 5602 //for backwards compatibility callback (to be removed in a future!) 5603 anchorLink: section.anchor, 5604 sectionIndex: section.index(), 5605 items: { 5606 origin: getState().activeSection, 5607 destination: getState().activeSection 5608 } 5609 }); 5610 } 5611 5612 if (isFunction(getOptions().afterRender)) { 5613 fireCallback('afterRender'); 5614 } 5615 } 5616 /** 5617 * Determines if the URL anchor destiny is the starting section (the one using 'active' class before initialization) 5618 */ 5619 5620 function isDestinyTheStartingSection() { 5621 var anchor = getAnchorsURL(); 5622 var destinationSection = getSectionByAnchor(anchor.section); 5623 return !anchor.section || !destinationSection || typeof destinationSection !== 'undefined' && destinationSection.index() === index(getStartingSection()); 5624 } 5625 5626 FP.setAllowScrolling = setAllowScrolling; 5627 /** 5628 * Adds or remove the possibility of scrolling through sections by using the mouse wheel/trackpad or touch gestures. 5629 * Optionally a second parameter can be used to specify the direction for which the action will be applied. 5630 * 5631 * @param directions string containing the direction or directions separated by comma. 5632 */ 5633 5634 function setAllowScrolling(value, directions) { 5635 if (typeof directions !== 'undefined') { 5636 directions = directions.replace(/ /g, '').split(','); 5637 directions.forEach(function (direction) { 5638 setIsScrollAllowed(value, direction, 'm'); 5639 }); 5640 } else { 5641 setIsScrollAllowed(value, 'all', 'm'); 5642 } 5643 } 5644 5645 /** 5646 * Scrolls to the anchor in the URL when loading the site 5647 */ 5648 5649 function scrollToAnchor() { 5650 var anchors = getAnchorsURL(); 5651 var sectionAnchor = anchors.section; 5652 var slideAnchor = anchors.slide; 5653 5654 if (sectionAnchor) { 5655 //if theres any # 5656 if (getOptions().animateAnchor) { 5657 scrollPageAndSlide(sectionAnchor, slideAnchor); 5658 } else { 5659 silentMoveTo(sectionAnchor, slideAnchor); 5660 } 5661 } else { 5662 EventEmitter.emit(events.onAfterRenderNoAnchor, null); 5663 } 5664 } 5665 5666 /* 5667 * Removes inline styles added by fullpage.js 5668 */ 5669 5670 function destroyStructure() { 5671 //reseting the `top` or `translate` properties to 0 5672 silentScroll(0); //loading all the lazy load content 5673 5674 $('img[data-src], source[data-src], audio[data-src], iframe[data-src]', getContainer()).forEach(function (item) { 5675 setSrc(item, 'src'); 5676 }); 5677 $('img[data-srcset]').forEach(function (item) { 5678 setSrc(item, 'srcset'); 5679 }); 5680 remove($(SECTION_NAV_SEL + ', ' + SLIDES_NAV_SEL + ', ' + SLIDES_ARROW_SEL)); //removing inline styles 5681 5682 css(getNodes(getState().sections), { 5683 'height': '', 5684 'background-color': '', 5685 'padding': '' 5686 }); 5687 css(getNodes(getState().slides), { 5688 'width': '' 5689 }); 5690 css(getContainer(), { 5691 'height': '', 5692 'position': '', 5693 '-ms-touch-action': '', 5694 'touch-action': '' 5695 }); 5696 css($htmlBody, { 5697 'overflow': '', 5698 'height': '' 5699 }); // remove .fp-enabled class 5700 5701 removeClass($html, ENABLED); // remove .fp-responsive class 5702 5703 removeClass($body, RESPONSIVE); // remove all of the .fp-viewing- classes 5704 5705 $body.className.split(/\s+/).forEach(function (className) { 5706 if (className.indexOf(VIEWING_PREFIX) === 0) { 5707 removeClass($body, className); 5708 } 5709 }); //removing added classes 5710 5711 getNodes(getState().panels).forEach(function (item) { 5712 if (getOptions().scrollOverflow) { 5713 scrollOverflowHandler.destroyWrapper(item); 5714 } 5715 5716 removeClass(item, TABLE + ' ' + ACTIVE + ' ' + COMPLETELY); 5717 var previousStyles = getAttr(item, 'data-fp-styles'); 5718 5719 if (previousStyles) { 5720 item.setAttribute('style', getAttr(item, 'data-fp-styles')); 5721 } //removing anchors if they were not set using the HTML markup 5722 5723 5724 if (hasClass(item, SECTION) && !getInitialAnchorsInDom()) { 5725 item.removeAttribute('data-anchor'); 5726 } 5727 }); //removing the applied transition from the fullpage wrapper 5728 5729 removeAnimation(getContainer()); //Unwrapping content 5730 5731 [TABLE_CELL_SEL, SLIDES_CONTAINER_SEL, SLIDES_WRAPPER_SEL].forEach(function (selector) { 5732 $(selector, getContainer()).forEach(function (item) { 5733 //unwrap not being use in case there's no child element inside and its just text 5734 unwrap(item); 5735 }); 5736 }); //removing the applied transition from the fullpage wrapper 5737 5738 css(getContainer(), { 5739 '-webkit-transition': 'none', 5740 'transition': 'none' 5741 }); //scrolling the page to the top with no animation 5742 5743 win.scrollTo(0, 0); //removing selectors 5744 5745 var usedSelectors = [SECTION, SLIDE, SLIDES_CONTAINER]; 5746 usedSelectors.forEach(function (item) { 5747 removeClass($('.' + item), item); 5748 }); 5749 } 5750 5751 FP.destroy = destroy; 5752 function init() { 5753 updateStructuralState(); 5754 updateState(); 5755 getOptions().scrollBar = getOptions().scrollBar || getOptions().hybrid; 5756 setOptionsFromDOM(); 5757 prepareDom(); 5758 setAllowScrolling(true); 5759 setMouseHijack(true); 5760 setAutoScrolling(getOptions().autoScrolling, 'internal'); 5761 responsive(); //setting the class for the body element 5762 5763 setBodyClass(); 5764 5765 if (doc.readyState === 'complete') { 5766 scrollToAnchor(); 5767 } 5768 5769 windowAddEvent('load', scrollToAnchor); 5770 afterRenderActions(); // Updating the state again with the new DOM 5771 5772 updateStructuralState(); 5773 updateState(); 5774 } 5775 /* 5776 * Destroys fullpage.js plugin events and optinally its html markup and styles 5777 */ 5778 5779 function destroy(all) { 5780 setAutoScrolling(false, 'internal'); 5781 setAllowScrolling(true); 5782 setMouseHijack(false); 5783 setKeyboardScrolling(false); 5784 addClass(getContainer(), DESTROYED); 5785 EventEmitter.emit(events.onDestroy); //lets make a mess! 5786 5787 if (all) { 5788 destroyStructure(); 5789 } 5790 } 5791 5792 var isOK = function isOK() { 5793 return getOptions() && state.isValid || doc.domain.indexOf('al' + 'varotri' + 'go' + '.' + 'com') > -1; 5794 }; 5795 /** 5796 * Displays warnings 5797 */ 5798 5799 5800 function displayWarnings() { 5801 var l = getOptions()['li' + 'c' + 'enseK' + 'e' + 'y']; 5802 var msgStyle = 'font-size: 15px;background:yellow;'; 5803 5804 if (getOptions().licenseKey.trim() === '') { 5805 showError('error', 'Fullpage.js requires a `licenseKey` option. Read about it on the following URL:'); 5806 showError('error', 'https://github.com/alvarotrigo/fullPage.js#options'); 5807 } else if (!isOK()) { 5808 showError('error', 'Incorrect `licenseKey`. Get one for fullPage.js version 4 here:'); 5809 showError('error', 'https://alvarotrigo.com/fullPage/pricing'); 5810 } else if (l && l.length < 20) { 5811 console.warn('%c This website was made using fullPage.js slider. More info on the following website:', msgStyle); 5812 console.warn('%c https://alvarotrigo.com/fullPage/', msgStyle); 5813 } 5814 5815 if (hasClass($html, ENABLED)) { 5816 showError('error', 'Fullpage.js can only be initialized once and you are doing it multiple times!'); 5817 return; 5818 } // Disable mutually exclusive settings 5819 5820 5821 if (getOptions().continuousVertical && (getOptions().loopTop || getOptions().loopBottom)) { 5822 getOptions().continuousVertical = false; 5823 showError('warn', 'Option `loopTop/loopBottom` is mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 5824 } 5825 5826 if (getOptions().scrollOverflow && (getOptions().scrollBar || !getOptions().autoScrolling)) { 5827 showError('warn', 'Options scrollBar:true and autoScrolling:false are mutually exclusive with scrollOverflow:true. Sections with scrollOverflow might not work well in Firefox'); 5828 } 5829 5830 if (getOptions().continuousVertical && (getOptions().scrollBar || !getOptions().autoScrolling)) { 5831 getOptions().continuousVertical = false; 5832 showError('warn', 'Scroll bars (`scrollBar:true` or `autoScrolling:false`) are mutually exclusive with `continuousVertical`; `continuousVertical` disabled'); 5833 } //using extensions? Wrong file! 5834 5835 5836 extensions.forEach(function (extension) { 5837 //is the option set to true? 5838 if (getOptions()[extension]) { 5839 showError('warn', 'fullpage.js extensions require fullpage.extensions.min.js file instead of the usual fullpage.js. Requested: ' + extension); 5840 } 5841 }); //anchors can not have the same value as any element ID or NAME 5842 5843 getOptions().anchors.forEach(function (name) { 5844 //case insensitive selectors (http://stackoverflow.com/a/19465187/1081396) 5845 var nameAttr = [].slice.call($('[name]')).filter(function (item) { 5846 return getAttr(item, 'name') && getAttr(item, 'name').toLowerCase() == name.toLowerCase(); 5847 }); 5848 var idAttr = [].slice.call($('[id]')).filter(function (item) { 5849 return getAttr(item, 'id') && getAttr(item, 'id').toLowerCase() == name.toLowerCase(); 5850 }); 5851 5852 if (idAttr.length || nameAttr.length) { 5853 showError('error', 'data-anchor tags can not have the same value as any `id` element on the site (or `name` element for IE).'); 5854 var propertyName = idAttr.length ? 'id' : 'name'; 5855 5856 if (idAttr.length || nameAttr.length) { 5857 showError('error', '"' + name + '" is is being used by another element `' + propertyName + '` property'); 5858 } 5859 } 5860 }); 5861 } 5862 5863 function fullpage(containerSelector, options) { 5864 setCache(); //only once my friend! 5865 5866 if (hasClass($html, ENABLED)) { 5867 displayWarnings(); 5868 return; 5869 } 5870 5871 setOption('touchWrapper', typeof containerSelector === 'string' ? $(containerSelector)[0] : containerSelector); // Creating some defaults, extending them with any options that were provided 5872 5873 setOptions(options); 5874 setContainer(typeof containerSelector === 'string' ? $(containerSelector)[0] : containerSelector); 5875 EventEmitter.emit(events.onInitialise); 5876 displayWarnings(); 5877 setAPI(); 5878 5879 if (getContainer()) { 5880 EventEmitter.emit(events.beforeInit); 5881 init(); 5882 EventEmitter.emit(events.bindEvents); 5883 } // @ts-ignore 5884 5885 5886 return win.fullpage_api; 5887 } 5888 5889 function setAPI() { 5890 FP.getFullpageData = function () { 5891 return { 5892 options: getOptions() 5893 }; 5894 }; //public functions 5895 5896 5897 FP.version = '4.0.17'; 5898 FP.test = Object.assign(FP.test, { 5899 top: '0px', 5900 translate3d: 'translate3d(0px, 0px, 0px)', 5901 translate3dH: function () { 5902 var a = []; 5903 5904 for (var i = 0; i < $(getOptions().sectionSelector, getContainer()).length; i++) { 5905 a.push('translate3d(0px, 0px, 0px)'); 5906 } 5907 5908 return a; 5909 }(), 5910 left: function () { 5911 var a = []; 5912 5913 for (var i = 0; i < $(getOptions().sectionSelector, getContainer()).length; i++) { 5914 a.push(0); 5915 } 5916 5917 return a; 5918 }(), 5919 options: getOptions(), 5920 setAutoScrolling: null 5921 }); //functions we want to share across files but which are not 5922 //mean to be used on their own by developers 5923 5924 FP.shared = Object.assign(FP.shared, { 5925 afterRenderActions: null, 5926 isNormalScrollElement: false 5927 }); // @ts-ignore 5928 5929 win.fullpage_api = FP; 5930 } 5931 5932 // @ts-ignore 5933 5934 win.fp_easings = deepExtend(win.fp_easings, { 5935 easeInOutCubic: function easeInOutCubic(t, b, c, d) { 5936 if ((t /= d / 2) < 1) return c / 2 * t * t * t + b; 5937 return c / 2 * ((t -= 2) * t * t + 2) + b; 5938 } 5939 }); 5940 5941 /** 5942 * jQuery adapter for fullPage.js 3.0.0 5943 */ 5944 // @ts-ignore 5945 5946 if (win.jQuery) { 5947 (function ($, fullpage) { 5948 5949 if (!$ || !fullpage) { 5950 showError('error', 'jQuery is required to use the jQuery fullpage adapter!'); 5951 return; 5952 } 5953 5954 $.fn.fullpage = function (options) { 5955 options = $.extend({}, options, { 5956 '$': $ 5957 }); 5958 new fullpage(this[0], options); // Creating the $.fn.fullpage object 5959 5960 Object.keys(FP).forEach(function (key) { 5961 getOptions().$.fn.fullpage[key] = FP[key]; 5962 }); 5963 }; // @ts-ignore 5964 5965 })(win.jQuery, fullpage); 5966 } 5967 5968 return fullpage; 5969 5970}));
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.