/scripts/custom-scrollbar-plugin/js/uncompressed/jquery.mCustomScrollbar.js
http://github.com/simogeo/Filemanager · JavaScript · 2199 lines · 1427 code · 225 blank · 547 comment · 392 complexity · ee6db1e09e68d8a6fb574ceb6fdc984c MD5 · raw file
Large files are truncated click here to view the full file
- /*
- == malihu jquery custom scrollbar plugin ==
- Version: 3.0.5
- Plugin URI: http://manos.malihu.gr/jquery-custom-content-scroller
- Author: malihu
- Author URI: http://manos.malihu.gr
- License: MIT License (MIT)
- */
- /*
- Copyright 2010 Manos Malihutsakis (email: manos@malihu.gr)
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
- /*
- The code below is fairly long, fully commented and should be normally used in development.
- For production, use either the minified jquery.mCustomScrollbar.min.js script or
- the production-ready jquery.mCustomScrollbar.concat.min.js which contains the plugin
- and dependencies (minified).
- */
- ;(function($,window,document,undefined){
- (function(init){
- var _rjs=typeof define==="function" && define.amd, /* RequireJS */
- _dlp=("https:"==document.location.protocol) ? "https:" : "http:", /* location protocol */
- _url="cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.11/jquery.mousewheel.min.js";
- if(!_rjs){
- /* load jquery-mousewheel plugin (via CDN) if it's not present or not loaded via RequireJS
- (works when mCustomScrollbar fn is called on window load) */
- $.event.special.mousewheel || $("head").append(decodeURI("%3Cscript src="+_dlp+"//"+_url+"%3E%3C/script%3E"));
- }
- init();
- }(function(){
-
- /*
- ----------------------------------------
- PLUGIN NAMESPACE, PREFIX, DEFAULT SELECTOR(S)
- ----------------------------------------
- */
-
- var pluginNS="mCustomScrollbar",
- pluginPfx="mCS",
- defaultSelector=".mCustomScrollbar",
-
-
-
-
-
- /*
- ----------------------------------------
- DEFAULT OPTIONS
- ----------------------------------------
- */
-
- defaults={
- /*
- set element/content width programmatically
- values: boolean, pixels, percentage
- */
- setWidth:false,
- /*
- set element/content height programmatically
- values: boolean, pixels, percentage
- */
- setHeight:false,
- /*
- set the initial css top property of content
- values: string (e.g. "-100px", "10%" etc.)
- */
- setTop:0,
- /*
- set the initial css left property of content
- values: string (e.g. "-100px", "10%" etc.)
- */
- setLeft:0,
- /*
- scrollbar axis (vertical and/or horizontal scrollbars)
- values (string): "y", "x", "yx"
- */
- axis:"y",
- /*
- position of scrollbar relative to content
- values (string): "inside", "outside" ("outside" requires elements with position:relative)
- */
- scrollbarPosition:"inside",
- /*
- scrolling inertia
- values: integer (milliseconds)
- */
- scrollInertia:950,
- /*
- auto-adjust scrollbar dragger length
- values: boolean
- */
- autoDraggerLength:true,
- /*
- auto-hide scrollbar when idle
- values: boolean
- */
- autoHideScrollbar:false,
- /*
- auto-expands scrollbar on mouse-over and dragging
- */
- autoExpandScrollbar:false,
- /*
- always show scrollbar, even when there's nothing to scroll
- values: integer (0=disable, 1=always show dragger rail, 2=always show dragger rail, dragger and buttons), boolean
- */
- alwaysShowScrollbar:0,
- /*
- scrolling always snaps to a multiple of this number in pixels
- values: integer
- */
- snapAmount:null,
- /*
- when snapping, snap with this number in pixels as an offset
- values: integer
- */
- snapOffset:0,
- /*
- mouse-wheel scrolling
- */
- mouseWheel:{
- /*
- enable mouse-wheel scrolling
- values: boolean
- */
- enable:true,
- /*
- scrolling amount in pixels
- values: "auto", integer
- */
- scrollAmount:"auto",
- /*
- mouse-wheel scrolling axis
- the default scrolling direction when both vertical and horizontal scrollbars are present
- values (string): "y", "x"
- */
- axis:"y",
- /*
- prevent the default behaviour which automatically scrolls the parent element(s)
- when end of scrolling is reached
- values: boolean
- */
- preventDefault:false,
- /*
- the reported mouse-wheel delta value. The number of lines (translated to pixels) one wheel notch scrolls.
- values: "auto", integer
- "auto" uses the default OS/browser value
- */
- deltaFactor:"auto",
- /*
- normalize mouse-wheel delta to -1 or 1 (disables mouse-wheel acceleration)
- values: boolean
- */
- normalizeDelta:false,
- /*
- invert mouse-wheel scrolling direction
- values: boolean
- */
- invert:false,
- /*
- the tags that disable mouse-wheel when cursor is over them
- */
- disableOver:["select","option","keygen","datalist","textarea"]
- },
- /*
- scrollbar buttons
- */
- scrollButtons:{
- /*
- enable scrollbar buttons
- values: boolean
- */
- enable:false,
- /*
- scrollbar buttons scrolling type
- values (string): "stepless", "stepped"
- */
- scrollType:"stepless",
- /*
- scrolling amount in pixels
- values: "auto", integer
- */
- scrollAmount:"auto"
- },
- /*
- keyboard scrolling
- */
- keyboard:{
- /*
- enable scrolling via keyboard
- values: boolean
- */
- enable:true,
- /*
- keyboard scrolling type
- values (string): "stepless", "stepped"
- */
- scrollType:"stepless",
- /*
- scrolling amount in pixels
- values: "auto", integer
- */
- scrollAmount:"auto"
- },
- /*
- enable content touch-swipe scrolling
- values: boolean, integer, string (number)
- integer values define the axis-specific minimum amount required for scrolling momentum
- */
- contentTouchScroll:25,
- /*
- advanced option parameters
- */
- advanced:{
- /*
- auto-expand content horizontally (for "x" or "yx" axis)
- values: boolean
- */
- autoExpandHorizontalScroll:false,
- /*
- auto-scroll to elements with focus
- */
- autoScrollOnFocus:"input,textarea,select,button,datalist,keygen,a[tabindex],area,object,[contenteditable='true']",
- /*
- auto-update scrollbars on content, element or viewport resize
- should be true for fluid layouts/elements, adding/removing content dynamically, hiding/showing elements, content with images etc.
- values: boolean
- */
- updateOnContentResize:true,
- /*
- auto-update scrollbars each time each image inside the element is fully loaded
- values: boolean
- */
- updateOnImageLoad:true,
- /*
- auto-update scrollbars based on the amount and size changes of specific selectors
- useful when you need to update the scrollbar(s) automatically, each time a type of element is added, removed or changes its size
- values: boolean, string (e.g. "ul li" will auto-update scrollbars each time list-items inside the element are changed)
- a value of true (boolean) will auto-update scrollbars each time any element is changed
- */
- updateOnSelectorChange:false,
- /*
- extra selectors that'll release scrollbar dragging upon mouseup, pointerup, touchend etc. (e.g. "selector-1, selector-2")
- */
- releaseDraggableSelectors:false
- },
- /*
- scrollbar theme
- values: string
- ready-to-use themes: "light", "dark", "light-2", "dark-2", "light-3", "dark-3", "light-thick", "dark-thick", "light-thin", "dark-thin",
- "rounded", "rounded-dark", "rounded-dots", "rounded-dots-dark", "3d", "3d-dark", "3d-thick", "3d-thick-dark", "minimal", "minimal-dark",
- "inset", "inset-dark", "inset-2", "inset-2-dark", "inset-3", "inset-3-dark"
- */
- theme:"light",
- /*
- user defined callback functions
- */
- callbacks:{
- /*
- function to call when the scrollbars have initialized
- values (function): function(){}
- */
- onInit:false,
- /*
- function to call when a scroll event starts
- values (function): function(){}
- */
- onScrollStart:false,
- /*
- function to call when a scroll event is complete
- values (function): function(){}
- */
- onScroll:false,
- /*
- function to call when a scroll event is complete and content is scrolled all the way to the end (bottom/right)
- values (function): function(){}
- */
- onTotalScroll:false,
- /*
- function to call when a scroll event is complete and content is scrolled back to the beginning (top/left)
- values (function): function(){}
- */
- onTotalScrollBack:false,
- /*
- function to call when a scroll event is running
- values (function): function(){}
- */
- whileScrolling:false,
- /*
- onTotalScroll offset value
- values: integer (pixels)
- */
- onTotalScrollOffset:0,
- /*
- onTotalScrollBack offset value
- values: integer (pixels)
- */
- onTotalScrollBackOffset:0,
- /*
- callback offsets will trigger even if content is already scrolled to the end or beginning
- values: boolean
- */
- alwaysTriggerOffsets:true,
- /*
- function to call when content becomes long enough and vertical scrollbar is added
- values (function): function(){}
- */
- onOverflowY:false,
- /*
- function to call when content becomes wide enough and horizontal scrollbar is added
- values (function): function(){}
- */
- onOverflowX:false,
- /*
- function to call when content becomes short enough and vertical scrollbar is removed
- values (function): function(){}
- */
- onOverflowYNone:false,
- /*
- function to call when content becomes narrow enough and horizontal scrollbar is removed
- values (function): function(){}
- */
- onOverflowXNone:false
- },
- /*
- add scrollbar(s) on all elements matching the current selector, now and in the future
- values: boolean, string
- string values: "on" (enable), "once" (disable after first invocation), "off" (disable)
- */
- live:false,
- /*
- the matching set of elements (instead of the current selector) to add scrollbar(s), now and in the future
- values: string (selector)
- */
- liveSelector:null
- },
-
-
-
-
-
- /*
- ----------------------------------------
- VARS, CONSTANTS
- ----------------------------------------
- */
-
- totalInstances=0, /* plugin instances amount */
- liveTimers={}, /* live option timers */
- /* live option timers removal */
- removeLiveTimers=function(selector){
- if(liveTimers[selector]){
- clearTimeout(liveTimers[selector]);
- functions._delete.call(null,liveTimers[selector]);
- }
- },
- oldIE=(window.attachEvent && !window.addEventListener) ? 1 : 0, /* detect IE < 9 */
- touchActive=false, /* global touch state (for touch and pointer events) */
-
-
-
-
-
- /*
- ----------------------------------------
- METHODS
- ----------------------------------------
- */
-
- methods={
-
- /*
- plugin initialization method
- creates the scrollbar(s), plugin data object and options
- ----------------------------------------
- */
-
- init:function(options){
-
- var options=$.extend(true,{},defaults,options),
- selector=functions._selector.call(this); /* validate selector */
-
- /*
- if live option is enabled, monitor for elements matching the current selector and
- apply scrollbar(s) when found (now and in the future)
- */
- if(options.live){
- var liveSelector=options.liveSelector || this.selector || defaultSelector, /* live selector(s) */
- $liveSelector=$(liveSelector); /* live selector(s) as jquery object */
- if(options.live==="off"){
- /*
- disable live if requested
- usage: $(selector).mCustomScrollbar({live:"off"});
- */
- removeLiveTimers(liveSelector);
- return;
- }
- liveTimers[liveSelector]=setTimeout(function(){
- /* call mCustomScrollbar fn on live selector(s) every half-second */
- $liveSelector.mCustomScrollbar(options);
- if(options.live==="once" && $liveSelector.length){
- /* disable live after first invocation */
- removeLiveTimers(liveSelector);
- }
- },500);
- }else{
- removeLiveTimers(liveSelector);
- }
-
- /* options backward compatibility (for versions < 3.0.0) and normalization */
- options.setWidth=(options.set_width) ? options.set_width : options.setWidth;
- options.setHeight=(options.set_height) ? options.set_height : options.setHeight;
- options.axis=(options.horizontalScroll) ? "x" : functions._findAxis.call(null,options.axis);
- options.scrollInertia=options.scrollInertia>0 && options.scrollInertia<17 ? 17 : options.scrollInertia;
- if(typeof options.mouseWheel!=="object" && options.mouseWheel==true){ /* old school mouseWheel option (non-object) */
- options.mouseWheel={enable:true,scrollAmount:"auto",axis:"y",preventDefault:false,deltaFactor:"auto",normalizeDelta:false,invert:false}
- }
- options.mouseWheel.scrollAmount=!options.mouseWheelPixels ? options.mouseWheel.scrollAmount : options.mouseWheelPixels;
- options.mouseWheel.normalizeDelta=!options.advanced.normalizeMouseWheelDelta ? options.mouseWheel.normalizeDelta : options.advanced.normalizeMouseWheelDelta;
- options.scrollButtons.scrollType=functions._findScrollButtonsType.call(null,options.scrollButtons.scrollType);
-
- functions._theme.call(null,options); /* theme-specific options */
-
- /* plugin constructor */
- return $(selector).each(function(){
-
- var $this=$(this);
-
- if(!$this.data(pluginPfx)){ /* prevent multiple instantiations */
-
- /* store options and create objects in jquery data */
- $this.data(pluginPfx,{
- idx:++totalInstances, /* instance index */
- opt:options, /* options */
- scrollRatio:{y:null,x:null}, /* scrollbar to content ratio */
- overflowed:null, /* overflowed axis */
- contentReset:{y:null,x:null}, /* object to check when content resets */
- bindEvents:false, /* object to check if events are bound */
- tweenRunning:false, /* object to check if tween is running */
- sequential:{}, /* sequential scrolling object */
- langDir:$this.css("direction"), /* detect/store direction (ltr or rtl) */
- cbOffsets:null, /* object to check whether callback offsets always trigger */
- /*
- object to check how scrolling events where last triggered
- "internal" (default - triggered by this script), "external" (triggered by other scripts, e.g. via scrollTo method)
- usage: object.data("mCS").trigger
- */
- trigger:null
- });
-
- /* HTML data attributes */
- var o=$this.data(pluginPfx).opt,
- htmlDataAxis=$this.data("mcs-axis"),htmlDataSbPos=$this.data("mcs-scrollbar-position"),htmlDataTheme=$this.data("mcs-theme");
- if(htmlDataAxis){o.axis=htmlDataAxis;} /* usage example: data-mcs-axis="y" */
- if(htmlDataSbPos){o.scrollbarPosition=htmlDataSbPos;} /* usage example: data-mcs-scrollbar-position="outside" */
- if(htmlDataTheme){ /* usage example: data-mcs-theme="minimal" */
- o.theme=htmlDataTheme;
- functions._theme.call(null,o); /* theme-specific options */
- }
-
- functions._pluginMarkup.call(this); /* add plugin markup */
-
- methods.update.call(null,$this); /* call the update method */
-
- }
-
- });
-
- },
- /* ---------------------------------------- */
-
-
-
- /*
- plugin update method
- updates content and scrollbar(s) values, events and status
- ----------------------------------------
- usage: $(selector).mCustomScrollbar("update");
- */
-
- update:function(el){
-
- var selector=el || functions._selector.call(this); /* validate selector */
-
- return $(selector).each(function(){
-
- var $this=$(this);
-
- if($this.data(pluginPfx)){ /* check if plugin has initialized */
-
- var d=$this.data(pluginPfx),o=d.opt,
- mCSB_container=$("#mCSB_"+d.idx+"_container"),
- mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")];
-
- if(!mCSB_container.length){return;}
-
- if(d.tweenRunning){functions._stop.call(null,$this);} /* stop any running tweens while updating */
-
- /* if element was disabled or destroyed, remove class(es) */
- if($this.hasClass("mCS_disabled")){$this.removeClass("mCS_disabled");}
- if($this.hasClass("mCS_destroyed")){$this.removeClass("mCS_destroyed");}
-
- functions._maxHeight.call(this); /* detect/set css max-height value */
-
- functions._expandContentHorizontally.call(this); /* expand content horizontally */
-
- if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){
- mCSB_container.css("width",functions._contentWidth(mCSB_container.children()));
- }
-
- d.overflowed=functions._overflowed.call(this); /* determine if scrolling is required */
-
- functions._scrollbarVisibility.call(this); /* show/hide scrollbar(s) */
-
- /* auto-adjust scrollbar dragger length analogous to content */
- if(o.autoDraggerLength){functions._setDraggerLength.call(this);}
-
- functions._scrollRatio.call(this); /* calculate and store scrollbar to content ratio */
-
- functions._bindEvents.call(this); /* bind scrollbar events */
-
- /* reset scrolling position and/or events */
- var to=[Math.abs(mCSB_container[0].offsetTop),Math.abs(mCSB_container[0].offsetLeft)];
- if(o.axis!=="x"){ /* y/yx axis */
- if(!d.overflowed[0]){ /* y scrolling is not required */
- functions._resetContentPosition.call(this); /* reset content position */
- if(o.axis==="y"){
- functions._unbindEvents.call(this);
- }else if(o.axis==="yx" && d.overflowed[1]){
- functions._scrollTo.call(this,$this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"});
- }
- }else if(mCSB_dragger[0].height()>mCSB_dragger[0].parent().height()){
- functions._resetContentPosition.call(this); /* reset content position */
- }else{ /* y scrolling is required */
- functions._scrollTo.call(this,$this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"});
- d.contentReset.y=null;
- }
- }
- if(o.axis!=="y"){ /* x/yx axis */
- if(!d.overflowed[1]){ /* x scrolling is not required */
- functions._resetContentPosition.call(this); /* reset content position */
- if(o.axis==="x"){
- functions._unbindEvents.call(this);
- }else if(o.axis==="yx" && d.overflowed[0]){
- functions._scrollTo.call(this,$this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"});
- }
- }else if(mCSB_dragger[1].width()>mCSB_dragger[1].parent().width()){
- functions._resetContentPosition.call(this); /* reset content position */
- }else{ /* x scrolling is required */
- functions._scrollTo.call(this,$this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"});
- d.contentReset.x=null;
- }
- }
-
- functions._autoUpdate.call(this); /* initialize automatic updating (for dynamic content, fluid layouts etc.) */
-
- }
-
- });
-
- },
- /* ---------------------------------------- */
-
-
-
- /*
- plugin scrollTo method
- triggers a scrolling event to a specific value
- ----------------------------------------
- usage: $(selector).mCustomScrollbar("scrollTo",value,options);
- */
-
- scrollTo:function(val,options){
-
- /* prevent silly things like $(selector).mCustomScrollbar("scrollTo",undefined); */
- if(typeof val=="undefined" || val==null){return;}
-
- var selector=functions._selector.call(this); /* validate selector */
-
- return $(selector).each(function(){
-
- var $this=$(this);
-
- if($this.data(pluginPfx)){ /* check if plugin has initialized */
-
- var d=$this.data(pluginPfx),o=d.opt,
- /* method default options */
- methodDefaults={
- trigger:"external", /* method is by default triggered externally (e.g. from other scripts) */
- scrollInertia:o.scrollInertia, /* scrolling inertia (animation duration) */
- scrollEasing:"mcsEaseInOut", /* animation easing */
- moveDragger:false, /* move dragger instead of content */
- timeout:60, /* scroll-to delay */
- callbacks:true, /* enable/disable callbacks */
- onStart:true,
- onUpdate:true,
- onComplete:true
- },
- methodOptions=$.extend(true,{},methodDefaults,options),
- to=functions._arr.call(this,val),dur=methodOptions.scrollInertia>0 && methodOptions.scrollInertia<17 ? 17 : methodOptions.scrollInertia;
-
- /* translate yx values to actual scroll-to positions */
- to[0]=functions._to.call(this,to[0],"y");
- to[1]=functions._to.call(this,to[1],"x");
-
- /*
- check if scroll-to value moves the dragger instead of content.
- Only pixel values apply on dragger (e.g. 100, "100px", "-=100" etc.)
- */
- if(methodOptions.moveDragger){
- to[0]*=d.scrollRatio.y;
- to[1]*=d.scrollRatio.x;
- }
-
- methodOptions.dur=dur;
-
- setTimeout(function(){
- /* do the scrolling */
- if(to[0]!==null && typeof to[0]!=="undefined" && o.axis!=="x" && d.overflowed[0]){ /* scroll y */
- methodOptions.dir="y";
- methodOptions.overwrite="all";
- functions._scrollTo.call(this,$this,to[0].toString(),methodOptions);
- }
- if(to[1]!==null && typeof to[1]!=="undefined" && o.axis!=="y" && d.overflowed[1]){ /* scroll x */
- methodOptions.dir="x";
- methodOptions.overwrite="none";
- functions._scrollTo.call(this,$this,to[1].toString(),methodOptions);
- }
- },methodOptions.timeout);
-
- }
-
- });
-
- },
- /* ---------------------------------------- */
-
-
-
- /*
- plugin stop method
- stops scrolling animation
- ----------------------------------------
- usage: $(selector).mCustomScrollbar("stop");
- */
- stop:function(){
-
- var selector=functions._selector.call(this); /* validate selector */
-
- return $(selector).each(function(){
-
- var $this=$(this);
-
- if($this.data(pluginPfx)){ /* check if plugin has initialized */
-
- functions._stop.call(null,$this);
-
- }
-
- });
-
- },
- /* ---------------------------------------- */
-
-
-
- /*
- plugin disable method
- temporarily disables the scrollbar(s)
- ----------------------------------------
- usage: $(selector).mCustomScrollbar("disable",reset);
- reset (boolean): resets content position to 0
- */
- disable:function(r){
-
- var selector=functions._selector.call(this); /* validate selector */
-
- return $(selector).each(function(){
-
- var $this=$(this);
-
- if($this.data(pluginPfx)){ /* check if plugin has initialized */
-
- var d=$this.data(pluginPfx),o=d.opt;
-
- functions._autoUpdate.call(this,"remove"); /* remove automatic updating */
-
- functions._unbindEvents.call(this); /* unbind events */
-
- if(r){functions._resetContentPosition.call(this);} /* reset content position */
-
- functions._scrollbarVisibility.call(this,true); /* show/hide scrollbar(s) */
-
- $this.addClass("mCS_disabled"); /* add disable class */
-
- }
-
- });
-
- },
- /* ---------------------------------------- */
-
-
-
- /*
- plugin destroy method
- completely removes the scrollbar(s) and returns the element to its original state
- ----------------------------------------
- usage: $(selector).mCustomScrollbar("destroy");
- */
- destroy:function(){
-
- var selector=functions._selector.call(this); /* validate selector */
-
- return $(selector).each(function(){
-
- var $this=$(this);
-
- if($this.data(pluginPfx)){ /* check if plugin has initialized */
-
- var d=$this.data(pluginPfx),o=d.opt,
- mCustomScrollBox=$("#mCSB_"+d.idx),
- mCSB_container=$("#mCSB_"+d.idx+"_container"),
- scrollbar=$(".mCSB_"+d.idx+"_scrollbar");
-
- if(o.live){removeLiveTimers(selector);} /* remove live timer */
-
- functions._autoUpdate.call(this,"remove"); /* remove automatic updating */
-
- functions._unbindEvents.call(this); /* unbind events */
-
- functions._resetContentPosition.call(this); /* reset content position */
-
- $this.removeData(pluginPfx); /* remove plugin data object */
-
- functions._delete.call(null,this.mcs); /* delete callbacks object */
-
- /* remove plugin markup */
- scrollbar.remove(); /* remove scrollbar(s) first (those can be either inside or outside plugin's inner wrapper) */
- mCustomScrollBox.replaceWith(mCSB_container.contents()); /* replace plugin's inner wrapper with the original content */
- /* remove plugin classes from the element and add destroy class */
- $this.removeClass(pluginNS+" _"+pluginPfx+"_"+d.idx+" mCS-autoHide mCS-dir-rtl mCS_no_scrollbar mCS_disabled").addClass("mCS_destroyed");
-
- }
-
- });
-
- }
- /* ---------------------------------------- */
-
- },
-
-
-
-
-
- /*
- ----------------------------------------
- FUNCTIONS
- ----------------------------------------
- */
-
- functions={
-
- /* validates selector (if selector is invalid or undefined uses the default one) */
- _selector:function(){
- return (typeof $(this)!=="object" || $(this).length<1) ? defaultSelector : this;
- },
- /* -------------------- */
-
- /* changes options according to theme */
- _theme:function(obj){
- var fixedSizeScrollbarThemes=["rounded","rounded-dark","rounded-dots","rounded-dots-dark"],
- nonExpandedScrollbarThemes=["rounded-dots","rounded-dots-dark","3d","3d-dark","3d-thick","3d-thick-dark","inset","inset-dark","inset-2","inset-2-dark","inset-3","inset-3-dark"],
- disabledScrollButtonsThemes=["minimal","minimal-dark"],
- enabledAutoHideScrollbarThemes=["minimal","minimal-dark"],
- scrollbarPositionOutsideThemes=["minimal","minimal-dark"];
- obj.autoDraggerLength=$.inArray(obj.theme,fixedSizeScrollbarThemes) > -1 ? false : obj.autoDraggerLength;
- obj.autoExpandScrollbar=$.inArray(obj.theme,nonExpandedScrollbarThemes) > -1 ? false : obj.autoExpandScrollbar;
- obj.scrollButtons.enable=$.inArray(obj.theme,disabledScrollButtonsThemes) > -1 ? false : obj.scrollButtons.enable;
- obj.autoHideScrollbar=$.inArray(obj.theme,enabledAutoHideScrollbarThemes) > -1 ? true : obj.autoHideScrollbar;
- obj.scrollbarPosition=$.inArray(obj.theme,scrollbarPositionOutsideThemes) > -1 ? "outside" : obj.scrollbarPosition;
- },
- /* -------------------- */
-
-
- /* normalizes axis option to valid values: "y", "x", "yx" */
- _findAxis:function(val){
- return (val==="yx" || val==="xy" || val==="auto") ? "yx" : (val==="x" || val==="horizontal") ? "x" : "y";
- },
- /* -------------------- */
-
-
- /* normalizes scrollButtons.scrollType option to valid values: "stepless", "stepped" */
- _findScrollButtonsType:function(val){
- return (val==="stepped" || val==="pixels" || val==="step" || val==="click") ? "stepped" : "stepless";
- },
- /* -------------------- */
-
-
- /* generates plugin markup */
- _pluginMarkup:function(){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
- expandClass=o.autoExpandScrollbar ? " mCSB_scrollTools_onDrag_expand" : "",
- scrollbar=["<div id='mCSB_"+d.idx+"_scrollbar_vertical' class='mCSB_scrollTools mCSB_"+d.idx+"_scrollbar mCS-"+o.theme+" mCSB_scrollTools_vertical"+expandClass+"'><div class='mCSB_draggerContainer'><div id='mCSB_"+d.idx+"_dragger_vertical' class='mCSB_dragger' style='position:absolute;' oncontextmenu='return false;'><div class='mCSB_dragger_bar' /></div><div class='mCSB_draggerRail' /></div></div>","<div id='mCSB_"+d.idx+"_scrollbar_horizontal' class='mCSB_scrollTools mCSB_"+d.idx+"_scrollbar mCS-"+o.theme+" mCSB_scrollTools_horizontal"+expandClass+"'><div class='mCSB_draggerContainer'><div id='mCSB_"+d.idx+"_dragger_horizontal' class='mCSB_dragger' style='position:absolute;' oncontextmenu='return false;'><div class='mCSB_dragger_bar' /></div><div class='mCSB_draggerRail' /></div></div>"],
- wrapperClass=o.axis==="yx" ? "mCSB_vertical_horizontal" : o.axis==="x" ? "mCSB_horizontal" : "mCSB_vertical",
- scrollbars=o.axis==="yx" ? scrollbar[0]+scrollbar[1] : o.axis==="x" ? scrollbar[1] : scrollbar[0],
- contentWrapper=o.axis==="yx" ? "<div id='mCSB_"+d.idx+"_container_wrapper' class='mCSB_container_wrapper' />" : "",
- autoHideClass=o.autoHideScrollbar ? " mCS-autoHide" : "",
- scrollbarDirClass=(o.axis!=="x" && d.langDir==="rtl") ? " mCS-dir-rtl" : "";
- if(o.setWidth){$this.css("width",o.setWidth);} /* set element width */
- if(o.setHeight){$this.css("height",o.setHeight);} /* set element height */
- o.setLeft=(o.axis!=="y" && d.langDir==="rtl") ? "989999px" : o.setLeft; /* adjust left position for rtl direction */
- $this.addClass(pluginNS+" _"+pluginPfx+"_"+d.idx+autoHideClass+scrollbarDirClass).wrapInner("<div id='mCSB_"+d.idx+"' class='mCustomScrollBox mCS-"+o.theme+" "+wrapperClass+"'><div id='mCSB_"+d.idx+"_container' class='mCSB_container' style='position:relative; top:"+o.setTop+"; left:"+o.setLeft+";' dir="+d.langDir+" /></div>");
- var mCustomScrollBox=$("#mCSB_"+d.idx),
- mCSB_container=$("#mCSB_"+d.idx+"_container");
- if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){
- mCSB_container.css("width",functions._contentWidth(mCSB_container.children()));
- }
- if(o.scrollbarPosition==="outside"){
- if($this.css("position")==="static"){ /* requires elements with non-static position */
- $this.css("position","relative");
- }
- $this.css("overflow","visible");
- mCustomScrollBox.addClass("mCSB_outside").after(scrollbars);
- }else{
- mCustomScrollBox.addClass("mCSB_inside").append(scrollbars);
- mCSB_container.wrap(contentWrapper);
- }
- functions._scrollButtons.call(this); /* add scrollbar buttons */
- /* minimum dragger length */
- var mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")];
- mCSB_dragger[0].css("min-height",mCSB_dragger[0].height());
- mCSB_dragger[1].css("min-width",mCSB_dragger[1].width());
- },
- /* -------------------- */
-
-
- /* calculates content width */
- _contentWidth:function(el){
- return Math.max.apply(Math,el.map(function(){return $(this).outerWidth(true);}).get());
- },
- /* -------------------- */
-
-
- /* expands content horizontally */
- _expandContentHorizontally:function(){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
- mCSB_container=$("#mCSB_"+d.idx+"_container");
- if(o.advanced.autoExpandHorizontalScroll && o.axis!=="y"){
- /*
- wrap content with an infinite width div and set its position to absolute and width to auto.
- Setting width to auto before calculating the actual width is important!
- We must let the browser set the width as browser zoom values are impossible to calculate.
- */
- mCSB_container.css({"position":"absolute","width":"auto"})
- .wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />")
- .css({ /* set actual width, original position and un-wrap */
- /*
- get the exact width (with decimals) and then round-up.
- Using jquery outerWidth() will round the width value which will mess up with inner elements that have non-integer width
- */
- "width":(Math.ceil(mCSB_container[0].getBoundingClientRect().right+0.4)-Math.floor(mCSB_container[0].getBoundingClientRect().left)),
- "position":"relative"
- }).unwrap();
- }
- },
- /* -------------------- */
-
-
- /* adds scrollbar buttons */
- _scrollButtons:function(){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
- mCSB_scrollTools=$(".mCSB_"+d.idx+"_scrollbar:first"),
- btnHTML=[
- "<a href='#' class='mCSB_buttonUp' oncontextmenu='return false;' />","<a href='#' class='mCSB_buttonDown' oncontextmenu='return false;' />",
- "<a href='#' class='mCSB_buttonLeft' oncontextmenu='return false;' />","<a href='#' class='mCSB_buttonRight' oncontextmenu='return false;' />"
- ],
- btn=[(o.axis==="x" ? btnHTML[2] : btnHTML[0]),(o.axis==="x" ? btnHTML[3] : btnHTML[1]),btnHTML[2],btnHTML[3]];
- if(o.scrollButtons.enable){
- mCSB_scrollTools.prepend(btn[0]).append(btn[1]).next(".mCSB_scrollTools").prepend(btn[2]).append(btn[3]);
- }
- },
- /* -------------------- */
-
-
- /* detects/sets css max-height value */
- _maxHeight:function(){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
- mCustomScrollBox=$("#mCSB_"+d.idx),
- mh=$this.css("max-height"),pct=mh.indexOf("%")!==-1,
- bs=$this.css("box-sizing");
- if(mh!=="none"){
- var val=pct ? $this.parent().height()*parseInt(mh)/100 : parseInt(mh);
- /* if element's css box-sizing is "border-box", subtract any paddings and/or borders from max-height value */
- if(bs==="border-box"){val-=(($this.innerHeight()-$this.height())+($this.outerHeight()-$this.innerHeight()));}
- mCustomScrollBox.css("max-height",Math.round(val));
- }
- },
- /* -------------------- */
-
-
- /* auto-adjusts scrollbar dragger length */
- _setDraggerLength:function(){
- var $this=$(this),d=$this.data(pluginPfx),
- mCustomScrollBox=$("#mCSB_"+d.idx),
- mCSB_container=$("#mCSB_"+d.idx+"_container"),
- mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
- ratio=[mCustomScrollBox.height()/mCSB_container.outerHeight(false),mCustomScrollBox.width()/mCSB_container.outerWidth(false)],
- l=[
- parseInt(mCSB_dragger[0].css("min-height")),Math.round(ratio[0]*mCSB_dragger[0].parent().height()),
- parseInt(mCSB_dragger[1].css("min-width")),Math.round(ratio[1]*mCSB_dragger[1].parent().width())
- ],
- h=oldIE && (l[1]<l[0]) ? l[0] : l[1],w=oldIE && (l[3]<l[2]) ? l[2] : l[3];
- mCSB_dragger[0].css({
- "height":h,"max-height":(mCSB_dragger[0].parent().height()-10)
- }).find(".mCSB_dragger_bar").css({"line-height":l[0]+"px"});
- mCSB_dragger[1].css({
- "width":w,"max-width":(mCSB_dragger[1].parent().width()-10)
- });
- },
- /* -------------------- */
-
-
- /* calculates scrollbar to content ratio */
- _scrollRatio:function(){
- var $this=$(this),d=$this.data(pluginPfx),
- mCustomScrollBox=$("#mCSB_"+d.idx),
- mCSB_container=$("#mCSB_"+d.idx+"_container"),
- mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
- scrollAmount=[mCSB_container.outerHeight(false)-mCustomScrollBox.height(),mCSB_container.outerWidth(false)-mCustomScrollBox.width()],
- ratio=[
- scrollAmount[0]/(mCSB_dragger[0].parent().height()-mCSB_dragger[0].height()),
- scrollAmount[1]/(mCSB_dragger[1].parent().width()-mCSB_dragger[1].width())
- ];
- d.scrollRatio={y:ratio[0],x:ratio[1]};
- },
- /* -------------------- */
-
-
- /* toggles scrolling classes */
- _onDragClasses:function(el,action,xpnd){
- var expandClass=xpnd ? "mCSB_dragger_onDrag_expanded" : "",classes=["mCSB_dragger_onDrag","mCSB_scrollTools_onDrag"],
- scrollbar=el.closest(".mCSB_scrollTools");
- if(action==="active"){
- el.toggleClass(classes[0]+" "+expandClass); scrollbar.toggleClass(classes[1]);
- el[0]._draggable=el[0]._draggable ? 0 : 1;
- }else{
- if(!el[0]._draggable){
- if(action==="hide"){
- el.removeClass(classes[0]); scrollbar.removeClass(classes[1]);
- }else{
- el.addClass(classes[0]); scrollbar.addClass(classes[1]);
- }
- }
- }
- },
- /* -------------------- */
-
-
- /* checks if content overflows its container to determine if scrolling is required */
- _overflowed:function(){
- var $this=$(this),d=$this.data(pluginPfx),
- mCustomScrollBox=$("#mCSB_"+d.idx),
- mCSB_container=$("#mCSB_"+d.idx+"_container"),
- contentHeight=d.overflowed==null ? mCSB_container.height() : mCSB_container.outerHeight(false),
- contentWidth=d.overflowed==null ? mCSB_container.width() : mCSB_container.outerWidth(false);
- return [contentHeight>mCustomScrollBox.height(),contentWidth>mCustomScrollBox.width()];
- },
- /* -------------------- */
-
-
- /* resets content position to 0 */
- _resetContentPosition:function(){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
- mCustomScrollBox=$("#mCSB_"+d.idx),
- mCSB_container=$("#mCSB_"+d.idx+"_container"),
- mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")];
- functions._stop($this); /* stop any current scrolling before resetting */
- if((o.axis!=="x" && !d.overflowed[0]) || (o.axis==="y" && d.overflowed[0])){ /* reset y */
- mCSB_dragger[0].add(mCSB_container).css("top",0);
- functions._scrollTo($this,"_resetY");
- }
- if((o.axis!=="y" && !d.overflowed[1]) || (o.axis==="x" && d.overflowed[1])){ /* reset x */
- var cx=dx=0;
- if(d.langDir==="rtl"){ /* adjust left position for rtl direction */
- cx=mCustomScrollBox.width()-mCSB_container.outerWidth(false);
- dx=Math.abs(cx/d.scrollRatio.x);
- }
- mCSB_container.css("left",cx);
- mCSB_dragger[1].css("left",dx);
- functions._scrollTo($this,"_resetX");
- }
- },
- /* -------------------- */
-
-
- /* binds scrollbar events */
- _bindEvents:function(){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt;
- if(!d.bindEvents){ /* check if events are already bound */
- functions._draggable.call(this);
- if(o.contentTouchScroll){functions._contentDraggable.call(this);}
- if(o.mouseWheel.enable){ /* bind mousewheel fn when plugin is available */
- function _mwt(){
- mousewheelTimeout=setTimeout(function(){
- if(!$.event.special.mousewheel){
- _mwt();
- }else{
- clearTimeout(mousewheelTimeout);
- functions._mousewheel.call($this[0]);
- }
- },1000);
- }
- var mousewheelTimeout;
- _mwt();
- }
- functions._draggerRail.call(this);
- functions._wrapperScroll.call(this);
- if(o.advanced.autoScrollOnFocus){functions._focus.call(this);}
- if(o.scrollButtons.enable){functions._buttons.call(this);}
- if(o.keyboard.enable){functions._keyboard.call(this);}
- d.bindEvents=true;
- }
- },
- /* -------------------- */
-
-
- /* unbinds scrollbar events */
- _unbindEvents:function(){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
- namespace=pluginPfx+"_"+d.idx,
- sb=".mCSB_"+d.idx+"_scrollbar",
- sel=$("#mCSB_"+d.idx+",#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,"+sb+" .mCSB_draggerContainer,#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal,"+sb+">a"),
- mCSB_container=$("#mCSB_"+d.idx+"_container");
- if(o.advanced.releaseDraggableSelectors){sel.add($(o.advanced.releaseDraggableSelectors));}
- if(d.bindEvents){ /* check if events are bound */
- /* unbind namespaced events from document/selectors */
- $(document).unbind("."+namespace);
- sel.each(function(){
- $(this).unbind("."+namespace);
- });
- /* clear and delete timeouts/objects */
- clearTimeout($this[0]._focusTimeout); functions._delete.call(null,$this[0]._focusTimeout);
- clearTimeout(d.sequential.step); functions._delete.call(null,d.sequential.step);
- clearTimeout(mCSB_container[0].onCompleteTimeout); functions._delete.call(null,mCSB_container[0].onCompleteTimeout);
- d.bindEvents=false;
- }
- },
- /* -------------------- */
-
-
- /* toggles scrollbar visibility */
- _scrollbarVisibility:function(disabled){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
- contentWrapper=$("#mCSB_"+d.idx+"_container_wrapper"),
- content=contentWrapper.length ? contentWrapper : $("#mCSB_"+d.idx+"_container"),
- scrollbar=[$("#mCSB_"+d.idx+"_scrollbar_vertical"),$("#mCSB_"+d.idx+"_scrollbar_horizontal")],
- mCSB_dragger=[scrollbar[0].find(".mCSB_dragger"),scrollbar[1].find(".mCSB_dragger")];
- if(o.axis!=="x"){
- if(d.overflowed[0] && !disabled){
- scrollbar[0].add(mCSB_dragger[0]).add(scrollbar[0].children("a")).css("display","block");
- content.removeClass("mCS_no_scrollbar_y mCS_y_hidden");
- }else{
- if(o.alwaysShowScrollbar){
- if(o.alwaysShowScrollbar!==2){mCSB_dragger[0].add(scrollbar[0].children("a")).css("display","none");}
- content.removeClass("mCS_y_hidden");
- }else{
- scrollbar[0].css("display","none");
- content.addClass("mCS_y_hidden");
- }
- content.addClass("mCS_no_scrollbar_y");
- }
- }
- if(o.axis!=="y"){
- if(d.overflowed[1] && !disabled){
- scrollbar[1].add(mCSB_dragger[1]).add(scrollbar[1].children("a")).css("display","block");
- content.removeClass("mCS_no_scrollbar_x mCS_x_hidden");
- }else{
- if(o.alwaysShowScrollbar){
- if(o.alwaysShowScrollbar!==2){mCSB_dragger[1].add(scrollbar[1].children("a")).css("display","none");}
- content.removeClass("mCS_x_hidden");
- }else{
- scrollbar[1].css("display","none");
- content.addClass("mCS_x_hidden");
- }
- content.addClass("mCS_no_scrollbar_x");
- }
- }
- if(!d.overflowed[0] && !d.overflowed[1]){
- $this.addClass("mCS_no_scrollbar");
- }else{
- $this.removeClass("mCS_no_scrollbar");
- }
- },
- /* -------------------- */
-
-
- /* returns input coordinates of pointer, touch and mouse events (relative to document) */
- _coordinates:function(e){
- var t=e.type;
- switch(t){
- case "pointerdown": case "MSPointerDown": case "pointermove": case "MSPointerMove": case "pointerup": case "MSPointerUp":
- return [e.originalEvent.pageY,e.originalEvent.pageX,false];
- break;
- case "touchstart": case "touchmove": case "touchend":
- var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0],
- touches=e.originalEvent.touches.length || e.originalEvent.changedTouches.length;
- return [touch.pageY,touch.pageX,touches>1];
- break;
- default:
- return [e.pageY,e.pageX,false];
- }
- },
- /* -------------------- */
-
-
- /*
- SCROLLBAR DRAG EVENTS
- scrolls content via scrollbar dragging
- */
- _draggable:function(){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
- namespace=pluginPfx+"_"+d.idx,
- draggerId=["mCSB_"+d.idx+"_dragger_vertical","mCSB_"+d.idx+"_dragger_horizontal"],
- mCSB_container=$("#mCSB_"+d.idx+"_container"),
- mCSB_dragger=$("#"+draggerId[0]+",#"+draggerId[1]),
- draggable,dragY,dragX,
- rds=o.advanced.releaseDraggableSelectors ? mCSB_dragger.add($(o.advanced.releaseDraggableSelectors)) : mCSB_dragger;
- mCSB_dragger.bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){
- e.stopImmediatePropagation();
- e.preventDefault();
- if(!functions._mouseBtnLeft(e)){return;} /* left mouse button only */
- touchActive=true;
- if(oldIE){document.onselectstart=function(){return false;}} /* disable text selection for IE < 9 */
- _iframe(false); /* enable scrollbar dragging over iframes by disabling their events */
- functions._stop($this);
- draggable=$(this);
- var offset=draggable.offset(),y=functions._coordinates(e)[0]-offset.top,x=functions._coordinates(e)[1]-offset.left,
- h=draggable.height()+offset.top,w=draggable.width()+offset.left;
- if(y<h && y>0 && x<w && x>0){
- dragY=y;
- dragX=x;
- }
- functions._onDragClasses(draggable,"active",o.autoExpandScrollbar);
- }).bind("touchmove."+namespace,function(e){
- e.stopImmediatePropagation();
- e.preventDefault();
- var offset=draggable.offset(),y=functions._coordinates(e)[0]-offset.top,x=functions._coordinates(e)[1]-offset.left;
- _drag(dragY,dragX,y,x);
- });
- $(document).bind("mousemove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace,function(e){
- if(draggable){
- var offset=draggable.offset(),y=functions._coordinates(e)[0]-offset.top,x=functions._coordinates(e)[1]-offset.left;
- if(dragY===y){return;} /* has it really moved? */
- _drag(dragY,dragX,y,x);
- }
- }).add(rds).bind("mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){
- if(draggable){
- functions._onDragClasses(draggable,"active",o.autoExpandScrollbar);
- draggable=null;
- }
- touchActive=false;
- if(oldIE){document.onselectstart=null;} /* enable text selection for IE < 9 */
- _iframe(true); /* enable iframes events */
- });
- function _iframe(evt){
- var el=mCSB_container.find("iframe");
- if(!el.length){return;} /* check if content contains iframes */
- var val=!evt ? "none" : "auto";
- el.css("pointer-events",val); /* for IE11, iframe's display property should not be "block" */
- }
- function _drag(dragY,dragX,y,x){
- mCSB_container[0].idleTimer=o.scrollInertia<233 ? 250 : 0;
- if(draggable.attr("id")===draggerId[1]){
- var dir="x",to=((draggable[0].offsetLeft-dragX)+x)*d.scrollRatio.x;
- }else{
- var dir="y",to=((draggable[0].offsetTop-dragY)+y)*d.scrollRatio.y;
- }
- functions._scrollTo($this,to.toString(),{dir:dir,drag:true});
- }
- },
- /* -------------------- */
-
-
- /*
- TOUCH SWIPE EVENTS
- scrolls content via touch swipe
- Emulates the native touch-swipe scrolling with momentum found in iOS, Android and WP devices
- */
- _contentDraggable:function(){
- var $this=$(this),d=$this.data(pluginPfx),o=d.opt,
- namespace=pluginPfx+"_"+d.idx,
- mCustomScrollBox=$("#mCSB_"+d.idx),
- mCSB_container=$("#mCSB_"+d.idx+"_container"),
- mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")],
- dragY,dragX,touchStartY,touchStartX,touchMoveY=[],touchMoveX=[],startTime,runningTime,endTime,distance,speed,amount,
- durA=0,durB,overwrite=o.axis==="yx" ? "none" : "all",touchIntent=[];
- mCSB_container.bind("touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){
- if(!functions._pointerTouch(e) || touchActive || functions._coordinates(e)[2]){return;}
- var offset=mCSB_container.offset();
- dragY=functions._coordinates(e)[0]-offset.top;
- dragX=functions._coordinates(e)[1]-offset.left;
- touchIntent=[functions._coordinates(e)[0],functions._coordinates(e)[1]];
- }).bind("touchmove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace,function(e){
- if(!functions._pointerTouch(e) || touchActive || functions._coordinates(e)[2]){return;}
- e.stopImmediatePropagation();
- runningTime=functions._getTime();
- var offset=mCustomScrollBox.offset(),y=functions._coordinates(e)[0]-offset.top,x=functions._coordinates(e)[1]-offset.left,
- easing="mcsLinearOut";
- touchMoveY.push(y);
- touchMoveX.push(x);
- touchIntent[2]=Math.abs(functions._coordinates(e)[0]-touchIntent[0]); touchIntent[3]=Math.abs(functions._coordinates(e)[1]-touchIntent[1]);
- if(d.overflowed[0]){
- var limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(),
- prevent=((dragY-y)>0 && (y-dragY)>-(limit*d.scrollRatio.y) && (touchIntent[3]*2<touchIntent[2] || o.axis==="yx"));
- }
- if(d.overflowed[1]){
- var limitX=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(),
- preventX=((dragX-x)>0 && (x-dragX)>-(limitX*d.scrollRatio.x) && (touchIntent[2]*2<touchIntent[3] || o.axis==="yx"));
- }
- if(prevent || preventX){e.preventDefault();} /* prevent native document scrolling */
- amount=o.axis==="yx" ? [(dragY-y),(dragX-x)] : o.axis==="x" ? [null,(dragX-x)] : [(dragY-y),null];
- mCSB_container[0].idleTimer=250;
- if(d.overflowed[0]){_drag(amount[0],durA,easing,"y","all",true);}
- if(d.overflowed[1]){_drag(amount[1],durA,easing,"x",overwrite,true);}
- });
- mCustomScrollBox.bind("touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){
- if(!functions._pointerTouch(e) || touchActive || functions._coordinates(e)[2]){return;}
- e.stopImmediatePropagation();
- functions._stop($this);
- startTime=functions._getTime();
- var offset=mCustomScrollBox.offset();
- touchStartY=functions._coordinates(e)[0]-offset.top;
- touchStartX=functions._coordinates(e)[1]-offset.left;
- touchMoveY=[]; touchMoveX=[];
- }).bind("touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){
- if(!functions._pointerTouch(e) || touchActive || functions._coordinates(e)[2]){return;}
- e.stopImmediatePropagation();
- endTime=functions._getTime();
- var offset=mCustomScrollBox.offset(),y=functions._coordinates(e)[0]-offset.top,x=functions._coordinates(e)[1]-offset.left;
- if((endTime-runningTime)>30){return;}
- speed=1000/(endTime-startTime);
- var easing="mcsEaseOut",slow=speed<2.5,
- diff=slow ? [touchMoveY[touchMoveY.length-2],touchMoveX[touchMoveX.length-2]] : [0,0];
- distance=slow ? [(y-diff[0]),(x-diff[1])] : [y-touchStartY,x-touchStartX];
- var absDistance=[Math.abs(distance[0]),Math.abs(distance[1])];
- speed=slow ? [Math.abs(distance[0]/4),Math.abs(distance[1]/4)] : [speed,speed];
- var a=[
- Math.abs(mCSB_container[0].offsetTop)-(distance[0]*_m((absDistance[0]/speed[0]),speed[0])),
- Math.abs(mCSB_container[0].offsetLeft)-(distance[1]*_m((absDistance[1]/speed[1]),speed[1]))
- ];
- amount=o.axis==="yx" ? [a[0],a[1]] : o.axis==="x" ? [null…