1 /* perfect-scrollbar v0.6.11 */
2 (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<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
5 var ps = require('../main');
6 var psInstances = require('../plugin/instances');
8 function mountJQuery(jQuery) {
9 jQuery.fn.perfectScrollbar = function (settingOrCommand) {
10 return this.each(function () {
11 if (typeof settingOrCommand === 'object' ||
12 typeof settingOrCommand === 'undefined') {
13 // If it's an object or none, initialize.
14 var settings = settingOrCommand;
16 if (!psInstances.get(this)) {
17 ps.initialize(this, settings);
20 // Unless, it may be a command.
21 var command = settingOrCommand;
23 if (command === 'update') {
25 } else if (command === 'destroy') {
33 if (typeof define === 'function' && define.amd) {
34 // AMD. Register as an anonymous module.
35 define(['jquery'], mountJQuery);
37 var jq = window.jQuery ? window.jQuery : window.$;
38 if (typeof jq !== 'undefined') {
43 module.exports = mountJQuery;
45 },{"../main":7,"../plugin/instances":18}],2:[function(require,module,exports){
48 function oldAdd(element, className) {
49 var classes = element.className.split(' ');
50 if (classes.indexOf(className) < 0) {
51 classes.push(className);
53 element.className = classes.join(' ');
56 function oldRemove(element, className) {
57 var classes = element.className.split(' ');
58 var idx = classes.indexOf(className);
60 classes.splice(idx, 1);
62 element.className = classes.join(' ');
65 exports.add = function (element, className) {
66 if (element.classList) {
67 element.classList.add(className);
69 oldAdd(element, className);
73 exports.remove = function (element, className) {
74 if (element.classList) {
75 element.classList.remove(className);
77 oldRemove(element, className);
81 exports.list = function (element) {
82 if (element.classList) {
83 return Array.prototype.slice.apply(element.classList);
85 return element.className.split(' ');
89 },{}],3:[function(require,module,exports){
94 DOM.e = function (tagName, className) {
95 var element = document.createElement(tagName);
96 element.className = className;
100 DOM.appendTo = function (child, parent) {
101 parent.appendChild(child);
105 function cssGet(element, styleName) {
106 return window.getComputedStyle(element)[styleName];
109 function cssSet(element, styleName, styleValue) {
110 if (typeof styleValue === 'number') {
111 styleValue = styleValue.toString() + 'px';
113 element.style[styleName] = styleValue;
117 function cssMultiSet(element, obj) {
118 for (var key in obj) {
120 if (typeof val === 'number') {
121 val = val.toString() + 'px';
123 element.style[key] = val;
128 DOM.css = function (element, styleNameOrObject, styleValue) {
129 if (typeof styleNameOrObject === 'object') {
130 // multiple set with object
131 return cssMultiSet(element, styleNameOrObject);
133 if (typeof styleValue === 'undefined') {
134 return cssGet(element, styleNameOrObject);
136 return cssSet(element, styleNameOrObject, styleValue);
141 DOM.matches = function (element, query) {
142 if (typeof element.matches !== 'undefined') {
143 return element.matches(query);
145 if (typeof element.matchesSelector !== 'undefined') {
146 return element.matchesSelector(query);
147 } else if (typeof element.webkitMatchesSelector !== 'undefined') {
148 return element.webkitMatchesSelector(query);
149 } else if (typeof element.mozMatchesSelector !== 'undefined') {
150 return element.mozMatchesSelector(query);
151 } else if (typeof element.msMatchesSelector !== 'undefined') {
152 return element.msMatchesSelector(query);
157 DOM.remove = function (element) {
158 if (typeof element.remove !== 'undefined') {
161 if (element.parentNode) {
162 element.parentNode.removeChild(element);
167 DOM.queryChildren = function (element, selector) {
168 return Array.prototype.filter.call(element.childNodes, function (child) {
169 return DOM.matches(child, selector);
173 module.exports = DOM;
175 },{}],4:[function(require,module,exports){
178 var EventElement = function (element) {
179 this.element = element;
183 EventElement.prototype.bind = function (eventName, handler) {
184 if (typeof this.events[eventName] === 'undefined') {
185 this.events[eventName] = [];
187 this.events[eventName].push(handler);
188 this.element.addEventListener(eventName, handler, false);
191 EventElement.prototype.unbind = function (eventName, handler) {
192 var isHandlerProvided = (typeof handler !== 'undefined');
193 this.events[eventName] = this.events[eventName].filter(function (hdlr) {
194 if (isHandlerProvided && hdlr !== handler) {
197 this.element.removeEventListener(eventName, hdlr, false);
202 EventElement.prototype.unbindAll = function () {
203 for (var name in this.events) {
208 var EventManager = function () {
209 this.eventElements = [];
212 EventManager.prototype.eventElement = function (element) {
213 var ee = this.eventElements.filter(function (eventElement) {
214 return eventElement.element === element;
216 if (typeof ee === 'undefined') {
217 ee = new EventElement(element);
218 this.eventElements.push(ee);
223 EventManager.prototype.bind = function (element, eventName, handler) {
224 this.eventElement(element).bind(eventName, handler);
227 EventManager.prototype.unbind = function (element, eventName, handler) {
228 this.eventElement(element).unbind(eventName, handler);
231 EventManager.prototype.unbindAll = function () {
232 for (var i = 0; i < this.eventElements.length; i++) {
233 this.eventElements[i].unbindAll();
237 EventManager.prototype.once = function (element, eventName, handler) {
238 var ee = this.eventElement(element);
239 var onceHandler = function (e) {
240 ee.unbind(eventName, onceHandler);
243 ee.bind(eventName, onceHandler);
246 module.exports = EventManager;
248 },{}],5:[function(require,module,exports){
251 module.exports = (function () {
253 return Math.floor((1 + Math.random()) * 0x10000)
258 return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
259 s4() + '-' + s4() + s4() + s4();
263 },{}],6:[function(require,module,exports){
266 var cls = require('./class');
267 var dom = require('./dom');
269 var toInt = exports.toInt = function (x) {
270 return parseInt(x, 10) || 0;
273 var clone = exports.clone = function (obj) {
276 } else if (obj.constructor === Array) {
277 return obj.map(clone);
278 } else if (typeof obj === 'object') {
280 for (var key in obj) {
281 result[key] = clone(obj[key]);
289 exports.extend = function (original, source) {
290 var result = clone(original);
291 for (var key in source) {
292 result[key] = clone(source[key]);
297 exports.isEditable = function (el) {
298 return dom.matches(el, "input,[contenteditable]") ||
299 dom.matches(el, "select,[contenteditable]") ||
300 dom.matches(el, "textarea,[contenteditable]") ||
301 dom.matches(el, "button,[contenteditable]");
304 exports.removePsClasses = function (element) {
305 var clsList = cls.list(element);
306 for (var i = 0; i < clsList.length; i++) {
307 var className = clsList[i];
308 if (className.indexOf('ps-') === 0) {
309 cls.remove(element, className);
314 exports.outerWidth = function (element) {
315 return toInt(dom.css(element, 'width')) +
316 toInt(dom.css(element, 'paddingLeft')) +
317 toInt(dom.css(element, 'paddingRight')) +
318 toInt(dom.css(element, 'borderLeftWidth')) +
319 toInt(dom.css(element, 'borderRightWidth'));
322 exports.startScrolling = function (element, axis) {
323 cls.add(element, 'ps-in-scrolling');
324 if (typeof axis !== 'undefined') {
325 cls.add(element, 'ps-' + axis);
327 cls.add(element, 'ps-x');
328 cls.add(element, 'ps-y');
332 exports.stopScrolling = function (element, axis) {
333 cls.remove(element, 'ps-in-scrolling');
334 if (typeof axis !== 'undefined') {
335 cls.remove(element, 'ps-' + axis);
337 cls.remove(element, 'ps-x');
338 cls.remove(element, 'ps-y');
343 isWebKit: 'WebkitAppearance' in document.documentElement.style,
344 supportsTouch: (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),
345 supportsIePointer: window.navigator.msMaxTouchPoints !== null
348 },{"./class":2,"./dom":3}],7:[function(require,module,exports){
351 var destroy = require('./plugin/destroy');
352 var initialize = require('./plugin/initialize');
353 var update = require('./plugin/update');
356 initialize: initialize,
361 },{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(require,module,exports){
365 handlers: ['click-rail', 'drag-scrollbar', 'keyboard', 'wheel', 'touch'],
366 maxScrollbarLength: null,
367 minScrollbarLength: null,
368 scrollXMarginOffset: 0,
369 scrollYMarginOffset: 0,
370 stopPropagationOnClick: true,
371 suppressScrollX: false,
372 suppressScrollY: false,
373 swipePropagation: true,
374 useBothWheelAxes: false,
375 wheelPropagation: false,
380 },{}],9:[function(require,module,exports){
383 var _ = require('../lib/helper');
384 var dom = require('../lib/dom');
385 var instances = require('./instances');
387 module.exports = function (element) {
388 var i = instances.get(element);
395 dom.remove(i.scrollbarX);
396 dom.remove(i.scrollbarY);
397 dom.remove(i.scrollbarXRail);
398 dom.remove(i.scrollbarYRail);
399 _.removePsClasses(element);
401 instances.remove(element);
404 },{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(require,module,exports){
407 var _ = require('../../lib/helper');
408 var instances = require('../instances');
409 var updateGeometry = require('../update-geometry');
410 var updateScroll = require('../update-scroll');
412 function bindClickRailHandler(element, i) {
413 function pageOffset(el) {
414 return el.getBoundingClientRect();
416 var stopPropagation = function (e) { e.stopPropagation(); };
418 if (i.settings.stopPropagationOnClick) {
419 i.event.bind(i.scrollbarY, 'click', stopPropagation);
421 i.event.bind(i.scrollbarYRail, 'click', function (e) {
422 var halfOfScrollbarLength = _.toInt(i.scrollbarYHeight / 2);
423 var positionTop = i.railYRatio * (e.pageY - window.pageYOffset - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength);
424 var maxPositionTop = i.railYRatio * (i.railYHeight - i.scrollbarYHeight);
425 var positionRatio = positionTop / maxPositionTop;
427 if (positionRatio < 0) {
429 } else if (positionRatio > 1) {
433 updateScroll(element, 'top', (i.contentHeight - i.containerHeight) * positionRatio);
434 updateGeometry(element);
439 if (i.settings.stopPropagationOnClick) {
440 i.event.bind(i.scrollbarX, 'click', stopPropagation);
442 i.event.bind(i.scrollbarXRail, 'click', function (e) {
443 var halfOfScrollbarLength = _.toInt(i.scrollbarXWidth / 2);
444 var positionLeft = i.railXRatio * (e.pageX - window.pageXOffset - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength);
445 var maxPositionLeft = i.railXRatio * (i.railXWidth - i.scrollbarXWidth);
446 var positionRatio = positionLeft / maxPositionLeft;
448 if (positionRatio < 0) {
450 } else if (positionRatio > 1) {
454 updateScroll(element, 'left', ((i.contentWidth - i.containerWidth) * positionRatio) - i.negativeScrollAdjustment);
455 updateGeometry(element);
461 module.exports = function (element) {
462 var i = instances.get(element);
463 bindClickRailHandler(element, i);
466 },{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(require,module,exports){
469 var _ = require('../../lib/helper');
470 var dom = require('../../lib/dom');
471 var instances = require('../instances');
472 var updateGeometry = require('../update-geometry');
473 var updateScroll = require('../update-scroll');
475 function bindMouseScrollXHandler(element, i) {
476 var currentLeft = null;
477 var currentPageX = null;
479 function updateScrollLeft(deltaX) {
480 var newLeft = currentLeft + (deltaX * i.railXRatio);
481 var maxLeft = Math.max(0, i.scrollbarXRail.getBoundingClientRect().left) + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));
484 i.scrollbarXLeft = 0;
485 } else if (newLeft > maxLeft) {
486 i.scrollbarXLeft = maxLeft;
488 i.scrollbarXLeft = newLeft;
491 var scrollLeft = _.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment;
492 updateScroll(element, 'left', scrollLeft);
495 var mouseMoveHandler = function (e) {
496 updateScrollLeft(e.pageX - currentPageX);
497 updateGeometry(element);
502 var mouseUpHandler = function () {
503 _.stopScrolling(element, 'x');
504 i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
507 i.event.bind(i.scrollbarX, 'mousedown', function (e) {
508 currentPageX = e.pageX;
509 currentLeft = _.toInt(dom.css(i.scrollbarX, 'left')) * i.railXRatio;
510 _.startScrolling(element, 'x');
512 i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
513 i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
520 function bindMouseScrollYHandler(element, i) {
521 var currentTop = null;
522 var currentPageY = null;
524 function updateScrollTop(deltaY) {
525 var newTop = currentTop + (deltaY * i.railYRatio);
526 var maxTop = Math.max(0, i.scrollbarYRail.getBoundingClientRect().top) + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));
530 } else if (newTop > maxTop) {
531 i.scrollbarYTop = maxTop;
533 i.scrollbarYTop = newTop;
536 var scrollTop = _.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));
537 updateScroll(element, 'top', scrollTop);
540 var mouseMoveHandler = function (e) {
541 updateScrollTop(e.pageY - currentPageY);
542 updateGeometry(element);
547 var mouseUpHandler = function () {
548 _.stopScrolling(element, 'y');
549 i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
552 i.event.bind(i.scrollbarY, 'mousedown', function (e) {
553 currentPageY = e.pageY;
554 currentTop = _.toInt(dom.css(i.scrollbarY, 'top')) * i.railYRatio;
555 _.startScrolling(element, 'y');
557 i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
558 i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
565 module.exports = function (element) {
566 var i = instances.get(element);
567 bindMouseScrollXHandler(element, i);
568 bindMouseScrollYHandler(element, i);
571 },{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(require,module,exports){
574 var _ = require('../../lib/helper');
575 var dom = require('../../lib/dom');
576 var instances = require('../instances');
577 var updateGeometry = require('../update-geometry');
578 var updateScroll = require('../update-scroll');
580 function bindKeyboardHandler(element, i) {
582 i.event.bind(element, 'mouseenter', function () {
585 i.event.bind(element, 'mouseleave', function () {
589 var shouldPrevent = false;
590 function shouldPreventDefault(deltaX, deltaY) {
591 var scrollTop = element.scrollTop;
593 if (!i.scrollbarYActive) {
596 if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
597 return !i.settings.wheelPropagation;
601 var scrollLeft = element.scrollLeft;
603 if (!i.scrollbarXActive) {
606 if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
607 return !i.settings.wheelPropagation;
613 i.event.bind(i.ownerDocument, 'keydown', function (e) {
614 if (e.isDefaultPrevented && e.isDefaultPrevented()) {
618 var focused = dom.matches(i.scrollbarX, ':focus') ||
619 dom.matches(i.scrollbarY, ':focus');
621 if (!hovered && !focused) {
625 var activeElement = document.activeElement ? document.activeElement : i.ownerDocument.activeElement;
627 if (activeElement.tagName === 'IFRAME') {
628 activeElement = activeElement.contentDocument.activeElement;
630 // go deeper if element is a webcomponent
631 while (activeElement.shadowRoot) {
632 activeElement = activeElement.shadowRoot.activeElement;
635 if (_.isEditable(activeElement)) {
659 case 32: // space bar
666 case 34: // page down
671 deltaY = -i.contentHeight;
673 deltaY = -i.containerHeight;
678 deltaY = element.scrollTop;
680 deltaY = i.containerHeight;
687 updateScroll(element, 'top', element.scrollTop - deltaY);
688 updateScroll(element, 'left', element.scrollLeft + deltaX);
689 updateGeometry(element);
691 shouldPrevent = shouldPreventDefault(deltaX, deltaY);
698 module.exports = function (element) {
699 var i = instances.get(element);
700 bindKeyboardHandler(element, i);
703 },{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(require,module,exports){
706 var instances = require('../instances');
707 var updateGeometry = require('../update-geometry');
708 var updateScroll = require('../update-scroll');
710 function bindMouseWheelHandler(element, i) {
711 var shouldPrevent = false;
713 function shouldPreventDefault(deltaX, deltaY) {
714 var scrollTop = element.scrollTop;
716 if (!i.scrollbarYActive) {
719 if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
720 return !i.settings.wheelPropagation;
724 var scrollLeft = element.scrollLeft;
726 if (!i.scrollbarXActive) {
729 if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
730 return !i.settings.wheelPropagation;
736 function getDeltaFromEvent(e) {
737 var deltaX = e.deltaX;
738 var deltaY = -1 * e.deltaY;
740 if (typeof deltaX === "undefined" || typeof deltaY === "undefined") {
742 deltaX = -1 * e.wheelDeltaX / 6;
743 deltaY = e.wheelDeltaY / 6;
746 if (e.deltaMode && e.deltaMode === 1) {
747 // Firefox in deltaMode 1: Line scrolling
752 if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {
753 // IE in some mouse drivers
755 deltaY = e.wheelDelta;
758 return [deltaX, deltaY];
761 function shouldBeConsumedByChild(deltaX, deltaY) {
762 var child = element.querySelector('textarea:hover, .ps-child:hover');
764 if (child.tagName !== 'TEXTAREA' && !window.getComputedStyle(child).overflow.match(/(scroll|auto)/)) {
768 var maxScrollTop = child.scrollHeight - child.clientHeight;
769 if (maxScrollTop > 0) {
770 if (!(child.scrollTop === 0 && deltaY > 0) && !(child.scrollTop === maxScrollTop && deltaY < 0)) {
774 var maxScrollLeft = child.scrollLeft - child.clientWidth;
775 if (maxScrollLeft > 0) {
776 if (!(child.scrollLeft === 0 && deltaX < 0) && !(child.scrollLeft === maxScrollLeft && deltaX > 0)) {
784 function mousewheelHandler(e) {
785 var delta = getDeltaFromEvent(e);
787 var deltaX = delta[0];
788 var deltaY = delta[1];
790 if (shouldBeConsumedByChild(deltaX, deltaY)) {
794 shouldPrevent = false;
795 if (!i.settings.useBothWheelAxes) {
796 // deltaX will only be used for horizontal scrolling and deltaY will
797 // only be used for vertical scrolling - this is the default
798 updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
799 updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
800 } else if (i.scrollbarYActive && !i.scrollbarXActive) {
801 // only vertical scrollbar is active and useBothWheelAxes option is
802 // active, so let's scroll vertical bar using both mouse wheel axes
804 updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
806 updateScroll(element, 'top', element.scrollTop + (deltaX * i.settings.wheelSpeed));
808 shouldPrevent = true;
809 } else if (i.scrollbarXActive && !i.scrollbarYActive) {
810 // useBothWheelAxes and only horizontal bar is active, so use both
811 // wheel axes for horizontal bar
813 updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
815 updateScroll(element, 'left', element.scrollLeft - (deltaY * i.settings.wheelSpeed));
817 shouldPrevent = true;
820 updateGeometry(element);
822 shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
829 if (typeof window.onwheel !== "undefined") {
830 i.event.bind(element, 'wheel', mousewheelHandler);
831 } else if (typeof window.onmousewheel !== "undefined") {
832 i.event.bind(element, 'mousewheel', mousewheelHandler);
836 module.exports = function (element) {
837 var i = instances.get(element);
838 bindMouseWheelHandler(element, i);
841 },{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(require,module,exports){
844 var instances = require('../instances');
845 var updateGeometry = require('../update-geometry');
847 function bindNativeScrollHandler(element, i) {
848 i.event.bind(element, 'scroll', function () {
849 updateGeometry(element);
853 module.exports = function (element) {
854 var i = instances.get(element);
855 bindNativeScrollHandler(element, i);
858 },{"../instances":18,"../update-geometry":19}],15:[function(require,module,exports){
861 var _ = require('../../lib/helper');
862 var instances = require('../instances');
863 var updateGeometry = require('../update-geometry');
864 var updateScroll = require('../update-scroll');
866 function bindSelectionHandler(element, i) {
867 function getRangeNode() {
868 var selection = window.getSelection ? window.getSelection() :
869 document.getSelection ? document.getSelection() : '';
870 if (selection.toString().length === 0) {
873 return selection.getRangeAt(0).commonAncestorContainer;
877 var scrollingLoop = null;
878 var scrollDiff = {top: 0, left: 0};
879 function startScrolling() {
880 if (!scrollingLoop) {
881 scrollingLoop = setInterval(function () {
882 if (!instances.get(element)) {
883 clearInterval(scrollingLoop);
887 updateScroll(element, 'top', element.scrollTop + scrollDiff.top);
888 updateScroll(element, 'left', element.scrollLeft + scrollDiff.left);
889 updateGeometry(element);
890 }, 50); // every .1 sec
893 function stopScrolling() {
895 clearInterval(scrollingLoop);
896 scrollingLoop = null;
898 _.stopScrolling(element);
901 var isSelected = false;
902 i.event.bind(i.ownerDocument, 'selectionchange', function () {
903 if (element.contains(getRangeNode())) {
910 i.event.bind(window, 'mouseup', function () {
917 i.event.bind(window, 'mousemove', function (e) {
919 var mousePosition = {x: e.pageX, y: e.pageY};
920 var containerGeometry = {
921 left: element.offsetLeft,
922 right: element.offsetLeft + element.offsetWidth,
923 top: element.offsetTop,
924 bottom: element.offsetTop + element.offsetHeight
927 if (mousePosition.x < containerGeometry.left + 3) {
928 scrollDiff.left = -5;
929 _.startScrolling(element, 'x');
930 } else if (mousePosition.x > containerGeometry.right - 3) {
932 _.startScrolling(element, 'x');
937 if (mousePosition.y < containerGeometry.top + 3) {
938 if (containerGeometry.top + 3 - mousePosition.y < 5) {
941 scrollDiff.top = -20;
943 _.startScrolling(element, 'y');
944 } else if (mousePosition.y > containerGeometry.bottom - 3) {
945 if (mousePosition.y - containerGeometry.bottom + 3 < 5) {
950 _.startScrolling(element, 'y');
955 if (scrollDiff.top === 0 && scrollDiff.left === 0) {
964 module.exports = function (element) {
965 var i = instances.get(element);
966 bindSelectionHandler(element, i);
969 },{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(require,module,exports){
972 var _ = require('../../lib/helper');
973 var instances = require('../instances');
974 var updateGeometry = require('../update-geometry');
975 var updateScroll = require('../update-scroll');
977 function bindTouchHandler(element, i, supportsTouch, supportsIePointer) {
978 function shouldPreventDefault(deltaX, deltaY) {
979 var scrollTop = element.scrollTop;
980 var scrollLeft = element.scrollLeft;
981 var magnitudeX = Math.abs(deltaX);
982 var magnitudeY = Math.abs(deltaY);
984 if (magnitudeY > magnitudeX) {
985 // user is perhaps trying to swipe up/down the page
987 if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) ||
988 ((deltaY > 0) && (scrollTop === 0))) {
989 return !i.settings.swipePropagation;
991 } else if (magnitudeX > magnitudeY) {
992 // user is perhaps trying to swipe left/right across the page
994 if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) ||
995 ((deltaX > 0) && (scrollLeft === 0))) {
996 return !i.settings.swipePropagation;
1003 function applyTouchMove(differenceX, differenceY) {
1004 updateScroll(element, 'top', element.scrollTop - differenceY);
1005 updateScroll(element, 'left', element.scrollLeft - differenceX);
1007 updateGeometry(element);
1010 var startOffset = {};
1013 var easingLoop = null;
1014 var inGlobalTouch = false;
1015 var inLocalTouch = false;
1017 function globalTouchStart() {
1018 inGlobalTouch = true;
1020 function globalTouchEnd() {
1021 inGlobalTouch = false;
1024 function getTouch(e) {
1025 if (e.targetTouches) {
1026 return e.targetTouches[0];
1032 function shouldHandle(e) {
1033 if (e.targetTouches && e.targetTouches.length === 1) {
1036 if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
1041 function touchStart(e) {
1042 if (shouldHandle(e)) {
1043 inLocalTouch = true;
1045 var touch = getTouch(e);
1047 startOffset.pageX = touch.pageX;
1048 startOffset.pageY = touch.pageY;
1050 startTime = (new Date()).getTime();
1052 if (easingLoop !== null) {
1053 clearInterval(easingLoop);
1056 e.stopPropagation();
1059 function touchMove(e) {
1060 if (!inLocalTouch && i.settings.swipePropagation) {
1063 if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
1064 var touch = getTouch(e);
1066 var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
1068 var differenceX = currentOffset.pageX - startOffset.pageX;
1069 var differenceY = currentOffset.pageY - startOffset.pageY;
1071 applyTouchMove(differenceX, differenceY);
1072 startOffset = currentOffset;
1074 var currentTime = (new Date()).getTime();
1076 var timeGap = currentTime - startTime;
1078 speed.x = differenceX / timeGap;
1079 speed.y = differenceY / timeGap;
1080 startTime = currentTime;
1083 if (shouldPreventDefault(differenceX, differenceY)) {
1084 e.stopPropagation();
1089 function touchEnd() {
1090 if (!inGlobalTouch && inLocalTouch) {
1091 inLocalTouch = false;
1093 clearInterval(easingLoop);
1094 easingLoop = setInterval(function () {
1095 if (!instances.get(element)) {
1096 clearInterval(easingLoop);
1100 if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
1101 clearInterval(easingLoop);
1105 applyTouchMove(speed.x * 30, speed.y * 30);
1113 if (supportsTouch) {
1114 i.event.bind(window, 'touchstart', globalTouchStart);
1115 i.event.bind(window, 'touchend', globalTouchEnd);
1116 i.event.bind(element, 'touchstart', touchStart);
1117 i.event.bind(element, 'touchmove', touchMove);
1118 i.event.bind(element, 'touchend', touchEnd);
1121 if (supportsIePointer) {
1122 if (window.PointerEvent) {
1123 i.event.bind(window, 'pointerdown', globalTouchStart);
1124 i.event.bind(window, 'pointerup', globalTouchEnd);
1125 i.event.bind(element, 'pointerdown', touchStart);
1126 i.event.bind(element, 'pointermove', touchMove);
1127 i.event.bind(element, 'pointerup', touchEnd);
1128 } else if (window.MSPointerEvent) {
1129 i.event.bind(window, 'MSPointerDown', globalTouchStart);
1130 i.event.bind(window, 'MSPointerUp', globalTouchEnd);
1131 i.event.bind(element, 'MSPointerDown', touchStart);
1132 i.event.bind(element, 'MSPointerMove', touchMove);
1133 i.event.bind(element, 'MSPointerUp', touchEnd);
1138 module.exports = function (element) {
1139 if (!_.env.supportsTouch && !_.env.supportsIePointer) {
1143 var i = instances.get(element);
1144 bindTouchHandler(element, i, _.env.supportsTouch, _.env.supportsIePointer);
1147 },{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(require,module,exports){
1150 var _ = require('../lib/helper');
1151 var cls = require('../lib/class');
1152 var instances = require('./instances');
1153 var updateGeometry = require('./update-geometry');
1157 'click-rail': require('./handler/click-rail'),
1158 'drag-scrollbar': require('./handler/drag-scrollbar'),
1159 'keyboard': require('./handler/keyboard'),
1160 'wheel': require('./handler/mouse-wheel'),
1161 'touch': require('./handler/touch'),
1162 'selection': require('./handler/selection')
1164 var nativeScrollHandler = require('./handler/native-scroll');
1166 module.exports = function (element, userSettings) {
1167 userSettings = typeof userSettings === 'object' ? userSettings : {};
1169 cls.add(element, 'ps-container');
1171 // Create a plugin instance.
1172 var i = instances.add(element);
1174 i.settings = _.extend(i.settings, userSettings);
1175 cls.add(element, 'ps-theme-' + i.settings.theme);
1177 i.settings.handlers.forEach(function (handlerName) {
1178 handlers[handlerName](element);
1181 nativeScrollHandler(element);
1183 updateGeometry(element);
1186 },{"../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){
1189 var _ = require('../lib/helper');
1190 var cls = require('../lib/class');
1191 var defaultSettings = require('./default-setting');
1192 var dom = require('../lib/dom');
1193 var EventManager = require('../lib/event-manager');
1194 var guid = require('../lib/guid');
1198 function Instance(element) {
1201 i.settings = _.clone(defaultSettings);
1202 i.containerWidth = null;
1203 i.containerHeight = null;
1204 i.contentWidth = null;
1205 i.contentHeight = null;
1207 i.isRtl = dom.css(element, 'direction') === "rtl";
1208 i.isNegativeScroll = (function () {
1209 var originalScrollLeft = element.scrollLeft;
1211 element.scrollLeft = -1;
1212 result = element.scrollLeft < 0;
1213 element.scrollLeft = originalScrollLeft;
1216 i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
1217 i.event = new EventManager();
1218 i.ownerDocument = element.ownerDocument || document;
1221 cls.add(element, 'ps-focus');
1225 cls.remove(element, 'ps-focus');
1228 i.scrollbarXRail = dom.appendTo(dom.e('div', 'ps-scrollbar-x-rail'), element);
1229 i.scrollbarX = dom.appendTo(dom.e('div', 'ps-scrollbar-x'), i.scrollbarXRail);
1230 i.scrollbarX.setAttribute('tabindex', 0);
1231 i.event.bind(i.scrollbarX, 'focus', focus);
1232 i.event.bind(i.scrollbarX, 'blur', blur);
1233 i.scrollbarXActive = null;
1234 i.scrollbarXWidth = null;
1235 i.scrollbarXLeft = null;
1236 i.scrollbarXBottom = _.toInt(dom.css(i.scrollbarXRail, 'bottom'));
1237 i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN
1238 i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : _.toInt(dom.css(i.scrollbarXRail, 'top'));
1239 i.railBorderXWidth = _.toInt(dom.css(i.scrollbarXRail, 'borderLeftWidth')) + _.toInt(dom.css(i.scrollbarXRail, 'borderRightWidth'));
1240 // Set rail to display:block to calculate margins
1241 dom.css(i.scrollbarXRail, 'display', 'block');
1242 i.railXMarginWidth = _.toInt(dom.css(i.scrollbarXRail, 'marginLeft')) + _.toInt(dom.css(i.scrollbarXRail, 'marginRight'));
1243 dom.css(i.scrollbarXRail, 'display', '');
1244 i.railXWidth = null;
1245 i.railXRatio = null;
1247 i.scrollbarYRail = dom.appendTo(dom.e('div', 'ps-scrollbar-y-rail'), element);
1248 i.scrollbarY = dom.appendTo(dom.e('div', 'ps-scrollbar-y'), i.scrollbarYRail);
1249 i.scrollbarY.setAttribute('tabindex', 0);
1250 i.event.bind(i.scrollbarY, 'focus', focus);
1251 i.event.bind(i.scrollbarY, 'blur', blur);
1252 i.scrollbarYActive = null;
1253 i.scrollbarYHeight = null;
1254 i.scrollbarYTop = null;
1255 i.scrollbarYRight = _.toInt(dom.css(i.scrollbarYRail, 'right'));
1256 i.isScrollbarYUsingRight = i.scrollbarYRight === i.scrollbarYRight; // !isNaN
1257 i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : _.toInt(dom.css(i.scrollbarYRail, 'left'));
1258 i.scrollbarYOuterWidth = i.isRtl ? _.outerWidth(i.scrollbarY) : null;
1259 i.railBorderYWidth = _.toInt(dom.css(i.scrollbarYRail, 'borderTopWidth')) + _.toInt(dom.css(i.scrollbarYRail, 'borderBottomWidth'));
1260 dom.css(i.scrollbarYRail, 'display', 'block');
1261 i.railYMarginHeight = _.toInt(dom.css(i.scrollbarYRail, 'marginTop')) + _.toInt(dom.css(i.scrollbarYRail, 'marginBottom'));
1262 dom.css(i.scrollbarYRail, 'display', '');
1263 i.railYHeight = null;
1264 i.railYRatio = null;
1267 function getId(element) {
1268 return element.getAttribute('data-ps-id');
1271 function setId(element, id) {
1272 element.setAttribute('data-ps-id', id);
1275 function removeId(element) {
1276 element.removeAttribute('data-ps-id');
1279 exports.add = function (element) {
1281 setId(element, newId);
1282 instances[newId] = new Instance(element);
1283 return instances[newId];
1286 exports.remove = function (element) {
1287 delete instances[getId(element)];
1291 exports.get = function (element) {
1292 return instances[getId(element)];
1295 },{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(require,module,exports){
1298 var _ = require('../lib/helper');
1299 var cls = require('../lib/class');
1300 var dom = require('../lib/dom');
1301 var instances = require('./instances');
1302 var updateScroll = require('./update-scroll');
1304 function getThumbSize(i, thumbSize) {
1305 if (i.settings.minScrollbarLength) {
1306 thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);
1308 if (i.settings.maxScrollbarLength) {
1309 thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);
1314 function updateCss(element, i) {
1315 var xRailOffset = {width: i.railXWidth};
1317 xRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth - i.contentWidth;
1319 xRailOffset.left = element.scrollLeft;
1321 if (i.isScrollbarXUsingBottom) {
1322 xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop;
1324 xRailOffset.top = i.scrollbarXTop + element.scrollTop;
1326 dom.css(i.scrollbarXRail, xRailOffset);
1328 var yRailOffset = {top: element.scrollTop, height: i.railYHeight};
1329 if (i.isScrollbarYUsingRight) {
1331 yRailOffset.right = i.contentWidth - (i.negativeScrollAdjustment + element.scrollLeft) - i.scrollbarYRight - i.scrollbarYOuterWidth;
1333 yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
1337 yRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth;
1339 yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
1342 dom.css(i.scrollbarYRail, yRailOffset);
1344 dom.css(i.scrollbarX, {left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth});
1345 dom.css(i.scrollbarY, {top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth});
1348 module.exports = function (element) {
1349 var i = instances.get(element);
1351 i.containerWidth = element.clientWidth;
1352 i.containerHeight = element.clientHeight;
1353 i.contentWidth = element.scrollWidth;
1354 i.contentHeight = element.scrollHeight;
1357 if (!element.contains(i.scrollbarXRail)) {
1358 existingRails = dom.queryChildren(element, '.ps-scrollbar-x-rail');
1359 if (existingRails.length > 0) {
1360 existingRails.forEach(function (rail) {
1364 dom.appendTo(i.scrollbarXRail, element);
1366 if (!element.contains(i.scrollbarYRail)) {
1367 existingRails = dom.queryChildren(element, '.ps-scrollbar-y-rail');
1368 if (existingRails.length > 0) {
1369 existingRails.forEach(function (rail) {
1373 dom.appendTo(i.scrollbarYRail, element);
1376 if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) {
1377 i.scrollbarXActive = true;
1378 i.railXWidth = i.containerWidth - i.railXMarginWidth;
1379 i.railXRatio = i.containerWidth / i.railXWidth;
1380 i.scrollbarXWidth = getThumbSize(i, _.toInt(i.railXWidth * i.containerWidth / i.contentWidth));
1381 i.scrollbarXLeft = _.toInt((i.negativeScrollAdjustment + element.scrollLeft) * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
1383 i.scrollbarXActive = false;
1386 if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) {
1387 i.scrollbarYActive = true;
1388 i.railYHeight = i.containerHeight - i.railYMarginHeight;
1389 i.railYRatio = i.containerHeight / i.railYHeight;
1390 i.scrollbarYHeight = getThumbSize(i, _.toInt(i.railYHeight * i.containerHeight / i.contentHeight));
1391 i.scrollbarYTop = _.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight));
1393 i.scrollbarYActive = false;
1396 if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
1397 i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;
1399 if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {
1400 i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;
1403 updateCss(element, i);
1405 if (i.scrollbarXActive) {
1406 cls.add(element, 'ps-active-x');
1408 cls.remove(element, 'ps-active-x');
1409 i.scrollbarXWidth = 0;
1410 i.scrollbarXLeft = 0;
1411 updateScroll(element, 'left', 0);
1413 if (i.scrollbarYActive) {
1414 cls.add(element, 'ps-active-y');
1416 cls.remove(element, 'ps-active-y');
1417 i.scrollbarYHeight = 0;
1418 i.scrollbarYTop = 0;
1419 updateScroll(element, 'top', 0);
1423 },{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(require,module,exports){
1426 var instances = require('./instances');
1428 var upEvent = document.createEvent('Event');
1429 var downEvent = document.createEvent('Event');
1430 var leftEvent = document.createEvent('Event');
1431 var rightEvent = document.createEvent('Event');
1432 var yEvent = document.createEvent('Event');
1433 var xEvent = document.createEvent('Event');
1434 var xStartEvent = document.createEvent('Event');
1435 var xEndEvent = document.createEvent('Event');
1436 var yStartEvent = document.createEvent('Event');
1437 var yEndEvent = document.createEvent('Event');
1441 upEvent.initEvent('ps-scroll-up', true, true);
1442 downEvent.initEvent('ps-scroll-down', true, true);
1443 leftEvent.initEvent('ps-scroll-left', true, true);
1444 rightEvent.initEvent('ps-scroll-right', true, true);
1445 yEvent.initEvent('ps-scroll-y', true, true);
1446 xEvent.initEvent('ps-scroll-x', true, true);
1447 xStartEvent.initEvent('ps-x-reach-start', true, true);
1448 xEndEvent.initEvent('ps-x-reach-end', true, true);
1449 yStartEvent.initEvent('ps-y-reach-start', true, true);
1450 yEndEvent.initEvent('ps-y-reach-end', true, true);
1452 module.exports = function (element, axis, value) {
1453 if (typeof element === 'undefined') {
1454 throw 'You must provide an element to the update-scroll function';
1457 if (typeof axis === 'undefined') {
1458 throw 'You must provide an axis to the update-scroll function';
1461 if (typeof value === 'undefined') {
1462 throw 'You must provide a value to the update-scroll function';
1465 if (axis === 'top' && value <= 0) {
1466 element.scrollTop = value = 0; // don't allow negative scroll
1467 element.dispatchEvent(yStartEvent);
1470 if (axis === 'left' && value <= 0) {
1471 element.scrollLeft = value = 0; // don't allow negative scroll
1472 element.dispatchEvent(xStartEvent);
1475 var i = instances.get(element);
1477 if (axis === 'top' && value >= i.contentHeight - i.containerHeight) {
1478 // don't allow scroll past container
1479 value = i.contentHeight - i.containerHeight;
1480 if (value - element.scrollTop <= 1) {
1481 // mitigates rounding errors on non-subpixel scroll values
1482 value = element.scrollTop;
1484 element.scrollTop = value;
1486 element.dispatchEvent(yEndEvent);
1489 if (axis === 'left' && value >= i.contentWidth - i.containerWidth) {
1490 // don't allow scroll past container
1491 value = i.contentWidth - i.containerWidth;
1492 if (value - element.scrollLeft <= 1) {
1493 // mitigates rounding errors on non-subpixel scroll values
1494 value = element.scrollLeft;
1496 element.scrollLeft = value;
1498 element.dispatchEvent(xEndEvent);
1502 lastTop = element.scrollTop;
1506 lastLeft = element.scrollLeft;
1509 if (axis === 'top' && value < lastTop) {
1510 element.dispatchEvent(upEvent);
1513 if (axis === 'top' && value > lastTop) {
1514 element.dispatchEvent(downEvent);
1517 if (axis === 'left' && value < lastLeft) {
1518 element.dispatchEvent(leftEvent);
1521 if (axis === 'left' && value > lastLeft) {
1522 element.dispatchEvent(rightEvent);
1525 if (axis === 'top') {
1526 element.scrollTop = lastTop = value;
1527 element.dispatchEvent(yEvent);
1530 if (axis === 'left') {
1531 element.scrollLeft = lastLeft = value;
1532 element.dispatchEvent(xEvent);
1537 },{"./instances":18}],21:[function(require,module,exports){
1540 var _ = require('../lib/helper');
1541 var dom = require('../lib/dom');
1542 var instances = require('./instances');
1543 var updateGeometry = require('./update-geometry');
1544 var updateScroll = require('./update-scroll');
1546 module.exports = function (element) {
1547 var i = instances.get(element);
1553 // Recalcuate negative scrollLeft adjustment
1554 i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
1556 // Recalculate rail margins
1557 dom.css(i.scrollbarXRail, 'display', 'block');
1558 dom.css(i.scrollbarYRail, 'display', 'block');
1559 i.railXMarginWidth = _.toInt(dom.css(i.scrollbarXRail, 'marginLeft')) + _.toInt(dom.css(i.scrollbarXRail, 'marginRight'));
1560 i.railYMarginHeight = _.toInt(dom.css(i.scrollbarYRail, 'marginTop')) + _.toInt(dom.css(i.scrollbarYRail, 'marginBottom'));
1562 // Hide scrollbars not to affect scrollWidth and scrollHeight
1563 dom.css(i.scrollbarXRail, 'display', 'none');
1564 dom.css(i.scrollbarYRail, 'display', 'none');
1566 updateGeometry(element);
1568 // Update top/left scroll to trigger events
1569 updateScroll(element, 'top', element.scrollTop);
1570 updateScroll(element, 'left', element.scrollLeft);
1572 dom.css(i.scrollbarXRail, 'display', '');
1573 dom.css(i.scrollbarYRail, 'display', '');
1576 },{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]);