vendor: 4,783 bytes, lines 1-178
1/*! 2 * perfect-scrollbar v1.5.2 3 * Copyright 2021 Hyunje Jun, MDBootstrap and Contributors 4 * Licensed under MIT 5 */ 6 7(function (global, factory) { 8 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 9 typeof define === 'function' && define.amd ? define(factory) : 10 (global = global || self, global.PerfectScrollbar = factory()); 11}(this, (function () { 'use strict'; 12 13 function get(element) { 14 return getComputedStyle(element); 15 } 16 17 function set(element, obj) { 18 for (var key in obj) { 19 var val = obj[key]; 20 if (typeof val === 'number') { 21 val = val + "px"; 22 } 23 element.style[key] = val; 24 } 25 return element; 26 } 27 28 function div(className) { 29 var div = document.createElement('div'); 30 div.className = className; 31 return div; 32 } 33 34 var elMatches = 35 typeof Element !== 'undefined' && 36 (Element.prototype.matches || 37 Element.prototype.webkitMatchesSelector || 38 Element.prototype.mozMatchesSelector || 39 Element.prototype.msMatchesSelector); 40 41 function matches(element, query) { 42 if (!elMatches) { 43 throw new Error('No element matching method supported'); 44 } 45 46 return elMatches.call(element, query); 47 } 48 49 function remove(element) { 50 if (element.remove) { 51 element.remove(); 52 } else { 53 if (element.parentNode) { 54 element.parentNode.removeChild(element); 55 } 56 } 57 } 58 59 function queryChildren(element, selector) { 60 return Array.prototype.filter.call(element.children, function (child) { return matches(child, selector); } 61 ); 62 } 63 64 var cls = { 65 main: 'ps', 66 rtl: 'ps__rtl', 67 element: { 68 thumb: function (x) { return ("ps__thumb-" + x); }, 69 rail: function (x) { return ("ps__rail-" + x); }, 70 consuming: 'ps__child--consume', 71 }, 72 state: { 73 focus: 'ps--focus', 74 clicking: 'ps--clicking', 75 active: function (x) { return ("ps--active-" + x); }, 76 scrolling: function (x) { return ("ps--scrolling-" + x); }, 77 }, 78 }; 79 80 /* 81 * Helper methods 82 */ 83 var scrollingClassTimeout = { x: null, y: null }; 84 85 function addScrollingClass(i, x) { 86 var classList = i.element.classList; 87 var className = cls.state.scrolling(x); 88 89 if (classList.contains(className)) { 90 clearTimeout(scrollingClassTimeout[x]); 91 } else { 92 classList.add(className); 93 } 94 } 95 96 function removeScrollingClass(i, x) { 97 scrollingClassTimeout[x] = setTimeout( 98 function () { return i.isAlive && i.element.classList.remove(cls.state.scrolling(x)); }, 99 i.settings.scrollingThreshold 100 ); 101 } 102 103 function setScrollingClassInstantly(i, x) { 104 addScrollingClass(i, x); 105 removeScrollingClass(i, x); 106 } 107 108 var EventElement = function EventElement(element) { 109 this.element = element; 110 this.handlers = {}; 111 }; 112 113 var prototypeAccessors = { isEmpty: { configurable: true } }; 114 115 EventElement.prototype.bind = function bind (eventName, handler) { 116 if (typeof this.handlers[eventName] === 'undefined') { 117 this.handlers[eventName] = []; 118 } 119 this.handlers[eventName].push(handler); 120 this.element.addEventListener(eventName, handler, false); 121 }; 122 123 EventElement.prototype.unbind = function unbind (eventName, target) { 124 var this$1 = this; 125 126 this.handlers[eventName] = this.handlers[eventName].filter(function (handler) { 127 if (target && handler !== target) { 128 return true; 129 } 130 this$1.element.removeEventListener(eventName, handler, false); 131 return false; 132 }); 133 }; 134 135 EventElement.prototype.unbindAll = function unbindAll () { 136 for (var name in this.handlers) { 137 this.unbind(name); 138 } 139 }; 140 141 prototypeAccessors.isEmpty.get = function () { 142 var this$1 = this; 143 144 return Object.keys(this.handlers).every( 145 function (key) { return this$1.handlers[key].length === 0; } 146 ); 147 }; 148 149 Object.defineProperties( EventElement.prototype, prototypeAccessors ); 150 151 var EventManager = function EventManager() { 152 this.eventElements = []; 153 }; 154 155 EventManager.prototype.eventElement = function eventElement (element) { 156 var ee = this.eventElements.filter(function (ee) { return ee.element === element; })[0]; 157 if (!ee) { 158 ee = new EventElement(element); 159 this.eventElements.push(ee); 160 } 161 return ee; 162 }; 163 164 EventManager.prototype.bind = function bind (element, eventName, handler) { 165 this.eventElement(element).bind(eventName, handler); 166 }; 167 168 EventManager.prototype.unbind = function unbind (element, eventName, handler) { 169 var ee = this.eventElement(element); 170 ee.unbind(eventName, handler); 171 172 if (ee.isEmpty) { 173 // remove 174 this.eventElements.splice(this.eventElements.indexOf(ee), 1); 175 } 176 }; 177 178 EventManager.prototype.unbindAll = function unbindAll () {
vendor: 9,016 bytes, lines 179-493
179 this.eventElements.forEach(function (e) { return e.unbindAll(); }); 180 this.eventElements = []; 181 }; 182 183 EventManager.prototype.once = function once (element, eventName, handler) { 184 var ee = this.eventElement(element); 185 var onceHandler = function (evt) { 186 ee.unbind(eventName, onceHandler); 187 handler(evt); 188 }; 189 ee.bind(eventName, onceHandler); 190 }; 191 192 function createEvent(name) { 193 if (typeof window.CustomEvent === 'function') { 194 return new CustomEvent(name); 195 } else { 196 var evt = document.createEvent('CustomEvent'); 197 evt.initCustomEvent(name, false, false, undefined); 198 return evt; 199 } 200 } 201 202 function processScrollDiff( 203 i, 204 axis, 205 diff, 206 useScrollingClass, 207 forceFireReachEvent 208 ) { 209 if ( useScrollingClass === void 0 ) useScrollingClass = true; 210 if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false; 211 212 var fields; 213 if (axis === 'top') { 214 fields = [ 215 'contentHeight', 216 'containerHeight', 217 'scrollTop', 218 'y', 219 'up', 220 'down' ]; 221 } else if (axis === 'left') { 222 fields = [ 223 'contentWidth', 224 'containerWidth', 225 'scrollLeft', 226 'x', 227 'left', 228 'right' ]; 229 } else { 230 throw new Error('A proper axis should be provided'); 231 } 232 233 processScrollDiff$1(i, diff, fields, useScrollingClass, forceFireReachEvent); 234 } 235 236 function processScrollDiff$1( 237 i, 238 diff, 239 ref, 240 useScrollingClass, 241 forceFireReachEvent 242 ) { 243 var contentHeight = ref[0]; 244 var containerHeight = ref[1]; 245 var scrollTop = ref[2]; 246 var y = ref[3]; 247 var up = ref[4]; 248 var down = ref[5]; 249 if ( useScrollingClass === void 0 ) useScrollingClass = true; 250 if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false; 251 252 var element = i.element; 253 254 // reset reach 255 i.reach[y] = null; 256 257 // 1 for subpixel rounding 258 if (element[scrollTop] < 1) { 259 i.reach[y] = 'start'; 260 } 261 262 // 1 for subpixel rounding 263 if (element[scrollTop] > i[contentHeight] - i[containerHeight] - 1) { 264 i.reach[y] = 'end'; 265 } 266 267 if (diff) { 268 element.dispatchEvent(createEvent(("ps-scroll-" + y))); 269 270 if (diff < 0) { 271 element.dispatchEvent(createEvent(("ps-scroll-" + up))); 272 } else if (diff > 0) { 273 element.dispatchEvent(createEvent(("ps-scroll-" + down))); 274 } 275 276 if (useScrollingClass) { 277 setScrollingClassInstantly(i, y); 278 } 279 } 280 281 if (i.reach[y] && (diff || forceFireReachEvent)) { 282 element.dispatchEvent(createEvent(("ps-" + y + "-reach-" + (i.reach[y])))); 283 } 284 } 285 286 function toInt(x) { 287 return parseInt(x, 10) || 0; 288 } 289 290 function isEditable(el) { 291 return ( 292 matches(el, 'input,[contenteditable]') || 293 matches(el, 'select,[contenteditable]') || 294 matches(el, 'textarea,[contenteditable]') || 295 matches(el, 'button,[contenteditable]') 296 ); 297 } 298 299 function outerWidth(element) { 300 var styles = get(element); 301 return ( 302 toInt(styles.width) + 303 toInt(styles.paddingLeft) + 304 toInt(styles.paddingRight) + 305 toInt(styles.borderLeftWidth) + 306 toInt(styles.borderRightWidth) 307 ); 308 } 309 310 var env = { 311 isWebKit: 312 typeof document !== 'undefined' && 313 'WebkitAppearance' in document.documentElement.style, 314 supportsTouch: 315 typeof window !== 'undefined' && 316 ('ontouchstart' in window || 317 ('maxTouchPoints' in window.navigator && 318 window.navigator.maxTouchPoints > 0) || 319 (window.DocumentTouch && document instanceof window.DocumentTouch)), 320 supportsIePointer: 321 typeof navigator !== 'undefined' && navigator.msMaxTouchPoints, 322 isChrome: 323 typeof navigator !== 'undefined' && 324 /Chrome/i.test(navigator && navigator.userAgent), 325 }; 326 327 function updateGeometry(i) { 328 var element = i.element; 329 var roundedScrollTop = Math.floor(element.scrollTop); 330 var rect = element.getBoundingClientRect(); 331 332 i.containerWidth = Math.round(rect.width); 333 i.containerHeight = Math.round(rect.height); 334 335 i.contentWidth = element.scrollWidth; 336 i.contentHeight = element.scrollHeight; 337 338 if (!element.contains(i.scrollbarXRail)) { 339 // clean up and append 340 queryChildren(element, cls.element.rail('x')).forEach(function (el) { return remove(el); } 341 ); 342 element.appendChild(i.scrollbarXRail); 343 } 344 if (!element.contains(i.scrollbarYRail)) { 345 // clean up and append 346 queryChildren(element, cls.element.rail('y')).forEach(function (el) { return remove(el); } 347 ); 348 element.appendChild(i.scrollbarYRail); 349 } 350 351 if ( 352 !i.settings.suppressScrollX && 353 i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth 354 ) { 355 i.scrollbarXActive = true; 356 i.railXWidth = i.containerWidth - i.railXMarginWidth; 357 i.railXRatio = i.containerWidth / i.railXWidth; 358 i.scrollbarXWidth = getThumbSize( 359 i, 360 toInt((i.railXWidth * i.containerWidth) / i.contentWidth) 361 ); 362 i.scrollbarXLeft = toInt( 363 ((i.negativeScrollAdjustment + element.scrollLeft) * 364 (i.railXWidth - i.scrollbarXWidth)) / 365 (i.contentWidth - i.containerWidth) 366 ); 367 } else { 368 i.scrollbarXActive = false; 369 } 370 371 if ( 372 !i.settings.suppressScrollY && 373 i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight 374 ) { 375 i.scrollbarYActive = true; 376 i.railYHeight = i.containerHeight - i.railYMarginHeight; 377 i.railYRatio = i.containerHeight / i.railYHeight; 378 i.scrollbarYHeight = getThumbSize( 379 i, 380 toInt((i.railYHeight * i.containerHeight) / i.contentHeight) 381 ); 382 i.scrollbarYTop = toInt( 383 (roundedScrollTop * (i.railYHeight - i.scrollbarYHeight)) / 384 (i.contentHeight - i.containerHeight) 385 ); 386 } else { 387 i.scrollbarYActive = false; 388 } 389 390 if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) { 391 i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth; 392 } 393 if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) { 394 i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight; 395 } 396 397 updateCss(element, i); 398 399 if (i.scrollbarXActive) { 400 element.classList.add(cls.state.active('x')); 401 } else { 402 element.classList.remove(cls.state.active('x')); 403 i.scrollbarXWidth = 0; 404 i.scrollbarXLeft = 0; 405 element.scrollLeft = i.isRtl === true ? i.contentWidth : 0; 406 } 407 if (i.scrollbarYActive) { 408 element.classList.add(cls.state.active('y')); 409 } else { 410 element.classList.remove(cls.state.active('y')); 411 i.scrollbarYHeight = 0; 412 i.scrollbarYTop = 0; 413 element.scrollTop = 0; 414 } 415 } 416 417 function getThumbSize(i, thumbSize) { 418 if (i.settings.minScrollbarLength) { 419 thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength); 420 } 421 if (i.settings.maxScrollbarLength) { 422 thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength); 423 } 424 return thumbSize; 425 } 426 427 function updateCss(element, i) { 428 var xRailOffset = { width: i.railXWidth }; 429 var roundedScrollTop = Math.floor(element.scrollTop); 430 431 if (i.isRtl) { 432 xRailOffset.left = 433 i.negativeScrollAdjustment + 434 element.scrollLeft + 435 i.containerWidth - 436 i.contentWidth; 437 } else { 438 xRailOffset.left = element.scrollLeft; 439 } 440 if (i.isScrollbarXUsingBottom) { 441 xRailOffset.bottom = i.scrollbarXBottom - roundedScrollTop; 442 } else { 443 xRailOffset.top = i.scrollbarXTop + roundedScrollTop; 444 } 445 set(i.scrollbarXRail, xRailOffset); 446 447 var yRailOffset = { top: roundedScrollTop, height: i.railYHeight }; 448 if (i.isScrollbarYUsingRight) { 449 if (i.isRtl) { 450 yRailOffset.right = 451 i.contentWidth - 452 (i.negativeScrollAdjustment + element.scrollLeft) - 453 i.scrollbarYRight - 454 i.scrollbarYOuterWidth - 455 9; 456 } else { 457 yRailOffset.right = i.scrollbarYRight - element.scrollLeft; 458 } 459 } else { 460 if (i.isRtl) { 461 yRailOffset.left = 462 i.negativeScrollAdjustment + 463 element.scrollLeft + 464 i.containerWidth * 2 - 465 i.contentWidth - 466 i.scrollbarYLeft - 467 i.scrollbarYOuterWidth; 468 } else { 469 yRailOffset.left = i.scrollbarYLeft + element.scrollLeft; 470 } 471 } 472 set(i.scrollbarYRail, yRailOffset); 473 474 set(i.scrollbarX, { 475 left: i.scrollbarXLeft, 476 width: i.scrollbarXWidth - i.railBorderXWidth, 477 }); 478 set(i.scrollbarY, { 479 top: i.scrollbarYTop, 480 height: i.scrollbarYHeight - i.railBorderYWidth, 481 }); 482 } 483 484 function clickRail(i) { 485 var element = i.element; 486 487 i.event.bind(i.scrollbarY, 'mousedown', function (e) { return e.stopPropagation(); }); 488 i.event.bind(i.scrollbarYRail, 'mousedown', function (e) { 489 var positionTop = 490 e.pageY - 491 window.pageYOffset - 492 i.scrollbarYRail.getBoundingClientRect().top; 493 var direction = positionTop >
vendor: 7,653 bytes, lines 493-780
493 i.scrollbarYTop ? 1 : -1; 494 495 i.element.scrollTop += direction * i.containerHeight; 496 updateGeometry(i); 497 498 e.stopPropagation(); 499 }); 500 501 i.event.bind(i.scrollbarX, 'mousedown', function (e) { return e.stopPropagation(); }); 502 i.event.bind(i.scrollbarXRail, 'mousedown', function (e) { 503 var positionLeft = 504 e.pageX - 505 window.pageXOffset - 506 i.scrollbarXRail.getBoundingClientRect().left; 507 var direction = positionLeft > i.scrollbarXLeft ? 1 : -1; 508 509 i.element.scrollLeft += direction * i.containerWidth; 510 updateGeometry(i); 511 512 e.stopPropagation(); 513 }); 514 } 515 516 function dragThumb(i) { 517 bindMouseScrollHandler(i, [ 518 'containerWidth', 519 'contentWidth', 520 'pageX', 521 'railXWidth', 522 'scrollbarX', 523 'scrollbarXWidth', 524 'scrollLeft', 525 'x', 526 'scrollbarXRail' ]); 527 bindMouseScrollHandler(i, [ 528 'containerHeight', 529 'contentHeight', 530 'pageY', 531 'railYHeight', 532 'scrollbarY', 533 'scrollbarYHeight', 534 'scrollTop', 535 'y', 536 'scrollbarYRail' ]); 537 } 538 539 function bindMouseScrollHandler( 540 i, 541 ref 542 ) { 543 var containerHeight = ref[0]; 544 var contentHeight = ref[1]; 545 var pageY = ref[2]; 546 var railYHeight = ref[3]; 547 var scrollbarY = ref[4]; 548 var scrollbarYHeight = ref[5]; 549 var scrollTop = ref[6]; 550 var y = ref[7]; 551 var scrollbarYRail = ref[8]; 552 553 var element = i.element; 554 555 var startingScrollTop = null; 556 var startingMousePageY = null; 557 var scrollBy = null; 558 559 function mouseMoveHandler(e) { 560 if (e.touches && e.touches[0]) { 561 e[pageY] = e.touches[0].pageY; 562 } 563 element[scrollTop] = 564 startingScrollTop + scrollBy * (e[pageY] - startingMousePageY); 565 addScrollingClass(i, y); 566 updateGeometry(i); 567 568 e.stopPropagation(); 569 e.preventDefault(); 570 } 571 572 function mouseUpHandler() { 573 removeScrollingClass(i, y); 574 i[scrollbarYRail].classList.remove(cls.state.clicking); 575 i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler); 576 } 577 578 function bindMoves(e, touchMode) { 579 startingScrollTop = element[scrollTop]; 580 if (touchMode && e.touches) { 581 e[pageY] = e.touches[0].pageY; 582 } 583 startingMousePageY = e[pageY]; 584 scrollBy = 585 (i[contentHeight] - i[containerHeight]) / 586 (i[railYHeight] - i[scrollbarYHeight]); 587 if (!touchMode) { 588 i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); 589 i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler); 590 e.preventDefault(); 591 } else { 592 i.event.bind(i.ownerDocument, 'touchmove', mouseMoveHandler); 593 } 594 595 i[scrollbarYRail].classList.add(cls.state.clicking); 596 597 e.stopPropagation(); 598 } 599 600 i.event.bind(i[scrollbarY], 'mousedown', function (e) { 601 bindMoves(e); 602 }); 603 i.event.bind(i[scrollbarY], 'touchstart', function (e) { 604 bindMoves(e, true); 605 }); 606 } 607 608 function keyboard(i) { 609 var element = i.element; 610 611 var elementHovered = function () { return matches(element, ':hover'); }; 612 var scrollbarFocused = function () { return matches(i.scrollbarX, ':focus') || matches(i.scrollbarY, ':focus'); }; 613 614 function shouldPreventDefault(deltaX, deltaY) { 615 var scrollTop = Math.floor(element.scrollTop); 616 if (deltaX === 0) { 617 if (!i.scrollbarYActive) { 618 return false; 619 } 620 if ( 621 (scrollTop === 0 && deltaY > 0) || 622 (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0) 623 ) { 624 return !i.settings.wheelPropagation; 625 } 626 } 627 628 var scrollLeft = element.scrollLeft; 629 if (deltaY === 0) { 630 if (!i.scrollbarXActive) { 631 return false; 632 } 633 if ( 634 (scrollLeft === 0 && deltaX < 0) || 635 (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0) 636 ) { 637 return !i.settings.wheelPropagation; 638 } 639 } 640 return true; 641 } 642 643 i.event.bind(i.ownerDocument, 'keydown', function (e) { 644 if ( 645 (e.isDefaultPrevented && e.isDefaultPrevented()) || 646 e.defaultPrevented 647 ) { 648 return; 649 } 650 651 if (!elementHovered() && !scrollbarFocused()) { 652 return; 653 } 654 655 var activeElement = document.activeElement 656 ? document.activeElement 657 : i.ownerDocument.activeElement; 658 if (activeElement) { 659 if (activeElement.tagName === 'IFRAME') { 660 activeElement = activeElement.contentDocument.activeElement; 661 } else { 662 // go deeper if element is a webcomponent 663 while (activeElement.shadowRoot) { 664 activeElement = activeElement.shadowRoot.activeElement; 665 } 666 } 667 if (isEditable(activeElement)) { 668 return; 669 } 670 } 671 672 var deltaX = 0; 673 var deltaY = 0; 674 675 switch (e.which) { 676 case 37: // left 677 if (e.metaKey) { 678 deltaX = -i.contentWidth; 679 } else if (e.altKey) { 680 deltaX = -i.containerWidth; 681 } else { 682 deltaX = -30; 683 } 684 break; 685 case 38: // up 686 if (e.metaKey) { 687 deltaY = i.contentHeight; 688 } else if (e.altKey) { 689 deltaY = i.containerHeight; 690 } else { 691 deltaY = 30; 692 } 693 break; 694 case 39: // right 695 if (e.metaKey) { 696 deltaX = i.contentWidth; 697 } else if (e.altKey) { 698 deltaX = i.containerWidth; 699 } else { 700 deltaX = 30; 701 } 702 break; 703 case 40: // down 704 if (e.metaKey) { 705 deltaY = -i.contentHeight; 706 } else if (e.altKey) { 707 deltaY = -i.containerHeight; 708 } else { 709 deltaY = -30; 710 } 711 break; 712 case 32: // space bar 713 if (e.shiftKey) { 714 deltaY = i.containerHeight; 715 } else { 716 deltaY = -i.containerHeight; 717 } 718 break; 719 case 33: // page up 720 deltaY = i.containerHeight; 721 break; 722 case 34: // page down 723 deltaY = -i.containerHeight; 724 break; 725 case 36: // home 726 deltaY = i.contentHeight; 727 break; 728 case 35: // end 729 deltaY = -i.contentHeight; 730 break; 731 default: 732 return; 733 } 734 735 if (i.settings.suppressScrollX && deltaX !== 0) { 736 return; 737 } 738 if (i.settings.suppressScrollY && deltaY !== 0) { 739 return; 740 } 741 742 element.scrollTop -= deltaY; 743 element.scrollLeft += deltaX; 744 updateGeometry(i); 745 746 if (shouldPreventDefault(deltaX, deltaY)) { 747 e.preventDefault(); 748 } 749 }); 750 } 751 752 function wheel(i) { 753 var element = i.element; 754 755 function shouldPreventDefault(deltaX, deltaY) { 756 var roundedScrollTop = Math.floor(element.scrollTop); 757 var isTop = element.scrollTop === 0; 758 var isBottom = 759 roundedScrollTop + element.offsetHeight === element.scrollHeight; 760 var isLeft = element.scrollLeft === 0; 761 var isRight = 762 element.scrollLeft + element.offsetWidth === element.scrollWidth; 763 764 var hitsBound; 765 766 // pick axis with primary direction 767 if (Math.abs(deltaY) > Math.abs(deltaX)) { 768 hitsBound = isTop || isBottom; 769 } else { 770 hitsBound = isLeft || isRight; 771 } 772 773 return hitsBound ? !i.settings.wheelPropagation : true; 774 } 775 776 function getDeltaFromEvent(e) { 777 var deltaX = e.deltaX; 778 var deltaY = -1 * e.deltaY; 779 780 if (typeof deltaX === 'undefined' || typeof deltaY === 'undefined') {
vendor: 5,455 bytes, lines 781-966
781 // OS X Safari 782 deltaX = (-1 * e.wheelDeltaX) / 6; 783 deltaY = e.wheelDeltaY / 6; 784 } 785 786 if (e.deltaMode && e.deltaMode === 1) { 787 // Firefox in deltaMode 1: Line scrolling 788 deltaX *= 10; 789 deltaY *= 10; 790 } 791 792 if (deltaX !== deltaX && deltaY !== deltaY /* NaN checks */) { 793 // IE in some mouse drivers 794 deltaX = 0; 795 deltaY = e.wheelDelta; 796 } 797 798 if (e.shiftKey) { 799 // reverse axis with shift key 800 return [-deltaY, -deltaX]; 801 } 802 return [deltaX, deltaY]; 803 } 804 805 function shouldBeConsumedByChild(target, deltaX, deltaY) { 806 // FIXME: this is a workaround for <select> issue in FF and IE #571 807 if (!env.isWebKit && element.querySelector('select:focus')) { 808 return true; 809 } 810 811 if (!element.contains(target)) { 812 return false; 813 } 814 815 var cursor = target; 816 817 while (cursor && cursor !== element) { 818 if (cursor.classList.contains(cls.element.consuming)) { 819 return true; 820 } 821 822 var style = get(cursor); 823 824 // if deltaY && vertical scrollable 825 if (deltaY && style.overflowY.match(/(scroll|auto)/)) { 826 var maxScrollTop = cursor.scrollHeight - cursor.clientHeight; 827 if (maxScrollTop > 0) { 828 if ( 829 (cursor.scrollTop > 0 && deltaY < 0) || 830 (cursor.scrollTop < maxScrollTop && deltaY > 0) 831 ) { 832 return true; 833 } 834 } 835 } 836 // if deltaX && horizontal scrollable 837 if (deltaX && style.overflowX.match(/(scroll|auto)/)) { 838 var maxScrollLeft = cursor.scrollWidth - cursor.clientWidth; 839 if (maxScrollLeft > 0) { 840 if ( 841 (cursor.scrollLeft > 0 && deltaX < 0) || 842 (cursor.scrollLeft < maxScrollLeft && deltaX > 0) 843 ) { 844 return true; 845 } 846 } 847 } 848 849 cursor = cursor.parentNode; 850 } 851 852 return false; 853 } 854 855 function mousewheelHandler(e) { 856 var ref = getDeltaFromEvent(e); 857 var deltaX = ref[0]; 858 var deltaY = ref[1]; 859 860 if (shouldBeConsumedByChild(e.target, deltaX, deltaY)) { 861 return; 862 } 863 864 var shouldPrevent = false; 865 if (!i.settings.useBothWheelAxes) { 866 // deltaX will only be used for horizontal scrolling and deltaY will 867 // only be used for vertical scrolling - this is the default 868 element.scrollTop -= deltaY * i.settings.wheelSpeed; 869 element.scrollLeft += deltaX * i.settings.wheelSpeed; 870 } else if (i.scrollbarYActive && !i.scrollbarXActive) { 871 // only vertical scrollbar is active and useBothWheelAxes option is 872 // active, so let's scroll vertical bar using both mouse wheel axes 873 if (deltaY) { 874 element.scrollTop -= deltaY * i.settings.wheelSpeed; 875 } else { 876 element.scrollTop += deltaX * i.settings.wheelSpeed; 877 } 878 shouldPrevent = true; 879 } else if (i.scrollbarXActive && !i.scrollbarYActive) { 880 // useBothWheelAxes and only horizontal bar is active, so use both 881 // wheel axes for horizontal bar 882 if (deltaX) { 883 element.scrollLeft += deltaX * i.settings.wheelSpeed; 884 } else { 885 element.scrollLeft -= deltaY * i.settings.wheelSpeed; 886 } 887 shouldPrevent = true; 888 } 889 890 updateGeometry(i); 891 892 shouldPrevent = shouldPrevent || shouldPreventDefault(deltaX, deltaY); 893 if (shouldPrevent && !e.ctrlKey) { 894 e.stopPropagation(); 895 e.preventDefault(); 896 } 897 } 898 899 if (typeof window.onwheel !== 'undefined') { 900 i.event.bind(element, 'wheel', mousewheelHandler); 901 } else if (typeof window.onmousewheel !== 'undefined') { 902 i.event.bind(element, 'mousewheel', mousewheelHandler); 903 } 904 } 905 906 function touch(i) { 907 if (!env.supportsTouch && !env.supportsIePointer) { 908 return; 909 } 910 911 var element = i.element; 912 913 function shouldPrevent(deltaX, deltaY) { 914 var scrollTop = Math.floor(element.scrollTop); 915 var scrollLeft = element.scrollLeft; 916 var magnitudeX = Math.abs(deltaX); 917 var magnitudeY = Math.abs(deltaY); 918 919 if (magnitudeY > magnitudeX) { 920 // user is perhaps trying to swipe up/down the page 921 922 if ( 923 (deltaY < 0 && scrollTop === i.contentHeight - i.containerHeight) || 924 (deltaY > 0 && scrollTop === 0) 925 ) { 926 // set prevent for mobile Chrome refresh 927 return window.scrollY === 0 && deltaY > 0 && env.isChrome; 928 } 929 } else if (magnitudeX > magnitudeY) { 930 // user is perhaps trying to swipe left/right across the page 931 932 if ( 933 (deltaX < 0 && scrollLeft === i.contentWidth - i.containerWidth) || 934 (deltaX > 0 && scrollLeft === 0) 935 ) { 936 return true; 937 } 938 } 939 940 return true; 941 } 942 943 function applyTouchMove(differenceX, differenceY) { 944 element.scrollTop -= differenceY; 945 element.scrollLeft -= differenceX; 946 947 updateGeometry(i); 948 } 949 950 var startOffset = {}; 951 var startTime = 0; 952 var speed = {}; 953 var easingLoop = null; 954 955 function getTouch(e) { 956 if (e.targetTouches) { 957 return e.targetTouches[0]; 958 } else { 959 // Maybe IE pointer 960 return e; 961 } 962 } 963 964 function shouldHandle(e) { 965 if (e.pointerType && e.pointerType === 'pen' && e.buttons === 0) { 966 return false;
vendor: 6,435 bytes, lines 967-1196
967 } 968 if (e.targetTouches && e.targetTouches.length === 1) { 969 return true; 970 } 971 if ( 972 e.pointerType && 973 e.pointerType !== 'mouse' && 974 e.pointerType !== e.MSPOINTER_TYPE_MOUSE 975 ) { 976 return true; 977 } 978 return false; 979 } 980 981 function touchStart(e) { 982 if (!shouldHandle(e)) { 983 return; 984 } 985 986 var touch = getTouch(e); 987 988 startOffset.pageX = touch.pageX; 989 startOffset.pageY = touch.pageY; 990 991 startTime = new Date().getTime(); 992 993 if (easingLoop !== null) { 994 clearInterval(easingLoop); 995 } 996 } 997 998 function shouldBeConsumedByChild(target, deltaX, deltaY) { 999 if (!element.contains(target)) { 1000 return false; 1001 } 1002 1003 var cursor = target; 1004 1005 while (cursor && cursor !== element) { 1006 if (cursor.classList.contains(cls.element.consuming)) { 1007 return true; 1008 } 1009 1010 var style = get(cursor); 1011 1012 // if deltaY && vertical scrollable 1013 if (deltaY && style.overflowY.match(/(scroll|auto)/)) { 1014 var maxScrollTop = cursor.scrollHeight - cursor.clientHeight; 1015 if (maxScrollTop > 0) { 1016 if ( 1017 (cursor.scrollTop > 0 && deltaY < 0) || 1018 (cursor.scrollTop < maxScrollTop && deltaY > 0) 1019 ) { 1020 return true; 1021 } 1022 } 1023 } 1024 // if deltaX && horizontal scrollable 1025 if (deltaX && style.overflowX.match(/(scroll|auto)/)) { 1026 var maxScrollLeft = cursor.scrollWidth - cursor.clientWidth; 1027 if (maxScrollLeft > 0) { 1028 if ( 1029 (cursor.scrollLeft > 0 && deltaX < 0) || 1030 (cursor.scrollLeft < maxScrollLeft && deltaX > 0) 1031 ) { 1032 return true; 1033 } 1034 } 1035 } 1036 1037 cursor = cursor.parentNode; 1038 } 1039 1040 return false; 1041 } 1042 1043 function touchMove(e) { 1044 if (shouldHandle(e)) { 1045 var touch = getTouch(e); 1046 1047 var currentOffset = { pageX: touch.pageX, pageY: touch.pageY }; 1048 1049 var differenceX = currentOffset.pageX - startOffset.pageX; 1050 var differenceY = currentOffset.pageY - startOffset.pageY; 1051 1052 if (shouldBeConsumedByChild(e.target, differenceX, differenceY)) { 1053 return; 1054 } 1055 1056 applyTouchMove(differenceX, differenceY); 1057 startOffset = currentOffset; 1058 1059 var currentTime = new Date().getTime(); 1060 1061 var timeGap = currentTime - startTime; 1062 if (timeGap > 0) { 1063 speed.x = differenceX / timeGap; 1064 speed.y = differenceY / timeGap; 1065 startTime = currentTime; 1066 } 1067 1068 if (shouldPrevent(differenceX, differenceY)) { 1069 e.preventDefault(); 1070 } 1071 } 1072 } 1073 function touchEnd() { 1074 if (i.settings.swipeEasing) { 1075 clearInterval(easingLoop); 1076 easingLoop = setInterval(function() { 1077 if (i.isInitialized) { 1078 clearInterval(easingLoop); 1079 return; 1080 } 1081 1082 if (!speed.x && !speed.y) { 1083 clearInterval(easingLoop); 1084 return; 1085 } 1086 1087 if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) { 1088 clearInterval(easingLoop); 1089 return; 1090 } 1091 1092 if (!i.element) { 1093 clearInterval(easingLoop); 1094 return; 1095 } 1096 1097 applyTouchMove(speed.x * 30, speed.y * 30); 1098 1099 speed.x *= 0.8; 1100 speed.y *= 0.8; 1101 }, 10); 1102 } 1103 } 1104 1105 if (env.supportsTouch) { 1106 i.event.bind(element, 'touchstart', touchStart); 1107 i.event.bind(element, 'touchmove', touchMove); 1108 i.event.bind(element, 'touchend', touchEnd); 1109 } else if (env.supportsIePointer) { 1110 if (window.PointerEvent) { 1111 i.event.bind(element, 'pointerdown', touchStart); 1112 i.event.bind(element, 'pointermove', touchMove); 1113 i.event.bind(element, 'pointerup', touchEnd); 1114 } else if (window.MSPointerEvent) { 1115 i.event.bind(element, 'MSPointerDown', touchStart); 1116 i.event.bind(element, 'MSPointerMove', touchMove); 1117 i.event.bind(element, 'MSPointerUp', touchEnd); 1118 } 1119 } 1120 } 1121 1122 var defaultSettings = function () { return ({ 1123 handlers: ['click-rail', 'drag-thumb', 'keyboard', 'wheel', 'touch'], 1124 maxScrollbarLength: null, 1125 minScrollbarLength: null, 1126 scrollingThreshold: 1000, 1127 scrollXMarginOffset: 0, 1128 scrollYMarginOffset: 0, 1129 suppressScrollX: false, 1130 suppressScrollY: false, 1131 swipeEasing: true, 1132 useBothWheelAxes: false, 1133 wheelPropagation: true, 1134 wheelSpeed: 1, 1135 }); }; 1136 1137 var handlers = { 1138 'click-rail': clickRail, 1139 'drag-thumb': dragThumb, 1140 keyboard: keyboard, 1141 wheel: wheel, 1142 touch: touch, 1143 }; 1144 1145 var PerfectScrollbar = function PerfectScrollbar(element, userSettings) { 1146 var this$1 = this; 1147 if ( userSettings === void 0 ) userSettings = {}; 1148 1149 if (typeof element === 'string') { 1150 element = document.querySelector(element); 1151 } 1152 1153 if (!element || !element.nodeName) { 1154 throw new Error('no element is specified to initialize PerfectScrollbar'); 1155 } 1156 1157 this.element = element; 1158 1159 element.classList.add(cls.main); 1160 1161 this.settings = defaultSettings(); 1162 for (var key in userSettings) { 1163 this.settings[key] = userSettings[key]; 1164 } 1165 1166 this.containerWidth = null; 1167 this.containerHeight = null; 1168 this.contentWidth = null; 1169 this.contentHeight = null; 1170 1171 var focus = function () { return element.classList.add(cls.state.focus); }; 1172 var blur = function () { return element.classList.remove(cls.state.focus); }; 1173 1174 this.isRtl = get(element).direction === 'rtl'; 1175 if (this.isRtl === true) { 1176 element.classList.add(cls.rtl); 1177 } 1178 this.isNegativeScroll = (function () { 1179 var originalScrollLeft = element.scrollLeft; 1180 var result = null; 1181 element.scrollLeft = -1; 1182 result = element.scrollLeft < 0; 1183 element.scrollLeft = originalScrollLeft; 1184 return result; 1185 })(); 1186 this.negativeScrollAdjustment = this.isNegativeScroll 1187 ? element.scrollWidth - element.clientWidth 1188 : 0; 1189 this.event = new EventManager(); 1190 this.ownerDocument = element.ownerDocument || document; 1191 1192 this.scrollbarXRail = div(cls.element.rail('x')); 1193 element.appendChild(this.scrollbarXRail); 1194 this.scrollbarX = div(cls.element.thumb('x')); 1195 this.scrollbarXRail.appendChild(this.scrollbarX); 1196 this.scrollbarX.setAttribute('tabindex', 0);
vendor: 4,292 bytes, lines 1197-1317
1197 this.event.bind(this.scrollbarX, 'focus', focus); 1198 this.event.bind(this.scrollbarX, 'blur', blur); 1199 this.scrollbarXActive = null; 1200 this.scrollbarXWidth = null; 1201 this.scrollbarXLeft = null; 1202 var railXStyle = get(this.scrollbarXRail); 1203 this.scrollbarXBottom = parseInt(railXStyle.bottom, 10); 1204 if (isNaN(this.scrollbarXBottom)) { 1205 this.isScrollbarXUsingBottom = false; 1206 this.scrollbarXTop = toInt(railXStyle.top); 1207 } else { 1208 this.isScrollbarXUsingBottom = true; 1209 } 1210 this.railBorderXWidth = 1211 toInt(railXStyle.borderLeftWidth) + toInt(railXStyle.borderRightWidth); 1212 // Set rail to display:block to calculate margins 1213 set(this.scrollbarXRail, { display: 'block' }); 1214 this.railXMarginWidth = 1215 toInt(railXStyle.marginLeft) + toInt(railXStyle.marginRight); 1216 set(this.scrollbarXRail, { display: '' }); 1217 this.railXWidth = null; 1218 this.railXRatio = null; 1219 1220 this.scrollbarYRail = div(cls.element.rail('y')); 1221 element.appendChild(this.scrollbarYRail); 1222 this.scrollbarY = div(cls.element.thumb('y')); 1223 this.scrollbarYRail.appendChild(this.scrollbarY); 1224 this.scrollbarY.setAttribute('tabindex', 0); 1225 this.event.bind(this.scrollbarY, 'focus', focus); 1226 this.event.bind(this.scrollbarY, 'blur', blur); 1227 this.scrollbarYActive = null; 1228 this.scrollbarYHeight = null; 1229 this.scrollbarYTop = null; 1230 var railYStyle = get(this.scrollbarYRail); 1231 this.scrollbarYRight = parseInt(railYStyle.right, 10); 1232 if (isNaN(this.scrollbarYRight)) { 1233 this.isScrollbarYUsingRight = false; 1234 this.scrollbarYLeft = toInt(railYStyle.left); 1235 } else { 1236 this.isScrollbarYUsingRight = true; 1237 } 1238 this.scrollbarYOuterWidth = this.isRtl ? outerWidth(this.scrollbarY) : null; 1239 this.railBorderYWidth = 1240 toInt(railYStyle.borderTopWidth) + toInt(railYStyle.borderBottomWidth); 1241 set(this.scrollbarYRail, { display: 'block' }); 1242 this.railYMarginHeight = 1243 toInt(railYStyle.marginTop) + toInt(railYStyle.marginBottom); 1244 set(this.scrollbarYRail, { display: '' }); 1245 this.railYHeight = null; 1246 this.railYRatio = null; 1247 1248 this.reach = { 1249 x: 1250 element.scrollLeft <= 0 1251 ? 'start' 1252 : element.scrollLeft >= this.contentWidth - this.containerWidth 1253 ? 'end' 1254 : null, 1255 y: 1256 element.scrollTop <= 0 1257 ? 'start' 1258 : element.scrollTop >= this.contentHeight - this.containerHeight 1259 ? 'end' 1260 : null, 1261 }; 1262 1263 this.isAlive = true; 1264 1265 this.settings.handlers.forEach(function (handlerName) { return handlers[handlerName](this$1); }); 1266 1267 this.lastScrollTop = Math.floor(element.scrollTop); // for onScroll only 1268 this.lastScrollLeft = element.scrollLeft; // for onScroll only 1269 this.event.bind(this.element, 'scroll', function (e) { return this$1.onScroll(e); }); 1270 updateGeometry(this); 1271 }; 1272 1273 PerfectScrollbar.prototype.update = function update () { 1274 if (!this.isAlive) { 1275 return; 1276 } 1277 1278 // Recalcuate negative scrollLeft adjustment 1279 this.negativeScrollAdjustment = this.isNegativeScroll 1280 ? this.element.scrollWidth - this.element.clientWidth 1281 : 0; 1282 1283 // Recalculate rail margins 1284 set(this.scrollbarXRail, { display: 'block' }); 1285 set(this.scrollbarYRail, { display: 'block' }); 1286 this.railXMarginWidth = 1287 toInt(get(this.scrollbarXRail).marginLeft) + 1288 toInt(get(this.scrollbarXRail).marginRight); 1289 this.railYMarginHeight = 1290 toInt(get(this.scrollbarYRail).marginTop) + 1291 toInt(get(this.scrollbarYRail).marginBottom); 1292 1293 // Hide scrollbars not to affect scrollWidth and scrollHeight 1294 set(this.scrollbarXRail, { display: 'none' }); 1295 set(this.scrollbarYRail, { display: 'none' }); 1296 1297 updateGeometry(this); 1298 1299 processScrollDiff(this, 'top', 0, false, true); 1300 processScrollDiff(this, 'left', 0, false, true); 1301 1302 set(this.scrollbarXRail, { display: '' }); 1303 set(this.scrollbarYRail, { display: '' }); 1304 }; 1305 1306 PerfectScrollbar.prototype.onScroll = function onScroll (e) { 1307 if (!this.isAlive) { 1308 return; 1309 } 1310 1311 updateGeometry(this); 1312 processScrollDiff(this, 'top', this.element.scrollTop - this.lastScrollTop); 1313 processScrollDiff( 1314 this, 1315 'left', 1316 this.element.scrollLeft - this.lastScrollLeft 1317
vendor: 933 bytes, lines 1317-1355
1317); 1318 1319 this.lastScrollTop = Math.floor(this.element.scrollTop); 1320 this.lastScrollLeft = this.element.scrollLeft; 1321 }; 1322 1323 PerfectScrollbar.prototype.destroy = function destroy () { 1324 if (!this.isAlive) { 1325 return; 1326 } 1327 1328 this.event.unbindAll(); 1329 remove(this.scrollbarX); 1330 remove(this.scrollbarY); 1331 remove(this.scrollbarXRail); 1332 remove(this.scrollbarYRail); 1333 this.removePsClasses(); 1334 1335 // unset elements 1336 this.element = null; 1337 this.scrollbarX = null; 1338 this.scrollbarY = null; 1339 this.scrollbarXRail = null; 1340 this.scrollbarYRail = null; 1341 1342 this.isAlive = false; 1343 }; 1344 1345 PerfectScrollbar.prototype.removePsClasses = function removePsClasses () { 1346 this.element.className = this.element.className 1347 .split(' ') 1348 .filter(function (name) { return !name.match(/^ps([-_].+|)$/); }) 1349 .join(' '); 1350 }; 1351 1352 return PerfectScrollbar; 1353 1354}))); 1355//# sourceMappingURL=perfect-scrollbar.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.