vendor: 4,783 bytes, lines 1-178
1/*! 2 * perfect-scrollbar v1.5.0 3 * Copyright 2020 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: 4,072 bytes, lines 179-333
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.ceil(rect.width); 333 i.containerHeight = Math.ceil(rect.height);
vendor: 6,786 bytes, lines 333-568
333 334 i.contentWidth = element.scrollWidth; 335 i.contentHeight = element.scrollHeight; 336 337 if (!element.contains(i.scrollbarXRail)) { 338 // clean up and append 339 queryChildren(element, cls.element.rail('x')).forEach(function (el) { return remove(el); } 340 ); 341 element.appendChild(i.scrollbarXRail); 342 } 343 if (!element.contains(i.scrollbarYRail)) { 344 // clean up and append 345 queryChildren(element, cls.element.rail('y')).forEach(function (el) { return remove(el); } 346 ); 347 element.appendChild(i.scrollbarYRail); 348 } 349 350 if ( 351 !i.settings.suppressScrollX && 352 i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth 353 ) { 354 i.scrollbarXActive = true; 355 i.railXWidth = i.containerWidth - i.railXMarginWidth; 356 i.railXRatio = i.containerWidth / i.railXWidth; 357 i.scrollbarXWidth = getThumbSize( 358 i, 359 toInt((i.railXWidth * i.containerWidth) / i.contentWidth) 360 ); 361 i.scrollbarXLeft = toInt( 362 ((i.negativeScrollAdjustment + element.scrollLeft) * 363 (i.railXWidth - i.scrollbarXWidth)) / 364 (i.contentWidth - i.containerWidth) 365 ); 366 } else { 367 i.scrollbarXActive = false; 368 } 369 370 if ( 371 !i.settings.suppressScrollY && 372 i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight 373 ) { 374 i.scrollbarYActive = true; 375 i.railYHeight = i.containerHeight - i.railYMarginHeight; 376 i.railYRatio = i.containerHeight / i.railYHeight; 377 i.scrollbarYHeight = getThumbSize( 378 i, 379 toInt((i.railYHeight * i.containerHeight) / i.contentHeight) 380 ); 381 i.scrollbarYTop = toInt( 382 (roundedScrollTop * (i.railYHeight - i.scrollbarYHeight)) / 383 (i.contentHeight - i.containerHeight) 384 ); 385 } else { 386 i.scrollbarYActive = false; 387 } 388 389 if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) { 390 i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth; 391 } 392 if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) { 393 i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight; 394 } 395 396 updateCss(element, i); 397 398 if (i.scrollbarXActive) { 399 element.classList.add(cls.state.active('x')); 400 } else { 401 element.classList.remove(cls.state.active('x')); 402 i.scrollbarXWidth = 0; 403 i.scrollbarXLeft = 0; 404 element.scrollLeft = i.isRtl === true ? i.contentWidth : 0; 405 } 406 if (i.scrollbarYActive) { 407 element.classList.add(cls.state.active('y')); 408 } else { 409 element.classList.remove(cls.state.active('y')); 410 i.scrollbarYHeight = 0; 411 i.scrollbarYTop = 0; 412 element.scrollTop = 0; 413 } 414 } 415 416 function getThumbSize(i, thumbSize) { 417 if (i.settings.minScrollbarLength) { 418 thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength); 419 } 420 if (i.settings.maxScrollbarLength) { 421 thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength); 422 } 423 return thumbSize; 424 } 425 426 function updateCss(element, i) { 427 var xRailOffset = { width: i.railXWidth }; 428 var roundedScrollTop = Math.floor(element.scrollTop); 429 430 if (i.isRtl) { 431 xRailOffset.left = 432 i.negativeScrollAdjustment + 433 element.scrollLeft + 434 i.containerWidth - 435 i.contentWidth; 436 } else { 437 xRailOffset.left = element.scrollLeft; 438 } 439 if (i.isScrollbarXUsingBottom) { 440 xRailOffset.bottom = i.scrollbarXBottom - roundedScrollTop; 441 } else { 442 xRailOffset.top = i.scrollbarXTop + roundedScrollTop; 443 } 444 set(i.scrollbarXRail, xRailOffset); 445 446 var yRailOffset = { top: roundedScrollTop, height: i.railYHeight }; 447 if (i.isScrollbarYUsingRight) { 448 if (i.isRtl) { 449 yRailOffset.right = 450 i.contentWidth - 451 (i.negativeScrollAdjustment + element.scrollLeft) - 452 i.scrollbarYRight - 453 i.scrollbarYOuterWidth - 454 9; 455 } else { 456 yRailOffset.right = i.scrollbarYRight - element.scrollLeft; 457 } 458 } else { 459 if (i.isRtl) { 460 yRailOffset.left = 461 i.negativeScrollAdjustment + 462 element.scrollLeft + 463 i.containerWidth * 2 - 464 i.contentWidth - 465 i.scrollbarYLeft - 466 i.scrollbarYOuterWidth; 467 } else { 468 yRailOffset.left = i.scrollbarYLeft + element.scrollLeft; 469 } 470 } 471 set(i.scrollbarYRail, yRailOffset); 472 473 set(i.scrollbarX, { 474 left: i.scrollbarXLeft, 475 width: i.scrollbarXWidth - i.railBorderXWidth, 476 }); 477 set(i.scrollbarY, { 478 top: i.scrollbarYTop, 479 height: i.scrollbarYHeight - i.railBorderYWidth, 480 }); 481 } 482 483 function clickRail(i) { 484 var element = i.element; 485 486 i.event.bind(i.scrollbarY, 'mousedown', function (e) { return e.stopPropagation(); }); 487 i.event.bind(i.scrollbarYRail, 'mousedown', function (e) { 488 var positionTop = 489 e.pageY - 490 window.pageYOffset - 491 i.scrollbarYRail.getBoundingClientRect().top; 492 var direction = positionTop > i.scrollbarYTop ? 1 : -1; 493 494 i.element.scrollTop += direction * i.containerHeight; 495 updateGeometry(i); 496 497 e.stopPropagation(); 498 }); 499 500 i.event.bind(i.scrollbarX, 'mousedown', function (e) { return e.stopPropagation(); }); 501 i.event.bind(i.scrollbarXRail, 'mousedown', function (e) { 502 var positionLeft = 503 e.pageX - 504 window.pageXOffset - 505 i.scrollbarXRail.getBoundingClientRect().left; 506 var direction = positionLeft > i.scrollbarXLeft ? 1 : -1; 507 508 i.element.scrollLeft += direction * i.containerWidth; 509 updateGeometry(i); 510 511 e.stopPropagation(); 512 }); 513 } 514 515 function dragThumb(i) { 516 bindMouseScrollHandler(i, [ 517 'containerWidth', 518 'contentWidth', 519 'pageX', 520 'railXWidth', 521 'scrollbarX', 522 'scrollbarXWidth', 523 'scrollLeft', 524 'x', 525 'scrollbarXRail' ]); 526 bindMouseScrollHandler(i, [ 527 'containerHeight', 528 'contentHeight', 529 'pageY', 530 'railYHeight', 531 'scrollbarY', 532 'scrollbarYHeight', 533 'scrollTop', 534 'y', 535 'scrollbarYRail' ]); 536 } 537 538 function bindMouseScrollHandler( 539 i, 540 ref 541 ) { 542 var containerHeight = ref[0]; 543 var contentHeight = ref[1]; 544 var pageY = ref[2]; 545 var railYHeight = ref[3]; 546 var scrollbarY = ref[4]; 547 var scrollbarYHeight = ref[5]; 548 var scrollTop = ref[6]; 549 var y = ref[7]; 550 var scrollbarYRail = ref[8]; 551 552 var element = i.element; 553 554 var startingScrollTop = null; 555 var startingMousePageY = null; 556 var scrollBy = null; 557 558 function mouseMoveHandler(e) { 559 if (e.touches && e.touches[0]) { 560 e[pageY] = e.touches[0].pageY; 561 } 562 element[scrollTop] = 563 startingScrollTop + scrollBy * (e[pageY] - startingMousePageY); 564 addScrollingClass(i, y); 565 updateGeometry(i); 566 567 e.stopPropagation(); 568
568e.preventDefault();
vendor: 14,482 bytes, lines 568-1091
568 569 } 570 571 function mouseUpHandler() { 572 removeScrollingClass(i, y); 573 i[scrollbarYRail].classList.remove(cls.state.clicking); 574 i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler); 575 } 576 577 function bindMoves(e, touchMode) { 578 startingScrollTop = element[scrollTop]; 579 if (touchMode && e.touches) { 580 e[pageY] = e.touches[0].pageY; 581 } 582 startingMousePageY = e[pageY]; 583 scrollBy = 584 (i[contentHeight] - i[containerHeight]) / 585 (i[railYHeight] - i[scrollbarYHeight]); 586 if (!touchMode) { 587 i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); 588 i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler); 589 e.preventDefault(); 590 } else { 591 i.event.bind(i.ownerDocument, 'touchmove', mouseMoveHandler); 592 } 593 594 i[scrollbarYRail].classList.add(cls.state.clicking); 595 596 e.stopPropagation(); 597 } 598 599 i.event.bind(i[scrollbarY], 'mousedown', function (e) { 600 bindMoves(e); 601 }); 602 i.event.bind(i[scrollbarY], 'touchstart', function (e) { 603 bindMoves(e, true); 604 }); 605 } 606 607 function keyboard(i) { 608 var element = i.element; 609 610 var elementHovered = function () { return matches(element, ':hover'); }; 611 var scrollbarFocused = function () { return matches(i.scrollbarX, ':focus') || matches(i.scrollbarY, ':focus'); }; 612 613 function shouldPreventDefault(deltaX, deltaY) { 614 var scrollTop = Math.floor(element.scrollTop); 615 if (deltaX === 0) { 616 if (!i.scrollbarYActive) { 617 return false; 618 } 619 if ( 620 (scrollTop === 0 && deltaY > 0) || 621 (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0) 622 ) { 623 return !i.settings.wheelPropagation; 624 } 625 } 626 627 var scrollLeft = element.scrollLeft; 628 if (deltaY === 0) { 629 if (!i.scrollbarXActive) { 630 return false; 631 } 632 if ( 633 (scrollLeft === 0 && deltaX < 0) || 634 (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0) 635 ) { 636 return !i.settings.wheelPropagation; 637 } 638 } 639 return true; 640 } 641 642 i.event.bind(i.ownerDocument, 'keydown', function (e) { 643 if ( 644 (e.isDefaultPrevented && e.isDefaultPrevented()) || 645 e.defaultPrevented 646 ) { 647 return; 648 } 649 650 if (!elementHovered() && !scrollbarFocused()) { 651 return; 652 } 653 654 var activeElement = document.activeElement 655 ? document.activeElement 656 : i.ownerDocument.activeElement; 657 if (activeElement) { 658 if (activeElement.tagName === 'IFRAME') { 659 activeElement = activeElement.contentDocument.activeElement; 660 } else { 661 // go deeper if element is a webcomponent 662 while (activeElement.shadowRoot) { 663 activeElement = activeElement.shadowRoot.activeElement; 664 } 665 } 666 if (isEditable(activeElement)) { 667 return; 668 } 669 } 670 671 var deltaX = 0; 672 var deltaY = 0; 673 674 switch (e.which) { 675 case 37: // left 676 if (e.metaKey) { 677 deltaX = -i.contentWidth; 678 } else if (e.altKey) { 679 deltaX = -i.containerWidth; 680 } else { 681 deltaX = -30; 682 } 683 break; 684 case 38: // up 685 if (e.metaKey) { 686 deltaY = i.contentHeight; 687 } else if (e.altKey) { 688 deltaY = i.containerHeight; 689 } else { 690 deltaY = 30; 691 } 692 break; 693 case 39: // right 694 if (e.metaKey) { 695 deltaX = i.contentWidth; 696 } else if (e.altKey) { 697 deltaX = i.containerWidth; 698 } else { 699 deltaX = 30; 700 } 701 break; 702 case 40: // down 703 if (e.metaKey) { 704 deltaY = -i.contentHeight; 705 } else if (e.altKey) { 706 deltaY = -i.containerHeight; 707 } else { 708 deltaY = -30; 709 } 710 break; 711 case 32: // space bar 712 if (e.shiftKey) { 713 deltaY = i.containerHeight; 714 } else { 715 deltaY = -i.containerHeight; 716 } 717 break; 718 case 33: // page up 719 deltaY = i.containerHeight; 720 break; 721 case 34: // page down 722 deltaY = -i.containerHeight; 723 break; 724 case 36: // home 725 deltaY = i.contentHeight; 726 break; 727 case 35: // end 728 deltaY = -i.contentHeight; 729 break; 730 default: 731 return; 732 } 733 734 if (i.settings.suppressScrollX && deltaX !== 0) { 735 return; 736 } 737 if (i.settings.suppressScrollY && deltaY !== 0) { 738 return; 739 } 740 741 element.scrollTop -= deltaY; 742 element.scrollLeft += deltaX; 743 updateGeometry(i); 744 745 if (shouldPreventDefault(deltaX, deltaY)) { 746 e.preventDefault(); 747 } 748 }); 749 } 750 751 function wheel(i) { 752 var element = i.element; 753 754 function shouldPreventDefault(deltaX, deltaY) { 755 var roundedScrollTop = Math.floor(element.scrollTop); 756 var isTop = element.scrollTop === 0; 757 var isBottom = 758 roundedScrollTop + element.offsetHeight === element.scrollHeight; 759 var isLeft = element.scrollLeft === 0; 760 var isRight = 761 element.scrollLeft + element.offsetWidth === element.scrollWidth; 762 763 var hitsBound; 764 765 // pick axis with primary direction 766 if (Math.abs(deltaY) > Math.abs(deltaX)) { 767 hitsBound = isTop || isBottom; 768 } else { 769 hitsBound = isLeft || isRight; 770 } 771 772 return hitsBound ? !i.settings.wheelPropagation : true; 773 } 774 775 function getDeltaFromEvent(e) { 776 var deltaX = e.deltaX; 777 var deltaY = -1 * e.deltaY; 778 779 if (typeof deltaX === 'undefined' || typeof deltaY === 'undefined') { 780 // OS X Safari 781 deltaX = (-1 * e.wheelDeltaX) / 6; 782 deltaY = e.wheelDeltaY / 6; 783 } 784 785 if (e.deltaMode && e.deltaMode === 1) { 786 // Firefox in deltaMode 1: Line scrolling 787 deltaX *= 10; 788 deltaY *= 10; 789 } 790 791 if (deltaX !== deltaX && deltaY !== deltaY /* NaN checks */) { 792 // IE in some mouse drivers 793 deltaX = 0; 794 deltaY = e.wheelDelta; 795 } 796 797 if (e.shiftKey) { 798 // reverse axis with shift key 799 return [-deltaY, -deltaX]; 800 } 801 return [deltaX, deltaY]; 802 } 803 804 function shouldBeConsumedByChild(target, deltaX, deltaY) { 805 // FIXME: this is a workaround for <select> issue in FF and IE #571 806 if (!env.isWebKit && element.querySelector('select:focus')) { 807 return true; 808 } 809 810 if (!element.contains(target)) { 811 return false; 812 } 813 814 var cursor = target; 815 816 while (cursor && cursor !== element) { 817 if (cursor.classList.contains(cls.element.consuming)) { 818 return true; 819 } 820 821 var style = get(cursor); 822 823 // if deltaY && vertical scrollable 824 if (deltaY && style.overflowY.match(/(scroll|auto)/)) { 825 var maxScrollTop = cursor.scrollHeight - cursor.clientHeight; 826 if (maxScrollTop > 0) { 827 if ( 828 (cursor.scrollTop > 0 && deltaY < 0) || 829 (cursor.scrollTop < maxScrollTop && deltaY > 0) 830 ) { 831 return true; 832 } 833 } 834 } 835 // if deltaX && horizontal scrollable 836 if (deltaX && style.overflowX.match(/(scroll|auto)/)) { 837 var maxScrollLeft = cursor.scrollWidth - cursor.clientWidth; 838 if (maxScrollLeft > 0) { 839 if ( 840 (cursor.scrollLeft > 0 && deltaX < 0) || 841 (cursor.scrollLeft < maxScrollLeft && deltaX > 0) 842 ) { 843 return true; 844 } 845 } 846 } 847 848 cursor = cursor.parentNode; 849 } 850 851 return false; 852 } 853 854 function mousewheelHandler(e) { 855 var ref = getDeltaFromEvent(e); 856 var deltaX = ref[0]; 857 var deltaY = ref[1]; 858 859 if (shouldBeConsumedByChild(e.target, deltaX, deltaY)) { 860 return; 861 } 862 863 var shouldPrevent = false; 864 if (!i.settings.useBothWheelAxes) { 865 // deltaX will only be used for horizontal scrolling and deltaY will 866 // only be used for vertical scrolling - this is the default 867 element.scrollTop -= deltaY * i.settings.wheelSpeed; 868 element.scrollLeft += deltaX * i.settings.wheelSpeed; 869 } else if (i.scrollbarYActive && !i.scrollbarXActive) { 870 // only vertical scrollbar is active and useBothWheelAxes option is 871 // active, so let's scroll vertical bar using both mouse wheel axes 872 if (deltaY) { 873 element.scrollTop -= deltaY * i.settings.wheelSpeed; 874 } else { 875 element.scrollTop += deltaX * i.settings.wheelSpeed; 876 } 877 shouldPrevent = true; 878 } else if (i.scrollbarXActive && !i.scrollbarYActive) { 879 // useBothWheelAxes and only horizontal bar is active, so use both 880 // wheel axes for horizontal bar 881 if (deltaX) { 882 element.scrollLeft += deltaX * i.settings.wheelSpeed; 883 } else { 884 element.scrollLeft -= deltaY * i.settings.wheelSpeed; 885 } 886 shouldPrevent = true; 887 } 888 889 updateGeometry(i); 890 891 shouldPrevent = shouldPrevent || shouldPreventDefault(deltaX, deltaY); 892 if (shouldPrevent && !e.ctrlKey) { 893 e.stopPropagation(); 894 e.preventDefault(); 895 } 896 } 897 898 if (typeof window.onwheel !== 'undefined') { 899 i.event.bind(element, 'wheel', mousewheelHandler); 900 } else if (typeof window.onmousewheel !== 'undefined') { 901 i.event.bind(element, 'mousewheel', mousewheelHandler); 902 } 903 } 904 905 function touch(i) { 906 if (!env.supportsTouch && !env.supportsIePointer) { 907 return; 908 } 909 910 var element = i.element; 911 912 function shouldPrevent(deltaX, deltaY) { 913 var scrollTop = Math.floor(element.scrollTop); 914 var scrollLeft = element.scrollLeft; 915 var magnitudeX = Math.abs(deltaX); 916 var magnitudeY = Math.abs(deltaY); 917 918 if (magnitudeY > magnitudeX) { 919 // user is perhaps trying to swipe up/down the page 920 921 if ( 922 (deltaY < 0 && scrollTop === i.contentHeight - i.containerHeight) || 923 (deltaY > 0 && scrollTop === 0) 924 ) { 925 // set prevent for mobile Chrome refresh 926 return window.scrollY === 0 && deltaY > 0 && env.isChrome; 927 } 928 } else if (magnitudeX > magnitudeY) { 929 // user is perhaps trying to swipe left/right across the page 930 931 if ( 932 (deltaX < 0 && scrollLeft === i.contentWidth - i.containerWidth) || 933 (deltaX > 0 && scrollLeft === 0) 934 ) { 935 return true; 936 } 937 } 938 939 return true; 940 } 941 942 function applyTouchMove(differenceX, differenceY) { 943 element.scrollTop -= differenceY; 944 element.scrollLeft -= differenceX; 945 946 updateGeometry(i); 947 } 948 949 var startOffset = {}; 950 var startTime = 0; 951 var speed = {}; 952 var easingLoop = null; 953 954 function getTouch(e) { 955 if (e.targetTouches) { 956 return e.targetTouches[0]; 957 } else { 958 // Maybe IE pointer 959 return e; 960 } 961 } 962 963 function shouldHandle(e) { 964 if (e.pointerType && e.pointerType === 'pen' && e.buttons === 0) { 965 return false; 966 } 967 if (e.targetTouches && e.targetTouches.length === 1) { 968 return true; 969 } 970 if ( 971 e.pointerType && 972 e.pointerType !== 'mouse' && 973 e.pointerType !== e.MSPOINTER_TYPE_MOUSE 974 ) { 975 return true; 976 } 977 return false; 978 } 979 980 function touchStart(e) { 981 if (!shouldHandle(e)) { 982 return; 983 } 984 985 var touch = getTouch(e); 986 987 startOffset.pageX = touch.pageX; 988 startOffset.pageY = touch.pageY; 989 990 startTime = new Date().getTime(); 991 992 if (easingLoop !== null) { 993 clearInterval(easingLoop); 994 } 995 } 996 997 function shouldBeConsumedByChild(target, deltaX, deltaY) { 998 if (!element.contains(target)) { 999 return false; 1000 } 1001 1002 var cursor = target; 1003 1004 while (cursor && cursor !== element) { 1005 if (cursor.classList.contains(cls.element.consuming)) { 1006 return true; 1007 } 1008 1009 var style = get(cursor); 1010 1011 // if deltaY && vertical scrollable 1012 if (deltaY && style.overflowY.match(/(scroll|auto)/)) { 1013 var maxScrollTop = cursor.scrollHeight - cursor.clientHeight; 1014 if (maxScrollTop > 0) { 1015 if ( 1016 (cursor.scrollTop > 0 && deltaY < 0) || 1017 (cursor.scrollTop < maxScrollTop && deltaY > 0) 1018 ) { 1019 return true; 1020 } 1021 } 1022 } 1023 // if deltaX && horizontal scrollable 1024 if (deltaX && style.overflowX.match(/(scroll|auto)/)) { 1025 var maxScrollLeft = cursor.scrollWidth - cursor.clientWidth; 1026 if (maxScrollLeft > 0) { 1027 if ( 1028 (cursor.scrollLeft > 0 && deltaX < 0) || 1029 (cursor.scrollLeft < maxScrollLeft && deltaX > 0) 1030 ) { 1031 return true; 1032 } 1033 } 1034 } 1035 1036 cursor = cursor.parentNode; 1037 } 1038 1039 return false; 1040 } 1041 1042 function touchMove(e) { 1043 if (shouldHandle(e)) { 1044 var touch = getTouch(e); 1045 1046 var currentOffset = { pageX: touch.pageX, pageY: touch.pageY }; 1047 1048 var differenceX = currentOffset.pageX - startOffset.pageX; 1049 var differenceY = currentOffset.pageY - startOffset.pageY; 1050 1051 if (shouldBeConsumedByChild(e.target, differenceX, differenceY)) { 1052 return; 1053 } 1054 1055 applyTouchMove(differenceX, differenceY); 1056 startOffset = currentOffset; 1057 1058 var currentTime = new Date().getTime(); 1059 1060 var timeGap = currentTime - startTime; 1061 if (timeGap > 0) { 1062 speed.x = differenceX / timeGap; 1063 speed.y = differenceY / timeGap; 1064 startTime = currentTime; 1065 } 1066 1067 if (shouldPrevent(differenceX, differenceY)) { 1068 e.preventDefault(); 1069 } 1070 } 1071 } 1072 function touchEnd() { 1073 if (i.settings.swipeEasing) { 1074 clearInterval(easingLoop); 1075 easingLoop = setInterval(function() { 1076 if (i.isInitialized) { 1077 clearInterval(easingLoop); 1078 return; 1079 } 1080 1081 if (!speed.x && !speed.y) { 1082 clearInterval(easingLoop); 1083 return; 1084 } 1085 1086 if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) { 1087 clearInterval(easingLoop); 1088 return; 1089 } 1090 1091
vendor: 1,522 bytes, lines 1091-1141
1091applyTouchMove(speed.x * 30, speed.y * 30); 1092 1093 speed.x *= 0.8; 1094 speed.y *= 0.8; 1095 }, 10); 1096 } 1097 } 1098 1099 if (env.supportsTouch) { 1100 i.event.bind(element, 'touchstart', touchStart); 1101 i.event.bind(element, 'touchmove', touchMove); 1102 i.event.bind(element, 'touchend', touchEnd); 1103 } else if (env.supportsIePointer) { 1104 if (window.PointerEvent) { 1105 i.event.bind(element, 'pointerdown', touchStart); 1106 i.event.bind(element, 'pointermove', touchMove); 1107 i.event.bind(element, 'pointerup', touchEnd); 1108 } else if (window.MSPointerEvent) { 1109 i.event.bind(element, 'MSPointerDown', touchStart); 1110 i.event.bind(element, 'MSPointerMove', touchMove); 1111 i.event.bind(element, 'MSPointerUp', touchEnd); 1112 } 1113 } 1114 } 1115 1116 var defaultSettings = function () { return ({ 1117 handlers: ['click-rail', 'drag-thumb', 'keyboard', 'wheel', 'touch'], 1118 maxScrollbarLength: null, 1119 minScrollbarLength: null, 1120 scrollingThreshold: 1000, 1121 scrollXMarginOffset: 0, 1122 scrollYMarginOffset: 0, 1123 suppressScrollX: false, 1124 suppressScrollY: false, 1125 swipeEasing: true, 1126 useBothWheelAxes: false, 1127 wheelPropagation: true, 1128 wheelSpeed: 1, 1129 }); }; 1130 1131 var handlers = { 1132 'click-rail': clickRail, 1133 'drag-thumb': dragThumb, 1134 keyboard: keyboard, 1135 wheel: wheel, 1136 touch: touch, 1137 }; 1138 1139 var PerfectScrollbar = function PerfectScrollbar(element, userSettings) { 1140 var this$1 = this; 1141 if ( userSettings === void 0 ) userSettings = {};
vendor: 6,722 bytes, lines 1141-1346
1141 1142 1143 if (typeof element === 'string') { 1144 element = document.querySelector(element); 1145 } 1146 1147 if (!element || !element.nodeName) { 1148 throw new Error('no element is specified to initialize PerfectScrollbar'); 1149 } 1150 1151 this.element = element; 1152 1153 element.classList.add(cls.main); 1154 1155 this.settings = defaultSettings(); 1156 for (var key in userSettings) { 1157 this.settings[key] = userSettings[key]; 1158 } 1159 1160 this.containerWidth = null; 1161 this.containerHeight = null; 1162 this.contentWidth = null; 1163 this.contentHeight = null; 1164 1165 var focus = function () { return element.classList.add(cls.state.focus); }; 1166 var blur = function () { return element.classList.remove(cls.state.focus); }; 1167 1168 this.isRtl = get(element).direction === 'rtl'; 1169 if (this.isRtl === true) { 1170 element.classList.add(cls.rtl); 1171 } 1172 this.isNegativeScroll = (function () { 1173 var originalScrollLeft = element.scrollLeft; 1174 var result = null; 1175 element.scrollLeft = -1; 1176 result = element.scrollLeft < 0; 1177 element.scrollLeft = originalScrollLeft; 1178 return result; 1179 })(); 1180 this.negativeScrollAdjustment = this.isNegativeScroll 1181 ? element.scrollWidth - element.clientWidth 1182 : 0; 1183 this.event = new EventManager(); 1184 this.ownerDocument = element.ownerDocument || document; 1185 1186 this.scrollbarXRail = div(cls.element.rail('x')); 1187 element.appendChild(this.scrollbarXRail); 1188 this.scrollbarX = div(cls.element.thumb('x')); 1189 this.scrollbarXRail.appendChild(this.scrollbarX); 1190 this.scrollbarX.setAttribute('tabindex', 0); 1191 this.event.bind(this.scrollbarX, 'focus', focus); 1192 this.event.bind(this.scrollbarX, 'blur', blur); 1193 this.scrollbarXActive = null; 1194 this.scrollbarXWidth = null; 1195 this.scrollbarXLeft = null; 1196 var railXStyle = get(this.scrollbarXRail); 1197 this.scrollbarXBottom = parseInt(railXStyle.bottom, 10); 1198 if (isNaN(this.scrollbarXBottom)) { 1199 this.isScrollbarXUsingBottom = false; 1200 this.scrollbarXTop = toInt(railXStyle.top); 1201 } else { 1202 this.isScrollbarXUsingBottom = true; 1203 } 1204 this.railBorderXWidth = 1205 toInt(railXStyle.borderLeftWidth) + toInt(railXStyle.borderRightWidth); 1206 // Set rail to display:block to calculate margins 1207 set(this.scrollbarXRail, { display: 'block' }); 1208 this.railXMarginWidth = 1209 toInt(railXStyle.marginLeft) + toInt(railXStyle.marginRight); 1210 set(this.scrollbarXRail, { display: '' }); 1211 this.railXWidth = null; 1212 this.railXRatio = null; 1213 1214 this.scrollbarYRail = div(cls.element.rail('y')); 1215 element.appendChild(this.scrollbarYRail); 1216 this.scrollbarY = div(cls.element.thumb('y')); 1217 this.scrollbarYRail.appendChild(this.scrollbarY); 1218 this.scrollbarY.setAttribute('tabindex', 0); 1219 this.event.bind(this.scrollbarY, 'focus', focus); 1220 this.event.bind(this.scrollbarY, 'blur', blur); 1221 this.scrollbarYActive = null; 1222 this.scrollbarYHeight = null; 1223 this.scrollbarYTop = null; 1224 var railYStyle = get(this.scrollbarYRail); 1225 this.scrollbarYRight = parseInt(railYStyle.right, 10); 1226 if (isNaN(this.scrollbarYRight)) { 1227 this.isScrollbarYUsingRight = false; 1228 this.scrollbarYLeft = toInt(railYStyle.left); 1229 } else { 1230 this.isScrollbarYUsingRight = true; 1231 } 1232 this.scrollbarYOuterWidth = this.isRtl ? outerWidth(this.scrollbarY) : null; 1233 this.railBorderYWidth = 1234 toInt(railYStyle.borderTopWidth) + toInt(railYStyle.borderBottomWidth); 1235 set(this.scrollbarYRail, { display: 'block' }); 1236 this.railYMarginHeight = 1237 toInt(railYStyle.marginTop) + toInt(railYStyle.marginBottom); 1238 set(this.scrollbarYRail, { display: '' }); 1239 this.railYHeight = null; 1240 this.railYRatio = null; 1241 1242 this.reach = { 1243 x: 1244 element.scrollLeft <= 0 1245 ? 'start' 1246 : element.scrollLeft >= this.contentWidth - this.containerWidth 1247 ? 'end' 1248 : null, 1249 y: 1250 element.scrollTop <= 0 1251 ? 'start' 1252 : element.scrollTop >= this.contentHeight - this.containerHeight 1253 ? 'end' 1254 : null, 1255 }; 1256 1257 this.isAlive = true; 1258 1259 this.settings.handlers.forEach(function (handlerName) { return handlers[handlerName](this$1); }); 1260 1261 this.lastScrollTop = Math.floor(element.scrollTop); // for onScroll only 1262 this.lastScrollLeft = element.scrollLeft; // for onScroll only 1263 this.event.bind(this.element, 'scroll', function (e) { return this$1.onScroll(e); }); 1264 updateGeometry(this); 1265 }; 1266 1267 PerfectScrollbar.prototype.update = function update () { 1268 if (!this.isAlive) { 1269 return; 1270 } 1271 1272 // Recalcuate negative scrollLeft adjustment 1273 this.negativeScrollAdjustment = this.isNegativeScroll 1274 ? this.element.scrollWidth - this.element.clientWidth 1275 : 0; 1276 1277 // Recalculate rail margins 1278 set(this.scrollbarXRail, { display: 'block' }); 1279 set(this.scrollbarYRail, { display: 'block' }); 1280 this.railXMarginWidth = 1281 toInt(get(this.scrollbarXRail).marginLeft) + 1282 toInt(get(this.scrollbarXRail).marginRight); 1283 this.railYMarginHeight = 1284 toInt(get(this.scrollbarYRail).marginTop) + 1285 toInt(get(this.scrollbarYRail).marginBottom); 1286 1287 // Hide scrollbars not to affect scrollWidth and scrollHeight 1288 set(this.scrollbarXRail, { display: 'none' }); 1289 set(this.scrollbarYRail, { display: 'none' }); 1290 1291 updateGeometry(this); 1292 1293 processScrollDiff(this, 'top', 0, false, true); 1294 processScrollDiff(this, 'left', 0, false, true); 1295 1296 set(this.scrollbarXRail, { display: '' }); 1297 set(this.scrollbarYRail, { display: '' }); 1298 }; 1299 1300 PerfectScrollbar.prototype.onScroll = function onScroll (e) { 1301 if (!this.isAlive) { 1302 return; 1303 } 1304 1305 updateGeometry(this); 1306 processScrollDiff(this, 'top', this.element.scrollTop - this.lastScrollTop); 1307 processScrollDiff( 1308 this, 1309 'left', 1310 this.element.scrollLeft - this.lastScrollLeft 1311 ); 1312 1313 this.lastScrollTop = Math.floor(this.element.scrollTop); 1314 this.lastScrollLeft = this.element.scrollLeft; 1315 }; 1316 1317 PerfectScrollbar.prototype.destroy = function destroy () { 1318 if (!this.isAlive) { 1319 return; 1320 } 1321 1322 this.event.unbindAll(); 1323 remove(this.scrollbarX); 1324 remove(this.scrollbarY); 1325 remove(this.scrollbarXRail); 1326 remove(this.scrollbarYRail); 1327 this.removePsClasses(); 1328 1329 // unset elements 1330 this.element = null; 1331 this.scrollbarX = null; 1332 this.scrollbarY = null; 1333 this.scrollbarXRail = null; 1334 this.scrollbarYRail = null; 1335 1336 this.isAlive = false; 1337 }; 1338 1339 PerfectScrollbar.prototype.removePsClasses = function removePsClasses () { 1340 this.element.className = this.element.className 1341 .split(' ') 1342 .filter(function (name) { return !name.match(/^ps([-_].+|)$/); }) 1343 .join(' '); 1344 }; 1345 1346
1346return PerfectScrollbar; 1347 1348})));
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.