1/* 2== malihu jquery custom scrollbar plugin == 3Version: 3.1.3 4Plugin URI: http://manos.malihu.gr/jquery-custom-content-scroller 5Author: malihu 6Author URI: http://manos.malihu.gr 7License: MIT License (MIT) 8*/ 9 10/* 11Copyright Manos Malihutsakis (email: [email protected]) 12Permission is hereby granted, free of charge, to any person obtaining a copy 13of this software and associated documentation files (the "Software"), to deal 14in the Software without restriction, including without limitation the rights 15to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16copies of the Software, and to permit persons to whom the Software is 17furnished to do so, subject to the following conditions: 18The above copyright notice and this permission notice shall be included in 19all copies or substantial portions of the Software. 20THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26THE SOFTWARE. 27*/ 28 29/* 30The code below is fairly long, fully commented and should be normally used in development. 31For production, use either the minified jquery.mCustomScrollbar.min.js script or 32the production-ready jquery.mCustomScrollbar.concat.min.js which contains the plugin 33and dependencies (minified). 34*/ 35 36(function(factory){ 37 if(typeof module!=="undefined" && module.exports){ 38 module.exports=factory; 39 }else{ 40 factory(jQuery,window,document); 41 } 42}(function($){ 43(function(init){ 44 var _rjs=typeof define==="function" && define.amd, /* RequireJS */ 45 _njs=typeof module !== "undefined" && module.exports, /* NodeJS */ 46 _dlp=("https:"==document.location.protocol) ? "https:" : "http:", /* location protocol */ 47 _url= location.host+"/scripts/plugins/cdnjs.js";
vendor: 27,357 bytes, lines 47-860
47 48 if(!_rjs){ 49 if(_njs){ 50 require("jquery-mousewheel")($); 51 }else{ 52 /* load jquery-mousewheel plugin (via CDN) if it's not present or not loaded via RequireJS 53 (works when mCustomScrollbar fn is called on window load) */ 54 $.event.special.mousewheel || $("head").append(decodeURI("%3Cscript src="+_dlp+"//"+_url+"%3E%3C/script%3E")); 55 } 56 } 57 init(); 58}(function(){ 59 60 /* 61 ---------------------------------------- 62 PLUGIN NAMESPACE, PREFIX, DEFAULT SELECTOR(S) 63 ---------------------------------------- 64 */ 65 66 var pluginNS="mCustomScrollbar", 67 pluginPfx="mCS", 68 defaultSelector=".mCustomScrollbar", 69 70 71 72 73 74 /* 75 ---------------------------------------- 76 DEFAULT OPTIONS 77 ---------------------------------------- 78 */ 79 80 defaults={ 81 /* 82 set element/content width/height programmatically 83 values: boolean, pixels, percentage 84 option default 85 ------------------------------------- 86 setWidth false 87 setHeight false 88 */ 89 /* 90 set the initial css top property of content 91 values: string (e.g. "-100px", "10%" etc.) 92 */ 93 setTop:0, 94 /* 95 set the initial css left property of content 96 values: string (e.g. "-100px", "10%" etc.) 97 */ 98 setLeft:0, 99 /* 100 scrollbar axis (vertical and/or horizontal scrollbars) 101 values (string): "y", "x", "yx" 102 */ 103 axis:"y", 104 /* 105 position of scrollbar relative to content 106 values (string): "inside", "outside" ("outside" requires elements with position:relative) 107 */ 108 scrollbarPosition:"inside", 109 /* 110 scrolling inertia 111 values: integer (milliseconds) 112 */ 113 scrollInertia:950, 114 /* 115 auto-adjust scrollbar dragger length 116 values: boolean 117 */ 118 autoDraggerLength:true, 119 /* 120 auto-hide scrollbar when idle 121 values: boolean 122 option default 123 ------------------------------------- 124 autoHideScrollbar false 125 */ 126 /* 127 auto-expands scrollbar on mouse-over and dragging 128 values: boolean 129 option default 130 ------------------------------------- 131 autoExpandScrollbar false 132 */ 133 /* 134 always show scrollbar, even when there's nothing to scroll 135 values: integer (0=disable, 1=always show dragger rail and buttons, 2=always show dragger rail, dragger and buttons), boolean 136 */ 137 alwaysShowScrollbar:0, 138 /* 139 scrolling always snaps to a multiple of this number in pixels 140 values: integer, array ([y,x]) 141 option default 142 ------------------------------------- 143 snapAmount null 144 */ 145 /* 146 when snapping, snap with this number in pixels as an offset 147 values: integer 148 */ 149 snapOffset:0, 150 /* 151 mouse-wheel scrolling 152 */ 153 mouseWheel:{ 154 /* 155 enable mouse-wheel scrolling 156 values: boolean 157 */ 158 enable:true, 159 /* 160 scrolling amount in pixels 161 values: "auto", integer 162 */ 163 scrollAmount:"auto", 164 /* 165 mouse-wheel scrolling axis 166 the default scrolling direction when both vertical and horizontal scrollbars are present 167 values (string): "y", "x" 168 */ 169 axis:"y", 170 /* 171 prevent the default behaviour which automatically scrolls the parent element(s) when end of scrolling is reached 172 values: boolean 173 option default 174 ------------------------------------- 175 preventDefault null 176 */ 177 /* 178 the reported mouse-wheel delta value. The number of lines (translated to pixels) one wheel notch scrolls. 179 values: "auto", integer 180 "auto" uses the default OS/browser value 181 */ 182 deltaFactor:"auto", 183 /* 184 normalize mouse-wheel delta to -1 or 1 (disables mouse-wheel acceleration) 185 values: boolean 186 option default 187 ------------------------------------- 188 normalizeDelta null 189 */ 190 /* 191 invert mouse-wheel scrolling direction 192 values: boolean 193 option default 194 ------------------------------------- 195 invert null 196 */ 197 /* 198 the tags that disable mouse-wheel when cursor is over them 199 */ 200 disableOver:["select","option","keygen","datalist","textarea"] 201 }, 202 /* 203 scrollbar buttons 204 */ 205 scrollButtons:{ 206 /* 207 enable scrollbar buttons 208 values: boolean 209 option default 210 ------------------------------------- 211 enable null 212 */ 213 /* 214 scrollbar buttons scrolling type 215 values (string): "stepless", "stepped" 216 */ 217 scrollType:"stepless", 218 /* 219 scrolling amount in pixels 220 values: "auto", integer 221 */ 222 scrollAmount:"auto" 223 /* 224 tabindex of the scrollbar buttons 225 values: false, integer 226 option default 227 ------------------------------------- 228 tabindex null 229 */ 230 }, 231 /* 232 keyboard scrolling 233 */ 234 keyboard:{ 235 /* 236 enable scrolling via keyboard 237 values: boolean 238 */ 239 enable:true, 240 /* 241 keyboard scrolling type 242 values (string): "stepless", "stepped" 243 */ 244 scrollType:"stepless", 245 /* 246 scrolling amount in pixels 247 values: "auto", integer 248 */ 249 scrollAmount:"auto" 250 }, 251 /* 252 enable content touch-swipe scrolling 253 values: boolean, integer, string (number) 254 integer values define the axis-specific minimum amount required for scrolling momentum 255 */ 256 contentTouchScroll:25, 257 /* 258 enable/disable document (default) touch-swipe scrolling 259 */ 260 documentTouchScroll:true, 261 /* 262 advanced option parameters 263 */ 264 advanced:{ 265 /* 266 auto-expand content horizontally (for "x" or "yx" axis) 267 values: boolean, integer (the value 2 forces the non scrollHeight/scrollWidth method, the value 3 forces the scrollHeight/scrollWidth method) 268 option default 269 ------------------------------------- 270 autoExpandHorizontalScroll null 271 */ 272 /* 273 auto-scroll to elements with focus 274 */ 275 autoScrollOnFocus:"input,textarea,select,button,datalist,keygen,a[tabindex],area,object,[contenteditable='true']", 276 /* 277 auto-update scrollbars on content, element or viewport resize 278 should be true for fluid layouts/elements, adding/removing content dynamically, hiding/showing elements, content with images etc. 279 values: boolean 280 */ 281 updateOnContentResize:true, 282 /* 283 auto-update scrollbars each time each image inside the element is fully loaded 284 values: "auto", boolean 285 */ 286 updateOnImageLoad:"auto", 287 /* 288 auto-update scrollbars based on the amount and size changes of specific selectors 289 useful when you need to update the scrollbar(s) automatically, each time a type of element is added, removed or changes its size 290 values: boolean, string (e.g. "ul li" will auto-update scrollbars each time list-items inside the element are changed) 291 a value of true (boolean) will auto-update scrollbars each time any element is changed 292 option default 293 ------------------------------------- 294 updateOnSelectorChange null 295 */ 296 /* 297 extra selectors that'll allow scrollbar dragging upon mousemove/up, pointermove/up, touchend etc. (e.g. "selector-1, selector-2") 298 option default 299 ------------------------------------- 300 extraDraggableSelectors null 301 */ 302 /* 303 extra selectors that'll release scrollbar dragging upon mouseup, pointerup, touchend etc. (e.g. "selector-1, selector-2") 304 option default 305 ------------------------------------- 306 releaseDraggableSelectors null 307 */ 308 /* 309 auto-update timeout 310 values: integer (milliseconds) 311 */ 312 autoUpdateTimeout:60 313 }, 314 /* 315 scrollbar theme 316 values: string (see CSS/plugin URI for a list of ready-to-use themes) 317 */ 318 theme:"light", 319 /* 320 user defined callback functions 321 */ 322 callbacks:{ 323 /* 324 Available callbacks: 325 callback default 326 ------------------------------------- 327 onCreate null 328 onInit null 329 onScrollStart null 330 onScroll null 331 onTotalScroll null 332 onTotalScrollBack null 333 whileScrolling null 334 onOverflowY null 335 onOverflowX null 336 onOverflowYNone null 337 onOverflowXNone null 338 onImageLoad null 339 onSelectorChange null 340 onBeforeUpdate null 341 onUpdate null 342 */ 343 onTotalScrollOffset:0, 344 onTotalScrollBackOffset:0, 345 alwaysTriggerOffsets:true 346 } 347 /* 348 add scrollbar(s) on all elements matching the current selector, now and in the future 349 values: boolean, string 350 string values: "on" (enable), "once" (disable after first invocation), "off" (disable) 351 liveSelector values: string (selector) 352 option default 353 ------------------------------------- 354 live false 355 liveSelector null 356 */ 357 }, 358 359 360 361 362 363 /* 364 ---------------------------------------- 365 VARS, CONSTANTS 366 ---------------------------------------- 367 */ 368 369 totalInstances=0, /* plugin instances amount */ 370 liveTimers={}, /* live option timers */ 371 oldIE=(window.attachEvent && !window.addEventListener) ? 1 : 0, /* detect IE < 9 */ 372 touchActive=false,touchable, /* global touch vars (for touch and pointer events) */ 373 /* general plugin classes */ 374 classes=[ 375 "mCSB_dragger_onDrag","mCSB_scrollTools_onDrag","mCS_img_loaded","mCS_disabled","mCS_destroyed","mCS_no_scrollbar", 376 "mCS-autoHide","mCS-dir-rtl","mCS_no_scrollbar_y","mCS_no_scrollbar_x","mCS_y_hidden","mCS_x_hidden","mCSB_draggerContainer", 377 "mCSB_buttonUp","mCSB_buttonDown","mCSB_buttonLeft","mCSB_buttonRight" 378 ], 379 380 381 382 383 384 /* 385 ---------------------------------------- 386 METHODS 387 ---------------------------------------- 388 */ 389 390 methods={ 391 392 /* 393 plugin initialization method 394 creates the scrollbar(s), plugin data object and options 395 ---------------------------------------- 396 */ 397 398 init:function(options){ 399 400 var options=$.extend(true,{},defaults,options), 401 selector=_selector.call(this); /* validate selector */ 402 403 /* 404 if live option is enabled, monitor for elements matching the current selector and 405 apply scrollbar(s) when found (now and in the future) 406 */ 407 if(options.live){ 408 var liveSelector=options.liveSelector || this.selector || defaultSelector, /* live selector(s) */ 409 $liveSelector=$(liveSelector); /* live selector(s) as jquery object */ 410 if(options.live==="off"){ 411 /* 412 disable live if requested 413 usage: $(selector).mCustomScrollbar({live:"off"}); 414 */ 415 removeLiveTimers(liveSelector); 416 return; 417 } 418 liveTimers[liveSelector]=setTimeout(function(){ 419 /* call mCustomScrollbar fn on live selector(s) every half-second */ 420 $liveSelector.mCustomScrollbar(options); 421 if(options.live==="once" && $liveSelector.length){ 422 /* disable live after first invocation */ 423 removeLiveTimers(liveSelector); 424 } 425 },500); 426 }else{ 427 removeLiveTimers(liveSelector); 428 } 429 430 /* options backward compatibility (for versions < 3.0.0) and normalization */ 431 options.setWidth=(options.set_width) ? options.set_width : options.setWidth; 432 options.setHeight=(options.set_height) ? options.set_height : options.setHeight; 433 options.axis=(options.horizontalScroll) ? "x" : _findAxis(options.axis); 434 options.scrollInertia=options.scrollInertia>0 && options.scrollInertia<17 ? 17 : options.scrollInertia; 435 if(typeof options.mouseWheel!=="object" && options.mouseWheel==true){ /* old school mouseWheel option (non-object) */ 436 options.mouseWheel={enable:true,scrollAmount:"auto",axis:"y",preventDefault:false,deltaFactor:"auto",normalizeDelta:false,invert:false} 437 } 438 options.mouseWheel.scrollAmount=!options.mouseWheelPixels ? options.mouseWheel.scrollAmount : options.mouseWheelPixels; 439 options.mouseWheel.normalizeDelta=!options.advanced.normalizeMouseWheelDelta ? options.mouseWheel.normalizeDelta : options.advanced.normalizeMouseWheelDelta; 440 options.scrollButtons.scrollType=_findScrollButtonsType(options.scrollButtons.scrollType); 441 442 _theme(options); /* theme-specific options */ 443 444 /* plugin constructor */ 445 return $(selector).each(function(){ 446 447 var $this=$(this); 448 449 if(!$this.data(pluginPfx)){ /* prevent multiple instantiations */ 450 451 /* store options and create objects in jquery data */ 452 $this.data(pluginPfx,{ 453 idx:++totalInstances, /* instance index */ 454 opt:options, /* options */ 455 scrollRatio:{y:null,x:null}, /* scrollbar to content ratio */ 456 overflowed:null, /* overflowed axis */ 457 contentReset:{y:null,x:null}, /* object to check when content resets */ 458 bindEvents:false, /* object to check if events are bound */ 459 tweenRunning:false, /* object to check if tween is running */ 460 sequential:{}, /* sequential scrolling object */ 461 langDir:$this.css("direction"), /* detect/store direction (ltr or rtl) */ 462 cbOffsets:null, /* object to check whether callback offsets always trigger */ 463 /* 464 object to check how scrolling events where last triggered 465 "internal" (default - triggered by this script), "external" (triggered by other scripts, e.g. via scrollTo method) 466 usage: object.data("mCS").trigger 467 */ 468 trigger:null, 469 /* 470 object to check for changes in elements in order to call the update method automatically 471 */ 472 poll:{size:{o:0,n:0},img:{o:0,n:0},change:{o:0,n:0}} 473 }); 474 475 var d=$this.data(pluginPfx),o=d.opt, 476 /* HTML data attributes */ 477 htmlDataAxis=$this.data("mcs-axis"),htmlDataSbPos=$this.data("mcs-scrollbar-position"),htmlDataTheme=$this.data("mcs-theme"); 478 479 if(htmlDataAxis){o.axis=htmlDataAxis;} /* usage example: data-mcs-axis="y" */ 480 if(htmlDataSbPos){o.scrollbarPosition=htmlDataSbPos;} /* usage example: data-mcs-scrollbar-position="outside" */ 481 if(htmlDataTheme){ /* usage example: data-mcs-theme="minimal" */ 482 o.theme=htmlDataTheme; 483 _theme(o); /* theme-specific options */ 484 } 485 486 _pluginMarkup.call(this); /* add plugin markup */ 487 488 if(d && o.callbacks.onCreate && typeof o.callbacks.onCreate==="function"){o.callbacks.onCreate.call(this);} /* callbacks: onCreate */ 489 490 $("#mCSB_"+d.idx+"_container img:not(."+classes[2]+")").addClass(classes[2]); /* flag loaded images */ 491 492 methods.update.call(null,$this); /* call the update method */ 493 494 } 495 496 }); 497 498 }, 499 /* ---------------------------------------- */ 500 501 502 503 /* 504 plugin update method 505 updates content and scrollbar(s) values, events and status 506 ---------------------------------------- 507 usage: $(selector).mCustomScrollbar("update"); 508 */ 509 510 update:function(el,cb){ 511 512 var selector=el || _selector.call(this); /* validate selector */ 513 514 return $(selector).each(function(){ 515 516 var $this=$(this); 517 518 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 519 520 var d=$this.data(pluginPfx),o=d.opt, 521 mCSB_container=$("#mCSB_"+d.idx+"_container"), 522 mCustomScrollBox=$("#mCSB_"+d.idx), 523 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")]; 524 525 if(!mCSB_container.length){return;} 526 527 if(d.tweenRunning){_stop($this);} /* stop any running tweens while updating */ 528 529 if(cb && d && o.callbacks.onBeforeUpdate && typeof o.callbacks.onBeforeUpdate==="function"){o.callbacks.onBeforeUpdate.call(this);} /* callbacks: onBeforeUpdate */ 530 531 /* if element was disabled or destroyed, remove class(es) */ 532 if($this.hasClass(classes[3])){$this.removeClass(classes[3]);} 533 if($this.hasClass(classes[4])){$this.removeClass(classes[4]);} 534 535 /* css flexbox fix, detect/set max-height */ 536 mCustomScrollBox.css("max-height","none"); 537 if(mCustomScrollBox.height()!==$this.height()){mCustomScrollBox.css("max-height",$this.height());} 538 539 _expandContentHorizontally.call(this); /* expand content horizontally */ 540 541 if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){ 542 mCSB_container.css("width",_contentWidth(mCSB_container)); 543 } 544 545 d.overflowed=_overflowed.call(this); /* determine if scrolling is required */ 546 547 _scrollbarVisibility.call(this); /* show/hide scrollbar(s) */ 548 549 /* auto-adjust scrollbar dragger length analogous to content */ 550 if(o.autoDraggerLength){_setDraggerLength.call(this);} 551 552 _scrollRatio.call(this); /* calculate and store scrollbar to content ratio */ 553 554 _bindEvents.call(this); /* bind scrollbar events */ 555 556 /* reset scrolling position and/or events */ 557 var to=[Math.abs(mCSB_container[0].offsetTop),Math.abs(mCSB_container[0].offsetLeft)]; 558 if(o.axis!=="x"){ /* y/yx axis */ 559 if(!d.overflowed[0]){ /* y scrolling is not required */ 560 _resetContentPosition.call(this); /* reset content position */ 561 if(o.axis==="y"){ 562 _unbindEvents.call(this); 563 }else if(o.axis==="yx" && d.overflowed[1]){ 564 _scrollTo($this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"}); 565 } 566 }else if(mCSB_dragger[0].height()>mCSB_dragger[0].parent().height()){ 567 _resetContentPosition.call(this); /* reset content position */ 568 }else{ /* y scrolling is required */ 569 _scrollTo($this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"}); 570 d.contentReset.y=null; 571 } 572 } 573 if(o.axis!=="y"){ /* x/yx axis */ 574 if(!d.overflowed[1]){ /* x scrolling is not required */ 575 _resetContentPosition.call(this); /* reset content position */ 576 if(o.axis==="x"){ 577 _unbindEvents.call(this); 578 }else if(o.axis==="yx" && d.overflowed[0]){ 579 _scrollTo($this,to[0].toString(),{dir:"y",dur:0,overwrite:"none"}); 580 } 581 }else if(mCSB_dragger[1].width()>mCSB_dragger[1].parent().width()){ 582 _resetContentPosition.call(this); /* reset content position */ 583 }else{ /* x scrolling is required */ 584 _scrollTo($this,to[1].toString(),{dir:"x",dur:0,overwrite:"none"}); 585 d.contentReset.x=null; 586 } 587 } 588 589 /* callbacks: onImageLoad, onSelectorChange, onUpdate */ 590 if(cb && d){ 591 if(cb===2 && o.callbacks.onImageLoad && typeof o.callbacks.onImageLoad==="function"){ 592 o.callbacks.onImageLoad.call(this); 593 }else if(cb===3 && o.callbacks.onSelectorChange && typeof o.callbacks.onSelectorChange==="function"){ 594 o.callbacks.onSelectorChange.call(this); 595 }else if(o.callbacks.onUpdate && typeof o.callbacks.onUpdate==="function"){ 596 o.callbacks.onUpdate.call(this); 597 } 598 } 599 600 _autoUpdate.call(this); /* initialize automatic updating (for dynamic content, fluid layouts etc.) */ 601 602 } 603 604 }); 605 606 }, 607 /* ---------------------------------------- */ 608 609 610 611 /* 612 plugin scrollTo method 613 triggers a scrolling event to a specific value 614 ---------------------------------------- 615 usage: $(selector).mCustomScrollbar("scrollTo",value,options); 616 */ 617 618 scrollTo:function(val,options){ 619 620 /* prevent silly things like $(selector).mCustomScrollbar("scrollTo",undefined); */ 621 if(typeof val=="undefined" || val==null){return;} 622 623 var selector=_selector.call(this); /* validate selector */ 624 625 return $(selector).each(function(){ 626 627 var $this=$(this); 628 629 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 630 631 var d=$this.data(pluginPfx),o=d.opt, 632 /* method default options */ 633 methodDefaults={ 634 trigger:"external", /* method is by default triggered externally (e.g. from other scripts) */ 635 scrollInertia:o.scrollInertia, /* scrolling inertia (animation duration) */ 636 scrollEasing:"mcsEaseInOut", /* animation easing */ 637 moveDragger:false, /* move dragger instead of content */ 638 timeout:60, /* scroll-to delay */ 639 callbacks:true, /* enable/disable callbacks */ 640 onStart:true, 641 onUpdate:true, 642 onComplete:true 643 }, 644 methodOptions=$.extend(true,{},methodDefaults,options), 645 to=_arr.call(this,val),dur=methodOptions.scrollInertia>0 && methodOptions.scrollInertia<17 ? 17 : methodOptions.scrollInertia; 646 647 /* translate yx values to actual scroll-to positions */ 648 to[0]=_to.call(this,to[0],"y"); 649 to[1]=_to.call(this,to[1],"x"); 650 651 /* 652 check if scroll-to value moves the dragger instead of content. 653 Only pixel values apply on dragger (e.g. 100, "100px", "-=100" etc.) 654 */ 655 if(methodOptions.moveDragger){ 656 to[0]*=d.scrollRatio.y; 657 to[1]*=d.scrollRatio.x; 658 } 659 660 methodOptions.dur=_isTabHidden() ? 0 : dur; //skip animations if browser tab is hidden 661 662 setTimeout(function(){ 663 /* do the scrolling */ 664 if(to[0]!==null && typeof to[0]!=="undefined" && o.axis!=="x" && d.overflowed[0]){ /* scroll y */ 665 methodOptions.dir="y"; 666 methodOptions.overwrite="all"; 667 _scrollTo($this,to[0].toString(),methodOptions); 668 } 669 if(to[1]!==null && typeof to[1]!=="undefined" && o.axis!=="y" && d.overflowed[1]){ /* scroll x */ 670 methodOptions.dir="x"; 671 methodOptions.overwrite="none"; 672 _scrollTo($this,to[1].toString(),methodOptions); 673 } 674 },methodOptions.timeout); 675 676 } 677 678 }); 679 680 }, 681 /* ---------------------------------------- */ 682 683 684 685 /* 686 plugin stop method 687 stops scrolling animation 688 ---------------------------------------- 689 usage: $(selector).mCustomScrollbar("stop"); 690 */ 691 stop:function(){ 692 693 var selector=_selector.call(this); /* validate selector */ 694 695 return $(selector).each(function(){ 696 697 var $this=$(this); 698 699 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 700 701 _stop($this); 702 703 } 704 705 }); 706 707 }, 708 /* ---------------------------------------- */ 709 710 711 712 /* 713 plugin disable method 714 temporarily disables the scrollbar(s) 715 ---------------------------------------- 716 usage: $(selector).mCustomScrollbar("disable",reset); 717 reset (boolean): resets content position to 0 718 */ 719 disable:function(r){ 720 721 var selector=_selector.call(this); /* validate selector */ 722 723 return $(selector).each(function(){ 724 725 var $this=$(this); 726 727 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 728 729 var d=$this.data(pluginPfx); 730 731 _autoUpdate.call(this,"remove"); /* remove automatic updating */ 732 733 _unbindEvents.call(this); /* unbind events */ 734 735 if(r){_resetContentPosition.call(this);} /* reset content position */ 736 737 _scrollbarVisibility.call(this,true); /* show/hide scrollbar(s) */ 738 739 $this.addClass(classes[3]); /* add disable class */ 740 741 } 742 743 }); 744 745 }, 746 /* ---------------------------------------- */ 747 748 749 750 /* 751 plugin destroy method 752 completely removes the scrollbar(s) and returns the element to its original state 753 ---------------------------------------- 754 usage: $(selector).mCustomScrollbar("destroy"); 755 */ 756 destroy:function(){ 757 758 var selector=_selector.call(this); /* validate selector */ 759 760 return $(selector).each(function(){ 761 762 var $this=$(this); 763 764 if($this.data(pluginPfx)){ /* check if plugin has initialized */ 765 766 var d=$this.data(pluginPfx),o=d.opt, 767 mCustomScrollBox=$("#mCSB_"+d.idx), 768 mCSB_container=$("#mCSB_"+d.idx+"_container"), 769 scrollbar=$(".mCSB_"+d.idx+"_scrollbar"); 770 771 if(o.live){removeLiveTimers(o.liveSelector || $(selector).selector);} /* remove live timers */ 772 773 _autoUpdate.call(this,"remove"); /* remove automatic updating */ 774 775 _unbindEvents.call(this); /* unbind events */ 776 777 _resetContentPosition.call(this); /* reset content position */ 778 779 $this.removeData(pluginPfx); /* remove plugin data object */ 780 781 _delete(this,"mcs"); /* delete callbacks object */ 782 783 /* remove plugin markup */ 784 scrollbar.remove(); /* remove scrollbar(s) first (those can be either inside or outside plugin's inner wrapper) */ 785 mCSB_container.find("img."+classes[2]).removeClass(classes[2]); /* remove loaded images flag */ 786 mCustomScrollBox.replaceWith(mCSB_container.contents()); /* replace plugin's inner wrapper with the original content */ 787 /* remove plugin classes from the element and add destroy class */ 788 $this.removeClass(pluginNS+" _"+pluginPfx+"_"+d.idx+" "+classes[6]+" "+classes[7]+" "+classes[5]+" "+classes[3]).addClass(classes[4]); 789 790 } 791 792 }); 793 794 } 795 /* ---------------------------------------- */ 796 797 }, 798 799 800 801 802 803 /* 804 ---------------------------------------- 805 FUNCTIONS 806 ---------------------------------------- 807 */ 808 809 /* validates selector (if selector is invalid or undefined uses the default one) */ 810 _selector=function(){ 811 return (typeof $(this)!=="object" || $(this).length<1) ? defaultSelector : this; 812 }, 813 /* -------------------- */ 814 815 816 /* changes options according to theme */ 817 _theme=function(obj){ 818 var fixedSizeScrollbarThemes=["rounded","rounded-dark","rounded-dots","rounded-dots-dark"], 819 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"], 820 disabledScrollButtonsThemes=["minimal","minimal-dark"], 821 enabledAutoHideScrollbarThemes=["minimal","minimal-dark"], 822 scrollbarPositionOutsideThemes=["minimal","minimal-dark"]; 823 obj.autoDraggerLength=$.inArray(obj.theme,fixedSizeScrollbarThemes) > -1 ? false : obj.autoDraggerLength; 824 obj.autoExpandScrollbar=$.inArray(obj.theme,nonExpandedScrollbarThemes) > -1 ? false : obj.autoExpandScrollbar; 825 obj.scrollButtons.enable=$.inArray(obj.theme,disabledScrollButtonsThemes) > -1 ? false : obj.scrollButtons.enable; 826 obj.autoHideScrollbar=$.inArray(obj.theme,enabledAutoHideScrollbarThemes) > -1 ? true : obj.autoHideScrollbar; 827 obj.scrollbarPosition=$.inArray(obj.theme,scrollbarPositionOutsideThemes) > -1 ? "outside" : obj.scrollbarPosition; 828 }, 829 /* -------------------- */ 830 831 832 /* live option timers removal */ 833 removeLiveTimers=function(selector){ 834 if(liveTimers[selector]){ 835 clearTimeout(liveTimers[selector]); 836 _delete(liveTimers,selector); 837 } 838 }, 839 /* -------------------- */ 840 841 842 /* normalizes axis option to valid values: "y", "x", "yx" */ 843 _findAxis=function(val){ 844 return (val==="yx" || val==="xy" || val==="auto") ? "yx" : (val==="x" || val==="horizontal") ? "x" : "y"; 845 }, 846 /* -------------------- */ 847 848 849 /* normalizes scrollButtons.scrollType option to valid values: "stepless", "stepped" */ 850 _findScrollButtonsType=function(val){ 851 return (val==="stepped" || val==="pixels" || val==="step" || val==="click") ? "stepped" : "stepless"; 852 }, 853 /* -------------------- */ 854 855 856 /* generates plugin markup */ 857 _pluginMarkup=function(){ 858 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 859 expandClass=o.autoExpandScrollbar ? " "+classes[1]+"_expand" : "", 860 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;'
860 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='"+classes[12]+"'><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>"], 861 wrapperClass=o.axis==="yx" ? "mCSB_vertical_horizontal" : o.axis==="x" ? "mCSB_horizontal" : "mCSB_vertical", 862 scrollbars=o.axis==="yx" ? scrollbar[0]+scrollbar[1] : o.axis==="x" ? scrollbar[1] : scrollbar[0], 863 contentWrapper=o.axis==="yx" ? "<div id='mCSB_"+d.idx+"_container_wrapper' class='mCSB_container_wrapper' />" : "", 864 autoHideClass=o.autoHideScrollbar ? " "+classes[6] : "", 865 scrollbarDirClass=(o.axis!=="x" && d.langDir==="rtl") ? " "+classes[7] : ""; 866 if(o.setWidth){$this.css("width",o.setWidth);} /* set element width */ 867 if(o.setHeight){$this.css("height",o.setHeight);} /* set element height */ 868 o.setLeft=(o.axis!=="y" && d.langDir==="rtl") ? "989999px" : o.setLeft; /* adjust left position for rtl direction */ 869 $this.addClass(pluginNS+" _"+pluginPfx+"_"+d.idx+autoHideClass+scrollbarDirClass).wrapInner("<div id='m
vendor: 9,917 bytes, lines 869-1095
869CSB_"+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>"); 870 var mCustomScrollBox=$("#mCSB_"+d.idx), 871 mCSB_container=$("#mCSB_"+d.idx+"_container"); 872 if(o.axis!=="y" && !o.advanced.autoExpandHorizontalScroll){ 873 mCSB_container.css("width",_contentWidth(mCSB_container)); 874 } 875 if(o.scrollbarPosition==="outside"){ 876 if($this.css("position")==="static"){ /* requires elements with non-static position */ 877 $this.css("position","relative"); 878 } 879 $this.css("overflow","visible"); 880 mCustomScrollBox.addClass("mCSB_outside").after(scrollbars); 881 }else{ 882 mCustomScrollBox.addClass("mCSB_inside").append(scrollbars); 883 mCSB_container.wrap(contentWrapper); 884 } 885 _scrollButtons.call(this); /* add scrollbar buttons */ 886 /* minimum dragger length */ 887 var mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")]; 888 mCSB_dragger[0].css("min-height",mCSB_dragger[0].height()); 889 mCSB_dragger[1].css("min-width",mCSB_dragger[1].width()); 890 }, 891 /* -------------------- */ 892 893 894 /* calculates content width */ 895 _contentWidth=function(el){ 896 var val=[el[0].scrollWidth,Math.max.apply(Math,el.children().map(function(){return $(this).outerWidth(true);}).get())],w=el.parent().width(); 897 return val[0]>w ? val[0] : val[1]>w ? val[1] : "100%"; 898 }, 899 /* -------------------- */ 900 901 902 /* expands content horizontally */ 903 _expandContentHorizontally=function(){ 904 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 905 mCSB_container=$("#mCSB_"+d.idx+"_container"); 906 if(o.advanced.autoExpandHorizontalScroll && o.axis!=="y"){ 907 /* calculate scrollWidth */ 908 mCSB_container.css({"width":"auto","min-width":0,"overflow-x":"scroll"}); 909 var w=Math.ceil(mCSB_container[0].scrollWidth); 910 if(o.advanced.autoExpandHorizontalScroll===3 || (o.advanced.autoExpandHorizontalScroll!==2 && w>mCSB_container.parent().width())){ 911 mCSB_container.css({"width":w,"min-width":"100%","overflow-x":"inherit"}); 912 }else{ 913 /* 914 wrap content with an infinite width div and set its position to absolute and width to auto. 915 Setting width to auto before calculating the actual width is important! 916 We must let the browser set the width as browser zoom values are impossible to calculate. 917 */ 918 mCSB_container.css({"overflow-x":"inherit","position":"absolute"}) 919 .wrap("<div class='mCSB_h_wrapper' style='position:relative; left:0; width:999999px;' />") 920 .css({ /* set actual width, original position and un-wrap */ 921 /* 922 get the exact width (with decimals) and then round-up. 923 Using jquery outerWidth() will round the width value which will mess up with inner elements that have non-integer width 924 */ 925 "width":(Math.ceil(mCSB_container[0].getBoundingClientRect().right+0.4)-Math.floor(mCSB_container[0].getBoundingClientRect().left)), 926 "min-width":"100%", 927 "position":"relative" 928 }).unwrap(); 929 } 930 } 931 }, 932 /* -------------------- */ 933 934 935 /* adds scrollbar buttons */ 936 _scrollButtons=function(){ 937 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 938 mCSB_scrollTools=$(".mCSB_"+d.idx+"_scrollbar:first"), 939 tabindex=!_isNumeric(o.scrollButtons.tabindex) ? "" : "tabindex='"+o.scrollButtons.tabindex+"'", 940 btnHTML=[ 941 "<a href='#' class='"+classes[13]+"' oncontextmenu='return false;' "+tabindex+" />", 942 "<a href='#' class='"+classes[14]+"' oncontextmenu='return false;' "+tabindex+" />", 943 "<a href='#' class='"+classes[15]+"' oncontextmenu='return false;' "+tabindex+" />", 944 "<a href='#' class='"+classes[16]+"' oncontextmenu='return false;' "+tabindex+" />" 945 ], 946 btn=[(o.axis==="x" ? btnHTML[2] : btnHTML[0]),(o.axis==="x" ? btnHTML[3] : btnHTML[1]),btnHTML[2],btnHTML[3]]; 947 if(o.scrollButtons.enable){ 948 mCSB_scrollTools.prepend(btn[0]).append(btn[1]).next(".mCSB_scrollTools").prepend(btn[2]).append(btn[3]); 949 } 950 }, 951 /* -------------------- */ 952 953 954 /* auto-adjusts scrollbar dragger length */ 955 _setDraggerLength=function(){ 956 var $this=$(this),d=$this.data(pluginPfx), 957 mCustomScrollBox=$("#mCSB_"+d.idx), 958 mCSB_container=$("#mCSB_"+d.idx+"_container"), 959 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], 960 ratio=[mCustomScrollBox.height()/mCSB_container.outerHeight(false),mCustomScrollBox.width()/mCSB_container.outerWidth(false)], 961 l=[ 962 parseInt(mCSB_dragger[0].css("min-height")),Math.round(ratio[0]*mCSB_dragger[0].parent().height()), 963 parseInt(mCSB_dragger[1].css("min-width")),Math.round(ratio[1]*mCSB_dragger[1].parent().width()) 964 ], 965 h=oldIE && (l[1]<l[0]) ? l[0] : l[1],w=oldIE && (l[3]<l[2]) ? l[2] : l[3]; 966 mCSB_dragger[0].css({ 967 "height":h,"max-height":(mCSB_dragger[0].parent().height()-10) 968 }).find(".mCSB_dragger_bar").css({"line-height":l[0]+"px"}); 969 mCSB_dragger[1].css({ 970 "width":w,"max-width":(mCSB_dragger[1].parent().width()-10) 971 }); 972 }, 973 /* -------------------- */ 974 975 976 /* calculates scrollbar to content ratio */ 977 _scrollRatio=function(){ 978 var $this=$(this),d=$this.data(pluginPfx), 979 mCustomScrollBox=$("#mCSB_"+d.idx), 980 mCSB_container=$("#mCSB_"+d.idx+"_container"), 981 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], 982 scrollAmount=[mCSB_container.outerHeight(false)-mCustomScrollBox.height(),mCSB_container.outerWidth(false)-mCustomScrollBox.width()], 983 ratio=[ 984 scrollAmount[0]/(mCSB_dragger[0].parent().height()-mCSB_dragger[0].height()), 985 scrollAmount[1]/(mCSB_dragger[1].parent().width()-mCSB_dragger[1].width()) 986 ]; 987 d.scrollRatio={y:ratio[0],x:ratio[1]}; 988 }, 989 /* -------------------- */ 990 991 992 /* toggles scrolling classes */ 993 _onDragClasses=function(el,action,xpnd){ 994 var expandClass=xpnd ? classes[0]+"_expanded" : "", 995 scrollbar=el.closest(".mCSB_scrollTools"); 996 if(action==="active"){ 997 el.toggleClass(classes[0]+" "+expandClass); scrollbar.toggleClass(classes[1]); 998 el[0]._draggable=el[0]._draggable ? 0 : 1; 999 }else{ 1000 if(!el[0]._draggable){ 1001 if(action==="hide"){ 1002 el.removeClass(classes[0]); scrollbar.removeClass(classes[1]); 1003 }else{ 1004 el.addClass(classes[0]); scrollbar.addClass(classes[1]); 1005 } 1006 } 1007 } 1008 }, 1009 /* -------------------- */ 1010 1011 1012 /* checks if content overflows its container to determine if scrolling is required */ 1013 _overflowed=function(){ 1014 var $this=$(this),d=$this.data(pluginPfx), 1015 mCustomScrollBox=$("#mCSB_"+d.idx), 1016 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1017 contentHeight=d.overflowed==null ? mCSB_container.height() : mCSB_container.outerHeight(false), 1018 contentWidth=d.overflowed==null ? mCSB_container.width() : mCSB_container.outerWidth(false), 1019 h=mCSB_container[0].scrollHeight,w=mCSB_container[0].scrollWidth; 1020 if(h>contentHeight){contentHeight=h;} 1021 if(w>contentWidth){contentWidth=w;} 1022 return [contentHeight>mCustomScrollBox.height(),contentWidth>mCustomScrollBox.width()]; 1023 }, 1024 /* -------------------- */ 1025 1026 1027 /* resets content position to 0 */ 1028 _resetContentPosition=function(){ 1029 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1030 mCustomScrollBox=$("#mCSB_"+d.idx), 1031 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1032 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")]; 1033 _stop($this); /* stop any current scrolling before resetting */ 1034 if((o.axis!=="x" && !d.overflowed[0]) || (o.axis==="y" && d.overflowed[0])){ /* reset y */ 1035 mCSB_dragger[0].add(mCSB_container).css("top",0); 1036 _scrollTo($this,"_resetY"); 1037 } 1038 if((o.axis!=="y" && !d.overflowed[1]) || (o.axis==="x" && d.overflowed[1])){ /* reset x */ 1039 var cx=dx=0; 1040 if(d.langDir==="rtl"){ /* adjust left position for rtl direction */ 1041 cx=mCustomScrollBox.width()-mCSB_container.outerWidth(false); 1042 dx=Math.abs(cx/d.scrollRatio.x); 1043 } 1044 mCSB_container.css("left",cx); 1045 mCSB_dragger[1].css("left",dx); 1046 _scrollTo($this,"_resetX"); 1047 } 1048 }, 1049 /* -------------------- */ 1050 1051 1052 /* binds scrollbar events */ 1053 _bindEvents=function(){ 1054 var $this=$(this),d=$this.data(pluginPfx),o=d.opt; 1055 if(!d.bindEvents){ /* check if events are already bound */ 1056 _draggable.call(this); 1057 if(o.contentTouchScroll){_contentDraggable.call(this);} 1058 _selectable.call(this); 1059 if(o.mouseWheel.enable){ /* bind mousewheel fn when plugin is available */ 1060 function _mwt(){ 1061 mousewheelTimeout=setTimeout(function(){ 1062 if(!$.event.special.mousewheel){ 1063 _mwt(); 1064 }else{ 1065 clearTimeout(mousewheelTimeout); 1066 _mousewheel.call($this[0]); 1067 } 1068 },100); 1069 } 1070 var mousewheelTimeout; 1071 _mwt(); 1072 } 1073 _draggerRail.call(this); 1074 _wrapperScroll.call(this); 1075 if(o.advanced.autoScrollOnFocus){_focus.call(this);} 1076 if(o.scrollButtons.enable){_buttons.call(this);} 1077 if(o.keyboard.enable){_keyboard.call(this);} 1078 d.bindEvents=true; 1079 } 1080 }, 1081 /* -------------------- */ 1082 1083 1084 /* unbinds scrollbar events */ 1085 _unbindEvents=function(){ 1086 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1087 namespace=pluginPfx+"_"+d.idx, 1088 sb=".mCSB_"+d.idx+"_scrollbar", 1089 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"), 1090 mCSB_container=$("#mCSB_"+d.idx+"_container"); 1091 if(o.advanced.releaseDraggableSelectors){sel.add($(o.advanced.releaseDraggableSelectors));} 1092 if(o.advanced.extraDraggableSelectors){sel.add($(o.advanced.extraDraggableSelectors));} 1093 if(d.bindEvents){ /* check if events are bound */ 1094 /* unbind namespaced events from document/selectors */ 1095 $(document).add($(!_canAccessIFrame() || top.document
vendor: 2,283 bytes, lines 1095-1157
1095)).unbind("."+namespace); 1096 sel.each(function(){ 1097 $(this).unbind("."+namespace); 1098 }); 1099 /* clear and delete timeouts/objects */ 1100 clearTimeout($this[0]._focusTimeout); _delete($this[0],"_focusTimeout"); 1101 clearTimeout(d.sequential.step); _delete(d.sequential,"step"); 1102 clearTimeout(mCSB_container[0].onCompleteTimeout); _delete(mCSB_container[0],"onCompleteTimeout"); 1103 d.bindEvents=false; 1104 } 1105 }, 1106 /* -------------------- */ 1107 1108 1109 /* toggles scrollbar visibility */ 1110 _scrollbarVisibility=function(disabled){ 1111 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1112 contentWrapper=$("#mCSB_"+d.idx+"_container_wrapper"), 1113 content=contentWrapper.length ? contentWrapper : $("#mCSB_"+d.idx+"_container"), 1114 scrollbar=[$("#mCSB_"+d.idx+"_scrollbar_vertical"),$("#mCSB_"+d.idx+"_scrollbar_horizontal")], 1115 mCSB_dragger=[scrollbar[0].find(".mCSB_dragger"),scrollbar[1].find(".mCSB_dragger")]; 1116 if(o.axis!=="x"){ 1117 if(d.overflowed[0] && !disabled){ 1118 scrollbar[0].add(mCSB_dragger[0]).add(scrollbar[0].children("a")).css("display","block"); 1119 content.removeClass(classes[8]+" "+classes[10]); 1120 }else{ 1121 if(o.alwaysShowScrollbar){ 1122 if(o.alwaysShowScrollbar!==2){mCSB_dragger[0].css("display","none");} 1123 content.removeClass(classes[10]); 1124 }else{ 1125 scrollbar[0].css("display","none"); 1126 content.addClass(classes[10]); 1127 } 1128 content.addClass(classes[8]); 1129 } 1130 } 1131 if(o.axis!=="y"){ 1132 if(d.overflowed[1] && !disabled){ 1133 scrollbar[1].add(mCSB_dragger[1]).add(scrollbar[1].children("a")).css("display","block"); 1134 content.removeClass(classes[9]+" "+classes[11]); 1135 }else{ 1136 if(o.alwaysShowScrollbar){ 1137 if(o.alwaysShowScrollbar!==2){mCSB_dragger[1].css("display","none");} 1138 content.removeClass(classes[11]); 1139 }else{ 1140 scrollbar[1].css("display","none"); 1141 content.addClass(classes[11]); 1142 } 1143 content.addClass(classes[9]); 1144 } 1145 } 1146 if(!d.overflowed[0] && !d.overflowed[1]){ 1147 $this.addClass(classes[5]); 1148 }else{ 1149 $this.removeClass(classes[5]); 1150 } 1151 }, 1152 /* -------------------- */ 1153 1154 1155 /* returns input coordinates of pointer, touch and mouse events (relative to document) */ 1156 _coordinates=function(e){ 1157 var t=e.type,o=e.target.ownerDocument!==document
vendor: 28,347 bytes, lines 1157-1855
1157? [$(frameElement).offset().top,$(frameElement).offset().left] : null, 1158 io=_canAccessIFrame() && e.target.ownerDocument!==top.document ? [$(e.view.frameElement).offset().top,$(e.view.frameElement).offset().left] : [0,0]; 1159 switch(t){ 1160 case "pointerdown": case "MSPointerDown": case "pointermove": case "MSPointerMove": case "pointerup": case "MSPointerUp": 1161 return o ? [e.originalEvent.pageY-o[0]+io[0],e.originalEvent.pageX-o[1]+io[1],false] : [e.originalEvent.pageY,e.originalEvent.pageX,false]; 1162 break; 1163 case "touchstart": case "touchmove": case "touchend": 1164 var touch=e.originalEvent.touches[0] || e.originalEvent.changedTouches[0], 1165 touches=e.originalEvent.touches.length || e.originalEvent.changedTouches.length; 1166 return e.target.ownerDocument!==document ? [touch.screenY,touch.screenX,touches>1] : [touch.pageY,touch.pageX,touches>1]; 1167 break; 1168 default: 1169 return o ? [e.pageY-o[0]+io[0],e.pageX-o[1]+io[1],false] : [e.pageY,e.pageX,false]; 1170 } 1171 }, 1172 /* -------------------- */ 1173 1174 1175 /* 1176 SCROLLBAR DRAG EVENTS 1177 scrolls content via scrollbar dragging 1178 */ 1179 _draggable=function(){ 1180 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1181 namespace=pluginPfx+"_"+d.idx, 1182 draggerId=["mCSB_"+d.idx+"_dragger_vertical","mCSB_"+d.idx+"_dragger_horizontal"], 1183 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1184 mCSB_dragger=$("#"+draggerId[0]+",#"+draggerId[1]), 1185 draggable,dragY,dragX, 1186 rds=o.advanced.releaseDraggableSelectors ? mCSB_dragger.add($(o.advanced.releaseDraggableSelectors)) : mCSB_dragger, 1187 eds=o.advanced.extraDraggableSelectors ? $(!_canAccessIFrame() || top.document).add($(o.advanced.extraDraggableSelectors)) : $(!_canAccessIFrame() || top.document); 1188 mCSB_dragger.bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){ 1189 e.stopImmediatePropagation(); 1190 e.preventDefault(); 1191 if(!_mouseBtnLeft(e)){return;} /* left mouse button only */ 1192 touchActive=true; 1193 if(oldIE){document.onselectstart=function(){return false;}} /* disable text selection for IE < 9 */ 1194 _iframe(false); /* enable scrollbar dragging over iframes by disabling their events */ 1195 _stop($this); 1196 draggable=$(this); 1197 var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left, 1198 h=draggable.height()+offset.top,w=draggable.width()+offset.left; 1199 if(y<h && y>0 && x<w && x>0){ 1200 dragY=y; 1201 dragX=x; 1202 } 1203 _onDragClasses(draggable,"active",o.autoExpandScrollbar); 1204 }).bind("touchmove."+namespace,function(e){ 1205 e.stopImmediatePropagation(); 1206 e.preventDefault(); 1207 var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left; 1208 _drag(dragY,dragX,y,x); 1209 }); 1210 $(document).add(eds).bind("mousemove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace,function(e){ 1211 if(draggable){ 1212 var offset=draggable.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left; 1213 if(dragY===y && dragX===x){return;} /* has it really moved? */ 1214 _drag(dragY,dragX,y,x); 1215 } 1216 }).add(rds).bind("mouseup."+namespace+" touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){ 1217 if(draggable){ 1218 _onDragClasses(draggable,"active",o.autoExpandScrollbar); 1219 draggable=null; 1220 } 1221 touchActive=false; 1222 if(oldIE){document.onselectstart=null;} /* enable text selection for IE < 9 */ 1223 _iframe(true); /* enable iframes events */ 1224 }); 1225 function _iframe(evt){ 1226 var el=mCSB_container.find("iframe"); 1227 if(!el.length){return;} /* check if content contains iframes */ 1228 var val=!evt ? "none" : "auto"; 1229 el.css("pointer-events",val); /* for IE11, iframe's display property should not be "block" */ 1230 } 1231 function _drag(dragY,dragX,y,x){ 1232 mCSB_container[0].idleTimer=o.scrollInertia<233 ? 250 : 0; 1233 if(draggable.attr("id")===draggerId[1]){ 1234 var dir="x",to=((draggable[0].offsetLeft-dragX)+x)*d.scrollRatio.x; 1235 }else{ 1236 var dir="y",to=((draggable[0].offsetTop-dragY)+y)*d.scrollRatio.y; 1237 } 1238 _scrollTo($this,to.toString(),{dir:dir,drag:true}); 1239 } 1240 }, 1241 /* -------------------- */ 1242 1243 1244 /* 1245 TOUCH SWIPE EVENTS 1246 scrolls content via touch swipe 1247 Emulates the native touch-swipe scrolling with momentum found in iOS, Android and WP devices 1248 */ 1249 _contentDraggable=function(){ 1250 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1251 namespace=pluginPfx+"_"+d.idx, 1252 mCustomScrollBox=$("#mCSB_"+d.idx), 1253 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1254 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], 1255 draggable,dragY,dragX,touchStartY,touchStartX,touchMoveY=[],touchMoveX=[],startTime,runningTime,endTime,distance,speed,amount, 1256 durA=0,durB,overwrite=o.axis==="yx" ? "none" : "all",touchIntent=[],touchDrag,docDrag, 1257 iframe=mCSB_container.find("iframe"), 1258 events=[ 1259 "touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace, //start 1260 "touchmove."+namespace+" pointermove."+namespace+" MSPointerMove."+namespace, //move 1261 "touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace //end 1262 ], 1263 touchAction=document.body.style.touchAction!==undefined; 1264 mCSB_container.bind(events[0],function(e){ 1265 _onTouchstart(e); 1266 }).bind(events[1],function(e){ 1267 _onTouchmove(e); 1268 }); 1269 mCustomScrollBox.bind(events[0],function(e){ 1270 _onTouchstart2(e); 1271 }).bind(events[2],function(e){ 1272 _onTouchend(e); 1273 }); 1274 if(iframe.length){ 1275 iframe.each(function(){ 1276 $(this).load(function(){ 1277 /* bind events on accessible iframes */ 1278 if(_canAccessIFrame(this)){ 1279 $(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){ 1280 _onTouchstart(e); 1281 _onTouchstart2(e); 1282 }).bind(events[1],function(e){ 1283 _onTouchmove(e); 1284 }).bind(events[2],function(e){ 1285 _onTouchend(e); 1286 }); 1287 } 1288 }); 1289 }); 1290 } 1291 function _onTouchstart(e){ 1292 if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){touchable=0; return;} 1293 touchable=1; touchDrag=0; docDrag=0; draggable=1; 1294 $this.removeClass("mCS_touch_action"); 1295 var offset=mCSB_container.offset(); 1296 dragY=_coordinates(e)[0]-offset.top; 1297 dragX=_coordinates(e)[1]-offset.left; 1298 touchIntent=[_coordinates(e)[0],_coordinates(e)[1]]; 1299 } 1300 function _onTouchmove(e){ 1301 if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){return;} 1302 if(!o.documentTouchScroll){e.preventDefault();} 1303 e.stopImmediatePropagation(); 1304 if(docDrag && !touchDrag){return;} 1305 if(draggable){ 1306 runningTime=_getTime(); 1307 var offset=mCustomScrollBox.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left, 1308 easing="mcsLinearOut"; 1309 touchMoveY.push(y); 1310 touchMoveX.push(x); 1311 touchIntent[2]=Math.abs(_coordinates(e)[0]-touchIntent[0]); touchIntent[3]=Math.abs(_coordinates(e)[1]-touchIntent[1]); 1312 if(d.overflowed[0]){ 1313 var limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(), 1314 prevent=((dragY-y)>0 && (y-dragY)>-(limit*d.scrollRatio.y) && (touchIntent[3]*2<touchIntent[2] || o.axis==="yx")); 1315 } 1316 if(d.overflowed[1]){ 1317 var limitX=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(), 1318 preventX=((dragX-x)>0 && (x-dragX)>-(limitX*d.scrollRatio.x) && (touchIntent[2]*2<touchIntent[3] || o.axis==="yx")); 1319 } 1320 if(prevent || preventX){ /* prevent native document scrolling */ 1321 if(!touchAction){e.preventDefault();} 1322 touchDrag=1; 1323 }else{ 1324 docDrag=1; 1325 $this.addClass("mCS_touch_action"); 1326 } 1327 if(touchAction){e.preventDefault();} 1328 amount=o.axis==="yx" ? [(dragY-y),(dragX-x)] : o.axis==="x" ? [null,(dragX-x)] : [(dragY-y),null]; 1329 mCSB_container[0].idleTimer=250; 1330 if(d.overflowed[0]){_drag(amount[0],durA,easing,"y","all",true);} 1331 if(d.overflowed[1]){_drag(amount[1],durA,easing,"x",overwrite,true);} 1332 } 1333 } 1334 function _onTouchstart2(e){ 1335 if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){touchable=0; return;} 1336 touchable=1; 1337 e.stopImmediatePropagation(); 1338 _stop($this); 1339 startTime=_getTime(); 1340 var offset=mCustomScrollBox.offset(); 1341 touchStartY=_coordinates(e)[0]-offset.top; 1342 touchStartX=_coordinates(e)[1]-offset.left; 1343 touchMoveY=[]; touchMoveX=[]; 1344 } 1345 function _onTouchend(e){ 1346 if(!_pointerTouch(e) || touchActive || _coordinates(e)[2]){return;} 1347 draggable=0; 1348 e.stopImmediatePropagation(); 1349 touchDrag=0; docDrag=0; 1350 endTime=_getTime(); 1351 var offset=mCustomScrollBox.offset(),y=_coordinates(e)[0]-offset.top,x=_coordinates(e)[1]-offset.left; 1352 if((endTime-runningTime)>30){return;} 1353 speed=1000/(endTime-startTime); 1354 var easing="mcsEaseOut",slow=speed<2.5, 1355 diff=slow ? [touchMoveY[touchMoveY.length-2],touchMoveX[touchMoveX.length-2]] : [0,0]; 1356 distance=slow ? [(y-diff[0]),(x-diff[1])] : [y-touchStartY,x-touchStartX]; 1357 var absDistance=[Math.abs(distance[0]),Math.abs(distance[1])]; 1358 speed=slow ? [Math.abs(distance[0]/4),Math.abs(distance[1]/4)] : [speed,speed]; 1359 var a=[ 1360 Math.abs(mCSB_container[0].offsetTop)-(distance[0]*_m((absDistance[0]/speed[0]),speed[0])), 1361 Math.abs(mCSB_container[0].offsetLeft)-(distance[1]*_m((absDistance[1]/speed[1]),speed[1])) 1362 ]; 1363 amount=o.axis==="yx" ? [a[0],a[1]] : o.axis==="x" ? [null,a[1]] : [a[0],null]; 1364 durB=[(absDistance[0]*4)+o.scrollInertia,(absDistance[1]*4)+o.scrollInertia]; 1365 var md=parseInt(o.contentTouchScroll) || 0; /* absolute minimum distance required */ 1366 amount[0]=absDistance[0]>md ? amount[0] : 0; 1367 amount[1]=absDistance[1]>md ? amount[1] : 0; 1368 if(d.overflowed[0]){_drag(amount[0],durB[0],easing,"y",overwrite,false);} 1369 if(d.overflowed[1]){_drag(amount[1],durB[1],easing,"x",overwrite,false);} 1370 } 1371 function _m(ds,s){ 1372 var r=[s*1.5,s*2,s/1.5,s/2]; 1373 if(ds>90){ 1374 return s>4 ? r[0] : r[3]; 1375 }else if(ds>60){ 1376 return s>3 ? r[3] : r[2]; 1377 }else if(ds>30){ 1378 return s>8 ? r[1] : s>6 ? r[0] : s>4 ? s : r[2]; 1379 }else{ 1380 return s>8 ? s : r[3]; 1381 } 1382 } 1383 function _drag(amount,dur,easing,dir,overwrite,drag){ 1384 if(!amount){return;} 1385 _scrollTo($this,amount.toString(),{dur:dur,scrollEasing:easing,dir:dir,overwrite:overwrite,drag:drag}); 1386 } 1387 }, 1388 /* -------------------- */ 1389 1390 1391 /* 1392 SELECT TEXT EVENTS 1393 scrolls content when text is selected 1394 */ 1395 _selectable=function(){ 1396 var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential, 1397 namespace=pluginPfx+"_"+d.idx, 1398 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1399 wrapper=mCSB_container.parent(), 1400 action; 1401 mCSB_container.bind("mousedown."+namespace,function(e){ 1402 if(touchable){return;} 1403 if(!action){action=1; touchActive=true;} 1404 }).add(document).bind("mousemove."+namespace,function(e){ 1405 if(!touchable && action && _sel()){ 1406 var offset=mCSB_container.offset(), 1407 y=_coordinates(e)[0]-offset.top+mCSB_container[0].offsetTop,x=_coordinates(e)[1]-offset.left+mCSB_container[0].offsetLeft; 1408 if(y>0 && y<wrapper.height() && x>0 && x<wrapper.width()){ 1409 if(seq.step){_seq("off",null,"stepped");} 1410 }else{ 1411 if(o.axis!=="x" && d.overflowed[0]){ 1412 if(y<0){ 1413 _seq("on",38); 1414 }else if(y>wrapper.height()){ 1415 _seq("on",40); 1416 } 1417 } 1418 if(o.axis!=="y" && d.overflowed[1]){ 1419 if(x<0){ 1420 _seq("on",37); 1421 }else if(x>wrapper.width()){ 1422 _seq("on",39); 1423 } 1424 } 1425 } 1426 } 1427 }).bind("mouseup."+namespace+" dragend."+namespace,function(e){ 1428 if(touchable){return;} 1429 if(action){action=0; _seq("off",null);} 1430 touchActive=false; 1431 }); 1432 function _sel(){ 1433 return window.getSelection ? window.getSelection().toString() : 1434 document.selection && document.selection.type!="Control" ? document.selection.createRange().text : 0; 1435 } 1436 function _seq(a,c,s){ 1437 seq.type=s && action ? "stepped" : "stepless"; 1438 seq.scrollAmount=10; 1439 _sequentialScroll($this,a,c,"mcsLinearOut",s ? 60 : null); 1440 } 1441 }, 1442 /* -------------------- */ 1443 1444 1445 /* 1446 MOUSE WHEEL EVENT 1447 scrolls content via mouse-wheel 1448 via mouse-wheel plugin (https://github.com/brandonaaron/jquery-mousewheel) 1449 */ 1450 _mousewheel=function(){ 1451 if(!$(this).data(pluginPfx)){return;} /* Check if the scrollbar is ready to use mousewheel events (issue: #185) */ 1452 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1453 namespace=pluginPfx+"_"+d.idx, 1454 mCustomScrollBox=$("#mCSB_"+d.idx), 1455 mCSB_dragger=[$("#mCSB_"+d.idx+"_dragger_vertical"),$("#mCSB_"+d.idx+"_dragger_horizontal")], 1456 iframe=$("#mCSB_"+d.idx+"_container").find("iframe"); 1457 if(iframe.length){ 1458 iframe.each(function(){ 1459 $(this).load(function(){ 1460 /* bind events on accessible iframes */ 1461 if(_canAccessIFrame(this)){ 1462 $(this.contentDocument || this.contentWindow.document).bind("mousewheel."+namespace,function(e,delta){ 1463 _onMousewheel(e,delta); 1464 }); 1465 } 1466 }); 1467 }); 1468 } 1469 mCustomScrollBox.bind("mousewheel."+namespace,function(e,delta){ 1470 _onMousewheel(e,delta); 1471 }); 1472 function _onMousewheel(e,delta){ 1473 _stop($this); 1474 if(_disableMousewheel($this,e.target)){return;} /* disables mouse-wheel when hovering specific elements */ 1475 var deltaFactor=o.mouseWheel.deltaFactor!=="auto" ? parseInt(o.mouseWheel.deltaFactor) : (oldIE && e.deltaFactor<100) ? 100 : e.deltaFactor || 100, 1476 dur=o.scrollInertia; 1477 if(o.axis==="x" || o.mouseWheel.axis==="x"){ 1478 var dir="x", 1479 px=[Math.round(deltaFactor*d.scrollRatio.x),parseInt(o.mouseWheel.scrollAmount)], 1480 amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.width() ? mCustomScrollBox.width()*0.9 : px[0], 1481 contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetLeft), 1482 draggerPos=mCSB_dragger[1][0].offsetLeft, 1483 limit=mCSB_dragger[1].parent().width()-mCSB_dragger[1].width(), 1484 dlt=e.deltaX || e.deltaY || delta; 1485 }else{ 1486 var dir="y", 1487 px=[Math.round(deltaFactor*d.scrollRatio.y),parseInt(o.mouseWheel.scrollAmount)], 1488 amount=o.mouseWheel.scrollAmount!=="auto" ? px[1] : px[0]>=mCustomScrollBox.height() ? mCustomScrollBox.height()*0.9 : px[0], 1489 contentPos=Math.abs($("#mCSB_"+d.idx+"_container")[0].offsetTop), 1490 draggerPos=mCSB_dragger[0][0].offsetTop, 1491 limit=mCSB_dragger[0].parent().height()-mCSB_dragger[0].height(), 1492 dlt=e.deltaY || delta; 1493 } 1494 if((dir==="y" && !d.overflowed[0]) || (dir==="x" && !d.overflowed[1])){return;} 1495 if(o.mouseWheel.invert || e.webkitDirectionInvertedFromDevice){dlt=-dlt;} 1496 if(o.mouseWheel.normalizeDelta){dlt=dlt<0 ? -1 : 1;} 1497 if((dlt>0 && draggerPos!==0) || (dlt<0 && draggerPos!==limit) || o.mouseWheel.preventDefault){ 1498 e.stopImmediatePropagation(); 1499 e.preventDefault(); 1500 } 1501 if(e.deltaFactor<2 && !o.mouseWheel.normalizeDelta){ 1502 //very low deltaFactor values mean some kind of delta acceleration (e.g. osx trackpad), so adjusting scrolling accordingly 1503 amount=e.deltaFactor; dur=17; 1504 } 1505 _scrollTo($this,(contentPos-(dlt*amount)).toString(),{dir:dir,dur:dur}); 1506 } 1507 }, 1508 /* -------------------- */ 1509 1510 1511 /* checks if iframe can be accessed */ 1512 _canAccessIFrame=function(iframe){ 1513 var html=null; 1514 if(!iframe){ 1515 try{ 1516 var doc=top.document; 1517 html=doc.body.innerHTML; 1518 }catch(err){/* do nothing */} 1519 return(html!==null); 1520 }else{ 1521 try{ 1522 var doc=iframe.contentDocument || iframe.contentWindow.document; 1523 html=doc.body.innerHTML; 1524 }catch(err){/* do nothing */} 1525 return(html!==null); 1526 } 1527 }, 1528 /* -------------------- */ 1529 1530 1531 /* disables mouse-wheel when hovering specific elements like select, datalist etc. */ 1532 _disableMousewheel=function(el,target){ 1533 var tag=target.nodeName.toLowerCase(), 1534 tags=el.data(pluginPfx).opt.mouseWheel.disableOver, 1535 /* elements that require focus */ 1536 focusTags=["select","textarea"]; 1537 return $.inArray(tag,tags) > -1 && !($.inArray(tag,focusTags) > -1 && !$(target).is(":focus")); 1538 }, 1539 /* -------------------- */ 1540 1541 1542 /* 1543 DRAGGER RAIL CLICK EVENT 1544 scrolls content via dragger rail 1545 */ 1546 _draggerRail=function(){ 1547 var $this=$(this),d=$this.data(pluginPfx), 1548 namespace=pluginPfx+"_"+d.idx, 1549 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1550 wrapper=mCSB_container.parent(), 1551 mCSB_draggerContainer=$(".mCSB_"+d.idx+"_scrollbar ."+classes[12]), 1552 clickable; 1553 mCSB_draggerContainer.bind("mousedown."+namespace+" touchstart."+namespace+" pointerdown."+namespace+" MSPointerDown."+namespace,function(e){ 1554 touchActive=true; 1555 if(!$(e.target).hasClass("mCSB_dragger")){clickable=1;} 1556 }).bind("touchend."+namespace+" pointerup."+namespace+" MSPointerUp."+namespace,function(e){ 1557 touchActive=false; 1558 }).bind("click."+namespace,function(e){ 1559 if(!clickable){return;} 1560 clickable=0; 1561 if($(e.target).hasClass(classes[12]) || $(e.target).hasClass("mCSB_draggerRail")){ 1562 _stop($this); 1563 var el=$(this),mCSB_dragger=el.find(".mCSB_dragger"); 1564 if(el.parent(".mCSB_scrollTools_horizontal").length>0){ 1565 if(!d.overflowed[1]){return;} 1566 var dir="x", 1567 clickDir=e.pageX>mCSB_dragger.offset().left ? -1 : 1, 1568 to=Math.abs(mCSB_container[0].offsetLeft)-(clickDir*(wrapper.width()*0.9)); 1569 }else{ 1570 if(!d.overflowed[0]){return;} 1571 var dir="y", 1572 clickDir=e.pageY>mCSB_dragger.offset().top ? -1 : 1, 1573 to=Math.abs(mCSB_container[0].offsetTop)-(clickDir*(wrapper.height()*0.9)); 1574 } 1575 _scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"}); 1576 } 1577 }); 1578 }, 1579 /* -------------------- */ 1580 1581 1582 /* 1583 FOCUS EVENT 1584 scrolls content via element focus (e.g. clicking an input, pressing TAB key etc.) 1585 */ 1586 _focus=function(){ 1587 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1588 namespace=pluginPfx+"_"+d.idx, 1589 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1590 wrapper=mCSB_container.parent(); 1591 mCSB_container.bind("focusin."+namespace,function(e){ 1592 var el=$(document.activeElement), 1593 nested=mCSB_container.find(".mCustomScrollBox").length, 1594 dur=0; 1595 if(!el.is(o.advanced.autoScrollOnFocus)){return;} 1596 _stop($this); 1597 clearTimeout($this[0]._focusTimeout); 1598 $this[0]._focusTimer=nested ? (dur+17)*nested : 0; 1599 $this[0]._focusTimeout=setTimeout(function(){ 1600 var to=[_childPos(el)[0],_childPos(el)[1]], 1601 contentPos=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft], 1602 isVisible=[ 1603 (contentPos[0]+to[0]>=0 && contentPos[0]+to[0]<wrapper.height()-el.outerHeight(false)), 1604 (contentPos[1]+to[1]>=0 && contentPos[0]+to[1]<wrapper.width()-el.outerWidth(false)) 1605 ], 1606 overwrite=(o.axis==="yx" && !isVisible[0] && !isVisible[1]) ? "none" : "all"; 1607 if(o.axis!=="x" && !isVisible[0]){ 1608 _scrollTo($this,to[0].toString(),{dir:"y",scrollEasing:"mcsEaseInOut",overwrite:overwrite,dur:dur}); 1609 } 1610 if(o.axis!=="y" && !isVisible[1]){ 1611 _scrollTo($this,to[1].toString(),{dir:"x",scrollEasing:"mcsEaseInOut",overwrite:overwrite,dur:dur}); 1612 } 1613 },$this[0]._focusTimer); 1614 }); 1615 }, 1616 /* -------------------- */ 1617 1618 1619 /* sets content wrapper scrollTop/scrollLeft always to 0 */ 1620 _wrapperScroll=function(){ 1621 var $this=$(this),d=$this.data(pluginPfx), 1622 namespace=pluginPfx+"_"+d.idx, 1623 wrapper=$("#mCSB_"+d.idx+"_container").parent(); 1624 wrapper.bind("scroll."+namespace,function(e){ 1625 if(wrapper.scrollTop()!==0 || wrapper.scrollLeft()!==0){ 1626 $(".mCSB_"+d.idx+"_scrollbar").css("visibility","hidden"); /* hide scrollbar(s) */ 1627 } 1628 }); 1629 }, 1630 /* -------------------- */ 1631 1632 1633 /* 1634 BUTTONS EVENTS 1635 scrolls content via up, down, left and right buttons 1636 */ 1637 _buttons=function(){ 1638 var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential, 1639 namespace=pluginPfx+"_"+d.idx, 1640 sel=".mCSB_"+d.idx+"_scrollbar", 1641 btn=$(sel+">a"); 1642 btn.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){ 1643 e.preventDefault(); 1644 if(!_mouseBtnLeft(e)){return;} /* left mouse button only */ 1645 var btnClass=$(this).attr("class"); 1646 seq.type=o.scrollButtons.scrollType; 1647 switch(e.type){ 1648 case "mousedown": case "touchstart": case "pointerdown": case "MSPointerDown": 1649 if(seq.type==="stepped"){return;} 1650 touchActive=true; 1651 d.tweenRunning=false; 1652 _seq("on",btnClass); 1653 break; 1654 case "mouseup": case "touchend": case "pointerup": case "MSPointerUp": 1655 case "mouseout": case "pointerout": case "MSPointerOut": 1656 if(seq.type==="stepped"){return;} 1657 touchActive=false; 1658 1659 1660 if(seq.dir){_seq("off",btnClass);} 1661 break; 1662 case "click": 1663 if(seq.type!=="stepped" || d.tweenRunning){return;} 1664 _seq("on",btnClass); 1665 break; 1666 } 1667 function _seq(a,c){ 1668 seq.scrollAmount=o.scrollButtons.scrollAmount; 1669 _sequentialScroll($this,a,c); 1670 } 1671 }); 1672 }, 1673 /* -------------------- */ 1674 1675 1676 /* 1677 KEYBOARD EVENTS 1678 scrolls content via keyboard 1679 Keys: up arrow, down arrow, left arrow, right arrow, PgUp, PgDn, Home, End 1680 */ 1681 _keyboard=function(){ 1682 var $this=$(this),d=$this.data(pluginPfx),o=d.opt,seq=d.sequential, 1683 namespace=pluginPfx+"_"+d.idx, 1684 mCustomScrollBox=$("#mCSB_"+d.idx), 1685 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1686 wrapper=mCSB_container.parent(), 1687 editables="input,textarea,select,datalist,keygen,[contenteditable='true']", 1688 iframe=mCSB_container.find("iframe"), 1689 events=["blur."+namespace+" keydown."+namespace+" keyup."+namespace]; 1690 if(iframe.length){ 1691 iframe.each(function(){ 1692 $(this).load(function(){ 1693 /* bind events on accessible iframes */ 1694 if(_canAccessIFrame(this)){ 1695 $(this.contentDocument || this.contentWindow.document).bind(events[0],function(e){ 1696 _onKeyboard(e); 1697 }); 1698 } 1699 }); 1700 }); 1701 } 1702 mCustomScrollBox.attr("tabindex","0").bind(events[0],function(e){ 1703 _onKeyboard(e); 1704 }); 1705 function _onKeyboard(e){ 1706 switch(e.type){ 1707 case "blur": 1708 if(d.tweenRunning && seq.dir){_seq("off",null);} 1709 break; 1710 case "keydown": case "keyup": 1711 var code=e.keyCode ? e.keyCode : e.which,action="on"; 1712 if((o.axis!=="x" && (code===38 || code===40)) || (o.axis!=="y" && (code===37 || code===39))){ 1713 /* up (38), down (40), left (37), right (39) arrows */ 1714 if(((code===38 || code===40) && !d.overflowed[0]) || ((code===37 || code===39) && !d.overflowed[1])){return;} 1715 if(e.type==="keyup"){action="off";} 1716 if(!$(document.activeElement).is(editables)){ 1717 e.preventDefault(); 1718 e.stopImmediatePropagation(); 1719 _seq(action,code); 1720 } 1721 }else if(code===33 || code===34){ 1722 /* PgUp (33), PgDn (34) */ 1723 if(d.overflowed[0] || d.overflowed[1]){ 1724 e.preventDefault(); 1725 e.stopImmediatePropagation(); 1726 } 1727 if(e.type==="keyup"){ 1728 _stop($this); 1729 var keyboardDir=code===34 ? -1 : 1; 1730 if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){ 1731 var dir="x",to=Math.abs(mCSB_container[0].offsetLeft)-(keyboardDir*(wrapper.width()*0.9)); 1732 }else{ 1733 var dir="y",to=Math.abs(mCSB_container[0].offsetTop)-(keyboardDir*(wrapper.height()*0.9)); 1734 } 1735 _scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"}); 1736 } 1737 }else if(code===35 || code===36){ 1738 /* End (35), Home (36) */ 1739 if(!$(document.activeElement).is(editables)){ 1740 if(d.overflowed[0] || d.overflowed[1]){ 1741 e.preventDefault(); 1742 e.stopImmediatePropagation(); 1743 } 1744 if(e.type==="keyup"){ 1745 if(o.axis==="x" || (o.axis==="yx" && d.overflowed[1] && !d.overflowed[0])){ 1746 var dir="x",to=code===35 ? Math.abs(wrapper.width()-mCSB_container.outerWidth(false)) : 0; 1747 }else{ 1748 var dir="y",to=code===35 ? Math.abs(wrapper.height()-mCSB_container.outerHeight(false)) : 0; 1749 } 1750 _scrollTo($this,to.toString(),{dir:dir,scrollEasing:"mcsEaseInOut"}); 1751 } 1752 } 1753 } 1754 break; 1755 } 1756 function _seq(a,c){ 1757 seq.type=o.keyboard.scrollType; 1758 seq.scrollAmount=o.keyboard.scrollAmount; 1759 if(seq.type==="stepped" && d.tweenRunning){return;} 1760 _sequentialScroll($this,a,c); 1761 } 1762 } 1763 }, 1764 /* -------------------- */ 1765 1766 1767 /* scrolls content sequentially (used when scrolling via buttons, keyboard arrows etc.) */ 1768 _sequentialScroll=function(el,action,trigger,e,s){ 1769 var d=el.data(pluginPfx),o=d.opt,seq=d.sequential, 1770 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1771 once=seq.type==="stepped" ? true : false, 1772 steplessSpeed=o.scrollInertia < 26 ? 26 : o.scrollInertia, /* 26/1.5=17 */ 1773 steppedSpeed=o.scrollInertia < 1 ? 17 : o.scrollInertia; 1774 switch(action){ 1775 case "on": 1776 seq.dir=[ 1777 (trigger===classes[16] || trigger===classes[15] || trigger===39 || trigger===37 ? "x" : "y"), 1778 (trigger===classes[13] || trigger===classes[15] || trigger===38 || trigger===37 ? -1 : 1) 1779 ]; 1780 _stop(el); 1781 if(_isNumeric(trigger) && seq.type==="stepped"){return;} 1782 _on(once); 1783 break; 1784 case "off": 1785 _off(); 1786 if(once || (d.tweenRunning && seq.dir)){ 1787 _on(true); 1788 } 1789 break; 1790 } 1791 1792 /* starts sequence */ 1793 function _on(once){ 1794 if(o.snapAmount){seq.scrollAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : seq.dir[0]==="x" ? o.snapAmount[1] : o.snapAmount[0];} /* scrolling snapping */ 1795 var c=seq.type!=="stepped", /* continuous scrolling */ 1796 t=s ? s : !once ? 1000/60 : c ? steplessSpeed/1.5 : steppedSpeed, /* timer */ 1797 m=!once ? 2.5 : c ? 7.5 : 40, /* multiplier */ 1798 contentPos=[Math.abs(mCSB_container[0].offsetTop),Math.abs(mCSB_container[0].offsetLeft)], 1799 ratio=[d.scrollRatio.y>10 ? 10 : d.scrollRatio.y,d.scrollRatio.x>10 ? 10 : d.scrollRatio.x], 1800 amount=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*(ratio[1]*m)) : contentPos[0]+(seq.dir[1]*(ratio[0]*m)), 1801 px=seq.dir[0]==="x" ? contentPos[1]+(seq.dir[1]*parseInt(seq.scrollAmount)) : contentPos[0]+(seq.dir[1]*parseInt(seq.scrollAmount)), 1802 to=seq.scrollAmount!=="auto" ? px : amount, 1803 easing=e ? e : !once ? "mcsLinear" : c ? "mcsLinearOut" : "mcsEaseInOut", 1804 onComplete=!once ? false : true; 1805 if(once && t<17){ 1806 to=seq.dir[0]==="x" ? contentPos[1] : contentPos[0]; 1807 } 1808 _scrollTo(el,to.toString(),{dir:seq.dir[0],scrollEasing:easing,dur:t,onComplete:onComplete}); 1809 if(once){ 1810 seq.dir=false; 1811 return; 1812 } 1813 clearTimeout(seq.step); 1814 seq.step=setTimeout(function(){ 1815 _on(); 1816 },t); 1817 } 1818 /* stops sequence */ 1819 function _off(){ 1820 clearTimeout(seq.step); 1821 _delete(seq,"step"); 1822 _stop(el); 1823 } 1824 }, 1825 /* -------------------- */ 1826 1827 1828 /* returns a yx array from value */ 1829 _arr=function(val){ 1830 var o=$(this).data(pluginPfx).opt,vals=[]; 1831 if(typeof val==="function"){val=val();} /* check if the value is a single anonymous function */ 1832 /* check if value is object or array, its length and create an array with yx values */ 1833 if(!(val instanceof Array)){ /* object value (e.g. {y:"100",x:"100"}, 100 etc.) */ 1834 vals[0]=val.y ? val.y : val.x || o.axis==="x" ? null : val; 1835 vals[1]=val.x ? val.x : val.y || o.axis==="y" ? null : val; 1836 }else{ /* array value (e.g. [100,100]) */ 1837 vals=val.length>1 ? [val[0],val[1]] : o.axis==="x" ? [null,val[0]] : [val[0],null]; 1838 } 1839 /* check if array values are anonymous functions */ 1840 if(typeof vals[0]==="function"){vals[0]=vals[0]();} 1841 if(typeof vals[1]==="function"){vals[1]=vals[1]();} 1842 return vals; 1843 }, 1844 /* -------------------- */ 1845 1846 1847 /* translates values (e.g. "top", 100, "100px", "#id") to actual scroll-to positions */ 1848 _to=function(val,dir){ 1849 if(val==null || typeof val=="undefined"){return;} 1850 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1851 mCSB_container=$("#mCSB_"+d.idx+"_container"), 1852 wrapper=mCSB_container.parent(), 1853 t=typeof val; 1854 if(!dir){dir=o.axis==="x" ? "x" : "y";} 1855 var contentLength=dir==="x" ? mCSB_container.outerWidth(false) : mCSB_container.outerHeight(false
vendor: 18,880 bytes, lines 1855-2399
1855), 1856 contentPos=dir==="x" ? mCSB_container[0].offsetLeft : mCSB_container[0].offsetTop, 1857 cssProp=dir==="x" ? "left" : "top"; 1858 switch(t){ 1859 case "function": /* this currently is not used. Consider removing it */ 1860 return val(); 1861 break; 1862 case "object": /* js/jquery object */ 1863 var obj=val.jquery ? val : $(val); 1864 if(!obj.length){return;} 1865 return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0]; 1866 break; 1867 case "string": case "number": 1868 if(_isNumeric(val)){ /* numeric value */ 1869 return Math.abs(val); 1870 }else if(val.indexOf("%")!==-1){ /* percentage value */ 1871 return Math.abs(contentLength*parseInt(val)/100); 1872 }else if(val.indexOf("-=")!==-1){ /* decrease value */ 1873 return Math.abs(contentPos-parseInt(val.split("-=")[1])); 1874 }else if(val.indexOf("+=")!==-1){ /* inrease value */ 1875 var p=(contentPos+parseInt(val.split("+=")[1])); 1876 return p>=0 ? 0 : Math.abs(p); 1877 }else if(val.indexOf("px")!==-1 && _isNumeric(val.split("px")[0])){ /* pixels string value (e.g. "100px") */ 1878 return Math.abs(val.split("px")[0]); 1879 }else{ 1880 if(val==="top" || val==="left"){ /* special strings */ 1881 return 0; 1882 }else if(val==="bottom"){ 1883 return Math.abs(wrapper.height()-mCSB_container.outerHeight(false)); 1884 }else if(val==="right"){ 1885 return Math.abs(wrapper.width()-mCSB_container.outerWidth(false)); 1886 }else if(val==="first" || val==="last"){ 1887 var obj=mCSB_container.find(":"+val); 1888 return dir==="x" ? _childPos(obj)[1] : _childPos(obj)[0]; 1889 }else{ 1890 if($(val).length){ /* jquery selector */ 1891 return dir==="x" ? _childPos($(val))[1] : _childPos($(val))[0]; 1892 }else{ /* other values (e.g. "100em") */ 1893 mCSB_container.css(cssProp,val); 1894 methods.update.call(null,$this[0]); 1895 return; 1896 } 1897 } 1898 } 1899 break; 1900 } 1901 }, 1902 /* -------------------- */ 1903 1904 1905 /* calls the update method automatically */ 1906 _autoUpdate=function(rem){ 1907 var $this=$(this),d=$this.data(pluginPfx),o=d.opt, 1908 mCSB_container=$("#mCSB_"+d.idx+"_container"); 1909 if(rem){ 1910 /* 1911 removes autoUpdate timer 1912 usage: _autoUpdate.call(this,"remove"); 1913 */ 1914 clearTimeout(mCSB_container[0].autoUpdate); 1915 _delete(mCSB_container[0],"autoUpdate"); 1916 return; 1917 } 1918 upd(); 1919 function upd(){ 1920 clearTimeout(mCSB_container[0].autoUpdate); 1921 if($this.parents("html").length===0){ 1922 /* check element in dom tree */ 1923 $this=null; 1924 return; 1925 } 1926 mCSB_container[0].autoUpdate=setTimeout(function(){ 1927 /* update on specific selector(s) length and size change */ 1928 if(o.advanced.updateOnSelectorChange){ 1929 d.poll.change.n=sizesSum(); 1930 if(d.poll.change.n!==d.poll.change.o){ 1931 d.poll.change.o=d.poll.change.n; 1932 doUpd(3); 1933 return; 1934 } 1935 } 1936 /* update on main element and scrollbar size changes */ 1937 if(o.advanced.updateOnContentResize){ 1938 d.poll.size.n=$this[0].scrollHeight+$this[0].scrollWidth+mCSB_container[0].offsetHeight+$this[0].offsetHeight+$this[0].offsetWidth; 1939 if(d.poll.size.n!==d.poll.size.o){ 1940 d.poll.size.o=d.poll.size.n; 1941 doUpd(1); 1942 return; 1943 } 1944 } 1945 /* update on image load */ 1946 if(o.advanced.updateOnImageLoad){ 1947 if(!(o.advanced.updateOnImageLoad==="auto" && o.axis==="y")){ //by default, it doesn't run on vertical content 1948 d.poll.img.n=mCSB_container.find("img").length; 1949 if(d.poll.img.n!==d.poll.img.o){ 1950 d.poll.img.o=d.poll.img.n; 1951 mCSB_container.find("img").each(function(){ 1952 imgLoader(this); 1953 }); 1954 return; 1955 } 1956 } 1957 } 1958 if(o.advanced.updateOnSelectorChange || o.advanced.updateOnContentResize || o.advanced.updateOnImageLoad){upd();} 1959 },o.advanced.autoUpdateTimeout); 1960 } 1961 /* a tiny image loader */ 1962 function imgLoader(el){ 1963 if($(el).hasClass(classes[2])){doUpd(); return;} 1964 var img=new Image(); 1965 function createDelegate(contextObject,delegateMethod){ 1966 return function(){return delegateMethod.apply(contextObject,arguments);} 1967 } 1968 function imgOnLoad(){ 1969 this.onload=null; 1970 $(el).addClass(classes[2]); 1971 doUpd(2); 1972 } 1973 img.onload=createDelegate(img,imgOnLoad); 1974 img.src=el.src; 1975 } 1976 /* returns the total height and width sum of all elements matching the selector */ 1977 function sizesSum(){ 1978 if(o.advanced.updateOnSelectorChange===true){o.advanced.updateOnSelectorChange="*";} 1979 var total=0,sel=mCSB_container.find(o.advanced.updateOnSelectorChange); 1980 if(o.advanced.updateOnSelectorChange && sel.length>0){sel.each(function(){total+=this.offsetHeight+this.offsetWidth;});} 1981 return total; 1982 } 1983 /* calls the update method */ 1984 function doUpd(cb){ 1985 clearTimeout(mCSB_container[0].autoUpdate); 1986 methods.update.call(null,$this[0],cb); 1987 } 1988 }, 1989 /* -------------------- */ 1990 1991 1992 /* snaps scrolling to a multiple of a pixels number */ 1993 _snapAmount=function(to,amount,offset){ 1994 return (Math.round(to/amount)*amount-offset); 1995 }, 1996 /* -------------------- */ 1997 1998 1999 /* stops content and scrollbar animations */ 2000 _stop=function(el){ 2001 var d=el.data(pluginPfx), 2002 sel=$("#mCSB_"+d.idx+"_container,#mCSB_"+d.idx+"_container_wrapper,#mCSB_"+d.idx+"_dragger_vertical,#mCSB_"+d.idx+"_dragger_horizontal"); 2003 sel.each(function(){ 2004 _stopTween.call(this); 2005 }); 2006 }, 2007 /* -------------------- */ 2008 2009 2010 /* 2011 ANIMATES CONTENT 2012 This is where the actual scrolling happens 2013 */ 2014 _scrollTo=function(el,to,options){ 2015 var d=el.data(pluginPfx),o=d.opt, 2016 defaults={ 2017 trigger:"internal", 2018 dir:"y", 2019 scrollEasing:"mcsEaseOut", 2020 drag:false, 2021 dur:o.scrollInertia, 2022 overwrite:"all", 2023 callbacks:true, 2024 onStart:true, 2025 onUpdate:true, 2026 onComplete:true 2027 }, 2028 options=$.extend(defaults,options), 2029 dur=[options.dur,(options.drag ? 0 : options.dur)], 2030 mCustomScrollBox=$("#mCSB_"+d.idx), 2031 mCSB_container=$("#mCSB_"+d.idx+"_container"), 2032 wrapper=mCSB_container.parent(), 2033 totalScrollOffsets=o.callbacks.onTotalScrollOffset ? _arr.call(el,o.callbacks.onTotalScrollOffset) : [0,0], 2034 totalScrollBackOffsets=o.callbacks.onTotalScrollBackOffset ? _arr.call(el,o.callbacks.onTotalScrollBackOffset) : [0,0]; 2035 d.trigger=options.trigger; 2036 if(wrapper.scrollTop()!==0 || wrapper.scrollLeft()!==0){ /* always reset scrollTop/Left */ 2037 $(".mCSB_"+d.idx+"_scrollbar").css("visibility","visible"); 2038 wrapper.scrollTop(0).scrollLeft(0); 2039 } 2040 if(to==="_resetY" && !d.contentReset.y){ 2041 /* callbacks: onOverflowYNone */ 2042 if(_cb("onOverflowYNone")){o.callbacks.onOverflowYNone.call(el[0]);} 2043 d.contentReset.y=1; 2044 } 2045 if(to==="_resetX" && !d.contentReset.x){ 2046 /* callbacks: onOverflowXNone */ 2047 if(_cb("onOverflowXNone")){o.callbacks.onOverflowXNone.call(el[0]);} 2048 d.contentReset.x=1; 2049 } 2050 if(to==="_resetY" || to==="_resetX"){return;} 2051 if((d.contentReset.y || !el[0].mcs) && d.overflowed[0]){ 2052 /* callbacks: onOverflowY */ 2053 if(_cb("onOverflowY")){o.callbacks.onOverflowY.call(el[0]);} 2054 d.contentReset.x=null; 2055 } 2056 if((d.contentReset.x || !el[0].mcs) && d.overflowed[1]){ 2057 /* callbacks: onOverflowX */ 2058 if(_cb("onOverflowX")){o.callbacks.onOverflowX.call(el[0]);} 2059 d.contentReset.x=null; 2060 } 2061 if(o.snapAmount){ /* scrolling snapping */ 2062 var snapAmount=!(o.snapAmount instanceof Array) ? o.snapAmount : options.dir==="x" ? o.snapAmount[1] : o.snapAmount[0]; 2063 to=_snapAmount(to,snapAmount,o.snapOffset); 2064 } 2065 switch(options.dir){ 2066 case "x": 2067 var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_horizontal"), 2068 property="left", 2069 contentPos=mCSB_container[0].offsetLeft, 2070 limit=[ 2071 mCustomScrollBox.width()-mCSB_container.outerWidth(false), 2072 mCSB_dragger.parent().width()-mCSB_dragger.width() 2073 ], 2074 scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.x)], 2075 tso=totalScrollOffsets[1], 2076 tsbo=totalScrollBackOffsets[1], 2077 totalScrollOffset=tso>0 ? tso/d.scrollRatio.x : 0, 2078 totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.x : 0; 2079 break; 2080 case "y": 2081 var mCSB_dragger=$("#mCSB_"+d.idx+"_dragger_vertical"), 2082 property="top", 2083 contentPos=mCSB_container[0].offsetTop, 2084 limit=[ 2085 mCustomScrollBox.height()-mCSB_container.outerHeight(false), 2086 mCSB_dragger.parent().height()-mCSB_dragger.height() 2087 ], 2088 scrollTo=[to,to===0 ? 0 : (to/d.scrollRatio.y)], 2089 tso=totalScrollOffsets[0], 2090 tsbo=totalScrollBackOffsets[0], 2091 totalScrollOffset=tso>0 ? tso/d.scrollRatio.y : 0, 2092 totalScrollBackOffset=tsbo>0 ? tsbo/d.scrollRatio.y : 0; 2093 break; 2094 } 2095 if(scrollTo[1]<0 || (scrollTo[0]===0 && scrollTo[1]===0)){ 2096 scrollTo=[0,0]; 2097 }else if(scrollTo[1]>=limit[1]){ 2098 scrollTo=[limit[0],limit[1]]; 2099 }else{ 2100 scrollTo[0]=-scrollTo[0]; 2101 } 2102 if(!el[0].mcs){ 2103 _mcs(); /* init mcs object (once) to make it available before callbacks */ 2104 if(_cb("onInit")){o.callbacks.onInit.call(el[0]);} /* callbacks: onInit */ 2105 } 2106 clearTimeout(mCSB_container[0].onCompleteTimeout); 2107 _tweenTo(mCSB_dragger[0],property,Math.round(scrollTo[1]),dur[1],options.scrollEasing); 2108 if(!d.tweenRunning && ((contentPos===0 && scrollTo[0]>=0) || (contentPos===limit[0] && scrollTo[0]<=limit[0]))){return;} 2109 _tweenTo(mCSB_container[0],property,Math.round(scrollTo[0]),dur[0],options.scrollEasing,options.overwrite,{ 2110 onStart:function(){ 2111 if(options.callbacks && options.onStart && !d.tweenRunning){ 2112 /* callbacks: onScrollStart */ 2113 if(_cb("onScrollStart")){_mcs(); o.callbacks.onScrollStart.call(el[0]);} 2114 d.tweenRunning=true; 2115 _onDragClasses(mCSB_dragger); 2116 d.cbOffsets=_cbOffsets(); 2117 } 2118 },onUpdate:function(){ 2119 if(options.callbacks && options.onUpdate){ 2120 /* callbacks: whileScrolling */ 2121 if(_cb("whileScrolling")){_mcs(); o.callbacks.whileScrolling.call(el[0]);} 2122 } 2123 },onComplete:function(){ 2124 if(options.callbacks && options.onComplete){ 2125 if(o.axis==="yx"){clearTimeout(mCSB_container[0].onCompleteTimeout);} 2126 var t=mCSB_container[0].idleTimer || 0; 2127 mCSB_container[0].onCompleteTimeout=setTimeout(function(){ 2128 /* callbacks: onScroll, onTotalScroll, onTotalScrollBack */ 2129 if(_cb("onScroll")){_mcs(); o.callbacks.onScroll.call(el[0]);} 2130 if(_cb("onTotalScroll") && scrollTo[1]>=limit[1]-totalScrollOffset && d.cbOffsets[0]){_mcs(); o.callbacks.onTotalScroll.call(el[0]);} 2131 if(_cb("onTotalScrollBack") && scrollTo[1]<=totalScrollBackOffset && d.cbOffsets[1]){_mcs(); o.callbacks.onTotalScrollBack.call(el[0]);} 2132 d.tweenRunning=false; 2133 mCSB_container[0].idleTimer=0; 2134 _onDragClasses(mCSB_dragger,"hide"); 2135 },t); 2136 } 2137 } 2138 }); 2139 /* checks if callback function exists */ 2140 function _cb(cb){ 2141 return d && o.callbacks[cb] && typeof o.callbacks[cb]==="function"; 2142 } 2143 /* checks whether callback offsets always trigger */ 2144 function _cbOffsets(){ 2145 return [o.callbacks.alwaysTriggerOffsets || contentPos>=limit[0]+tso,o.callbacks.alwaysTriggerOffsets || contentPos<=-tsbo]; 2146 } 2147 /* 2148 populates object with useful values for the user 2149 values: 2150 content: this.mcs.content 2151 content top position: this.mcs.top 2152 content left position: this.mcs.left 2153 dragger top position: this.mcs.draggerTop 2154 dragger left position: this.mcs.draggerLeft 2155 scrolling y percentage: this.mcs.topPct 2156 scrolling x percentage: this.mcs.leftPct 2157 scrolling direction: this.mcs.direction 2158 */ 2159 function _mcs(){ 2160 var cp=[mCSB_container[0].offsetTop,mCSB_container[0].offsetLeft], /* content position */ 2161 dp=[mCSB_dragger[0].offsetTop,mCSB_dragger[0].offsetLeft], /* dragger position */ 2162 cl=[mCSB_container.outerHeight(false),mCSB_container.outerWidth(false)], /* content length */ 2163 pl=[mCustomScrollBox.height(),mCustomScrollBox.width()]; /* content parent length */ 2164 el[0].mcs={ 2165 content:mCSB_container, /* original content wrapper as jquery object */ 2166 top:cp[0],left:cp[1],draggerTop:dp[0],draggerLeft:dp[1], 2167 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])), 2168 direction:options.dir 2169 }; 2170 /* 2171 this refers to the original element containing the scrollbar(s) 2172 usage: this.mcs.top, this.mcs.leftPct etc. 2173 */ 2174 } 2175 }, 2176 /* -------------------- */ 2177 2178 2179 /* 2180 CUSTOM JAVASCRIPT ANIMATION TWEEN 2181 Lighter and faster than jquery animate() and css transitions 2182 Animates top/left properties and includes easings 2183 */ 2184 _tweenTo=function(el,prop,to,duration,easing,overwrite,callbacks){ 2185 if(!el._mTween){el._mTween={top:{},left:{}};} 2186 var callbacks=callbacks || {}, 2187 onStart=callbacks.onStart || function(){},onUpdate=callbacks.onUpdate || function(){},onComplete=callbacks.onComplete || function(){}, 2188 startTime=_getTime(),_delay,progress=0,from=el.offsetTop,elStyle=el.style,_request,tobj=el._mTween[prop]; 2189 if(prop==="left"){from=el.offsetLeft;} 2190 var diff=to-from; 2191 tobj.stop=0; 2192 if(overwrite!=="none"){_cancelTween();} 2193 _startTween(); 2194 function _step(){ 2195 if(tobj.stop){return;} 2196 if(!progress){onStart.call();} 2197 progress=_getTime()-startTime; 2198 _tween(); 2199 if(progress>=tobj.time){ 2200 tobj.time=(progress>tobj.time) ? progress+_delay-(progress-tobj.time) : progress+_delay-1; 2201 if(tobj.time<progress+1){tobj.time=progress+1;} 2202 } 2203 if(tobj.time<duration){tobj.id=_request(_step);}else{onComplete.call();} 2204 } 2205 function _tween(){ 2206 if(duration>0){ 2207 tobj.currVal=_ease(tobj.time,from,diff,duration,easing); 2208 elStyle[prop]=Math.round(tobj.currVal)+"px"; 2209 }else{ 2210 elStyle[prop]=to+"px"; 2211 } 2212 onUpdate.call(); 2213 } 2214 function _startTween(){ 2215 _delay=1000/60; 2216 tobj.time=progress+_delay; 2217 _request=(!window.requestAnimationFrame) ? function(f){_tween(); return setTimeout(f,0.01);} : window.requestAnimationFrame; 2218 tobj.id=_request(_step); 2219 } 2220 function _cancelTween(){ 2221 if(tobj.id==null){return;} 2222 if(!window.requestAnimationFrame){clearTimeout(tobj.id); 2223 }else{window.cancelAnimationFrame(tobj.id);} 2224 tobj.id=null; 2225 } 2226 function _ease(t,b,c,d,type){ 2227 switch(type){ 2228 case "linear": case "mcsLinear": 2229 return c*t/d + b; 2230 break; 2231 case "mcsLinearOut": 2232 t/=d; t--; return c * Math.sqrt(1 - t*t) + b; 2233 break; 2234 case "easeInOutSmooth": 2235 t/=d/2; 2236 if(t<1) return c/2*t*t + b; 2237 t--; 2238 return -c/2 * (t*(t-2) - 1) + b; 2239 break; 2240 case "easeInOutStrong": 2241 t/=d/2; 2242 if(t<1) return c/2 * Math.pow( 2, 10 * (t - 1) ) + b; 2243 t--; 2244 return c/2 * ( -Math.pow( 2, -10 * t) + 2 ) + b; 2245 break; 2246 case "easeInOut": case "mcsEaseInOut": 2247 t/=d/2; 2248 if(t<1) return c/2*t*t*t + b; 2249 t-=2; 2250 return c/2*(t*t*t + 2) + b; 2251 break; 2252 case "easeOutSmooth": 2253 t/=d; t--; 2254 return -c * (t*t*t*t - 1) + b; 2255 break; 2256 case "easeOutStrong": 2257 return c * ( -Math.pow( 2, -10 * t/d ) + 1 ) + b; 2258 break; 2259 case "easeOut": case "mcsEaseOut": default: 2260 var ts=(t/=d)*t,tc=ts*t; 2261 return b+c*(0.499999999999997*tc*ts + -2.5*ts*ts + 5.5*tc + -6.5*ts + 4*t); 2262 } 2263 } 2264 }, 2265 /* -------------------- */ 2266 2267 2268 /* returns current time */ 2269 _getTime=function(){ 2270 if(window.performance && window.performance.now){ 2271 return window.performance.now(); 2272 }else{ 2273 if(window.performance && window.performance.webkitNow){ 2274 return window.performance.webkitNow(); 2275 }else{ 2276 if(Date.now){return Date.now();}else{return new Date().getTime();} 2277 } 2278 } 2279 }, 2280 /* -------------------- */ 2281 2282 2283 /* stops a tween */ 2284 _stopTween=function(){ 2285 var el=this; 2286 if(!el._mTween){el._mTween={top:{},left:{}};} 2287 var props=["top","left"]; 2288 for(var i=0; i<props.length; i++){ 2289 var prop=props[i]; 2290 if(el._mTween[prop].id){ 2291 if(!window.requestAnimationFrame){clearTimeout(el._mTween[prop].id); 2292 }else{window.cancelAnimationFrame(el._mTween[prop].id);} 2293 el._mTween[prop].id=null; 2294 el._mTween[prop].stop=1; 2295 } 2296 } 2297 }, 2298 /* -------------------- */ 2299 2300 2301 /* deletes a property (avoiding the exception thrown by IE) */ 2302 _delete=function(c,m){ 2303 try{delete c[m];}catch(e){c[m]=null;} 2304 }, 2305 /* -------------------- */ 2306 2307 2308 /* detects left mouse button */ 2309 _mouseBtnLeft=function(e){ 2310 return !(e.which && e.which!==1); 2311 }, 2312 /* -------------------- */ 2313 2314 2315 /* detects if pointer type event is touch */ 2316 _pointerTouch=function(e){ 2317 var t=e.originalEvent.pointerType; 2318 return !(t && t!=="touch" && t!==2); 2319 }, 2320 /* -------------------- */ 2321 2322 2323 /* checks if value is numeric */ 2324 _isNumeric=function(val){ 2325 return !isNaN(parseFloat(val)) && isFinite(val); 2326 }, 2327 /* -------------------- */ 2328 2329 2330 /* returns element position according to content */ 2331 _childPos=function(el){ 2332 var p=el.parents(".mCSB_container"); 2333 return [el.offset().top-p.offset().top,el.offset().left-p.offset().left]; 2334 }, 2335 /* -------------------- */ 2336 2337 2338 /* checks if browser tab is hidden/inactive via Page Visibility API */ 2339 _isTabHidden=function(){ 2340 var prop=_getHiddenProp(); 2341 if(!prop) return false; 2342 return document[prop]; 2343 function _getHiddenProp(){ 2344 var pfx=["webkit","moz","ms","o"]; 2345 if("hidden" in document) return "hidden"; //natively supported 2346 for(var i=0; i<pfx.length; i++){ //prefixed 2347 if((pfx[i]+"Hidden") in document) 2348 return pfx[i]+"Hidden"; 2349 } 2350 return null; //not supported 2351 } 2352 }; 2353 /* -------------------- */ 2354 2355 2356 2357 2358 2359 /* 2360 ---------------------------------------- 2361 PLUGIN SETUP 2362 ---------------------------------------- 2363 */ 2364 2365 /* plugin constructor functions */ 2366 $.fn[pluginNS]=function(method){ /* usage: $(selector).mCustomScrollbar(); */ 2367 if(methods[method]){ 2368 return methods[method].apply(this,Array.prototype.slice.call(arguments,1)); 2369 }else if(typeof method==="object" || !method){ 2370 return methods.init.apply(this,arguments); 2371 }else{ 2372 $.error("Method "+method+" does not exist"); 2373 } 2374 }; 2375 $[pluginNS]=function(method){ /* usage: $.mCustomScrollbar(); */ 2376 if(methods[method]){ 2377 return methods[method].apply(this,Array.prototype.slice.call(arguments,1)); 2378 }else if(typeof method==="object" || !method){ 2379 return methods.init.apply(this,arguments); 2380 }else{ 2381 $.error("Method "+method+" does not exist"); 2382 } 2383 }; 2384 2385 /* 2386 allow setting plugin default options. 2387 usage: $.mCustomScrollbar.defaults.scrollInertia=500; 2388 to apply any changed default options on default selectors (below), use inside document ready fn 2389 e.g.: $(document).ready(function(){ $.mCustomScrollbar.defaults.scrollInertia=500; }); 2390 */ 2391 $[pluginNS].defaults=defaults; 2392 2393 /* 2394 add window object (window.mCustomScrollbar) 2395 usage: if(window.mCustomScrollbar){console.log("custom scrollbar plugin loaded");} 2396 */ 2397 window[pluginNS]=true; 2398 2399 $(window).
vendor: 943 bytes, lines 2399-2424
2399load(function(){ 2400 2401 $(defaultSelector)[pluginNS](); /* add scrollbars automatically on default selector */ 2402 2403 /* extend jQuery expressions */ 2404 $.extend($.expr[":"],{ 2405 /* checks if element is within scrollable viewport */ 2406 mcsInView:$.expr[":"].mcsInView || function(el){ 2407 var $el=$(el),content=$el.parents(".mCSB_container"),wrapper,cPos; 2408 if(!content.length){return;} 2409 wrapper=content.parent(); 2410 cPos=[content[0].offsetTop,content[0].offsetLeft]; 2411 return cPos[0]+_childPos($el)[0]>=0 && cPos[0]+_childPos($el)[0]<wrapper.height()-$el.outerHeight(false) && 2412 cPos[1]+_childPos($el)[1]>=0 && cPos[1]+_childPos($el)[1]<wrapper.width()-$el.outerWidth(false); 2413 }, 2414 /* checks if element is overflowed having visible scrollbar(s) */ 2415 mcsOverflow:$.expr[":"].mcsOverflow || function(el){ 2416 var d=$(el).data(pluginPfx); 2417 if(!d){return;} 2418 return d.overflowed[0] || d.overflowed[1]; 2419 } 2420 }); 2421 2422 }); 2423 2424}))}));
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.