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