]> git.mxchange.org Git - friendica.git/blob - library/perfect-scrollbar/perfect-scrollbar.jquery.js
added curly braces + space
[friendica.git] / library / perfect-scrollbar / perfect-scrollbar.jquery.js
1 /* perfect-scrollbar v0.6.10
2  * 
3  * Copyright (c) 2015 Hyunje Alex Jun and other contributors
4  * Licensed under the MIT License
5  * 
6  * Source: https://github.com/noraesae/perfect-scrollbar
7  */
8
9 (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){
10 'use strict';
11
12 var ps = require('../main')
13   , psInstances = require('../plugin/instances');
14
15 function mountJQuery(jQuery) {
16   jQuery.fn.perfectScrollbar = function (settingOrCommand) {
17     return this.each(function () {
18       if (typeof settingOrCommand === 'object' ||
19           typeof settingOrCommand === 'undefined') {
20         // If it's an object or none, initialize.
21         var settings = settingOrCommand;
22
23         if (!psInstances.get(this)) {
24           ps.initialize(this, settings);
25         }
26       } else {
27         // Unless, it may be a command.
28         var command = settingOrCommand;
29
30         if (command === 'update') {
31           ps.update(this);
32         } else if (command === 'destroy') {
33           ps.destroy(this);
34         }
35       }
36
37       return jQuery(this);
38     });
39   };
40 }
41
42 if (typeof define === 'function' && define.amd) {
43   // AMD. Register as an anonymous module.
44   define(['jquery'], mountJQuery);
45 } else {
46   var jq = window.jQuery ? window.jQuery : window.$;
47   if (typeof jq !== 'undefined') {
48     mountJQuery(jq);
49   }
50 }
51
52 module.exports = mountJQuery;
53
54 },{"../main":7,"../plugin/instances":18}],2:[function(require,module,exports){
55 'use strict';
56
57 function oldAdd(element, className) {
58   var classes = element.className.split(' ');
59   if (classes.indexOf(className) < 0) {
60     classes.push(className);
61   }
62   element.className = classes.join(' ');
63 }
64
65 function oldRemove(element, className) {
66   var classes = element.className.split(' ');
67   var idx = classes.indexOf(className);
68   if (idx >= 0) {
69     classes.splice(idx, 1);
70   }
71   element.className = classes.join(' ');
72 }
73
74 exports.add = function (element, className) {
75   if (element.classList) {
76     element.classList.add(className);
77   } else {
78     oldAdd(element, className);
79   }
80 };
81
82 exports.remove = function (element, className) {
83   if (element.classList) {
84     element.classList.remove(className);
85   } else {
86     oldRemove(element, className);
87   }
88 };
89
90 exports.list = function (element) {
91   if (element.classList) {
92     return Array.prototype.slice.apply(element.classList);
93   } else {
94     return element.className.split(' ');
95   }
96 };
97
98 },{}],3:[function(require,module,exports){
99 'use strict';
100
101 var DOM = {};
102
103 DOM.e = function (tagName, className) {
104   var element = document.createElement(tagName);
105   element.className = className;
106   return element;
107 };
108
109 DOM.appendTo = function (child, parent) {
110   parent.appendChild(child);
111   return child;
112 };
113
114 function cssGet(element, styleName) {
115   return window.getComputedStyle(element)[styleName];
116 }
117
118 function cssSet(element, styleName, styleValue) {
119   if (typeof styleValue === 'number') {
120     styleValue = styleValue.toString() + 'px';
121   }
122   element.style[styleName] = styleValue;
123   return element;
124 }
125
126 function cssMultiSet(element, obj) {
127   for (var key in obj) {
128     var val = obj[key];
129     if (typeof val === 'number') {
130       val = val.toString() + 'px';
131     }
132     element.style[key] = val;
133   }
134   return element;
135 }
136
137 DOM.css = function (element, styleNameOrObject, styleValue) {
138   if (typeof styleNameOrObject === 'object') {
139     // multiple set with object
140     return cssMultiSet(element, styleNameOrObject);
141   } else {
142     if (typeof styleValue === 'undefined') {
143       return cssGet(element, styleNameOrObject);
144     } else {
145       return cssSet(element, styleNameOrObject, styleValue);
146     }
147   }
148 };
149
150 DOM.matches = function (element, query) {
151   if (typeof element.matches !== 'undefined') {
152     return element.matches(query);
153   } else {
154     if (typeof element.matchesSelector !== 'undefined') {
155       return element.matchesSelector(query);
156     } else if (typeof element.webkitMatchesSelector !== 'undefined') {
157       return element.webkitMatchesSelector(query);
158     } else if (typeof element.mozMatchesSelector !== 'undefined') {
159       return element.mozMatchesSelector(query);
160     } else if (typeof element.msMatchesSelector !== 'undefined') {
161       return element.msMatchesSelector(query);
162     }
163   }
164 };
165
166 DOM.remove = function (element) {
167   if (typeof element.remove !== 'undefined') {
168     element.remove();
169   } else {
170     if (element.parentNode) {
171       element.parentNode.removeChild(element);
172     }
173   }
174 };
175
176 DOM.queryChildren = function (element, selector) {
177   return Array.prototype.filter.call(element.childNodes, function (child) {
178     return DOM.matches(child, selector);
179   });
180 };
181
182 module.exports = DOM;
183
184 },{}],4:[function(require,module,exports){
185 'use strict';
186
187 var EventElement = function (element) {
188   this.element = element;
189   this.events = {};
190 };
191
192 EventElement.prototype.bind = function (eventName, handler) {
193   if (typeof this.events[eventName] === 'undefined') {
194     this.events[eventName] = [];
195   }
196   this.events[eventName].push(handler);
197   this.element.addEventListener(eventName, handler, false);
198 };
199
200 EventElement.prototype.unbind = function (eventName, handler) {
201   var isHandlerProvided = (typeof handler !== 'undefined');
202   this.events[eventName] = this.events[eventName].filter(function (hdlr) {
203     if (isHandlerProvided && hdlr !== handler) {
204       return true;
205     }
206     this.element.removeEventListener(eventName, hdlr, false);
207     return false;
208   }, this);
209 };
210
211 EventElement.prototype.unbindAll = function () {
212   for (var name in this.events) {
213     this.unbind(name);
214   }
215 };
216
217 var EventManager = function () {
218   this.eventElements = [];
219 };
220
221 EventManager.prototype.eventElement = function (element) {
222   var ee = this.eventElements.filter(function (eventElement) {
223     return eventElement.element === element;
224   })[0];
225   if (typeof ee === 'undefined') {
226     ee = new EventElement(element);
227     this.eventElements.push(ee);
228   }
229   return ee;
230 };
231
232 EventManager.prototype.bind = function (element, eventName, handler) {
233   this.eventElement(element).bind(eventName, handler);
234 };
235
236 EventManager.prototype.unbind = function (element, eventName, handler) {
237   this.eventElement(element).unbind(eventName, handler);
238 };
239
240 EventManager.prototype.unbindAll = function () {
241   for (var i = 0; i < this.eventElements.length; i++) {
242     this.eventElements[i].unbindAll();
243   }
244 };
245
246 EventManager.prototype.once = function (element, eventName, handler) {
247   var ee = this.eventElement(element);
248   var onceHandler = function (e) {
249     ee.unbind(eventName, onceHandler);
250     handler(e);
251   };
252   ee.bind(eventName, onceHandler);
253 };
254
255 module.exports = EventManager;
256
257 },{}],5:[function(require,module,exports){
258 'use strict';
259
260 module.exports = (function () {
261   function s4() {
262     return Math.floor((1 + Math.random()) * 0x10000)
263                .toString(16)
264                .substring(1);
265   }
266   return function () {
267     return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
268            s4() + '-' + s4() + s4() + s4();
269   };
270 })();
271
272 },{}],6:[function(require,module,exports){
273 'use strict';
274
275 var cls = require('./class')
276   , d = require('./dom');
277
278 exports.toInt = function (x) {
279   return parseInt(x, 10) || 0;
280 };
281
282 exports.clone = function (obj) {
283   if (obj === null) {
284     return null;
285   } else if (typeof obj === 'object') {
286     var result = {};
287     for (var key in obj) {
288       result[key] = this.clone(obj[key]);
289     }
290     return result;
291   } else {
292     return obj;
293   }
294 };
295
296 exports.extend = function (original, source) {
297   var result = this.clone(original);
298   for (var key in source) {
299     result[key] = this.clone(source[key]);
300   }
301   return result;
302 };
303
304 exports.isEditable = function (el) {
305   return d.matches(el, "input,[contenteditable]") ||
306          d.matches(el, "select,[contenteditable]") ||
307          d.matches(el, "textarea,[contenteditable]") ||
308          d.matches(el, "button,[contenteditable]");
309 };
310
311 exports.removePsClasses = function (element) {
312   var clsList = cls.list(element);
313   for (var i = 0; i < clsList.length; i++) {
314     var className = clsList[i];
315     if (className.indexOf('ps-') === 0) {
316       cls.remove(element, className);
317     }
318   }
319 };
320
321 exports.outerWidth = function (element) {
322   return this.toInt(d.css(element, 'width')) +
323          this.toInt(d.css(element, 'paddingLeft')) +
324          this.toInt(d.css(element, 'paddingRight')) +
325          this.toInt(d.css(element, 'borderLeftWidth')) +
326          this.toInt(d.css(element, 'borderRightWidth'));
327 };
328
329 exports.startScrolling = function (element, axis) {
330   cls.add(element, 'ps-in-scrolling');
331   if (typeof axis !== 'undefined') {
332     cls.add(element, 'ps-' + axis);
333   } else {
334     cls.add(element, 'ps-x');
335     cls.add(element, 'ps-y');
336   }
337 };
338
339 exports.stopScrolling = function (element, axis) {
340   cls.remove(element, 'ps-in-scrolling');
341   if (typeof axis !== 'undefined') {
342     cls.remove(element, 'ps-' + axis);
343   } else {
344     cls.remove(element, 'ps-x');
345     cls.remove(element, 'ps-y');
346   }
347 };
348
349 exports.env = {
350   isWebKit: 'WebkitAppearance' in document.documentElement.style,
351   supportsTouch: (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),
352   supportsIePointer: window.navigator.msMaxTouchPoints !== null
353 };
354
355 },{"./class":2,"./dom":3}],7:[function(require,module,exports){
356 'use strict';
357
358 var destroy = require('./plugin/destroy')
359   , initialize = require('./plugin/initialize')
360   , update = require('./plugin/update');
361
362 module.exports = {
363   initialize: initialize,
364   update: update,
365   destroy: destroy
366 };
367
368 },{"./plugin/destroy":9,"./plugin/initialize":17,"./plugin/update":21}],8:[function(require,module,exports){
369 'use strict';
370
371 module.exports = {
372   maxScrollbarLength: null,
373   minScrollbarLength: null,
374   scrollXMarginOffset: 0,
375   scrollYMarginOffset: 0,
376   stopPropagationOnClick: true,
377   suppressScrollX: false,
378   suppressScrollY: false,
379   swipePropagation: true,
380   useBothWheelAxes: false,
381   useKeyboard: true,
382   useSelectionScroll: false,
383   wheelPropagation: false,
384   wheelSpeed: 1,
385   theme: 'default'
386 };
387
388 },{}],9:[function(require,module,exports){
389 'use strict';
390
391 var d = require('../lib/dom')
392   , h = require('../lib/helper')
393   , instances = require('./instances');
394
395 module.exports = function (element) {
396   var i = instances.get(element);
397
398   if (!i) {
399     return;
400   }
401
402   i.event.unbindAll();
403   d.remove(i.scrollbarX);
404   d.remove(i.scrollbarY);
405   d.remove(i.scrollbarXRail);
406   d.remove(i.scrollbarYRail);
407   h.removePsClasses(element);
408
409   instances.remove(element);
410 };
411
412 },{"../lib/dom":3,"../lib/helper":6,"./instances":18}],10:[function(require,module,exports){
413 'use strict';
414
415 var h = require('../../lib/helper')
416   , instances = require('../instances')
417   , updateGeometry = require('../update-geometry')
418   , updateScroll = require('../update-scroll');
419
420 function bindClickRailHandler(element, i) {
421   function pageOffset(el) {
422     return el.getBoundingClientRect();
423   }
424   var stopPropagation = window.Event.prototype.stopPropagation.bind;
425
426   if (i.settings.stopPropagationOnClick) {
427     i.event.bind(i.scrollbarY, 'click', stopPropagation);
428   }
429   i.event.bind(i.scrollbarYRail, 'click', function (e) {
430     var halfOfScrollbarLength = h.toInt(i.scrollbarYHeight / 2);
431     var positionTop = i.railYRatio * (e.pageY - window.pageYOffset - pageOffset(i.scrollbarYRail).top - halfOfScrollbarLength);
432     var maxPositionTop = i.railYRatio * (i.railYHeight - i.scrollbarYHeight);
433     var positionRatio = positionTop / maxPositionTop;
434
435     if (positionRatio < 0) {
436       positionRatio = 0;
437     } else if (positionRatio > 1) {
438       positionRatio = 1;
439     }
440
441     updateScroll(element, 'top', (i.contentHeight - i.containerHeight) * positionRatio);
442     updateGeometry(element);
443
444     e.stopPropagation();
445   });
446
447   if (i.settings.stopPropagationOnClick) {
448     i.event.bind(i.scrollbarX, 'click', stopPropagation);
449   }
450   i.event.bind(i.scrollbarXRail, 'click', function (e) {
451     var halfOfScrollbarLength = h.toInt(i.scrollbarXWidth / 2);
452     var positionLeft = i.railXRatio * (e.pageX - window.pageXOffset - pageOffset(i.scrollbarXRail).left - halfOfScrollbarLength);
453     var maxPositionLeft = i.railXRatio * (i.railXWidth - i.scrollbarXWidth);
454     var positionRatio = positionLeft / maxPositionLeft;
455
456     if (positionRatio < 0) {
457       positionRatio = 0;
458     } else if (positionRatio > 1) {
459       positionRatio = 1;
460     }
461
462     updateScroll(element, 'left', ((i.contentWidth - i.containerWidth) * positionRatio) - i.negativeScrollAdjustment);
463     updateGeometry(element);
464
465     e.stopPropagation();
466   });
467 }
468
469 module.exports = function (element) {
470   var i = instances.get(element);
471   bindClickRailHandler(element, i);
472 };
473
474 },{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],11:[function(require,module,exports){
475 'use strict';
476
477 var d = require('../../lib/dom')
478   , h = require('../../lib/helper')
479   , instances = require('../instances')
480   , updateGeometry = require('../update-geometry')
481   , updateScroll = require('../update-scroll');
482
483 function bindMouseScrollXHandler(element, i) {
484   var currentLeft = null;
485   var currentPageX = null;
486
487   function updateScrollLeft(deltaX) {
488     var newLeft = currentLeft + (deltaX * i.railXRatio);
489     var maxLeft = Math.max(0, i.scrollbarXRail.getBoundingClientRect().left) + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));
490
491     if (newLeft < 0) {
492       i.scrollbarXLeft = 0;
493     } else if (newLeft > maxLeft) {
494       i.scrollbarXLeft = maxLeft;
495     } else {
496       i.scrollbarXLeft = newLeft;
497     }
498
499     var scrollLeft = h.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment;
500     updateScroll(element, 'left', scrollLeft);
501   }
502
503   var mouseMoveHandler = function (e) {
504     updateScrollLeft(e.pageX - currentPageX);
505     updateGeometry(element);
506     e.stopPropagation();
507     e.preventDefault();
508   };
509
510   var mouseUpHandler = function () {
511     h.stopScrolling(element, 'x');
512     i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
513   };
514
515   i.event.bind(i.scrollbarX, 'mousedown', function (e) {
516     currentPageX = e.pageX;
517     currentLeft = h.toInt(d.css(i.scrollbarX, 'left')) * i.railXRatio;
518     h.startScrolling(element, 'x');
519
520     i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
521     i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
522
523     e.stopPropagation();
524     e.preventDefault();
525   });
526 }
527
528 function bindMouseScrollYHandler(element, i) {
529   var currentTop = null;
530   var currentPageY = null;
531
532   function updateScrollTop(deltaY) {
533     var newTop = currentTop + (deltaY * i.railYRatio);
534     var maxTop = Math.max(0, i.scrollbarYRail.getBoundingClientRect().top) + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));
535
536     if (newTop < 0) {
537       i.scrollbarYTop = 0;
538     } else if (newTop > maxTop) {
539       i.scrollbarYTop = maxTop;
540     } else {
541       i.scrollbarYTop = newTop;
542     }
543
544     var scrollTop = h.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));
545     updateScroll(element, 'top', scrollTop);
546   }
547
548   var mouseMoveHandler = function (e) {
549     updateScrollTop(e.pageY - currentPageY);
550     updateGeometry(element);
551     e.stopPropagation();
552     e.preventDefault();
553   };
554
555   var mouseUpHandler = function () {
556     h.stopScrolling(element, 'y');
557     i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
558   };
559
560   i.event.bind(i.scrollbarY, 'mousedown', function (e) {
561     currentPageY = e.pageY;
562     currentTop = h.toInt(d.css(i.scrollbarY, 'top')) * i.railYRatio;
563     h.startScrolling(element, 'y');
564
565     i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
566     i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
567
568     e.stopPropagation();
569     e.preventDefault();
570   });
571 }
572
573 module.exports = function (element) {
574   var i = instances.get(element);
575   bindMouseScrollXHandler(element, i);
576   bindMouseScrollYHandler(element, i);
577 };
578
579 },{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],12:[function(require,module,exports){
580 'use strict';
581
582 var h = require('../../lib/helper')
583   , d = require('../../lib/dom')
584   , instances = require('../instances')
585   , updateGeometry = require('../update-geometry')
586   , updateScroll = require('../update-scroll');
587
588 function bindKeyboardHandler(element, i) {
589   var hovered = false;
590   i.event.bind(element, 'mouseenter', function () {
591     hovered = true;
592   });
593   i.event.bind(element, 'mouseleave', function () {
594     hovered = false;
595   });
596
597   var shouldPrevent = false;
598   function shouldPreventDefault(deltaX, deltaY) {
599     var scrollTop = element.scrollTop;
600     if (deltaX === 0) {
601       if (!i.scrollbarYActive) {
602         return false;
603       }
604       if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
605         return !i.settings.wheelPropagation;
606       }
607     }
608
609     var scrollLeft = element.scrollLeft;
610     if (deltaY === 0) {
611       if (!i.scrollbarXActive) {
612         return false;
613       }
614       if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
615         return !i.settings.wheelPropagation;
616       }
617     }
618     return true;
619   }
620
621   i.event.bind(i.ownerDocument, 'keydown', function (e) {
622     if (e.isDefaultPrevented && e.isDefaultPrevented()) {
623       return;
624     }
625
626     var focused = d.matches(i.scrollbarX, ':focus') ||
627                   d.matches(i.scrollbarY, ':focus');
628
629     if (!hovered && !focused) {
630       return;
631     }
632
633     var activeElement = document.activeElement ? document.activeElement : i.ownerDocument.activeElement;
634     if (activeElement) {
635       // go deeper if element is a webcomponent
636       while (activeElement.shadowRoot) {
637         activeElement = activeElement.shadowRoot.activeElement;
638       }
639       if (h.isEditable(activeElement)) {
640         return;
641       }
642     }
643
644     var deltaX = 0;
645     var deltaY = 0;
646
647     switch (e.which) {
648     case 37: // left
649       deltaX = -30;
650       break;
651     case 38: // up
652       deltaY = 30;
653       break;
654     case 39: // right
655       deltaX = 30;
656       break;
657     case 40: // down
658       deltaY = -30;
659       break;
660     case 33: // page up
661       deltaY = 90;
662       break;
663     case 32: // space bar
664       if (e.shiftKey) {
665         deltaY = 90;
666       } else {
667         deltaY = -90;
668       }
669       break;
670     case 34: // page down
671       deltaY = -90;
672       break;
673     case 35: // end
674       if (e.ctrlKey) {
675         deltaY = -i.contentHeight;
676       } else {
677         deltaY = -i.containerHeight;
678       }
679       break;
680     case 36: // home
681       if (e.ctrlKey) {
682         deltaY = element.scrollTop;
683       } else {
684         deltaY = i.containerHeight;
685       }
686       break;
687     default:
688       return;
689     }
690
691     updateScroll(element, 'top', element.scrollTop - deltaY);
692     updateScroll(element, 'left', element.scrollLeft + deltaX);
693     updateGeometry(element);
694
695     shouldPrevent = shouldPreventDefault(deltaX, deltaY);
696     if (shouldPrevent) {
697       e.preventDefault();
698     }
699   });
700 }
701
702 module.exports = function (element) {
703   var i = instances.get(element);
704   bindKeyboardHandler(element, i);
705 };
706
707 },{"../../lib/dom":3,"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],13:[function(require,module,exports){
708 'use strict';
709
710 var instances = require('../instances')
711   , updateGeometry = require('../update-geometry')
712   , updateScroll = require('../update-scroll');
713
714 function bindMouseWheelHandler(element, i) {
715   var shouldPrevent = false;
716
717   function shouldPreventDefault(deltaX, deltaY) {
718     var scrollTop = element.scrollTop;
719     if (deltaX === 0) {
720       if (!i.scrollbarYActive) {
721         return false;
722       }
723       if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
724         return !i.settings.wheelPropagation;
725       }
726     }
727
728     var scrollLeft = element.scrollLeft;
729     if (deltaY === 0) {
730       if (!i.scrollbarXActive) {
731         return false;
732       }
733       if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
734         return !i.settings.wheelPropagation;
735       }
736     }
737     return true;
738   }
739
740   function getDeltaFromEvent(e) {
741     var deltaX = e.deltaX;
742     var deltaY = -1 * e.deltaY;
743
744     if (typeof deltaX === "undefined" || typeof deltaY === "undefined") {
745       // OS X Safari
746       deltaX = -1 * e.wheelDeltaX / 6;
747       deltaY = e.wheelDeltaY / 6;
748     }
749
750     if (e.deltaMode && e.deltaMode === 1) {
751       // Firefox in deltaMode 1: Line scrolling
752       deltaX *= 10;
753       deltaY *= 10;
754     }
755
756     if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {
757       // IE in some mouse drivers
758       deltaX = 0;
759       deltaY = e.wheelDelta;
760     }
761
762     return [deltaX, deltaY];
763   }
764
765   function shouldBeConsumedByTextarea(deltaX, deltaY) {
766     var hoveredTextarea = element.querySelector('textarea:hover');
767     if (hoveredTextarea) {
768       var maxScrollTop = hoveredTextarea.scrollHeight - hoveredTextarea.clientHeight;
769       if (maxScrollTop > 0) {
770         if (!(hoveredTextarea.scrollTop === 0 && deltaY > 0) &&
771             !(hoveredTextarea.scrollTop === maxScrollTop && deltaY < 0)) {
772           return true;
773         }
774       }
775       var maxScrollLeft = hoveredTextarea.scrollLeft - hoveredTextarea.clientWidth;
776       if (maxScrollLeft > 0) {
777         if (!(hoveredTextarea.scrollLeft === 0 && deltaX < 0) &&
778             !(hoveredTextarea.scrollLeft === maxScrollLeft && deltaX > 0)) {
779           return true;
780         }
781       }
782     }
783     return false;
784   }
785
786   function mousewheelHandler(e) {
787     var delta = getDeltaFromEvent(e);
788
789     var deltaX = delta[0];
790     var deltaY = delta[1];
791
792     if (shouldBeConsumedByTextarea(deltaX, deltaY)) {
793       return;
794     }
795
796     shouldPrevent = false;
797     if (!i.settings.useBothWheelAxes) {
798       // deltaX will only be used for horizontal scrolling and deltaY will
799       // only be used for vertical scrolling - this is the default
800       updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
801       updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
802     } else if (i.scrollbarYActive && !i.scrollbarXActive) {
803       // only vertical scrollbar is active and useBothWheelAxes option is
804       // active, so let's scroll vertical bar using both mouse wheel axes
805       if (deltaY) {
806         updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
807       } else {
808         updateScroll(element, 'top', element.scrollTop + (deltaX * i.settings.wheelSpeed));
809       }
810       shouldPrevent = true;
811     } else if (i.scrollbarXActive && !i.scrollbarYActive) {
812       // useBothWheelAxes and only horizontal bar is active, so use both
813       // wheel axes for horizontal bar
814       if (deltaX) {
815         updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
816       } else {
817         updateScroll(element, 'left', element.scrollLeft - (deltaY * i.settings.wheelSpeed));
818       }
819       shouldPrevent = true;
820     }
821
822     updateGeometry(element);
823
824     shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
825     if (shouldPrevent) {
826       e.stopPropagation();
827       e.preventDefault();
828     }
829   }
830
831   if (typeof window.onwheel !== "undefined") {
832     i.event.bind(element, 'wheel', mousewheelHandler);
833   } else if (typeof window.onmousewheel !== "undefined") {
834     i.event.bind(element, 'mousewheel', mousewheelHandler);
835   }
836 }
837
838 module.exports = function (element) {
839   var i = instances.get(element);
840   bindMouseWheelHandler(element, i);
841 };
842
843 },{"../instances":18,"../update-geometry":19,"../update-scroll":20}],14:[function(require,module,exports){
844 'use strict';
845
846 var instances = require('../instances')
847   , updateGeometry = require('../update-geometry');
848
849 function bindNativeScrollHandler(element, i) {
850   i.event.bind(element, 'scroll', function () {
851     updateGeometry(element);
852   });
853 }
854
855 module.exports = function (element) {
856   var i = instances.get(element);
857   bindNativeScrollHandler(element, i);
858 };
859
860 },{"../instances":18,"../update-geometry":19}],15:[function(require,module,exports){
861 'use strict';
862
863 var h = require('../../lib/helper')
864   , instances = require('../instances')
865   , updateGeometry = require('../update-geometry')
866   , updateScroll = require('../update-scroll');
867
868 function bindSelectionHandler(element, i) {
869   function getRangeNode() {
870     var selection = window.getSelection ? window.getSelection() :
871                     document.getSelection ? document.getSelection() : '';
872     if (selection.toString().length === 0) {
873       return null;
874     } else {
875       return selection.getRangeAt(0).commonAncestorContainer;
876     }
877   }
878
879   var scrollingLoop = null;
880   var scrollDiff = {top: 0, left: 0};
881   function startScrolling() {
882     if (!scrollingLoop) {
883       scrollingLoop = setInterval(function () {
884         if (!instances.get(element)) {
885           clearInterval(scrollingLoop);
886           return;
887         }
888
889         updateScroll(element, 'top', element.scrollTop + scrollDiff.top);
890         updateScroll(element, 'left', element.scrollLeft + scrollDiff.left);
891         updateGeometry(element);
892       }, 50); // every .1 sec
893     }
894   }
895   function stopScrolling() {
896     if (scrollingLoop) {
897       clearInterval(scrollingLoop);
898       scrollingLoop = null;
899     }
900     h.stopScrolling(element);
901   }
902
903   var isSelected = false;
904   i.event.bind(i.ownerDocument, 'selectionchange', function () {
905     if (element.contains(getRangeNode())) {
906       isSelected = true;
907     } else {
908       isSelected = false;
909       stopScrolling();
910     }
911   });
912   i.event.bind(window, 'mouseup', function () {
913     if (isSelected) {
914       isSelected = false;
915       stopScrolling();
916     }
917   });
918
919   i.event.bind(window, 'mousemove', function (e) {
920     if (isSelected) {
921       var mousePosition = {x: e.pageX, y: e.pageY};
922       var containerGeometry = {
923         left: element.offsetLeft,
924         right: element.offsetLeft + element.offsetWidth,
925         top: element.offsetTop,
926         bottom: element.offsetTop + element.offsetHeight
927       };
928
929       if (mousePosition.x < containerGeometry.left + 3) {
930         scrollDiff.left = -5;
931         h.startScrolling(element, 'x');
932       } else if (mousePosition.x > containerGeometry.right - 3) {
933         scrollDiff.left = 5;
934         h.startScrolling(element, 'x');
935       } else {
936         scrollDiff.left = 0;
937       }
938
939       if (mousePosition.y < containerGeometry.top + 3) {
940         if (containerGeometry.top + 3 - mousePosition.y < 5) {
941           scrollDiff.top = -5;
942         } else {
943           scrollDiff.top = -20;
944         }
945         h.startScrolling(element, 'y');
946       } else if (mousePosition.y > containerGeometry.bottom - 3) {
947         if (mousePosition.y - containerGeometry.bottom + 3 < 5) {
948           scrollDiff.top = 5;
949         } else {
950           scrollDiff.top = 20;
951         }
952         h.startScrolling(element, 'y');
953       } else {
954         scrollDiff.top = 0;
955       }
956
957       if (scrollDiff.top === 0 && scrollDiff.left === 0) {
958         stopScrolling();
959       } else {
960         startScrolling();
961       }
962     }
963   });
964 }
965
966 module.exports = function (element) {
967   var i = instances.get(element);
968   bindSelectionHandler(element, i);
969 };
970
971 },{"../../lib/helper":6,"../instances":18,"../update-geometry":19,"../update-scroll":20}],16:[function(require,module,exports){
972 'use strict';
973
974 var instances = require('../instances')
975   , updateGeometry = require('../update-geometry')
976   , updateScroll = require('../update-scroll');
977
978 function bindTouchHandler(element, i, supportsTouch, supportsIePointer) {
979   function shouldPreventDefault(deltaX, deltaY) {
980     var scrollTop = element.scrollTop;
981     var scrollLeft = element.scrollLeft;
982     var magnitudeX = Math.abs(deltaX);
983     var magnitudeY = Math.abs(deltaY);
984
985     if (magnitudeY > magnitudeX) {
986       // user is perhaps trying to swipe up/down the page
987
988       if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) ||
989           ((deltaY > 0) && (scrollTop === 0))) {
990         return !i.settings.swipePropagation;
991       }
992     } else if (magnitudeX > magnitudeY) {
993       // user is perhaps trying to swipe left/right across the page
994
995       if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) ||
996           ((deltaX > 0) && (scrollLeft === 0))) {
997         return !i.settings.swipePropagation;
998       }
999     }
1000
1001     return true;
1002   }
1003
1004   function applyTouchMove(differenceX, differenceY) {
1005     updateScroll(element, 'top', element.scrollTop - differenceY);
1006     updateScroll(element, 'left', element.scrollLeft - differenceX);
1007
1008     updateGeometry(element);
1009   }
1010
1011   var startOffset = {};
1012   var startTime = 0;
1013   var speed = {};
1014   var easingLoop = null;
1015   var inGlobalTouch = false;
1016   var inLocalTouch = false;
1017
1018   function globalTouchStart() {
1019     inGlobalTouch = true;
1020   }
1021   function globalTouchEnd() {
1022     inGlobalTouch = false;
1023   }
1024
1025   function getTouch(e) {
1026     if (e.targetTouches) {
1027       return e.targetTouches[0];
1028     } else {
1029       // Maybe IE pointer
1030       return e;
1031     }
1032   }
1033   function shouldHandle(e) {
1034     if (e.targetTouches && e.targetTouches.length === 1) {
1035       return true;
1036     }
1037     if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
1038       return true;
1039     }
1040     return false;
1041   }
1042   function touchStart(e) {
1043     if (shouldHandle(e)) {
1044       inLocalTouch = true;
1045
1046       var touch = getTouch(e);
1047
1048       startOffset.pageX = touch.pageX;
1049       startOffset.pageY = touch.pageY;
1050
1051       startTime = (new Date()).getTime();
1052
1053       if (easingLoop !== null) {
1054         clearInterval(easingLoop);
1055       }
1056
1057       e.stopPropagation();
1058     }
1059   }
1060   function touchMove(e) {
1061     if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
1062       var touch = getTouch(e);
1063
1064       var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
1065
1066       var differenceX = currentOffset.pageX - startOffset.pageX;
1067       var differenceY = currentOffset.pageY - startOffset.pageY;
1068
1069       applyTouchMove(differenceX, differenceY);
1070       startOffset = currentOffset;
1071
1072       var currentTime = (new Date()).getTime();
1073
1074       var timeGap = currentTime - startTime;
1075       if (timeGap > 0) {
1076         speed.x = differenceX / timeGap;
1077         speed.y = differenceY / timeGap;
1078         startTime = currentTime;
1079       }
1080
1081       if (shouldPreventDefault(differenceX, differenceY)) {
1082         e.stopPropagation();
1083         e.preventDefault();
1084       }
1085     }
1086   }
1087   function touchEnd() {
1088     if (!inGlobalTouch && inLocalTouch) {
1089       inLocalTouch = false;
1090
1091       clearInterval(easingLoop);
1092       easingLoop = setInterval(function () {
1093         if (!instances.get(element)) {
1094           clearInterval(easingLoop);
1095           return;
1096         }
1097
1098         if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
1099           clearInterval(easingLoop);
1100           return;
1101         }
1102
1103         applyTouchMove(speed.x * 30, speed.y * 30);
1104
1105         speed.x *= 0.8;
1106         speed.y *= 0.8;
1107       }, 10);
1108     }
1109   }
1110
1111   if (supportsTouch) {
1112     i.event.bind(window, 'touchstart', globalTouchStart);
1113     i.event.bind(window, 'touchend', globalTouchEnd);
1114     i.event.bind(element, 'touchstart', touchStart);
1115     i.event.bind(element, 'touchmove', touchMove);
1116     i.event.bind(element, 'touchend', touchEnd);
1117   }
1118
1119   if (supportsIePointer) {
1120     if (window.PointerEvent) {
1121       i.event.bind(window, 'pointerdown', globalTouchStart);
1122       i.event.bind(window, 'pointerup', globalTouchEnd);
1123       i.event.bind(element, 'pointerdown', touchStart);
1124       i.event.bind(element, 'pointermove', touchMove);
1125       i.event.bind(element, 'pointerup', touchEnd);
1126     } else if (window.MSPointerEvent) {
1127       i.event.bind(window, 'MSPointerDown', globalTouchStart);
1128       i.event.bind(window, 'MSPointerUp', globalTouchEnd);
1129       i.event.bind(element, 'MSPointerDown', touchStart);
1130       i.event.bind(element, 'MSPointerMove', touchMove);
1131       i.event.bind(element, 'MSPointerUp', touchEnd);
1132     }
1133   }
1134 }
1135
1136 module.exports = function (element, supportsTouch, supportsIePointer) {
1137   var i = instances.get(element);
1138   bindTouchHandler(element, i, supportsTouch, supportsIePointer);
1139 };
1140
1141 },{"../instances":18,"../update-geometry":19,"../update-scroll":20}],17:[function(require,module,exports){
1142 'use strict';
1143
1144 var cls = require('../lib/class')
1145   , h = require('../lib/helper')
1146   , instances = require('./instances')
1147   , updateGeometry = require('./update-geometry');
1148
1149 // Handlers
1150 var clickRailHandler = require('./handler/click-rail')
1151   , dragScrollbarHandler = require('./handler/drag-scrollbar')
1152   , keyboardHandler = require('./handler/keyboard')
1153   , mouseWheelHandler = require('./handler/mouse-wheel')
1154   , nativeScrollHandler = require('./handler/native-scroll')
1155   , selectionHandler = require('./handler/selection')
1156   , touchHandler = require('./handler/touch');
1157
1158 module.exports = function (element, userSettings) {
1159   userSettings = typeof userSettings === 'object' ? userSettings : {};
1160
1161   cls.add(element, 'ps-container');
1162
1163   // Create a plugin instance.
1164   var i = instances.add(element);
1165
1166   i.settings = h.extend(i.settings, userSettings);
1167   cls.add(element, 'ps-theme-' + i.settings.theme);
1168
1169   clickRailHandler(element);
1170   dragScrollbarHandler(element);
1171   mouseWheelHandler(element);
1172   nativeScrollHandler(element);
1173
1174   if (i.settings.useSelectionScroll) {
1175     selectionHandler(element);
1176   }
1177
1178   if (h.env.supportsTouch || h.env.supportsIePointer) {
1179     touchHandler(element, h.env.supportsTouch, h.env.supportsIePointer);
1180   }
1181   if (i.settings.useKeyboard) {
1182     keyboardHandler(element);
1183   }
1184
1185   updateGeometry(element);
1186 };
1187
1188 },{"../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 'use strict';
1190
1191 var cls = require('../lib/class')
1192   , d = require('../lib/dom')
1193   , defaultSettings = require('./default-setting')
1194   , EventManager = require('../lib/event-manager')
1195   , guid = require('../lib/guid')
1196   , h = require('../lib/helper');
1197
1198 var instances = {};
1199
1200 function Instance(element) {
1201   var i = this;
1202
1203   i.settings = h.clone(defaultSettings);
1204   i.containerWidth = null;
1205   i.containerHeight = null;
1206   i.contentWidth = null;
1207   i.contentHeight = null;
1208
1209   i.isRtl = d.css(element, 'direction') === "rtl";
1210   i.isNegativeScroll = (function () {
1211     var originalScrollLeft = element.scrollLeft;
1212     var result = null;
1213     element.scrollLeft = -1;
1214     result = element.scrollLeft < 0;
1215     element.scrollLeft = originalScrollLeft;
1216     return result;
1217   })();
1218   i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
1219   i.event = new EventManager();
1220   i.ownerDocument = element.ownerDocument || document;
1221
1222   function focus() {
1223     cls.add(element, 'ps-focus');
1224   }
1225
1226   function blur() {
1227     cls.remove(element, 'ps-focus');
1228   }
1229
1230   i.scrollbarXRail = d.appendTo(d.e('div', 'ps-scrollbar-x-rail'), element);
1231   i.scrollbarX = d.appendTo(d.e('div', 'ps-scrollbar-x'), i.scrollbarXRail);
1232   i.scrollbarX.setAttribute('tabindex', 0);
1233   i.event.bind(i.scrollbarX, 'focus', focus);
1234   i.event.bind(i.scrollbarX, 'blur', blur);
1235   i.scrollbarXActive = null;
1236   i.scrollbarXWidth = null;
1237   i.scrollbarXLeft = null;
1238   i.scrollbarXBottom = h.toInt(d.css(i.scrollbarXRail, 'bottom'));
1239   i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN
1240   i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : h.toInt(d.css(i.scrollbarXRail, 'top'));
1241   i.railBorderXWidth = h.toInt(d.css(i.scrollbarXRail, 'borderLeftWidth')) + h.toInt(d.css(i.scrollbarXRail, 'borderRightWidth'));
1242   // Set rail to display:block to calculate margins
1243   d.css(i.scrollbarXRail, 'display', 'block');
1244   i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
1245   d.css(i.scrollbarXRail, 'display', '');
1246   i.railXWidth = null;
1247   i.railXRatio = null;
1248
1249   i.scrollbarYRail = d.appendTo(d.e('div', 'ps-scrollbar-y-rail'), element);
1250   i.scrollbarY = d.appendTo(d.e('div', 'ps-scrollbar-y'), i.scrollbarYRail);
1251   i.scrollbarY.setAttribute('tabindex', 0);
1252   i.event.bind(i.scrollbarY, 'focus', focus);
1253   i.event.bind(i.scrollbarY, 'blur', blur);
1254   i.scrollbarYActive = null;
1255   i.scrollbarYHeight = null;
1256   i.scrollbarYTop = null;
1257   i.scrollbarYRight = h.toInt(d.css(i.scrollbarYRail, 'right'));
1258   i.isScrollbarYUsingRight = i.scrollbarYRight === i.scrollbarYRight; // !isNaN
1259   i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : h.toInt(d.css(i.scrollbarYRail, 'left'));
1260   i.scrollbarYOuterWidth = i.isRtl ? h.outerWidth(i.scrollbarY) : null;
1261   i.railBorderYWidth = h.toInt(d.css(i.scrollbarYRail, 'borderTopWidth')) + h.toInt(d.css(i.scrollbarYRail, 'borderBottomWidth'));
1262   d.css(i.scrollbarYRail, 'display', 'block');
1263   i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
1264   d.css(i.scrollbarYRail, 'display', '');
1265   i.railYHeight = null;
1266   i.railYRatio = null;
1267 }
1268
1269 function getId(element) {
1270   if (typeof element.dataset === 'undefined') {
1271     return element.getAttribute('data-ps-id');
1272   } else {
1273     return element.dataset.psId;
1274   }
1275 }
1276
1277 function setId(element, id) {
1278   if (typeof element.dataset === 'undefined') {
1279     element.setAttribute('data-ps-id', id);
1280   } else {
1281     element.dataset.psId = id;
1282   }
1283 }
1284
1285 function removeId(element) {
1286   if (typeof element.dataset === 'undefined') {
1287     element.removeAttribute('data-ps-id');
1288   } else {
1289     delete element.dataset.psId;
1290   }
1291 }
1292
1293 exports.add = function (element) {
1294   var newId = guid();
1295   setId(element, newId);
1296   instances[newId] = new Instance(element);
1297   return instances[newId];
1298 };
1299
1300 exports.remove = function (element) {
1301   delete instances[getId(element)];
1302   removeId(element);
1303 };
1304
1305 exports.get = function (element) {
1306   return instances[getId(element)];
1307 };
1308
1309 },{"../lib/class":2,"../lib/dom":3,"../lib/event-manager":4,"../lib/guid":5,"../lib/helper":6,"./default-setting":8}],19:[function(require,module,exports){
1310 'use strict';
1311
1312 var cls = require('../lib/class')
1313   , d = require('../lib/dom')
1314   , h = require('../lib/helper')
1315   , instances = require('./instances')
1316   , updateScroll = require('./update-scroll');
1317
1318 function getThumbSize(i, thumbSize) {
1319   if (i.settings.minScrollbarLength) {
1320     thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);
1321   }
1322   if (i.settings.maxScrollbarLength) {
1323     thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);
1324   }
1325   return thumbSize;
1326 }
1327
1328 function updateCss(element, i) {
1329   var xRailOffset = {width: i.railXWidth};
1330   if (i.isRtl) {
1331     xRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth - i.contentWidth;
1332   } else {
1333     xRailOffset.left = element.scrollLeft;
1334   }
1335   if (i.isScrollbarXUsingBottom) {
1336     xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop;
1337   } else {
1338     xRailOffset.top = i.scrollbarXTop + element.scrollTop;
1339   }
1340   d.css(i.scrollbarXRail, xRailOffset);
1341
1342   var yRailOffset = {top: element.scrollTop, height: i.railYHeight};
1343   if (i.isScrollbarYUsingRight) {
1344     if (i.isRtl) {
1345       yRailOffset.right = i.contentWidth - (i.negativeScrollAdjustment + element.scrollLeft) - i.scrollbarYRight - i.scrollbarYOuterWidth;
1346     } else {
1347       yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
1348     }
1349   } else {
1350     if (i.isRtl) {
1351       yRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth;
1352     } else {
1353       yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
1354     }
1355   }
1356   d.css(i.scrollbarYRail, yRailOffset);
1357
1358   d.css(i.scrollbarX, {left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth});
1359   d.css(i.scrollbarY, {top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth});
1360 }
1361
1362 module.exports = function (element) {
1363   var i = instances.get(element);
1364
1365   i.containerWidth = element.clientWidth;
1366   i.containerHeight = element.clientHeight;
1367   i.contentWidth = element.scrollWidth;
1368   i.contentHeight = element.scrollHeight;
1369
1370   var existingRails;
1371   if (!element.contains(i.scrollbarXRail)) {
1372     existingRails = d.queryChildren(element, '.ps-scrollbar-x-rail');
1373     if (existingRails.length > 0) {
1374       existingRails.forEach(function (rail) {
1375         d.remove(rail);
1376       });
1377     }
1378     d.appendTo(i.scrollbarXRail, element);
1379   }
1380   if (!element.contains(i.scrollbarYRail)) {
1381     existingRails = d.queryChildren(element, '.ps-scrollbar-y-rail');
1382     if (existingRails.length > 0) {
1383       existingRails.forEach(function (rail) {
1384         d.remove(rail);
1385       });
1386     }
1387     d.appendTo(i.scrollbarYRail, element);
1388   }
1389
1390   if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) {
1391     i.scrollbarXActive = true;
1392     i.railXWidth = i.containerWidth - i.railXMarginWidth;
1393     i.railXRatio = i.containerWidth / i.railXWidth;
1394     i.scrollbarXWidth = getThumbSize(i, h.toInt(i.railXWidth * i.containerWidth / i.contentWidth));
1395     i.scrollbarXLeft = h.toInt((i.negativeScrollAdjustment + element.scrollLeft) * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
1396   } else {
1397     i.scrollbarXActive = false;
1398   }
1399
1400   if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) {
1401     i.scrollbarYActive = true;
1402     i.railYHeight = i.containerHeight - i.railYMarginHeight;
1403     i.railYRatio = i.containerHeight / i.railYHeight;
1404     i.scrollbarYHeight = getThumbSize(i, h.toInt(i.railYHeight * i.containerHeight / i.contentHeight));
1405     i.scrollbarYTop = h.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight));
1406   } else {
1407     i.scrollbarYActive = false;
1408   }
1409
1410   if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
1411     i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;
1412   }
1413   if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {
1414     i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;
1415   }
1416
1417   updateCss(element, i);
1418
1419   if (i.scrollbarXActive) {
1420     cls.add(element, 'ps-active-x');
1421   } else {
1422     cls.remove(element, 'ps-active-x');
1423     i.scrollbarXWidth = 0;
1424     i.scrollbarXLeft = 0;
1425     updateScroll(element, 'left', 0);
1426   }
1427   if (i.scrollbarYActive) {
1428     cls.add(element, 'ps-active-y');
1429   } else {
1430     cls.remove(element, 'ps-active-y');
1431     i.scrollbarYHeight = 0;
1432     i.scrollbarYTop = 0;
1433     updateScroll(element, 'top', 0);
1434   }
1435 };
1436
1437 },{"../lib/class":2,"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-scroll":20}],20:[function(require,module,exports){
1438 'use strict';
1439
1440 var instances = require('./instances');
1441
1442 var upEvent = document.createEvent('Event')
1443   , downEvent = document.createEvent('Event')
1444   , leftEvent = document.createEvent('Event')
1445   , rightEvent = document.createEvent('Event')
1446   , yEvent = document.createEvent('Event')
1447   , xEvent = document.createEvent('Event')
1448   , xStartEvent = document.createEvent('Event')
1449   , xEndEvent = document.createEvent('Event')
1450   , yStartEvent = document.createEvent('Event')
1451   , yEndEvent = document.createEvent('Event')
1452   , lastTop
1453   , lastLeft;
1454
1455 upEvent.initEvent('ps-scroll-up', true, true);
1456 downEvent.initEvent('ps-scroll-down', true, true);
1457 leftEvent.initEvent('ps-scroll-left', true, true);
1458 rightEvent.initEvent('ps-scroll-right', true, true);
1459 yEvent.initEvent('ps-scroll-y', true, true);
1460 xEvent.initEvent('ps-scroll-x', true, true);
1461 xStartEvent.initEvent('ps-x-reach-start', true, true);
1462 xEndEvent.initEvent('ps-x-reach-end', true, true);
1463 yStartEvent.initEvent('ps-y-reach-start', true, true);
1464 yEndEvent.initEvent('ps-y-reach-end', true, true);
1465
1466 module.exports = function (element, axis, value) {
1467   if (typeof element === 'undefined') {
1468     throw 'You must provide an element to the update-scroll function';
1469   }
1470
1471   if (typeof axis === 'undefined') {
1472     throw 'You must provide an axis to the update-scroll function';
1473   }
1474
1475   if (typeof value === 'undefined') {
1476     throw 'You must provide a value to the update-scroll function';
1477   }
1478
1479   if (axis === 'top' && value <= 0) {
1480     element.scrollTop = value = 0; // don't allow negative scroll
1481     element.dispatchEvent(yStartEvent);
1482   }
1483
1484   if (axis === 'left' && value <= 0) {
1485     element.scrollLeft = value = 0; // don't allow negative scroll
1486     element.dispatchEvent(xStartEvent);
1487   }
1488
1489   var i = instances.get(element);
1490
1491   if (axis === 'top' && value >= i.contentHeight - i.containerHeight) {
1492     element.scrollTop = value = i.contentHeight - i.containerHeight; // don't allow scroll past container
1493     element.dispatchEvent(yEndEvent);
1494   }
1495
1496   if (axis === 'left' && value >= i.contentWidth - i.containerWidth) {
1497     element.scrollLeft = value = i.contentWidth - i.containerWidth; // don't allow scroll past container
1498     element.dispatchEvent(xEndEvent);
1499   }
1500
1501   if (!lastTop) {
1502     lastTop = element.scrollTop;
1503   }
1504
1505   if (!lastLeft) {
1506     lastLeft = element.scrollLeft;
1507   }
1508
1509   if (axis === 'top' && value < lastTop) {
1510     element.dispatchEvent(upEvent);
1511   }
1512
1513   if (axis === 'top' && value > lastTop) {
1514     element.dispatchEvent(downEvent);
1515   }
1516
1517   if (axis === 'left' && value < lastLeft) {
1518     element.dispatchEvent(leftEvent);
1519   }
1520
1521   if (axis === 'left' && value > lastLeft) {
1522     element.dispatchEvent(rightEvent);
1523   }
1524
1525   if (axis === 'top') {
1526     element.scrollTop = lastTop = value;
1527     element.dispatchEvent(yEvent);
1528   }
1529
1530   if (axis === 'left') {
1531     element.scrollLeft = lastLeft = value;
1532     element.dispatchEvent(xEvent);
1533   }
1534
1535 };
1536
1537 },{"./instances":18}],21:[function(require,module,exports){
1538 'use strict';
1539
1540 var d = require('../lib/dom')
1541   , h = require('../lib/helper')
1542   , instances = require('./instances')
1543   , updateGeometry = require('./update-geometry')
1544   , updateScroll = require('./update-scroll');
1545
1546 module.exports = function (element) {
1547   var i = instances.get(element);
1548
1549   if (!i) {
1550     return;
1551   }
1552
1553   // Recalcuate negative scrollLeft adjustment
1554   i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
1555
1556   // Recalculate rail margins
1557   d.css(i.scrollbarXRail, 'display', 'block');
1558   d.css(i.scrollbarYRail, 'display', 'block');
1559   i.railXMarginWidth = h.toInt(d.css(i.scrollbarXRail, 'marginLeft')) + h.toInt(d.css(i.scrollbarXRail, 'marginRight'));
1560   i.railYMarginHeight = h.toInt(d.css(i.scrollbarYRail, 'marginTop')) + h.toInt(d.css(i.scrollbarYRail, 'marginBottom'));
1561
1562   // Hide scrollbars not to affect scrollWidth and scrollHeight
1563   d.css(i.scrollbarXRail, 'display', 'none');
1564   d.css(i.scrollbarYRail, 'display', 'none');
1565
1566   updateGeometry(element);
1567
1568   // Update top/left scroll to trigger events
1569   updateScroll(element, 'top', element.scrollTop);
1570   updateScroll(element, 'left', element.scrollLeft);
1571
1572   d.css(i.scrollbarXRail, 'display', '');
1573   d.css(i.scrollbarYRail, 'display', '');
1574 };
1575
1576 },{"../lib/dom":3,"../lib/helper":6,"./instances":18,"./update-geometry":19,"./update-scroll":20}]},{},[1]);