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