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