vendor: 4,498 bytes, lines 1-166
1(function(factory){ 2 if(typeof define==="function" && define.amd){ 3 define(["jquery"],factory); 4 }else if(typeof module!=="undefined" && module.exports){ 5 module.exports=factory; 6 }else{ 7 factory(jQuery,window,document); 8 } 9}(function($){ 10(function(init){ 11 var _rjs=typeof define==="function" && define.amd, /* RequireJS */ 12 _njs=typeof module !== "undefined" && module.exports, /* NodeJS */ 13 _dlp=("https:"==document.location.protocol) ? "https:" : "http:", /* location protocol */ 14 _url="cdn.bootcss.com/jquery-mousewheel/3.1.13/jquery.mousewheel.js"; 15 if(!_rjs){ 16 if(_njs){ 17 require("jquery-mousewheel")($); 18 }else{ 19 /* load jquery-mousewheel plugin (via CDN) if it's not present or not loaded via RequireJS 20 (works when mCustomScrollbar fn is called on window load) */ 21 $.event.special.mousewheel || $("head").append(decodeURI("%3Cscript src="+_dlp+"//"+_url+"%3E%3C/script%3E")); 22 } 23 } 24 init(); 25}(function(){ 26 27 /* 28 ---------------------------------------- 29 PLUGIN NAMESPACE, PREFIX, DEFAULT SELECTOR(S) 30 ---------------------------------------- 31 */ 32 33 var pluginNS="mCustomScrollbar", 34 pluginPfx="mCS", 35 defaultSelector=".mCustomScrollbar", 36 37 38 39 40 41 /* 42 ---------------------------------------- 43 DEFAULT OPTIONS 44 ---------------------------------------- 45 */ 46 47 defaults={ 48 /* 49 set element/content width/height programmatically 50 values: boolean, pixels, percentage 51 option default 52 ------------------------------------- 53 setWidth false 54 setHeight false 55 */ 56 /* 57 set the initial css top property of content 58 values: string (e.g. "-100px", "10%" etc.) 59 */ 60 setTop:0, 61 /* 62 set the initial css left property of content 63 values: string (e.g. "-100px", "10%" etc.) 64 */ 65 setLeft:0, 66 /* 67 scrollbar axis (vertical and/or horizontal scrollbars) 68 values (string): "y", "x", "yx" 69 */ 70 axis:"y", 71 /* 72 position of scrollbar relative to content 73 values (string): "inside", "outside" ("outside" requires elements with position:relative) 74 */ 75 scrollbarPosition:"inside", 76 /* 77 scrolling inertia 78 values: integer (milliseconds) 79 */ 80 scrollInertia:280, 81 /* 82 auto-adjust scrollbar dragger length 83 values: boolean 84 */ 85 autoDraggerLength:true, 86 /* 87 auto-hide scrollbar when idle 88 values: boolean 89 option default 90 ------------------------------------- 91 autoHideScrollbar false 92 */ 93 /* 94 auto-expands scrollbar on mouse-over and dragging 95 values: boolean 96 option default 97 ------------------------------------- 98 autoExpandScrollbar false 99 */ 100 /* 101 always show scrollbar, even when there's nothing to scroll 102 values: integer (0=disable, 1=always show dragger rail and buttons, 2=always show dragger rail, dragger and buttons), boolean 103 */ 104 alwaysShowScrollbar:0, 105 /* 106 scrolling always snaps to a multiple of this number in pixels 107 values: integer, array ([y,x]) 108 option default 109 ------------------------------------- 110 snapAmount null 111 */ 112 /* 113 when snapping, snap with this number in pixels as an offset 114 values: integer 115 */ 116 snapOffset:0, 117 /* 118 mouse-wheel scrolling 119 */ 120 mouseWheel:{ 121 /* 122 enable mouse-wheel scrolling 123 values: boolean 124 */ 125 enable:true, 126 /* 127 scrolling amount in pixels 128 values: "auto", integer 129 */ 130 scrollAmount:"auto", 131 /* 132 mouse-wheel scrolling axis 133 the default scrolling direction when both vertical and horizontal scrollbars are present 134 values (string): "y", "x" 135 */ 136 axis:"y", 137 /* 138 prevent the default behaviour which automatically scrolls the parent element(s) when end of scrolling is reached 139 values: boolean 140 option default 141 ------------------------------------- 142 preventDefault null 143 */ 144 /* 145 the reported mouse-wheel delta value. The number of lines (translated to pixels) one wheel notch scrolls. 146 values: "auto", integer 147 "auto" uses the default OS/browser value 148 */ 149 deltaFactor:"auto", 150 /* 151 normalize mouse-wheel delta to -1 or 1 (disables mouse-wheel acceleration) 152 values: boolean 153 option default 154 ------------------------------------- 155 normalizeDelta null 156 */ 157 /* 158 invert mouse-wheel scrolling direction 159 values: boolean 160 option default 161 ------------------------------------- 162 invert null 163 */ 164 /* 165 the tags that disable mouse-wheel when cursor is over them 166 */
167 disableOver:["select","option","keygen","datalist","textarea"] 168 }, 169 /* 170 scrollbar buttons 171 */ 172 scrollButtons:{ 173 /* 174 enable scrollbar buttons 175 values: boolean 176 option default 177 ------------------------------------- 178 enable null 179 */ 180 /* 181 scrollbar buttons scrolling type 182 values (string): "stepless", "stepped" 183 */ 184 scrollType:"stepless", 185 /* 186 scrolling amount in pixels 187 values: "auto", integer 188 */ 189 scrollAmount:"auto" 190 /* 191 tabindex of the scrollbar buttons 192 values: false, integer 193 option default 194 ------------------------------------- 195 tabindex null 196 */ 197 }, 198 /* 199 keyboard scrolling 200 */ 201 keyboard:{ 202 /* 203 enable scrolling via keyboard 204 values: boolean 205 */ 206 enable:true, 207 /* 208 keyboard scrolling type 209 values (string): "stepless", "stepped" 210 */ 211 scrollType:"stepless", 212 /* 213 scrolling amount in pixels 214 values: "auto", integer 215 */ 216 scrollAmount:"auto" 217 }, 218 /* 219 enable content touch-swipe scrolling 220 values: boolean, integer, string (number) 221 integer values define the axis-specific minimum amount required for scrolling momentum 222 */ 223 contentTouchScroll:25, 224 /* 225 enable/disable document (default) touch-swipe scrolling 226 */ 227 documentTouchScroll:true, 228 /* 229 advanced option parameters 230 */ 231 advanced:{ 232 /* 233 auto-expand content horizontally (for "x" or "yx" axis) 234 values: boolean, integer (the value 2 forces the non scrollHeight/scrollWidth method, the value 3 forces the scrollHeight/scrollWidth method) 235 option default 236 ------------------------------------- 237 autoExpandHorizontalScroll null 238 */ 239 /* 240 auto-scroll to elements with focus 241 */ 242 autoScrollOnFocus:"input,textarea,select,button,datalist,keygen,a[tabindex],area,object,[contenteditable='true']", 243 /* 244 auto-update scrollbars on content, element or viewport resize 245 should be true for fluid layouts/elements, adding/removing content dynamically, hiding/showing elements, content with images etc. 246 values: boolean 247 */ 248 updateOnContentResize:true, 249 /* 250 auto-update scrollbars each time each image inside the element is fully loaded 251 values: "auto", boolean 252 */ 253 updateOnImageLoad:"auto", 254 255 autoUpdateTimeout:120 256 }, 257 /* 258 scrollbar theme 259 values: string 260 */ 261 theme:"light", 262 /* 263 user defined callback functions 264 */ 265 callbacks:{ 266 /* 267 Available callbacks: 268 callback default 269 ------------------------------------- 270 onCreate null 271 onInit null 272 onScrollStart null 273 onScroll null 274 onTotalScroll null 275 onTotalScrollBack null 276 whileScrolling null 277 onOverflowY null 278 onOverflowX null 279 onOverflowYNone null 280 onOverflowXNone null 281 onImageLoad null 282 onSelectorChange null 283 onBeforeUpdate null 284 onUpdate null 285 */ 286 onTotalScrollOffset:0, 287 onTotalScrollBackOffset:0, 288 alwaysTriggerOffsets:true 289 } 290 /* 291 add scrollbar(s) on all elements matching the current selector, now and in the future 292 values: boolean, string 293 string values: "on" (enable), "once" (disable after first invocation), "off" (disable) 294 liveSelector values: string (selector) 295 option default 296 ------------------------------------- 297 live false 298 liveSelector null 299 */ 300 }, 301 302 /* 303 ---------------------------------------- 304 VARS, CONSTANTS 305 ---------------------------------------- 306 */ 307 308 totalInstances=0, /* plugin instances amount */ 309 liveTimers={}, /* live option timers */ 310 oldIE=(window.attachEvent && !window.addEventListener) ? 1 : 0, /* detect IE < 9 */ 311 touchActive=false,touchable, /* global touch vars (for touch and pointer events) */ 312 /* general plugin classes */ 313 classes=[ 314 "mCSB_dragger_onDrag","mCSB_scrollTools_onDrag","mCS_img_loaded","mCS_disabled","mCS_destroyed","mCS_no_scrollbar", 315 "mCS-autoHide","mCS-dir-rtl","mCS_no_scrollbar_y","mCS_no_scrollbar_x","mCS_y_hidden","mCS_x_hidden","mCSB_draggerContainer", 316 "mCSB_buttonUp","mCSB_buttonDown","mCSB_buttonLeft","mCSB_buttonRight" 317 ], 318 319 /* 320 ---------------------------------------- 321 FUNCTIONS 322 ---------------------------------------- 323 */ 324
vendor: 27,012 bytes, lines 325-943
325 /* validates selector (if selector is invalid or undefined uses the default one) */ 326 _selector=function(){ 327 return (typeof $(this)!=="object" || $(this).length<1) ? defaultSelector : this; 328 }, 329 /* -------------------- */ 330 331 /* live option timers removal */ 332 removeLiveTimers=function(selector){ 333 if(liveTimers[selector]){ 334 clearTimeout(liveTimers[selector]); 335 _delete(liveTimers,selector); 336 } 337 }, 338 /* -------------------- */ 339 340 341 /* normalizes axis option to valid values: "y", "x", "yx" */ 342 _findAxis=function(val){ 343 return (val==="yx" || val==="xy" || val==="auto") ? "yx" : (val==="x" || val==="horizontal") ? "x" : "y"; 344 }, 345 /* -------------------- */ 346 347 348 /* normalizes scrollButtons.scrollType option to valid values: "stepless", "stepped" */ 349 _findScrollButtonsType=function(val){ 350 return (val==="stepped" || val==="pixels" || val==="step" || val==="click") ? "stepped" : "stepless"; 351 }, 352 /* -------------------- */ 353 354 355 /* generates plugin markup */ 356 _pluginMarkup=function(){ 357 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 358 expandClass=o.autoExpandScrollbar ? " "+classes[1]+"_expand" : "", 359 scrollbar=["<div id='mCSB_"+d.idx+"_scrollbar_vertical' class='mCSB_scrollTools mCSB_"+d.idx+"_scrollbar mCS-"+o.theme+" mCSB_scrollTools_vertical"+expandClass+"'><div class='"+classes[12]+"'><div id='mCSB_"+d.idx+"_dragger_vertical' class='mCSB_dragger' style='position:absolute;'><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='"+classes[12]+"'><div id='mCSB_"+d.idx+"_dragger_horizontal' class='mCSB_dragger' style='position:absolute;'><div class='mCSB_dragger_bar' /></div><div class='mCSB_draggerRail' /></div></div>"], 360 wrapperClass=o.axis==="yx" ? "mCSB_vertical_horizontal" : o.axis==="x" ? "mCSB_horizontal" : "mCSB_vertical", 361 scrollbars=o.axis==="yx" ? scrollbar[0]+scrollbar[1] : o.axis==="x" ? scrollbar[1] : scrollbar[0], 362 contentWrapper=o.axis==="yx" ? "<div id='mCSB_"+d.idx+"_container_wrapper' class='mCSB_container_wrapper' />" : "", 363 autoHideClass=o.autoHideScrollbar ? " "+classes[6] : "", 364 scrollbarDirClass=(o.axis!=="x" && d.langDir==="rtl") ? " "+classes[7] : ""; 365 if(o.setWidth){$this.css("width",o.setWidth);} /* set element width */ 366 if(o.setHeight){$this.css("height",o.setHeight);} /* set element height */ 367 o.setLeft=(o.axis!=="y" && d.langDir==="rtl") ? "989999px" : o.setLeft; /* adjust left position for rtl direction */ 368 $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>"); 369 var mCustomScrollBox=$("#mCSB_"+d.idx), 370 mCSB_container=$("#mCSB_"+d.idx+"_container"); 371 if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){ 372 mCSB_container.css("width",_contentWidth(mCSB_container)); 373 } 374 if(o.scrollbarPosition==="outside"){ 375 if($this.css("position")==="static"){ /* requires elements with non-static position */ 376 $this.css("position","relative"); 377 } 378 $this.css("overflow","visible"); 379 mCustomScrollBox.addClass("mCSB_outside").after(scrollbars); 380 }else{ 381 mCustomScrollBox.addClass("mCSB_inside").append(scrollbars); 382 mCSB_container.wrap(contentWrapper); 383 } 384 _scrollButtons.call(this); /* add scrollbar buttons */ 385 /* minimum dragger length */ 386 var mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")]; 387 mCSB_dragger[0].css("min-height",mCSB_dragger[0].height()); 388 mCSB_dragger[1].css("min-width",mCSB_dragger[1].width()); 389 }, 390 /* -------------------- */ 391 392 393 /* calculates content width */ 394 _contentWidth=function(el){ 395 var val=[el[0].scrollWidth,Math.max.apply(Math,el.children().map(function(){return $(this).outerWidth(true);}).get())],w=el.parent().width(); 396 return val[0]>w ? val[0] : val[1]>w ? val[1] : "100%"; 397 }, 398 /* -------------------- */ 399 400 401 /* expands content horizontally */ 402 _expandContentHorizontally=function(){ 403 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 404 mCSB_container=$("#mCSB_"+d.idx+"_container"); 405 if(o.advanced.autoExpandHorizontalScroll && o.axis!=="y"){ 406 /* calculate scrollWidth */ 407 mCSB_container.css({"width":"auto","min-width":0,"overflow-x":"scroll"}); 408 var w=Math.ceil(mCSB_container[0].scrollWidth); 409 if(o.advanced.autoExpandHorizontalScroll===3 || (o.advanced.autoExpandHorizontalScroll!==2 && w>mCSB_container.parent().width())){ 410 mCSB_container.css({"width":w,"min-width":"100%","overflow-x":"inherit"}); 411 }else{ 412 /* 413 wrap content with an infinite width div and set its position to absolute and width to auto. 414 Setting width to auto before calculating the actual width is important! 415 We must let the browser set the width as browser zoom values are impossible to calculate. 416 */ 417 mCSB_container.css({"overflow-x":"inherit","position":"absolute"}) 418 .wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />") 419 .css({ /* set actual width, original position and un-wrap */ 420 /* 421 get the exact width (with decimals) and then round-up. 422 Using jquery outerWidth() will round the width value which will mess up with inner elements that have non-integer width 423 */ 424 "width":(Math.ceil(mCSB_container[0].getBoundingClientRect().right+0.4)-Math.floor(mCSB_container[0].getBoundingClientRect().left)), 425 "min-width":"100%", 426 "position":"relative" 427 }).unwrap(); 428 } 429 } 430 }, 431 /* -------------------- */ 432 433 434 /* adds scrollbar buttons */ 435 _scrollButtons=function(){ 436 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 437 mCSB_scrollTools=$(".mCSB_"+d.idx+"_scrollbar:first"), 438 tabindex=!_isNumeric(o.scrollButtons.tabindex) ? "" : "tabindex='"+o.scrollButtons.tabindex+"'", 439 btnHTML=[ 440 "<a href='#' class='"+classes[13]+"' "+tabindex+" />", 441 "<a href='#' class='"+classes[14]+"' "+tabindex+" />", 442 "<a href='#' class='"+classes[15]+"' "+tabindex+" />", 443 "<a href='#' class='"+classes[16]+"' "+tabindex+" />" 444 ], 445 btn=[(o.axis==="x" ? btnHTML[2] : btnHTML[0]),(o.axis==="x" ? btnHTML[3] : btnHTML[1]),btnHTML[2],btnHTML[3]]; 446 if(o.scrollButtons.enable){ 447 mCSB_scrollTools.prepend(btn[0]).append(btn[1]).next(".mCSB_scrollTools").prepend(btn[2]).append(btn[3]); 448 } 449 }, 450 /* -------------------- */ 451 452 453 /* auto-adjusts scrollbar dragger length */ 454 _setDraggerLength=function(){ 455 var $this=$(this),d=$this.data(pluginPfx), 456 mCustomScrollBox=$("#mCSB_"+d.idx), 457 mCSB_container=$("#mCSB_"+d.idx+"_container"), 458 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], 459 ratio=[mCustomScrollBox.height()/mCSB_container.outerHeight(false),mCustomScrollBox.width()/mCSB_container.outerWidth(false)], 460 l=[ 461 parseInt(mCSB_dragger[0].css("min-height")),Math.round(ratio[0]*mCSB_dragger[0].parent().height()), 462 parseInt(mCSB_dragger[1].css("min-width")),Math.round(ratio[1]*mCSB_dragger[1].parent().width()) 463 ], 464 h=oldIE && (l[1]<l[0]) ? l[0] : l[1],w=oldIE && (l[3]<l[2]) ? l[2] : l[3]; 465 mCSB_dragger[0].css({ 466 "height":h,"max-height":(mCSB_dragger[0].parent().height()-10) 467 }).find(".mCSB_dragger_bar").css({"line-height":l[0]+"px"}); 468 mCSB_dragger[1].css({ 469 "width":w,"max-width":(mCSB_dragger[1].parent().width()-10) 470 }); 471 }, 472 /* -------------------- */ 473 474 475 /* calculates scrollbar to content ratio */ 476 _scrollRatio=function(){ 477 var $this=$(this),d=$this.data(pluginPfx), 478 mCustomScrollBox=$("#mCSB_"+d.idx), 479 mCSB_container=$("#mCSB_"+d.idx+"_container"), 480 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], 481 scrollAmount=[mCSB_container.outerHeight(false)-mCustomScrollBox.height(),mCSB_container.outerWidth(false)-mCustomScrollBox.width()], 482 ratio=[ 483 scrollAmount[0]/(mCSB_dragger[0].parent().height()-mCSB_dragger[0].height()), 484 scrollAmount[1]/(mCSB_dragger[1].parent().width()-mCSB_dragger[1].width()) 485 ]; 486 d.scrollRatio={y:ratio[0],x:ratio[1]}; 487 }, 488 /* -------------------- */ 489 490 491 /* toggles scrolling classes */ 492 _onDragClasses=function(el,action,xpnd){ 493 var expandClass=xpnd ? classes[0]+"_expanded" : "", 494 scrollbar=el.closest(".mCSB_scrollTools"); 495 if(action==="active"){ 496 el.toggleClass(classes[0]+" "+expandClass); scrollbar.toggleClass(classes[1]); 497 el[0]._draggable=el[0]._draggable ? 0 : 1; 498 }else{ 499 if(!el[0]._draggable){ 500 if(action==="hide"){ 501 el.removeClass(classes[0]); scrollbar.removeClass(classes[1]); 502 }else{ 503 el.addClass(classes[0]); scrollbar.addClass(classes[1]); 504 } 505 } 506 } 507 }, 508 /* -------------------- */ 509 510 511 /* checks if content overflows its container to determine if scrolling is required */ 512 _overflowed=function(){ 513 var $this=$(this),d=$this.data(pluginPfx), 514 mCustomScrollBox=$("#mCSB_"+d.idx), 515 mCSB_container=$("#mCSB_"+d.idx+"_container"), 516 contentHeight=d.overflowed==null ? mCSB_container.height() : mCSB_container.outerHeight(false), 517 contentWidth=d.overflowed==null ? mCSB_container.width() : mCSB_container.outerWidth(false), 518 h=mCSB_container[0].scrollHeight,w=mCSB_container[0].scrollWidth; 519 if(h>contentHeight){contentHeight=h;} 520 if(w>contentWidth){contentWidth=w;} 521 return [contentHeight>mCustomScrollBox.height(),contentWidth>mCustomScrollBox.width()]; 522 }, 523 /* -------------------- */ 524 525 526 /* resets content position to 0 */ 527 _resetContentPosition=function(){ 528 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 529 mCustomScrollBox=$("#mCSB_"+d.idx), 530 mCSB_container=$("#mCSB_"+d.idx+"_container"), 531 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")]; 532 _stop($this); /* stop any current scrolling before resetting */ 533 if((o.axis!=="x" && !d.overflowed[0]) || (o.axis==="y" && d.overflowed[0])){ /* reset y */ 534 mCSB_dragger[0].add(mCSB_container).css("top",0); 535 _scrollTo($this,"_resetY"); 536 } 537 if((o.axis!=="y" && !d.overflowed[1]) || (o.axis==="x" && d.overflowed[1])){ /* reset x */ 538 var cx=dx=0; 539 if(d.langDir==="rtl"){ /* adjust left position for rtl direction */ 540 cx=mCustomScrollBox.width()-mCSB_container.outerWidth(false); 541 dx=Math.abs(cx/d.scrollRatio.x); 542 } 543 mCSB_container.css("left",cx); 544 mCSB_dragger[1].css("left",dx); 545 _scrollTo($this,"_resetX"); 546 } 547 }, 548 /* -------------------- */ 549 550 551 /* binds scrollbar events */ 552 _bindEvents=function(){ 553 var $this=$(this),d=$this.data(pluginPfx),o=d.opt; 554 if(!d.bindEvents){ /* check if events are already bound */ 555 _draggable.call(this); 556 if(o.contentTouchScroll){_contentDraggable.call(this);} 557 _selectable.call(this); 558 if(o.mouseWheel.enable){ /* bind mousewheel fn when plugin is available */ 559 function _mwt(){ 560 mousewheelTimeout=setTimeout(function(){ 561 if(!$.event.special.mousewheel){ 562 _mwt(); 563 }else{ 564 clearTimeout(mousewheelTimeout); 565 _mousewheel.call($this[0]); 566 } 567 },100); 568 } 569 var mousewheelTimeout; 570 _mwt(); 571 } 572 _draggerRail.call(this); 573 _wrapperScroll.call(this); 574 if(o.advanced.autoScrollOnFocus){_focus.call(this);} 575 if(o.scrollButtons.enable){_buttons.call(this);} 576 if(o.keyboard.enable){_keyboard.call(this);} 577 d.bindEvents=true; 578 } 579 }, 580 /* -------------------- */ 581 582 583 /* unbinds scrollbar events */ 584 _unbindEvents=function(){ 585 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 586 namespace=pluginPfx+"_"+d.idx, 587 sb=".mCSB_"+d.idx+"_scrollbar", 588 sel=$("#mCSB_"+d.idx+",#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,"+sb+" ."+classes[12]+",#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal,"+sb+">a"), 589 mCSB_container=$("#mCSB_"+d.idx+"_container"); 590 if(o.advanced.releaseDraggableSelectors){sel.add($(o.advanced.releaseDraggableSelectors));} 591 if(o.advanced.extraDraggableSelectors){sel.add($(o.advanced.extraDraggableSelectors));} 592 if(d.bindEvents){ /* check if events are bound */ 593 /* unbind namespaced events from document/selectors */ 594 $(document).add($(!_canAccessIFrame() || top.document)).unbind("."+namespace); 595 sel.each(function(){ 596 $(this).unbind("."+namespace); 597 }); 598 /* clear and delete timeouts/objects */ 599 clearTimeout($this[0]._focusTimeout); _delete($this[0],"_focusTimeout"); 600 clearTimeout(d.sequential.step); _delete(d.sequential,"step"); 601 clearTimeout(mCSB_container[0].onCompleteTimeout); _delete(mCSB_container[0],"onCompleteTimeout"); 602 d.bindEvents=false; 603 } 604 }, 605 /* -------------------- */ 606 607 608 /* toggles scrollbar visibility */ 609 _scrollbarVisibility=function(disabled){ 610 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 611 contentWrapper=$("#mCSB_"+d.idx+"_container_wrapper"), 612 content=contentWrapper.length ? contentWrapper : $("#mCSB_"+d.idx+"_container"), 613 scrollbar=[$("#mCSB_"+d.idx+"_scrollbar_vertical"),$("#mCSB_"+d.idx+"_scrollbar_horizontal")], 614 mCSB_dragger=[scrollbar[0].find(".mCSB_dragger"),scrollbar[1].find(".mCSB_dragger")]; 615 if(o.axis!=="x"){ 616 if(d.overflowed[0] && !disabled){ 617 scrollbar[0].add(mCSB_dragger[0]).add(scrollbar[0].children("a")).css("display","block"); 618 content.removeClass(classes[8]+" "+classes[10]); 619 }else{ 620 if(o.alwaysShowScrollbar){ 621 if(o.alwaysShowScrollbar!==2){mCSB_dragger[0].css("display","none");} 622 content.removeClass(classes[10]); 623 }else{ 624 scrollbar[0].css("display","none"); 625 content.addClass(classes[10]); 626 } 627 content.addClass(classes[8]); 628 } 629 } 630 if(o.axis!=="y"){ 631 if(d.overflowed[1] && !disabled){ 632 scrollbar[1].add(mCSB_dragger[1]).add(scrollbar[1].children("a")).css("display","block"); 633 content.removeClass(classes[9]+" "+classes[11]); 634 }else{ 635 if(o.alwaysShowScrollbar){ 636 if(o.alwaysShowScrollbar!==2){mCSB_dragger[1].css("display","none");} 637 content.removeClass(classes[11]); 638 }else{ 639 scrollbar[1].css("display","none"); 640 content.addClass(classes[11]); 641 } 642 content.addClass(classes[9]); 643 } 644 } 645 if(!d.overflowed[0] && !d.overflowed[1]){ 646 $this.addClass(classes[5]); 647 }else{ 648 $this.removeClass(classes[5]); 649 } 650 }, 651 /* -------------------- */ 652 653 654 /* returns input coordinates of pointer, touch and mouse events (relative to document) */ 655 _coordinates=function(e){ 656 var t=e.type,o=e.target.ownerDocument!==document && frameElement!==null ? [$(frameElement).offset().top,$(frameElement).offset().left] : null, 657 io=_canAccessIFrame() && e.target.ownerDocument!==top.document && frameElement!==null ? [$(e.view.frameElement).offset().top,$(e.view.frameElement).offset().left] : [0,0]; 658 switch(t){ 659 case "pointerdown": case "MSPointerDown": case "pointermove": case "MSPointerMove": case "pointerup": case "MSPointerUp": 660 return o ? [e.originalEvent.pageY-o[0]+io[0],e.originalEvent.pageX-o[1]+io[1],false] : [e.originalEvent.pageY,e.originalEvent.pageX,false]; 661 break; 662 case "touchstart": case "touchmove": case "touchend": 663 var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0], 664 touches=e.originalEvent.touches.length || e.originalEvent.changedTouches.length; 665 return e.target.ownerDocument!==document ? [touch.screenY,touch.screenX,touches>1] : [touch.pageY,touch.pageX,touches>1]; 666 break; 667 default: 668 return o ? [e.pageY-o[0]+io[0],e.pageX-o[1]+io[1],false] : [e.pageY,e.pageX,false]; 669 } 670 }, 671 /* -------------------- */ 672 673 674 /* 675 SCROLLBAR DRAG EVENTS 676 scrolls content via scrollbar dragging 677 */ 678 _draggable=function(){ 679 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 680 namespace=pluginPfx+"_"+d.idx, 681 draggerId=["mCSB_"+d.idx+"_dragger_vertical","mCSB_"+d.idx+"_dragger_horizontal"], 682 mCSB_container=$("#mCSB_"+d.idx+"_container"), 683 mCSB_dragger=$("#"+draggerId[0]+",#"+draggerId[1]), 684 draggable,dragY,dragX, 685 rds=o.advanced.releaseDraggableSelectors ? mCSB_dragger.add($(o.advanced.releaseDraggableSelectors)) : mCSB_dragger, 686 eds=o.advanced.extraDraggableSelectors ? $(!_canAccessIFrame() || top.document).add($(o.advanced.extraDraggableSelectors)) : $(!_canAccessIFrame() || top.document); 687 mCSB_dragger.bind("contextmenu."+namespace,function(e){ 688 e.preventDefault(); //prevent right click 689 }).bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){ 690 e.stopImmediatePropagation(); 691 e.preventDefault(); 692 if(!_mouseBtnLeft(e)){return;} /* left mouse button only */ 693 touchActive=true; 694 if(oldIE){document.onselectstart=function(){return false;}} /* disable text selection for IE < 9 */ 695 _iframe.call(mCSB_container,false); /* enable scrollbar dragging over iframes by disabling their events */ 696 _stop($this); 697 draggable=$(this); 698 var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left, 699 h=draggable.height()+offset.top,w=draggable.width()+offset.left; 700 if(y<h && y>0 && x<w && x>0){ 701 dragY=y; 702 dragX=x; 703 } 704 _onDragClasses(draggable,"active",o.autoExpandScrollbar); 705 }).bind("touchmove."+namespace,function(e){ 706 e.stopImmediatePropagation(); 707 e.preventDefault(); 708 var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left; 709 _drag(dragY,dragX,y,x); 710 }); 711 $(document).add(eds).bind("mousemove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace,function(e){ 712 if(draggable){ 713 var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left; 714 if(dragY===y && dragX===x){return;} /* has it really moved? */ 715 _drag(dragY,dragX,y,x); 716 } 717 }).add(rds).bind("mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){ 718 if(draggable){ 719 _onDragClasses(draggable,"active",o.autoExpandScrollbar); 720 draggable=null; 721 } 722 touchActive=false; 723 if(oldIE){document.onselectstart=null;} /* enable text selection for IE < 9 */ 724 _iframe.call(mCSB_container,true); /* enable iframes events */ 725 }); 726 function _drag(dragY,dragX,y,x){ 727 mCSB_container[0].idleTimer=o.scrollInertia<233 ? 250 : 0; 728 if(draggable.attr("id")===draggerId[1]){ 729 var dir="x",to=((draggable[0].offsetLeft-dragX)+x)*d.scrollRatio.x; 730 }else{ 731 var dir="y",to=((draggable[0].offsetTop-dragY)+y)*d.scrollRatio.y; 732 } 733 _scrollTo($this,to.toString(),{dir:dir,drag:true}); 734 } 735 }, 736 /* -------------------- */ 737 738 739 /* 740 TOUCH SWIPE EVENTS 741 scrolls content via touch swipe 742 Emulates the native touch-swipe scrolling with momentum found in iOS, Android and WP devices 743 */ 744 _contentDraggable=function(){ 745 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 746 namespace=pluginPfx+"_"+d.idx, 747 mCustomScrollBox=$("#mCSB_"+d.idx), 748 mCSB_container=$("#mCSB_"+d.idx+"_container"), 749 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], 750 draggable,dragY,dragX,touchStartY,touchStartX,touchMoveY=[],touchMoveX=[],startTime,runningTime,endTime,distance,speed,amount, 751 durA=0,durB,overwrite=o.axis==="yx" ? "none" : "all",touchIntent=[],touchDrag,docDrag, 752 iframe=mCSB_container.find("iframe"), 753 events=[ 754 "touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace, //start 755 "touchmove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace, //move 756 "touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace //end 757 ], 758 touchAction=document.body.style.touchAction!==undefined && document.body.style.touchAction!==""; 759 mCSB_container.bind(events[0],function(e){ 760 _onTouchstart(e); 761 }).bind(events[1],function(e){ 762 _onTouchmove(e); 763 }); 764 mCustomScrollBox.bind(events[0],function(e){ 765 _onTouchstart2(e); 766 }).bind(events[2],function(e){ 767 _onTouchend(e); 768 }); 769 if(iframe.length){ 770 iframe.each(function(){ 771 $(this).bind("load",function(){ 772 /* bind events on accessible iframes */ 773 if(_canAccessIFrame(this)){ 774 $(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){ 775 _onTouchstart(e); 776 _onTouchstart2(e); 777 }).bind(events[1],function(e){ 778 _onTouchmove(e); 779 }).bind(events[2],function(e){ 780 _onTouchend(e); 781 }); 782 } 783 }); 784 }); 785 } 786 function _onTouchstart(e){ 787 if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){touchable=0; return;} 788 touchable=1; touchDrag=0; docDrag=0; draggable=1; 789 $this.removeClass("mCS_touch_action"); 790 var offset=mCSB_container.offset(); 791 dragY=_coordinates(e)[0]-offset.top; 792 dragX=_coordinates(e)[1]-offset.left; 793 touchIntent=[_coordinates(e)[0],_coordinates(e)[1]]; 794 } 795 function _onTouchmove(e){ 796 if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){return;} 797 if(!o.documentTouchScroll){e.preventDefault();} 798 e.stopImmediatePropagation(); 799 if(docDrag && !touchDrag){return;} 800 if(draggable){ 801 runningTime=_getTime(); 802 var offset=mCustomScrollBox.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left, 803 easing="mcsLinearOut"; 804 touchMoveY.push(y); 805 touchMoveX.push(x); 806 touchIntent[2]=Math.abs(_coordinates(e)[0]-touchIntent[0]); touchIntent[3]=Math.abs(_coordinates(e)[1]-touchIntent[1]); 807 if(d.overflowed[0]){ 808 var limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(), 809 prevent=((dragY-y)>0 && (y-dragY)>-(limit*d.scrollRatio.y) && (touchIntent[3]*2<touchIntent[2] || o.axis==="yx")); 810 } 811 if(d.overflowed[1]){ 812 var limitX=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(), 813 preventX=((dragX-x)>0 && (x-dragX)>-(limitX*d.scrollRatio.x) && (touchIntent[2]*2<touchIntent[3] || o.axis==="yx")); 814 } 815 if(prevent || preventX){ /* prevent native document scrolling */ 816 if(!touchAction){e.preventDefault();} 817 touchDrag=1; 818 }else{ 819 docDrag=1; 820 $this.addClass("mCS_touch_action"); 821 } 822 if(touchAction){e.preventDefault();} 823 amount=o.axis==="yx" ? [(dragY-y),(dragX-x)] : o.axis==="x" ? [null,(dragX-x)] : [(dragY-y),null]; 824 mCSB_container[0].idleTimer=250; 825 if(d.overflowed[0]){_drag(amount[0],durA,easing,"y","all",true);} 826 if(d.overflowed[1]){_drag(amount[1],durA,easing,"x",overwrite,true);} 827 } 828 } 829 function _onTouchstart2(e){ 830 if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){touchable=0; return;} 831 touchable=1; 832 e.stopImmediatePropagation(); 833 _stop($this); 834 startTime=_getTime(); 835 var offset=mCustomScrollBox.offset(); 836 touchStartY=_coordinates(e)[0]-offset.top; 837 touchStartX=_coordinates(e)[1]-offset.left; 838 touchMoveY=[]; touchMoveX=[]; 839 } 840 function _onTouchend(e){ 841 if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){return;} 842 draggable=0; 843 e.stopImmediatePropagation(); 844 touchDrag=0; docDrag=0; 845 endTime=_getTime(); 846 var offset=mCustomScrollBox.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left; 847 if((endTime-runningTime)>30){return;} 848 speed=1000/(endTime-startTime); 849 var easing="mcsEaseOut",slow=speed<2.5, 850 diff=slow ? [touchMoveY[touchMoveY.length-2],touchMoveX[touchMoveX.length-2]] : [0,0]; 851 distance=slow ? [(y-diff[0]),(x-diff[1])] : [y-touchStartY,x-touchStartX]; 852 var absDistance=[Math.abs(distance[0]),Math.abs(distance[1])]; 853 speed=slow ? [Math.abs(distance[0]/4),Math.abs(distance[1]/4)] : [speed,speed]; 854 var a=[ 855 Math.abs(mCSB_container[0].offsetTop)-(distance[0]*_m((absDistance[0]/speed[0]),speed[0])), 856 Math.abs(mCSB_container[0].offsetLeft)-(distance[1]*_m((absDistance[1]/speed[1]),speed[1])) 857 ]; 858 amount=o.axis==="yx" ? [a[0],a[1]] : o.axis==="x" ? [null,a[1]] : [a[0],null]; 859 durB=[(absDistance[0]*4)+o.scrollInertia,(absDistance[1]*4)+o.scrollInertia]; 860 var md=parseInt(o.contentTouchScroll) || 0; /* absolute minimum distance required */ 861 amount[0]=absDistance[0]>md ? amount[0] : 0; 862 amount[1]=absDistance[1]>md ? amount[1] : 0; 863 if(d.overflowed[0]){_drag(amount[0],durB[0],easing,"y",overwrite,false);} 864 if(d.overflowed[1]){_drag(amount[1],durB[1],easing,"x",overwrite,false);} 865 } 866 function _m(ds,s){ 867 var r=[s*1.5,s*2,s/1.5,s/2]; 868 if(ds>90){ 869 return s>4 ? r[0] : r[3]; 870 }else if(ds>60){ 871 return s>3 ? r[3] : r[2]; 872 }else if(ds>30){ 873 return s>8 ? r[1] : s>6 ? r[0] : s>4 ? s : r[2]; 874 }else{ 875 return s>8 ? s : r[3]; 876 } 877 } 878 function _drag(amount,dur,easing,dir,overwrite,drag){ 879 if(!amount){return;} 880 _scrollTo($this,amount.toString(),{dur:dur,scrollEasing:easing,dir:dir,overwrite:overwrite,drag:drag}); 881 } 882 }, 883 /* -------------------- */ 884 885 886 /* 887 SELECT TEXT EVENTS 888 scrolls content when text is selected 889 */ 890 _selectable=function(){ 891 var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential, 892 namespace=pluginPfx+"_"+d.idx, 893 mCSB_container=$("#mCSB_"+d.idx+"_container"), 894 wrapper=mCSB_container.parent(), 895 action; 896 mCSB_container.bind("mousedown."+namespace,function(e){ 897 if(touchable){return;} 898 if(!action){action=1; touchActive=true;} 899 }).add(document).bind("mousemove."+namespace,function(e){ 900 if(!touchable && action && _sel()){ 901 var offset=mCSB_container.offset(), 902 y=_coordinates(e)[0]-offset.top+mCSB_container[0].offsetTop,x=_coordinates(e)[1]-offset.left+mCSB_container[0].offsetLeft; 903 if(y>0 && y<wrapper.height() && x>0 && x<wrapper.width()){ 904 if(seq.step){_seq("off",null,"stepped");} 905 }else{ 906 if(o.axis!=="x" && d.overflowed[0]){ 907 if(y<0){ 908 _seq("on",38); 909 }else if(y>wrapper.height()){ 910 _seq("on",40); 911 } 912 } 913 if(o.axis!=="y" && d.overflowed[1]){ 914 if(x<0){ 915 _seq("on",37); 916 }else if(x>wrapper.width()){ 917 _seq("on",39); 918 } 919 } 920 } 921 } 922 }).bind("mouseup."+namespace+" dragend."+namespace,function(e){ 923 if(touchable){return;} 924 if(action){action=0; _seq("off",null);} 925 touchActive=false; 926 }); 927 function _sel(){ 928 return window.getSelection ? window.getSelection().toString() : 929 document.selection && document.selection.type!="Control" ? document.selection.createRange().text : 0; 930 } 931 function _seq(a,c,s){ 932 seq.type=s && action ? "stepped" : "stepless"; 933 seq.scrollAmount=10; 934 _sequentialScroll($this,a,c,"mcsLinearOut",s ? 60 : null); 935 } 936 }, 937 /* -------------------- */ 938 939 940 /* 941 MOUSE WHEEL EVENT 942 scrolls content via mouse-wheel 943 via mouse-wheel plugin
vendor: 29,444 bytes, lines 943-1694
943 944 */ 945 _mousewheel=function(){ 946 if(!$(this).data(pluginPfx)){return;} /* Check if the scrollbar is ready to use mousewheel events (issue: #185) */ 947 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 948 namespace=pluginPfx+"_"+d.idx, 949 mCustomScrollBox=$("#mCSB_"+d.idx), 950 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], 951 iframe=$("#mCSB_"+d.idx+"_container").find("iframe"); 952 if(iframe.length){ 953 iframe.each(function(){ 954 $(this).bind("load",function(){ 955 /* bind events on accessible iframes */ 956 if(_canAccessIFrame(this)){ 957 $(this.contentDocument || this.contentWindow.document).bind("mousewheel."+namespace,function(e,delta){ 958 _onMousewheel(e,delta); 959 }); 960 } 961 }); 962 }); 963 } 964 mCustomScrollBox.bind("mousewheel."+namespace,function(e,delta){ 965 _onMousewheel(e,delta); 966 }); 967 function _onMousewheel(e,delta){ 968 _stop($this); 969 if(_disableMousewheel($this,e.target)){return;} /* disables mouse-wheel when hovering specific elements */ 970 var deltaFactor=o.mouseWheel.deltaFactor!=="auto" ? parseInt(o.mouseWheel.deltaFactor) : (oldIE && e.deltaFactor<100) ? 100 : e.deltaFactor || 100, 971 dur=o.scrollInertia; 972 if(o.axis==="x" || o.mouseWheel.axis==="x"){ 973 var dir="x", 974 px=[Math.round(deltaFactor*d.scrollRatio.x),parseInt(o.mouseWheel.scrollAmount)], 975 amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.width() ? mCustomScrollBox.width()*0.9 : px[0], 976 contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetLeft), 977 draggerPos=mCSB_dragger[1][0].offsetLeft, 978 limit=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(), 979 dlt=o.mouseWheel.axis==="y" ? (e.deltaY || delta) : e.deltaX; 980 }else{ 981 var dir="y", 982 px=[Math.round(deltaFactor*d.scrollRatio.y),parseInt(o.mouseWheel.scrollAmount)], 983 amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.height() ? mCustomScrollBox.height()*0.9 : px[0], 984 contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetTop), 985 draggerPos=mCSB_dragger[0][0].offsetTop, 986 limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(), 987 dlt=e.deltaY || delta; 988 } 989 if((dir==="y" && !d.overflowed[0]) || (dir==="x" && !d.overflowed[1])){return;} 990 if(o.mouseWheel.invert || e.webkitDirectionInvertedFromDevice){dlt=-dlt;} 991 if(o.mouseWheel.normalizeDelta){dlt=dlt<0 ? -1 : 1;} 992 if((dlt>0 && draggerPos!==0) || (dlt<0 && draggerPos!==limit) || o.mouseWheel.preventDefault){ 993 e.stopImmediatePropagation(); 994 e.preventDefault(); 995 } 996 if(e.deltaFactor<5 && !o.mouseWheel.normalizeDelta){ 997 //very low deltaFactor values mean some kind of delta acceleration (e.g. osx trackpad), so adjusting scrolling accordingly 998 amount=e.deltaFactor; dur=17; 999 } 1000 _scrollTo($this,(contentPos-(dlt*amount)).toString(),{dir:dir,dur:dur}); 1001 } 1002 }, 1003 /* -------------------- */ 1004 1005 1006 /* checks if iframe can be accessed */ 1007 _canAccessIFrameCache=new Object(), 1008 _canAccessIFrame=function(iframe){ 1009 var result=false,cacheKey=false,html=null; 1010 if(iframe===undefined){ 1011 cacheKey="#empty"; 1012 }else if($(iframe).attr("id")!==undefined){ 1013 cacheKey=$(iframe).attr("id"); 1014 } 1015 if(cacheKey!==false && _canAccessIFrameCache[cacheKey]!==undefined){ 1016 return _canAccessIFrameCache[cacheKey]; 1017 } 1018 if(!iframe){ 1019 try{ 1020 var doc=top.document; 1021 html=doc.body.innerHTML; 1022 }catch(err){/* do nothing */} 1023 result=(html!==null); 1024 }else{ 1025 try{ 1026 var doc=iframe.contentDocument || iframe.contentWindow.document; 1027 html=doc.body.innerHTML; 1028 }catch(err){/* do nothing */} 1029 result=(html!==null); 1030 } 1031 if(cacheKey!==false){_canAccessIFrameCache[cacheKey]=result;} 1032 return result; 1033 }, 1034 /* -------------------- */ 1035 1036 1037 /* switches iframe's pointer-events property (drag, mousewheel etc. over cross-domain iframes) */ 1038 _iframe=function(evt){ 1039 var el=this.find("iframe"); 1040 if(!el.length){return;} /* check if content contains iframes */ 1041 var val=!evt ? "none" : "auto"; 1042 el.css("pointer-events",val); /* for IE11, iframe's display property should not be "block" */ 1043 }, 1044 /* -------------------- */ 1045 1046 1047 /* disables mouse-wheel when hovering specific elements like select, datalist etc. */ 1048 _disableMousewheel=function(el,target){ 1049 var tag=target.nodeName.toLowerCase(), 1050 tags=el.data(pluginPfx).opt.mouseWheel.disableOver, 1051 /* elements that require focus */ 1052 focusTags=["select","textarea"]; 1053 return $.inArray(tag,tags) > -1 && !($.inArray(tag,focusTags) > -1 && !$(target).is(":focus")); 1054 }, 1055 /* -------------------- */ 1056 1057 1058 /* 1059 DRAGGER RAIL CLICK EVENT 1060 scrolls content via dragger rail 1061 */ 1062 _draggerRail=function(){ 1063 var $this=$(this),d=$this.data(pluginPfx), 1064 namespace=pluginPfx+"_"+d.idx, 1065 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1066 wrapper=mCSB_container.parent(), 1067 mCSB_draggerContainer=$(".mCSB_"+d.idx+"_scrollbar ."+classes[12]), 1068 clickable; 1069 mCSB_draggerContainer.bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){ 1070 touchActive=true; 1071 if(!$(e.target).hasClass("mCSB_dragger")){clickable=1;} 1072 }).bind("touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){ 1073 touchActive=false; 1074 }).bind("click."+namespace,function(e){ 1075 if(!clickable){return;} 1076 clickable=0; 1077 if($(e.target).hasClass(classes[12]) || $(e.target).hasClass("mCSB_draggerRail")){ 1078 _stop($this); 1079 var el=$(this),mCSB_dragger=el.find(".mCSB_dragger"); 1080 if(el.parent(".mCSB_scrollTools_horizontal").length>0){ 1081 if(!d.overflowed[1]){return;} 1082 var dir="x", 1083 clickDir=e.pageX>mCSB_dragger.offset().left ? -1 : 1, 1084 to=Math.abs(mCSB_container[0].offsetLeft)-(clickDir*(wrapper.width()*0.9)); 1085 }else{ 1086 if(!d.overflowed[0]){return;} 1087 var dir="y", 1088 clickDir=e.pageY>mCSB_dragger.offset().top ? -1 : 1, 1089 to=Math.abs(mCSB_container[0].offsetTop)-(clickDir*(wrapper.height()*0.9)); 1090 } 1091 _scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"}); 1092 } 1093 }); 1094 }, 1095 /* -------------------- */ 1096 1097 1098 /* 1099 FOCUS EVENT 1100 scrolls content via element focus (e.g. clicking an input, pressing TAB key etc.) 1101 */ 1102 _focus=function(){ 1103 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1104 namespace=pluginPfx+"_"+d.idx, 1105 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1106 wrapper=mCSB_container.parent(); 1107 mCSB_container.bind("focusin."+namespace,function(e){ 1108 var el=$(document.activeElement), 1109 nested=mCSB_container.find(".mCustomScrollBox").length, 1110 dur=0; 1111 if(!el.is(o.advanced.autoScrollOnFocus)){return;} 1112 _stop($this); 1113 clearTimeout($this[0]._focusTimeout); 1114 $this[0]._focusTimer=nested ? (dur+17)*nested : 0; 1115 $this[0]._focusTimeout=setTimeout(function(){ 1116 var to=[_childPos(el)[0],_childPos(el)[1]], 1117 contentPos=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft], 1118 isVisible=[ 1119 (contentPos[0]+to[0]>=0 && contentPos[0]+to[0]<wrapper.height()-el.outerHeight(false)), 1120 (contentPos[1]+to[1]>=0 && contentPos[0]+to[1]<wrapper.width()-el.outerWidth(false)) 1121 ], 1122 overwrite=(o.axis==="yx" && !isVisible[0] && !isVisible[1]) ? "none" : "all"; 1123 if(o.axis!=="x" && !isVisible[0]){ 1124 _scrollTo($this,to[0].toString(),{dir:"y",scrollEasing:"mcsEaseInOut",overwrite:overwrite,dur:dur}); 1125 } 1126 if(o.axis!=="y" && !isVisible[1]){ 1127 _scrollTo($this,to[1].toString(),{dir:"x",scrollEasing:"mcsEaseInOut",overwrite:overwrite,dur:dur}); 1128 } 1129 },$this[0]._focusTimer); 1130 }); 1131 }, 1132 /* -------------------- */ 1133 1134 1135 /* sets content wrapper scrollTop/scrollLeft always to 0 */ 1136 _wrapperScroll=function(){ 1137 var $this=$(this),d=$this.data(pluginPfx), 1138 namespace=pluginPfx+"_"+d.idx, 1139 wrapper=$("#mCSB_"+d.idx+"_container").parent(); 1140 wrapper.bind("scroll."+namespace,function(e){ 1141 if(wrapper.scrollTop()!==0 || wrapper.scrollLeft()!==0){ 1142 $(".mCSB_"+d.idx+"_scrollbar").css("visibility","hidden"); /* hide scrollbar(s) */ 1143 } 1144 }); 1145 }, 1146 /* -------------------- */ 1147 1148 1149 /* 1150 BUTTONS EVENTS 1151 scrolls content via up, down, left and right buttons 1152 */ 1153 _buttons=function(){ 1154 var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential, 1155 namespace=pluginPfx+"_"+d.idx, 1156 sel=".mCSB_"+d.idx+"_scrollbar", 1157 btn=$(sel+">a"); 1158 btn.bind("contextmenu."+namespace,function(e){ 1159 e.preventDefault(); //prevent right click 1160 }).bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace+" mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace+" mouseout."+namespace+" pointerout."+namespace+" MSPointerOut."+namespace+" click."+namespace,function(e){ 1161 e.preventDefault(); 1162 if(!_mouseBtnLeft(e)){return;} /* left mouse button only */ 1163 var btnClass=$(this).attr("class"); 1164 seq.type=o.scrollButtons.scrollType; 1165 switch(e.type){ 1166 case "mousedown": case "touchstart": case "pointerdown": case "MSPointerDown": 1167 if(seq.type==="stepped"){return;} 1168 touchActive=true; 1169 d.tweenRunning=false; 1170 _seq("on",btnClass); 1171 break; 1172 case "mouseup": case "touchend": case "pointerup": case "MSPointerUp": 1173 case "mouseout": case "pointerout": case "MSPointerOut": 1174 if(seq.type==="stepped"){return;} 1175 touchActive=false; 1176 if(seq.dir){_seq("off",btnClass);} 1177 break; 1178 case "click": 1179 if(seq.type!=="stepped" || d.tweenRunning){return;} 1180 _seq("on",btnClass); 1181 break; 1182 } 1183 function _seq(a,c){ 1184 seq.scrollAmount=o.scrollButtons.scrollAmount; 1185 _sequentialScroll($this,a,c); 1186 } 1187 }); 1188 }, 1189 /* -------------------- */ 1190 1191 1192 /* 1193 KEYBOARD EVENTS 1194 scrolls content via keyboard 1195 Keys: up arrow, down arrow, left arrow, right arrow, PgUp, PgDn, Home, End 1196 */ 1197 _keyboard=function(){ 1198 var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential, 1199 namespace=pluginPfx+"_"+d.idx, 1200 mCustomScrollBox=$("#mCSB_"+d.idx), 1201 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1202 wrapper=mCSB_container.parent(), 1203 editables="input,textarea,select,datalist,keygen,[contenteditable='true']", 1204 iframe=mCSB_container.find("iframe"), 1205 events=["blur."+namespace+" keydown."+namespace+" keyup."+namespace]; 1206 if(iframe.length){ 1207 iframe.each(function(){ 1208 $(this).bind("load",function(){ 1209 /* bind events on accessible iframes */ 1210 if(_canAccessIFrame(this)){ 1211 $(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){ 1212 _onKeyboard(e); 1213 }); 1214 } 1215 }); 1216 }); 1217 } 1218 mCustomScrollBox.attr("tabindex","0").bind(events[0],function(e){ 1219 _onKeyboard(e); 1220 }); 1221 function _onKeyboard(e){ 1222 switch(e.type){ 1223 case "blur": 1224 if(d.tweenRunning && seq.dir){_seq("off",null);} 1225 break; 1226 case "keydown": case "keyup": 1227 var code=e.keyCode ? e.keyCode : e.which,action="on"; 1228 if((o.axis!=="x" && (code===38 || code===40)) || (o.axis!=="y" && (code===37 || code===39))){ 1229 /* up (38), down (40), left (37), right (39) arrows */ 1230 if(((code===38 || code===40) && !d.overflowed[0]) || ((code===37 || code===39) && !d.overflowed[1])){return;} 1231 if(e.type==="keyup"){action="off";} 1232 if(!$(document.activeElement).is(editables)){ 1233 e.preventDefault(); 1234 e.stopImmediatePropagation(); 1235 _seq(action,code); 1236 } 1237 }else if(code===33 || code===34){ 1238 /* PgUp (33), PgDn (34) */ 1239 if(d.overflowed[0] || d.overflowed[1]){ 1240 e.preventDefault(); 1241 e.stopImmediatePropagation(); 1242 } 1243 if(e.type==="keyup"){ 1244 _stop($this); 1245 var keyboardDir=code===34 ? -1 : 1; 1246 if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){ 1247 var dir="x",to=Math.abs(mCSB_container[0].offsetLeft)-(keyboardDir*(wrapper.width()*0.9)); 1248 }else{ 1249 var dir="y",to=Math.abs(mCSB_container[0].offsetTop)-(keyboardDir*(wrapper.height()*0.9)); 1250 } 1251 _scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"}); 1252 } 1253 }else if(code===35 || code===36){ 1254 /* End (35), Home (36) */ 1255 if(!$(document.activeElement).is(editables)){ 1256 if(d.overflowed[0] || d.overflowed[1]){ 1257 e.preventDefault(); 1258 e.stopImmediatePropagation(); 1259 } 1260 if(e.type==="keyup"){ 1261 if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){ 1262 var dir="x",to=code===35 ? Math.abs(wrapper.width()-mCSB_container.outerWidth(false)) : 0; 1263 }else{ 1264 var dir="y",to=code===35 ? Math.abs(wrapper.height()-mCSB_container.outerHeight(false)) : 0; 1265 } 1266 _scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"}); 1267 } 1268 } 1269 } 1270 break; 1271 } 1272 function _seq(a,c){ 1273 seq.type=o.keyboard.scrollType; 1274 seq.scrollAmount=o.keyboard.scrollAmount; 1275 if(seq.type==="stepped" && d.tweenRunning){return;} 1276 _sequentialScroll($this,a,c); 1277 } 1278 } 1279 }, 1280 /* -------------------- */ 1281 1282 1283 /* scrolls content sequentially (used when scrolling via buttons, keyboard arrows etc.) */ 1284 _sequentialScroll=function(el,action,trigger,e,s){ 1285 var d=el.data(pluginPfx),o=d.opt,seq=d.sequential, 1286 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1287 once=seq.type==="stepped" ? true : false, 1288 steplessSpeed=o.scrollInertia < 26 ? 26 : o.scrollInertia, /* 26/1.5=17 */ 1289 steppedSpeed=o.scrollInertia < 1 ? 17 : o.scrollInertia; 1290 switch(action){ 1291 case "on": 1292 seq.dir=[ 1293 (trigger===classes[16] || trigger===classes[15] || trigger===39 || trigger===37 ? "x" : "y"), 1294 (trigger===classes[13] || trigger===classes[15] || trigger===38 || trigger===37 ? -1 : 1) 1295 ]; 1296 _stop(el); 1297 if(_isNumeric(trigger) && seq.type==="stepped"){return;} 1298 _on(once); 1299 break; 1300 case "off": 1301 _off(); 1302 if(once || (d.tweenRunning && seq.dir)){ 1303 _on(true); 1304 } 1305 break; 1306 } 1307 1308 /* starts sequence */ 1309 function _on(once){ 1310 if(o.snapAmount){seq.scrollAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : seq.dir[0]==="x" ? o.snapAmount[1] : o.snapAmount[0];} /* scrolling snapping */ 1311 var c=seq.type!=="stepped", /* continuous scrolling */ 1312 t=s ? s : !once ? 1000/60 : c ? steplessSpeed/1.5 : steppedSpeed, /* timer */ 1313 m=!once ? 2.5 : c ? 7.5 : 40, /* multiplier */ 1314 contentPos=[Math.abs(mCSB_container[0].offsetTop),Math.abs(mCSB_container[0].offsetLeft)], 1315 ratio=[d.scrollRatio.y>10 ? 10 : d.scrollRatio.y,d.scrollRatio.x>10 ? 10 : d.scrollRatio.x], 1316 amount=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*(ratio[1]*m)) : contentPos[0]+(seq.dir[1]*(ratio[0]*m)), 1317 px=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*parseInt(seq.scrollAmount)) : contentPos[0]+(seq.dir[1]*parseInt(seq.scrollAmount)), 1318 to=seq.scrollAmount!=="auto" ? px : amount, 1319 easing=e ? e : !once ? "mcsLinear" : c ? "mcsLinearOut" : "mcsEaseInOut", 1320 onComplete=!once ? false : true; 1321 if(once && t<17){ 1322 to=seq.dir[0]==="x" ? contentPos[1] : contentPos[0]; 1323 } 1324 _scrollTo(el,to.toString(),{dir:seq.dir[0],scrollEasing:easing,dur:t,onComplete:onComplete}); 1325 if(once){ 1326 seq.dir=false; 1327 return; 1328 } 1329 clearTimeout(seq.step); 1330 seq.step=setTimeout(function(){ 1331 _on(); 1332 },t); 1333 } 1334 /* stops sequence */ 1335 function _off(){ 1336 clearTimeout(seq.step); 1337 _delete(seq,"step"); 1338 _stop(el); 1339 } 1340 }, 1341 /* -------------------- */ 1342 1343 1344 /* returns a yx array from value */ 1345 _arr=function(val){ 1346 var o=$(this).data(pluginPfx).opt,vals=[]; 1347 if(typeof val==="function"){val=val();} /* check if the value is a single anonymous function */ 1348 /* check if value is object or array, its length and create an array with yx values */ 1349 if(!(val instanceof Array)){ /* object value (e.g. {y:"100",x:"100"}, 100 etc.) */ 1350 vals[0]=val.y ? val.y : val.x || o.axis==="x" ? null : val; 1351 vals[1]=val.x ? val.x : val.y || o.axis==="y" ? null : val; 1352 }else{ /* array value (e.g. [100,100]) */ 1353 vals=val.length>1 ? [val[0],val[1]] : o.axis==="x" ? [null,val[0]] : [val[0],null]; 1354 } 1355 /* check if array values are anonymous functions */ 1356 if(typeof vals[0]==="function"){vals[0]=vals[0]();} 1357 if(typeof vals[1]==="function"){vals[1]=vals[1]();} 1358 return vals; 1359 }, 1360 /* -------------------- */ 1361 1362 1363 /* translates values (e.g. "top", 100, "100px", "#id") to actual scroll-to positions */ 1364 _to=function(val,dir){ 1365 if(val==null || typeof val=="undefined"){return;} 1366 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1367 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1368 wrapper=mCSB_container.parent(), 1369 t=typeof val; 1370 if(!dir){dir=o.axis==="x" ? "x" : "y";} 1371 var contentLength=dir==="x" ? mCSB_container.outerWidth(false)-wrapper.width() : mCSB_container.outerHeight(false)-wrapper.height(), 1372 contentPos=dir==="x" ? mCSB_container[0].offsetLeft : mCSB_container[0].offsetTop, 1373 cssProp=dir==="x" ? "left" : "top"; 1374 switch(t){ 1375 case "function": /* this currently is not used. Consider removing it */ 1376 return val(); 1377 break; 1378 case "object": /* js/jquery object */ 1379 var obj=val.jquery ? val : $(val); 1380 if(!obj.length){return;} 1381 return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0]; 1382 break; 1383 case "string": case "number": 1384 if(_isNumeric(val)){ /* numeric value */ 1385 return Math.abs(val); 1386 }else if(val.indexOf("%")!==-1){ /* percentage value */ 1387 return Math.abs(contentLength*parseInt(val)/100); 1388 }else if(val.indexOf("-=")!==-1){ /* decrease value */ 1389 return Math.abs(contentPos-parseInt(val.split("-=")[1])); 1390 }else if(val.indexOf("+=")!==-1){ /* inrease value */ 1391 var p=(contentPos+parseInt(val.split("+=")[1])); 1392 return p>=0 ? 0 : Math.abs(p); 1393 }else if(val.indexOf("px")!==-1 && _isNumeric(val.split("px")[0])){ /* pixels string value (e.g. "100px") */ 1394 return Math.abs(val.split("px")[0]); 1395 }else{ 1396 if(val==="top" || val==="left"){ /* special strings */ 1397 return 0; 1398 }else if(val==="bottom"){ 1399 return Math.abs(wrapper.height()-mCSB_container.outerHeight(false)); 1400 }else if(val==="right"){ 1401 return Math.abs(wrapper.width()-mCSB_container.outerWidth(false)); 1402 }else if(val==="first" || val==="last"){ 1403 var obj=mCSB_container.find(":"+val); 1404 return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0]; 1405 }else{ 1406 if($(val).length){ /* jquery selector */ 1407 return dir==="x" ? _childPos($(val))[1] : _childPos($(val))[0]; 1408 }else{ /* other values (e.g. "100em") */ 1409 mCSB_container.css(cssProp,val); 1410 methods.update.call(null,$this[0]); 1411 return; 1412 } 1413 } 1414 } 1415 break; 1416 } 1417 }, 1418 /* -------------------- */ 1419 1420 1421 /* calls the update method automatically */ 1422 _autoUpdate=function(rem){ 1423 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1424 mCSB_container=$("#mCSB_"+d.idx+"_container"); 1425 if(rem){ 1426 /* 1427 removes autoUpdate timer 1428 usage: _autoUpdate.call(this,"remove"); 1429 */ 1430 clearTimeout(mCSB_container[0].autoUpdate); 1431 _delete(mCSB_container[0],"autoUpdate"); 1432 return; 1433 } 1434 upd(); 1435 function upd(){ 1436 clearTimeout(mCSB_container[0].autoUpdate); 1437 if($this.parents("html").length===0){ 1438 /* check element in dom tree */ 1439 $this=null; 1440 return; 1441 } 1442 mCSB_container[0].autoUpdate=setTimeout(function(){ 1443 /* update on specific selector(s) length and size change */ 1444 if(o.advanced.updateOnSelectorChange){ 1445 d.poll.change.n=sizesSum(); 1446 if(d.poll.change.n!==d.poll.change.o){ 1447 d.poll.change.o=d.poll.change.n; 1448 doUpd(3); 1449 return; 1450 } 1451 } 1452 /* update on main element and scrollbar size changes */ 1453 if(o.advanced.updateOnContentResize){ 1454 d.poll.size.n=$this[0].scrollHeight+$this[0].scrollWidth+mCSB_container[0].offsetHeight+$this[0].offsetHeight+$this[0].offsetWidth; 1455 if(d.poll.size.n!==d.poll.size.o){ 1456 d.poll.size.o=d.poll.size.n; 1457 doUpd(1); 1458 return; 1459 } 1460 } 1461 /* update on image load */ 1462 if(o.advanced.updateOnImageLoad){ 1463 if(!(o.advanced.updateOnImageLoad==="auto" && o.axis==="y")){ //by default, it doesn't run on vertical content 1464 d.poll.img.n=mCSB_container.find("img").length; 1465 if(d.poll.img.n!==d.poll.img.o){ 1466 d.poll.img.o=d.poll.img.n; 1467 mCSB_container.find("img").each(function(){ 1468 imgLoader(this); 1469 }); 1470 return; 1471 } 1472 1473 } 1474 } 1475 if(o.advanced.updateOnSelectorChange || o.advanced.updateOnContentResize || o.advanced.updateOnImageLoad){upd();} 1476 },o.advanced.autoUpdateTimeout); 1477 } 1478 /* a tiny image loader */ 1479 function imgLoader(el){ 1480 if($(el).hasClass(classes[2])){doUpd(); return;} 1481 var img=new Image(); 1482 function createDelegate(contextObject,delegateMethod){ 1483 return function(){return delegateMethod.apply(contextObject,arguments);} 1484 } 1485 function imgOnLoad(){ 1486 this.onload=null; 1487 $(el).addClass(classes[2]); 1488 doUpd(2); 1489 } 1490 img.onload=createDelegate(img,imgOnLoad); 1491 img.src=el.src; 1492 } 1493 /* returns the total height and width sum of all elements matching the selector */ 1494 function sizesSum(){ 1495 if(o.advanced.updateOnSelectorChange===true){o.advanced.updateOnSelectorChange="*";} 1496 var total=0,sel=mCSB_container.find(o.advanced.updateOnSelectorChange); 1497 if(o.advanced.updateOnSelectorChange && sel.length>0){sel.each(function(){total+=this.offsetHeight+this.offsetWidth;});} 1498 return total; 1499 } 1500 /* calls the update method */ 1501 function doUpd(cb){ 1502 clearTimeout(mCSB_container[0].autoUpdate); 1503 methods.update.call(null,$this[0],cb); 1504 } 1505 }, 1506 /* -------------------- */ 1507 1508 1509 /* snaps scrolling to a multiple of a pixels number */ 1510 _snapAmount=function(to,amount,offset){ 1511 return (Math.round(to/amount)*amount-offset); 1512 }, 1513 /* -------------------- */ 1514 1515 1516 /* stops content and scrollbar animations */ 1517 _stop=function(el){ 1518 var d=el.data(pluginPfx), 1519 sel=$("#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal"); 1520 sel.each(function(){ 1521 _stopTween.call(this); 1522 }); 1523 }, 1524 /* -------------------- */ 1525 1526 1527 /* 1528 ANIMATES CONTENT 1529 This is where the actual scrolling happens 1530 */ 1531 _scrollTo=function(el,to,options){ 1532 var d=el.data(pluginPfx),o=d.opt, 1533 defaults={ 1534 trigger:"internal", 1535 dir:"y", 1536 scrollEasing:"mcsEaseOut", 1537 drag:false, 1538 dur:o.scrollInertia, 1539 overwrite:"all", 1540 callbacks:true, 1541 onStart:true, 1542 onUpdate:true, 1543 onComplete:true 1544 }, 1545 options=$.extend(defaults,options), 1546 dur=[options.dur,(options.drag ? 0 : options.dur)], 1547 mCustomScrollBox=$("#mCSB_"+d.idx), 1548 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1549 wrapper=mCSB_container.parent(), 1550 totalScrollOffsets=o.callbacks.onTotalScrollOffset ? _arr.call(el,o.callbacks.onTotalScrollOffset) : [0,0], 1551 totalScrollBackOffsets=o.callbacks.onTotalScrollBackOffset ? _arr.call(el,o.callbacks.onTotalScrollBackOffset) : [0,0]; 1552 d.trigger=options.trigger; 1553 if(wrapper.scrollTop()!==0 || wrapper.scrollLeft()!==0){ /* always reset scrollTop/Left */ 1554 $(".mCSB_"+d.idx+"_scrollbar").css("visibility","visible"); 1555 wrapper.scrollTop(0).scrollLeft(0); 1556 } 1557 if(to==="_resetY" && !d.contentReset.y){ 1558 /* callbacks: onOverflowYNone */ 1559 if(_cb("onOverflowYNone")){o.callbacks.onOverflowYNone.call(el[0]);} 1560 d.contentReset.y=1; 1561 } 1562 if(to==="_resetX" && !d.contentReset.x){ 1563 /* callbacks: onOverflowXNone */ 1564 if(_cb("onOverflowXNone")){o.callbacks.onOverflowXNone.call(el[0]);} 1565 d.contentReset.x=1; 1566 } 1567 if(to==="_resetY" || to==="_resetX"){return;} 1568 if((d.contentReset.y || !el[0].mcs) && d.overflowed[0]){ 1569 /* callbacks: onOverflowY */ 1570 if(_cb("onOverflowY")){o.callbacks.onOverflowY.call(el[0]);} 1571 d.contentReset.x=null; 1572 } 1573 if((d.contentReset.x || !el[0].mcs) && d.overflowed[1]){ 1574 /* callbacks: onOverflowX */ 1575 if(_cb("onOverflowX")){o.callbacks.onOverflowX.call(el[0]);} 1576 d.contentReset.x=null; 1577 } 1578 if(o.snapAmount){ /* scrolling snapping */ 1579 var snapAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : options.dir==="x" ? o.snapAmount[1] : o.snapAmount[0]; 1580 to=_snapAmount(to,snapAmount,o.snapOffset); 1581 } 1582 switch(options.dir){ 1583 case "x": 1584 var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_horizontal"), 1585 property="left", 1586 contentPos=mCSB_container[0].offsetLeft, 1587 limit=[ 1588 mCustomScrollBox.width()-mCSB_container.outerWidth(false), 1589 mCSB_dragger.parent().width()-mCSB_dragger.width() 1590 ], 1591 scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.x)], 1592 tso=totalScrollOffsets[1], 1593 tsbo=totalScrollBackOffsets[1], 1594 totalScrollOffset=tso>0 ? tso/d.scrollRatio.x : 0, 1595 totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.x : 0; 1596 break; 1597 case "y": 1598 var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_vertical"), 1599 property="top", 1600 contentPos=mCSB_container[0].offsetTop, 1601 limit=[ 1602 mCustomScrollBox.height()-mCSB_container.outerHeight(false), 1603 mCSB_dragger.parent().height()-mCSB_dragger.height() 1604 ], 1605 scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.y)], 1606 tso=totalScrollOffsets[0], 1607 tsbo=totalScrollBackOffsets[0], 1608 totalScrollOffset=tso>0 ? tso/d.scrollRatio.y : 0, 1609 totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.y : 0; 1610 break; 1611 } 1612 if(scrollTo[1]<0 || (scrollTo[0]===0 && scrollTo[1]===0)){ 1613 scrollTo=[0,0]; 1614 }else if(scrollTo[1]>=limit[1]){ 1615 scrollTo=[limit[0],limit[1]]; 1616 }else{ 1617 scrollTo[0]=-scrollTo[0]; 1618 } 1619 if(!el[0].mcs){ 1620 _mcs(); /* init mcs object (once) to make it available before callbacks */ 1621 if(_cb("onInit")){o.callbacks.onInit.call(el[0]);} /* callbacks: onInit */ 1622 } 1623 clearTimeout(mCSB_container[0].onCompleteTimeout); 1624 _tweenTo(mCSB_dragger[0],property,Math.round(scrollTo[1]),dur[1],options.scrollEasing); 1625 if(!d.tweenRunning && ((contentPos===0 && scrollTo[0]>=0) || (contentPos===limit[0] && scrollTo[0]<=limit[0]))){return;} 1626 _tweenTo(mCSB_container[0],property,Math.round(scrollTo[0]),dur[0],options.scrollEasing,options.overwrite,{ 1627 onStart:function(){ 1628 if(options.callbacks && options.onStart && !d.tweenRunning){ 1629 /* callbacks: onScrollStart */ 1630 if(_cb("onScrollStart")){_mcs(); o.callbacks.onScrollStart.call(el[0]);} 1631 d.tweenRunning=true; 1632 _onDragClasses(mCSB_dragger); 1633 d.cbOffsets=_cbOffsets(); 1634 } 1635 },onUpdate:function(){ 1636 if(options.callbacks && options.onUpdate){ 1637 /* callbacks: whileScrolling */ 1638 if(_cb("whileScrolling")){_mcs(); o.callbacks.whileScrolling.call(el[0]);} 1639 } 1640 },onComplete:function(){ 1641 if(options.callbacks && options.onComplete){ 1642 if(o.axis==="yx"){clearTimeout(mCSB_container[0].onCompleteTimeout);} 1643 var t=mCSB_container[0].idleTimer || 0; 1644 mCSB_container[0].onCompleteTimeout=setTimeout(function(){ 1645 /* callbacks: onScroll, onTotalScroll, onTotalScrollBack */ 1646 if(_cb("onScroll")){_mcs(); o.callbacks.onScroll.call(el[0]);} 1647 if(_cb("onTotalScroll") && scrollTo[1]>=limit[1]-totalScrollOffset && d.cbOffsets[0]){_mcs(); o.callbacks.onTotalScroll.call(el[0]);} 1648 if(_cb("onTotalScrollBack") && scrollTo[1]<=totalScrollBackOffset && d.cbOffsets[1]){_mcs(); o.callbacks.onTotalScrollBack.call(el[0]);} 1649 d.tweenRunning=false; 1650 mCSB_container[0].idleTimer=0; 1651 _onDragClasses(mCSB_dragger,"hide"); 1652 },t); 1653 } 1654 } 1655 }); 1656 /* checks if callback function exists */ 1657 function _cb(cb){ 1658 return d && o.callbacks[cb] && typeof o.callbacks[cb]==="function"; 1659 } 1660 /* checks whether callback offsets always trigger */ 1661 function _cbOffsets(){ 1662 return [o.callbacks.alwaysTriggerOffsets || contentPos>=limit[0]+tso,o.callbacks.alwaysTriggerOffsets || contentPos<=-tsbo]; 1663 } 1664 /* 1665 populates object with useful values for the user 1666 values: 1667 content: this.mcs.content 1668 content top position: this.mcs.top 1669 content left position: this.mcs.left 1670 dragger top position: this.mcs.draggerTop 1671 dragger left position: this.mcs.draggerLeft 1672 scrolling y percentage: this.mcs.topPct 1673 scrolling x percentage: this.mcs.leftPct 1674 scrolling direction: this.mcs.direction 1675 */ 1676 function _mcs(){ 1677 var cp=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft], /* content position */ 1678 dp=[mCSB_dragger[0].offsetTop,mCSB_dragger[0].offsetLeft], /* dragger position */ 1679 cl=[mCSB_container.outerHeight(false),mCSB_container.outerWidth(false)], /* content length */ 1680 pl=[mCustomScrollBox.height(),mCustomScrollBox.width()]; /* content parent length */ 1681 el[0].mcs={ 1682 content:mCSB_container, /* original content wrapper as jquery object */ 1683 top:cp[0],left:cp[1],draggerTop:dp[0],draggerLeft:dp[1], 1684 topPct:Math.round((100*Math.abs(cp[0]))/(Math.abs(cl[0])-pl[0])),leftPct:Math.round((100*Math.abs(cp[1]))/(Math.abs(cl[1])-pl[1])), 1685 direction:options.dir 1686 }; 1687 /* 1688 this refers to the original element containing the scrollbar(s) 1689 usage: this.mcs.top, this.mcs.leftPct etc. 1690 */ 1691 } 1692 }, 1693 /* -------------------- */ 1694
vendor: 1,892 bytes, lines 1694-1765
1694/* CUSTOM JAVASCRIPT ANIMATION TWEEN 1695 Lighter and faster than jquery animate() and css transitions 1696 Animates top/left properties and includes easings */ 1697 /* returns current time */ 1698 _getTime=function(){ 1699 if(window.performance && window.performance.now){ 1700 return window.performance.now(); 1701 }else{ 1702 if(window.performance && window.performance.webkitNow){ 1703 return window.performance.webkitNow(); 1704 }else{ 1705 if(Date.now){return Date.now();}else{return new Date().getTime();} 1706 } 1707 } 1708 }, 1709 /* -------------------- */ 1710 1711 1712 /* stops a tween */ 1713 _stopTween=function(){ 1714 var el=this; 1715 if(!el._mTween){el._mTween={top:{},left:{}};} 1716 var props=["top","left"]; 1717 for(var i=0; i<props.length; i++){ 1718 var prop=props[i]; 1719 if(el._mTween[prop].id){ 1720 if(!window.requestAnimationFrame){clearTimeout(el._mTween[prop].id); 1721 }else{window.cancelAnimationFrame(el._mTween[prop].id);} 1722 el._mTween[prop].id=null; 1723 el._mTween[prop].stop=1; 1724 } 1725 } 1726 }, 1727 /* -------------------- */ 1728 1729 1730 /* deletes a property (avoiding the exception thrown by IE) */ 1731 _delete=function(c,m){ 1732 try{delete c[m];}catch(e){c[m]=null;} 1733 }, 1734 /* -------------------- */ 1735 1736 1737 /* detects left mouse button */ 1738 _mouseBtnLeft=function(e){ 1739 return !(e.which && e.which!==1); 1740 }, 1741 /* -------------------- */ 1742 1743 1744 /* detects if pointer type event is touch */ 1745 _pointerTouch=function(e){ 1746 var t=e.originalEvent.pointerType; 1747 return !(t && t!=="touch" && t!==2); 1748 }, 1749 /* -------------------- */ 1750 1751 1752 /* checks if value is numeric */ 1753 _isNumeric=function(val){ 1754 return !isNaN(parseFloat(val)) && isFinite(val); 1755 }, 1756 /* -------------------- */ 1757 1758 1759 /* returns element position according to content */ 1760 _childPos=function(el){ 1761 var p=el.parents(".mCSB_container"); 1762 return [el.offset().top-p.offset().top,el.offset().left-p.offset().left]; 1763 } 1764 1765}))}
vendor: 3 bytes, line 1765
1765));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.