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