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