/* perfect-scrollbar v0.6.10 * * Copyright (c) 2015 Hyunje Alex Jun and other contributors * Licensed under the MIT License * * Source: https://github.com/noraesae/perfect-scrollbar */ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0) { classes.splice(idx, 1); } element.className = classes.join(' '); } exports.add = function (element, className) { if (element.classList) { element.classList.add(className); } else { oldAdd(element, className); } }; exports.remove = function (element, className) { if (element.classList) { element.classList.remove(className); } else { oldRemove(element, className); } }; exports.list = function (element) { if (element.classList) { return Array.prototype.slice.apply(element.classList); } else { return element.className.split(' '); } }; },{}],3:[function(require,module,exports){ 'use strict'; var DOM = {}; DOM.e = function (tagName, className) { var element = document.createElement(tagName); element.className = className; return element; }; DOM.appendTo = function (child, parent) { parent.appendChild(child); return child; }; function cssGet(element, styleName) { return window.getComputedStyle(element)[styleName]; } function cssSet(element, styleName, styleValue) { if (typeof styleValue === 'number') { styleValue = styleValue.toString() + 'px'; } element.style[styleName] = styleValue; return element; } function cssMultiSet(element, obj) { for (var key in obj) { var val = obj[key]; if (typeof val === 'number') { val = val.toString() + 'px'; } element.style[key] = val; } return element; } DOM.css = function (element, styleNameOrObject, styleValue) { if (typeof styleNameOrObject === 'object') { // multiple set with object return cssMultiSet(element, styleNameOrObject); } else { if (typeof styleValue === 'undefined') { return cssGet(element, styleNameOrObject); } else { return cssSet(element, styleNameOrObject, styleValue); } } }; DOM.matches = function (element, query) { if (typeof element.matches !== 'undefined') { return element.matches(query); } else { if (typeof element.matchesSelector !== 'undefined') { return element.matchesSelector(query); } else if (typeof element.webkitMatchesSelector !== 'undefined') { return element.webkitMatchesSelector(query); } else if (typeof element.mozMatchesSelector !== 'undefined') { return element.mozMatchesSelector(query); } else if (typeof element.msMatchesSelector !== 'undefined') { return element.msMatchesSelector(query); } } }; DOM.remove = function (element) { if (typeof element.remove !== 'undefined') { element.remove(); } else { if (element.parentNode) { element.parentNode.removeChild(element); } } }; DOM.queryChildren = function (element, selector) { return Array.prototype.filter.call(element.childNodes, function (child) { return DOM.matches(child, selector); }); }; module.exports = DOM; },{}],4:[function(require,module,exports){ 'use strict'; var EventElement = function (element) { this.element = element; this.events = {}; }; EventElement.prototype.bind = function (eventName, handler) { if (typeof this.events[eventName] === 'undefined') { this.events[eventName] = []; } this.events[eventName].push(handler); this.element.addEventListener(eventName, handler, false); }; EventElement.prototype.unbind = function (eventName, handler) { var isHandlerProvided = (typeof handler !== 'undefined'); this.events[eventName] = this.events[eventName].filter(function (hdlr) { if (isHandlerProvided && hdlr !== handler) { return true; } this.element.removeEventListener(eventName, hdlr, false); return false; }, this); }; EventElement.prototype.unbindAll = function () { for (var name in this.events) { this.unbind(name); } }; var EventManager = function () { this.eventElements = []; }; EventManager.prototype.eventElement = function (element) { var ee = this.eventElements.filter(function (eventElement) { return eventElement.element === element; })[0]; if (typeof ee === 'undefined') { ee = new EventElement(element); this.eventElements.push(ee); } return ee; }; EventManager.prototype.bind = function (element, eventName, handler) { this.eventElement(element).bind(eventName, handler); }; EventManager.prototype.unbind = function (element, eventName, handler) { this.eventElement(element).unbind(eventName, handler); }; EventManager.prototype.unbindAll = function () { for (var i = 0; i < this.eventElements.length; i++) { this.eventElements[i].unbindAll(); } }; EventManager.prototype.once = function (element, eventName, handler) { var ee = this.eventElement(element); var onceHandler = function (e) { ee.unbind(eventName, onceHandler); handler(e); }; ee.bind(eventName, onceHandler); }; module.exports = EventManager; },{}],5:[function(require,module,exports){ 'use strict'; module.exports = (function () { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return function () { return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); }; })(); },{}],6:[function(require,module,exports){ 'use strict'; var cls = require('./class') , d = require('./dom'); exports.toInt = function (x) { return parseInt(x, 10) || 0; }; exports.clone = function (obj) { if (obj === null) { return null; } else if (typeof obj === 'object') { var result = {}; for (var key in obj) { result[key] = this.clone(obj[key]); } return result; } else { return obj; } }; exports.extend = function (original, source) { var result = this.clone(original); for (var key in source) { result[key] = this.clone(source[key]); } return result; }; exports.isEditable = function (el) { return d.matches(el, "input,[contenteditable]") || d.matches(el, "select,[contenteditable]") || d.matches(el, "textarea,[contenteditable]") || d.matches(el, "button,[contenteditable]"); }; exports.removePsClasses = function (element) { var clsList = cls.list(element); for (var i = 0; i < clsList.length; i++) { var className = clsList[i]; if (className.indexOf('ps-') === 0) { cls.remove(element, className); } } }; exports.outerWidth = function (element) { return this.toInt(d.css(element, 'width')) + this.toInt(d.css(element, 'paddingLeft')) + this.toInt(d.css(element, 'paddingRight')) + this.toInt(d.css(element, 'borderLeftWidth')) + this.toInt(d.css(element, 'borderRightWidth')); }; exports.startScrolling = function (element, axis) { cls.add(element, 'ps-in-scrolling'); if (typeof axis !== 'undefined') { cls.add(element, 'ps-' + axis); } else { cls.add(element, 'ps-x'); cls.add(element, 'ps-y'); } }; exports.stopScrolling = function (element, axis) { cls.remove(element, 'ps-in-scrolling'); if (typeof axis !== 'undefined') { cls.remove(element, 'ps-' + axis); } else { cls.remove(element, 'ps-x'); cls.remove(element, 'ps-y'); } }; exports.env = { isWebKit: 'WebkitAppearance' in document.documentElement.style, supportsTouch: (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch), supportsIePointer: window.navigator.msMaxTouchPoints !== null }; },{"./class":2,"./dom":3}],7:[function(require,module,exports){ 'use strict'; var destroy = require('./plugin/destroy') , initialize = require('./plugin/initialize') , update = require('./plugin/update'); module.exports = { initialize: initialize, update: update, destroy: destroy }; },{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(require,module,exports){ 'use strict'; module.exports = { maxScrollbarLength: null, minScrollbarLength: null, scrollXMarginOffset: 0, scrollYMarginOffset: 0, stopPropagationOnClick: true, suppressScrollX: false, suppressScrollY: false, swipePropagation: true, useBothWheelAxes: false, useKeyboard: true, useSelectionScroll: false, wheelPropagation: false, wheelSpeed: 1, theme: 'default' }; },{}],9:[function(require,module,exports){ 'use strict'; var d = require('../lib/dom') , h = require('../lib/helper') , instances = require('./instances'); module.exports = function (element) { var i = instances.get(element); if (!i) { return; } i.event.unbindAll(); d.remove(i.scrollbarX); d.remove(i.scrollbarY); d.remove(i.scrollbarXRail); d.remove(i.scrollbarYRail); h.removePsClasses(element); instances.remove(element); }; },{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(require,module,exports){ 'use strict'; var h = require('../../lib/helper') , instances = require('../instances') , updateGeometry = require('../update-geometry') , updateScroll = require('../update-scroll'); function bindClickRailHandler(element, i) { function pageOffset(el) { return el.getBoundingClientRect(); } var stopPropagation = window.Event.prototype.stopPropagation.bind; if (i.settings.stopPropagationOnClick) { i.event.bind(i.scrollbarY, 'click', stopPropagation); } i.event.bind(i.scrollbarYRail, 'click', function (e) { var halfOfScrollbarLength = h.toInt(i.scrollbarYHeight / 2); var positionTop = i.railYRatio * (e.pageY - window.pageYOffset - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength); var maxPositionTop = i.railYRatio * (i.railYHeight - i.scrollbarYHeight); var positionRatio = positionTop / maxPositionTop; if (positionRatio < 0) { positionRatio = 0; } else if (positionRatio > 1) { positionRatio = 1; } updateScroll(element, 'top', (i.contentHeight - i.containerHeight) * positionRatio); updateGeometry(element); e.stopPropagation(); }); if (i.settings.stopPropagationOnClick) { i.event.bind(i.scrollbarX, 'click', stopPropagation); } i.event.bind(i.scrollbarXRail, 'click', function (e) { var halfOfScrollbarLength = h.toInt(i.scrollbarXWidth / 2); var positionLeft = i.railXRatio * (e.pageX - window.pageXOffset - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength); var maxPositionLeft = i.railXRatio * (i.railXWidth - i.scrollbarXWidth); var positionRatio = positionLeft / maxPositionLeft; if (positionRatio < 0) { positionRatio = 0; } else if (positionRatio > 1) { positionRatio = 1; } updateScroll(element, 'left', ((i.contentWidth - i.containerWidth) * positionRatio) - i.negativeScrollAdjustment); updateGeometry(element); e.stopPropagation(); }); } module.exports = function (element) { var i = instances.get(element); bindClickRailHandler(element, i); }; },{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(require,module,exports){ 'use strict'; var d = require('../../lib/dom') , h = require('../../lib/helper') , instances = require('../instances') , updateGeometry = require('../update-geometry') , updateScroll = require('../update-scroll'); function bindMouseScrollXHandler(element, i) { var currentLeft = null; var currentPageX = null; function updateScrollLeft(deltaX) { var newLeft = currentLeft + (deltaX * i.railXRatio); var maxLeft = Math.max(0, i.scrollbarXRail.getBoundingClientRect().left) + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth)); if (newLeft < 0) { i.scrollbarXLeft = 0; } else if (newLeft > maxLeft) { i.scrollbarXLeft = maxLeft; } else { i.scrollbarXLeft = newLeft; } var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment; updateScroll(element, 'left', scrollLeft); } var mouseMoveHandler = function (e) { updateScrollLeft(e.pageX - currentPageX); updateGeometry(element); e.stopPropagation(); e.preventDefault(); }; var mouseUpHandler = function () { h.stopScrolling(element, 'x'); i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler); }; i.event.bind(i.scrollbarX, 'mousedown', function (e) { currentPageX = e.pageX; currentLeft = h.toInt(d.css(i.scrollbarX, 'left')) * i.railXRatio; h.startScrolling(element, 'x'); i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler); e.stopPropagation(); e.preventDefault(); }); } function bindMouseScrollYHandler(element, i) { var currentTop = null; var currentPageY = null; function updateScrollTop(deltaY) { var newTop = currentTop + (deltaY * i.railYRatio); var maxTop = Math.max(0, i.scrollbarYRail.getBoundingClientRect().top) + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight)); if (newTop < 0) { i.scrollbarYTop = 0; } else if (newTop > maxTop) { i.scrollbarYTop = maxTop; } else { i.scrollbarYTop = newTop; } var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight))); updateScroll(element, 'top', scrollTop); } var mouseMoveHandler = function (e) { updateScrollTop(e.pageY - currentPageY); updateGeometry(element); e.stopPropagation(); e.preventDefault(); }; var mouseUpHandler = function () { h.stopScrolling(element, 'y'); i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler); }; i.event.bind(i.scrollbarY, 'mousedown', function (e) { currentPageY = e.pageY; currentTop = h.toInt(d.css(i.scrollbarY, 'top')) * i.railYRatio; h.startScrolling(element, 'y'); i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler); i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler); e.stopPropagation(); e.preventDefault(); }); } module.exports = function (element) { var i = instances.get(element); bindMouseScrollXHandler(element, i); bindMouseScrollYHandler(element, i); }; },{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(require,module,exports){ 'use strict'; var h = require('../../lib/helper') , d = require('../../lib/dom') , instances = require('../instances') , updateGeometry = require('../update-geometry') , updateScroll = require('../update-scroll'); function bindKeyboardHandler(element, i) { var hovered = false; i.event.bind(element, 'mouseenter', function () { hovered = true; }); i.event.bind(element, 'mouseleave', function () { hovered = false; }); var shouldPrevent = false; function shouldPreventDefault(deltaX, deltaY) { var scrollTop = element.scrollTop; if (deltaX === 0) { if (!i.scrollbarYActive) { return false; } if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) { return !i.settings.wheelPropagation; } } var scrollLeft = element.scrollLeft; if (deltaY === 0) { if (!i.scrollbarXActive) { return false; } if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) { return !i.settings.wheelPropagation; } } return true; } i.event.bind(i.ownerDocument, 'keydown', function (e) { if (e.isDefaultPrevented && e.isDefaultPrevented()) { return; } var focused = d.matches(i.scrollbarX, ':focus') || d.matches(i.scrollbarY, ':focus'); if (!hovered && !focused) { return; } var activeElement = document.activeElement ? document.activeElement : i.ownerDocument.activeElement; if (activeElement) { // go deeper if element is a webcomponent while (activeElement.shadowRoot) { activeElement = activeElement.shadowRoot.activeElement; } if (h.isEditable(activeElement)) { return; } } var deltaX = 0; var deltaY = 0; switch (e.which) { case 37: // left deltaX = -30; break; case 38: // up deltaY = 30; break; case 39: // right deltaX = 30; break; case 40: // down deltaY = -30; break; case 33: // page up deltaY = 90; break; case 32: // space bar if (e.shiftKey) { deltaY = 90; } else { deltaY = -90; } break; case 34: // page down deltaY = -90; break; case 35: // end if (e.ctrlKey) { deltaY = -i.contentHeight; } else { deltaY = -i.containerHeight; } break; case 36: // home if (e.ctrlKey) { deltaY = element.scrollTop; } else { deltaY = i.containerHeight; } break; default: return; } updateScroll(element, 'top', element.scrollTop - deltaY); updateScroll(element, 'left', element.scrollLeft + deltaX); updateGeometry(element); shouldPrevent = shouldPreventDefault(deltaX, deltaY); if (shouldPrevent) { e.preventDefault(); } }); } module.exports = function (element) { var i = instances.get(element); bindKeyboardHandler(element, i); }; },{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(require,module,exports){ 'use strict'; var instances = require('../instances') , updateGeometry = require('../update-geometry') , updateScroll = require('../update-scroll'); function bindMouseWheelHandler(element, i) { var shouldPrevent = false; function shouldPreventDefault(deltaX, deltaY) { var scrollTop = element.scrollTop; if (deltaX === 0) { if (!i.scrollbarYActive) { return false; } if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) { return !i.settings.wheelPropagation; } } var scrollLeft = element.scrollLeft; if (deltaY === 0) { if (!i.scrollbarXActive) { return false; } if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) { return !i.settings.wheelPropagation; } } return true; } function getDeltaFromEvent(e) { var deltaX = e.deltaX; var deltaY = -1 * e.deltaY; if (typeof deltaX === "undefined" || typeof deltaY === "undefined") { // OS X Safari deltaX = -1 * e.wheelDeltaX / 6; deltaY = e.wheelDeltaY / 6; } if (e.deltaMode && e.deltaMode === 1) { // Firefox in deltaMode 1: Line scrolling deltaX *= 10; deltaY *= 10; } if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) { // IE in some mouse drivers deltaX = 0; deltaY = e.wheelDelta; } return [deltaX, deltaY]; } function shouldBeConsumedByTextarea(deltaX, deltaY) { var hoveredTextarea = element.querySelector('textarea:hover'); if (hoveredTextarea) { var maxScrollTop = hoveredTextarea.scrollHeight - hoveredTextarea.clientHeight; if (maxScrollTop > 0) { if (!(hoveredTextarea.scrollTop === 0 && deltaY > 0) && !(hoveredTextarea.scrollTop === maxScrollTop && deltaY < 0)) { return true; } } var maxScrollLeft = hoveredTextarea.scrollLeft - hoveredTextarea.clientWidth; if (maxScrollLeft > 0) { if (!(hoveredTextarea.scrollLeft === 0 && deltaX < 0) && !(hoveredTextarea.scrollLeft === maxScrollLeft && deltaX > 0)) { return true; } } } return false; } function mousewheelHandler(e) { var delta = getDeltaFromEvent(e); var deltaX = delta[0]; var deltaY = delta[1]; if (shouldBeConsumedByTextarea(deltaX, deltaY)) { return; } shouldPrevent = false; if (!i.settings.useBothWheelAxes) { // deltaX will only be used for horizontal scrolling and deltaY will // only be used for vertical scrolling - this is the default updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed)); updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed)); } else if (i.scrollbarYActive && !i.scrollbarXActive) { // only vertical scrollbar is active and useBothWheelAxes option is // active, so let's scroll vertical bar using both mouse wheel axes if (deltaY) { updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed)); } else { updateScroll(element, 'top', element.scrollTop + (deltaX * i.settings.wheelSpeed)); } shouldPrevent = true; } else if (i.scrollbarXActive && !i.scrollbarYActive) { // useBothWheelAxes and only horizontal bar is active, so use both // wheel axes for horizontal bar if (deltaX) { updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed)); } else { updateScroll(element, 'left', element.scrollLeft - (deltaY * i.settings.wheelSpeed)); } shouldPrevent = true; } updateGeometry(element); shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY)); if (shouldPrevent) { e.stopPropagation(); e.preventDefault(); } } if (typeof window.onwheel !== "undefined") { i.event.bind(element, 'wheel', mousewheelHandler); } else if (typeof window.onmousewheel !== "undefined") { i.event.bind(element, 'mousewheel', mousewheelHandler); } } module.exports = function (element) { var i = instances.get(element); bindMouseWheelHandler(element, i); }; },{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(require,module,exports){ 'use strict'; var instances = require('../instances') , updateGeometry = require('../update-geometry'); function bindNativeScrollHandler(element, i) { i.event.bind(element, 'scroll', function () { updateGeometry(element); }); } module.exports = function (element) { var i = instances.get(element); bindNativeScrollHandler(element, i); }; },{"../instances":18,"../update-geometry":19}],15:[function(require,module,exports){ 'use strict'; var h = require('../../lib/helper') , instances = require('../instances') , updateGeometry = require('../update-geometry') , updateScroll = require('../update-scroll'); function bindSelectionHandler(element, i) { function getRangeNode() { var selection = window.getSelection ? window.getSelection() : document.getSelection ? document.getSelection() : ''; if (selection.toString().length === 0) { return null; } else { return selection.getRangeAt(0).commonAncestorContainer; } } var scrollingLoop = null; var scrollDiff = {top: 0, left: 0}; function startScrolling() { if (!scrollingLoop) { scrollingLoop = setInterval(function () { if (!instances.get(element)) { clearInterval(scrollingLoop); return; } updateScroll(element, 'top', element.scrollTop + scrollDiff.top); updateScroll(element, 'left', element.scrollLeft + scrollDiff.left); updateGeometry(element); }, 50); // every .1 sec } } function stopScrolling() { if (scrollingLoop) { clearInterval(scrollingLoop); scrollingLoop = null; } h.stopScrolling(element); } var isSelected = false; i.event.bind(i.ownerDocument, 'selectionchange', function () { if (element.contains(getRangeNode())) { isSelected = true; } else { isSelected = false; stopScrolling(); } }); i.event.bind(window, 'mouseup', function () { if (isSelected) { isSelected = false; stopScrolling(); } }); i.event.bind(window, 'mousemove', function (e) { if (isSelected) { var mousePosition = {x: e.pageX, y: e.pageY}; var containerGeometry = { left: element.offsetLeft, right: element.offsetLeft + element.offsetWidth, top: element.offsetTop, bottom: element.offsetTop + element.offsetHeight }; if (mousePosition.x < containerGeometry.left + 3) { scrollDiff.left = -5; h.startScrolling(element, 'x'); } else if (mousePosition.x > containerGeometry.right - 3) { scrollDiff.left = 5; h.startScrolling(element, 'x'); } else { scrollDiff.left = 0; } if (mousePosition.y < containerGeometry.top + 3) { if (containerGeometry.top + 3 - mousePosition.y < 5) { scrollDiff.top = -5; } else { scrollDiff.top = -20; } h.startScrolling(element, 'y'); } else if (mousePosition.y > containerGeometry.bottom - 3) { if (mousePosition.y - containerGeometry.bottom + 3 < 5) { scrollDiff.top = 5; } else { scrollDiff.top = 20; } h.startScrolling(element, 'y'); } else { scrollDiff.top = 0; } if (scrollDiff.top === 0 && scrollDiff.left === 0) { stopScrolling(); } else { startScrolling(); } } }); } module.exports = function (element) { var i = instances.get(element); bindSelectionHandler(element, i); }; },{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(require,module,exports){ 'use strict'; var instances = require('../instances') , updateGeometry = require('../update-geometry') , updateScroll = require('../update-scroll'); function bindTouchHandler(element, i, supportsTouch, supportsIePointer) { function shouldPreventDefault(deltaX, deltaY) { var scrollTop = element.scrollTop; var scrollLeft = element.scrollLeft; var magnitudeX = Math.abs(deltaX); var magnitudeY = Math.abs(deltaY); if (magnitudeY > magnitudeX) { // user is perhaps trying to swipe up/down the page if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) || ((deltaY > 0) && (scrollTop === 0))) { return !i.settings.swipePropagation; } } else if (magnitudeX > magnitudeY) { // user is perhaps trying to swipe left/right across the page if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) || ((deltaX > 0) && (scrollLeft === 0))) { return !i.settings.swipePropagation; } } return true; } function applyTouchMove(differenceX, differenceY) { updateScroll(element, 'top', element.scrollTop - differenceY); updateScroll(element, 'left', element.scrollLeft - differenceX); updateGeometry(element); } var startOffset = {}; var startTime = 0; var speed = {}; var easingLoop = null; var inGlobalTouch = false; var inLocalTouch = false; function globalTouchStart() { inGlobalTouch = true; } function globalTouchEnd() { inGlobalTouch = false; } function getTouch(e) { if (e.targetTouches) { return e.targetTouches[0]; } else { // Maybe IE pointer return e; } } function shouldHandle(e) { if (e.targetTouches && e.targetTouches.length === 1) { return true; } if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) { return true; } return false; } function touchStart(e) { if (shouldHandle(e)) { inLocalTouch = true; var touch = getTouch(e); startOffset.pageX = touch.pageX; startOffset.pageY = touch.pageY; startTime = (new Date()).getTime(); if (easingLoop !== null) { clearInterval(easingLoop); } e.stopPropagation(); } } function touchMove(e) { if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) { var touch = getTouch(e); var currentOffset = {pageX: touch.pageX, pageY: touch.pageY}; var differenceX = currentOffset.pageX - startOffset.pageX; var differenceY = currentOffset.pageY - startOffset.pageY; applyTouchMove(differenceX, differenceY); startOffset = currentOffset; var currentTime = (new Date()).getTime(); var timeGap = currentTime - startTime; if (timeGap > 0) { speed.x = differenceX / timeGap; speed.y = differenceY / timeGap; startTime = currentTime; } if (shouldPreventDefault(differenceX, differenceY)) { e.stopPropagation(); e.preventDefault(); } } } function touchEnd() { if (!inGlobalTouch && inLocalTouch) { inLocalTouch = false; clearInterval(easingLoop); easingLoop = setInterval(function () { if (!instances.get(element)) { clearInterval(easingLoop); return; } if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) { clearInterval(easingLoop); return; } applyTouchMove(speed.x * 30, speed.y * 30); speed.x *= 0.8; speed.y *= 0.8; }, 10); } } if (supportsTouch) { i.event.bind(window, 'touchstart', globalTouchStart); i.event.bind(window, 'touchend', globalTouchEnd); i.event.bind(element, 'touchstart', touchStart); i.event.bind(element, 'touchmove', touchMove); i.event.bind(element, 'touchend', touchEnd); } if (supportsIePointer) { if (window.PointerEvent) { i.event.bind(window, 'pointerdown', globalTouchStart); i.event.bind(window, 'pointerup', globalTouchEnd); i.event.bind(element, 'pointerdown', touchStart); i.event.bind(element, 'pointermove', touchMove); i.event.bind(element, 'pointerup', touchEnd); } else if (window.MSPointerEvent) { i.event.bind(window, 'MSPointerDown', globalTouchStart); i.event.bind(window, 'MSPointerUp', globalTouchEnd); i.event.bind(element, 'MSPointerDown', touchStart); i.event.bind(element, 'MSPointerMove', touchMove); i.event.bind(element, 'MSPointerUp', touchEnd); } } } module.exports = function (element, supportsTouch, supportsIePointer) { var i = instances.get(element); bindTouchHandler(element, i, supportsTouch, supportsIePointer); }; },{"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(require,module,exports){ 'use strict'; var cls = require('../lib/class') , h = require('../lib/helper') , instances = require('./instances') , updateGeometry = require('./update-geometry'); // Handlers var clickRailHandler = require('./handler/click-rail') , dragScrollbarHandler = require('./handler/drag-scrollbar') , keyboardHandler = require('./handler/keyboard') , mouseWheelHandler = require('./handler/mouse-wheel') , nativeScrollHandler = require('./handler/native-scroll') , selectionHandler = require('./handler/selection') , touchHandler = require('./handler/touch'); module.exports = function (element, userSettings) { userSettings = typeof userSettings === 'object' ? userSettings : {}; cls.add(element, 'ps-container'); // Create a plugin instance. var i = instances.add(element); i.settings = h.extend(i.settings, userSettings); cls.add(element, 'ps-theme-' + i.settings.theme); clickRailHandler(element); dragScrollbarHandler(element); mouseWheelHandler(element); nativeScrollHandler(element); if (i.settings.useSelectionScroll) { selectionHandler(element); } if (h.env.supportsTouch || h.env.supportsIePointer) { touchHandler(element, h.env.supportsTouch, h.env.supportsIePointer); } if (i.settings.useKeyboard) { keyboardHandler(element); } updateGeometry(element); }; },{"../lib/class":2,"../lib/helper":6,"./handler/click-rail":10,"./handler/drag-scrollbar":11,"./handler/keyboard":12,"./handler/mouse-wheel":13,"./handler/native-scroll":14,"./handler/selection":15,"./handler/touch":16,"./instances":18,"./update-geometry":19}],18:[function(require,module,exports){ 'use strict'; var cls = require('../lib/class') , d = require('../lib/dom') , defaultSettings = require('./default-setting') , EventManager = require('../lib/event-manager') , guid = require('../lib/guid') , h = require('../lib/helper'); var instances = {}; function Instance(element) { var i = this; i.settings = h.clone(defaultSettings); i.containerWidth = null; i.containerHeight = null; i.contentWidth = null; i.contentHeight = null; i.isRtl = d.css(element, 'direction') === "rtl"; i.isNegativeScroll = (function () { var originalScrollLeft = element.scrollLeft; var result = null; element.scrollLeft = -1; result = element.scrollLeft < 0; element.scrollLeft = originalScrollLeft; return result; })(); i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0; i.event = new EventManager(); i.ownerDocument = element.ownerDocument || document; function focus() { cls.add(element, 'ps-focus'); } function blur() { cls.remove(element, 'ps-focus'); } i.scrollbarXRail = d.appendTo(d.e('div', 'ps-scrollbar-x-rail'), element); i.scrollbarX = d.appendTo(d.e('div', 'ps-scrollbar-x'), i.scrollbarXRail); i.scrollbarX.setAttribute('tabindex', 0); i.event.bind(i.scrollbarX, 'focus', focus); i.event.bind(i.scrollbarX, 'blur', blur); i.scrollbarXActive = null; i.scrollbarXWidth = null; i.scrollbarXLeft = null; i.scrollbarXBottom = h.toInt(d.css(i.scrollbarXRail, 'bottom')); i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : h.toInt(d.css(i.scrollbarXRail, 'top')); i.railBorderXWidth = h.toInt(d.css(i.scrollbarXRail, 'borderLeftWidth')) + h.toInt(d.css(i.scrollbarXRail, 'borderRightWidth')); // Set rail to display:block to calculate margins d.css(i.scrollbarXRail, 'display', 'block'); i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight')); d.css(i.scrollbarXRail, 'display', ''); i.railXWidth = null; i.railXRatio = null; i.scrollbarYRail = d.appendTo(d.e('div', 'ps-scrollbar-y-rail'), element); i.scrollbarY = d.appendTo(d.e('div', 'ps-scrollbar-y'), i.scrollbarYRail); i.scrollbarY.setAttribute('tabindex', 0); i.event.bind(i.scrollbarY, 'focus', focus); i.event.bind(i.scrollbarY, 'blur', blur); i.scrollbarYActive = null; i.scrollbarYHeight = null; i.scrollbarYTop = null; i.scrollbarYRight = h.toInt(d.css(i.scrollbarYRail, 'right')); i.isScrollbarYUsingRight = i.scrollbarYRight === i.scrollbarYRight; // !isNaN i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : h.toInt(d.css(i.scrollbarYRail, 'left')); i.scrollbarYOuterWidth = i.isRtl ? h.outerWidth(i.scrollbarY) : null; i.railBorderYWidth = h.toInt(d.css(i.scrollbarYRail, 'borderTopWidth')) + h.toInt(d.css(i.scrollbarYRail, 'borderBottomWidth')); d.css(i.scrollbarYRail, 'display', 'block'); i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom')); d.css(i.scrollbarYRail, 'display', ''); i.railYHeight = null; i.railYRatio = null; } function getId(element) { if (typeof element.dataset === 'undefined') { return element.getAttribute('data-ps-id'); } else { return element.dataset.psId; } } function setId(element, id) { if (typeof element.dataset === 'undefined') { element.setAttribute('data-ps-id', id); } else { element.dataset.psId = id; } } function removeId(element) { if (typeof element.dataset === 'undefined') { element.removeAttribute('data-ps-id'); } else { delete element.dataset.psId; } } exports.add = function (element) { var newId = guid(); setId(element, newId); instances[newId] = new Instance(element); return instances[newId]; }; exports.remove = function (element) { delete instances[getId(element)]; removeId(element); }; exports.get = function (element) { return instances[getId(element)]; }; },{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(require,module,exports){ 'use strict'; var cls = require('../lib/class') , d = require('../lib/dom') , h = require('../lib/helper') , instances = require('./instances') , updateScroll = require('./update-scroll'); function getThumbSize(i, thumbSize) { if (i.settings.minScrollbarLength) { thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength); } if (i.settings.maxScrollbarLength) { thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength); } return thumbSize; } function updateCss(element, i) { var xRailOffset = {width: i.railXWidth}; if (i.isRtl) { xRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth - i.contentWidth; } else { xRailOffset.left = element.scrollLeft; } if (i.isScrollbarXUsingBottom) { xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop; } else { xRailOffset.top = i.scrollbarXTop + element.scrollTop; } d.css(i.scrollbarXRail, xRailOffset); var yRailOffset = {top: element.scrollTop, height: i.railYHeight}; if (i.isScrollbarYUsingRight) { if (i.isRtl) { yRailOffset.right = i.contentWidth - (i.negativeScrollAdjustment + element.scrollLeft) - i.scrollbarYRight - i.scrollbarYOuterWidth; } else { yRailOffset.right = i.scrollbarYRight - element.scrollLeft; } } else { if (i.isRtl) { yRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth; } else { yRailOffset.left = i.scrollbarYLeft + element.scrollLeft; } } d.css(i.scrollbarYRail, yRailOffset); d.css(i.scrollbarX, {left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth}); d.css(i.scrollbarY, {top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth}); } module.exports = function (element) { var i = instances.get(element); i.containerWidth = element.clientWidth; i.containerHeight = element.clientHeight; i.contentWidth = element.scrollWidth; i.contentHeight = element.scrollHeight; var existingRails; if (!element.contains(i.scrollbarXRail)) { existingRails = d.queryChildren(element, '.ps-scrollbar-x-rail'); if (existingRails.length > 0) { existingRails.forEach(function (rail) { d.remove(rail); }); } d.appendTo(i.scrollbarXRail, element); } if (!element.contains(i.scrollbarYRail)) { existingRails = d.queryChildren(element, '.ps-scrollbar-y-rail'); if (existingRails.length > 0) { existingRails.forEach(function (rail) { d.remove(rail); }); } d.appendTo(i.scrollbarYRail, element); } if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) { i.scrollbarXActive = true; i.railXWidth = i.containerWidth - i.railXMarginWidth; i.railXRatio = i.containerWidth / i.railXWidth; i.scrollbarXWidth = getThumbSize(i, h.toInt(i.railXWidth * i.containerWidth / i.contentWidth)); i.scrollbarXLeft = h.toInt((i.negativeScrollAdjustment + element.scrollLeft) * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth)); } else { i.scrollbarXActive = false; } if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) { i.scrollbarYActive = true; i.railYHeight = i.containerHeight - i.railYMarginHeight; i.railYRatio = i.containerHeight / i.railYHeight; i.scrollbarYHeight = getThumbSize(i, h.toInt(i.railYHeight * i.containerHeight / i.contentHeight)); i.scrollbarYTop = h.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight)); } else { i.scrollbarYActive = false; } if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) { i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth; } if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) { i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight; } updateCss(element, i); if (i.scrollbarXActive) { cls.add(element, 'ps-active-x'); } else { cls.remove(element, 'ps-active-x'); i.scrollbarXWidth = 0; i.scrollbarXLeft = 0; updateScroll(element, 'left', 0); } if (i.scrollbarYActive) { cls.add(element, 'ps-active-y'); } else { cls.remove(element, 'ps-active-y'); i.scrollbarYHeight = 0; i.scrollbarYTop = 0; updateScroll(element, 'top', 0); } }; },{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(require,module,exports){ 'use strict'; var instances = require('./instances'); var upEvent = document.createEvent('Event') , downEvent = document.createEvent('Event') , leftEvent = document.createEvent('Event') , rightEvent = document.createEvent('Event') , yEvent = document.createEvent('Event') , xEvent = document.createEvent('Event') , xStartEvent = document.createEvent('Event') , xEndEvent = document.createEvent('Event') , yStartEvent = document.createEvent('Event') , yEndEvent = document.createEvent('Event') , lastTop , lastLeft; upEvent.initEvent('ps-scroll-up', true, true); downEvent.initEvent('ps-scroll-down', true, true); leftEvent.initEvent('ps-scroll-left', true, true); rightEvent.initEvent('ps-scroll-right', true, true); yEvent.initEvent('ps-scroll-y', true, true); xEvent.initEvent('ps-scroll-x', true, true); xStartEvent.initEvent('ps-x-reach-start', true, true); xEndEvent.initEvent('ps-x-reach-end', true, true); yStartEvent.initEvent('ps-y-reach-start', true, true); yEndEvent.initEvent('ps-y-reach-end', true, true); module.exports = function (element, axis, value) { if (typeof element === 'undefined') { throw 'You must provide an element to the update-scroll function'; } if (typeof axis === 'undefined') { throw 'You must provide an axis to the update-scroll function'; } if (typeof value === 'undefined') { throw 'You must provide a value to the update-scroll function'; } if (axis === 'top' && value <= 0) { element.scrollTop = value = 0; // don't allow negative scroll element.dispatchEvent(yStartEvent); } if (axis === 'left' && value <= 0) { element.scrollLeft = value = 0; // don't allow negative scroll element.dispatchEvent(xStartEvent); } var i = instances.get(element); if (axis === 'top' && value >= i.contentHeight - i.containerHeight) { element.scrollTop = value = i.contentHeight - i.containerHeight; // don't allow scroll past container element.dispatchEvent(yEndEvent); } if (axis === 'left' && value >= i.contentWidth - i.containerWidth) { element.scrollLeft = value = i.contentWidth - i.containerWidth; // don't allow scroll past container element.dispatchEvent(xEndEvent); } if (!lastTop) { lastTop = element.scrollTop; } if (!lastLeft) { lastLeft = element.scrollLeft; } if (axis === 'top' && value < lastTop) { element.dispatchEvent(upEvent); } if (axis === 'top' && value > lastTop) { element.dispatchEvent(downEvent); } if (axis === 'left' && value < lastLeft) { element.dispatchEvent(leftEvent); } if (axis === 'left' && value > lastLeft) { element.dispatchEvent(rightEvent); } if (axis === 'top') { element.scrollTop = lastTop = value; element.dispatchEvent(yEvent); } if (axis === 'left') { element.scrollLeft = lastLeft = value; element.dispatchEvent(xEvent); } }; },{"./instances":18}],21:[function(require,module,exports){ 'use strict'; var d = require('../lib/dom') , h = require('../lib/helper') , instances = require('./instances') , updateGeometry = require('./update-geometry') , updateScroll = require('./update-scroll'); module.exports = function (element) { var i = instances.get(element); if (!i) { return; } // Recalcuate negative scrollLeft adjustment i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0; // Recalculate rail margins d.css(i.scrollbarXRail, 'display', 'block'); d.css(i.scrollbarYRail, 'display', 'block'); i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight')); i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom')); // Hide scrollbars not to affect scrollWidth and scrollHeight d.css(i.scrollbarXRail, 'display', 'none'); d.css(i.scrollbarYRail, 'display', 'none'); updateGeometry(element); // Update top/left scroll to trigger events updateScroll(element, 'top', element.scrollTop); updateScroll(element, 'left', element.scrollLeft); d.css(i.scrollbarXRail, 'display', ''); d.css(i.scrollbarYRail, 'display', ''); }; },{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]);