PageSourceSearch

https://laguna22.ru/js/jquery.custom-scrollbar.js?v=20260902d

js laguna22.ru collected 2026-09-28 22:45:42 UTC 25,781 bytes, 812 lines download raw bytes

1(function ($) {
2
3  $.fn.customScrollbar = function (options, args) {
4
5    var defaultOptions = {
6      skin: undefined,
7      hScroll: true,
8      vScroll: true,
9      updateOnWindowResize: false,
10      animationSpeed: 300,
11      onCustomScroll: undefined,
12      swipeSpeed: 1,
13      wheelSpeed: 40,
14      fixedThumbWidth: undefined,
15      fixedThumbHeight: undefined,
16      preventDefaultScroll: false
17    }
18
19    var Scrollable = function (element, options) {
20      this.$element = $(element);
21      this.options = options;
22      this.addScrollableClass();
23      this.addSkinClass();
24      this.addScrollBarComponents();
25      if (this.options.vScroll)
26        this.vScrollbar = new Scrollbar(this, new VSizing());
27      if (this.options.hScroll)
28        this.hScrollbar = new Scrollbar(this, new HSizing());
29      this.$element.data("scrollable", this);
30      this.initKeyboardScrolling();
31      this.bindEvents();
32    }
33
34    Scrollable.prototype = {
35
36      addScrollableClass: function () {
37        if (!this.$element.hasClass("scrollable")) {
38          this.scrollableAdded = true;
39          this.$element.addClass("scrollable");
40        }
41      },
42
43      removeScrollableClass: function () {
44        if (this.scrollableAdded)
45          this.$element.removeClass("scrollable");
46      },
47
48      addSkinClass: function () {
49        if (typeof(this.options.skin) == "string" && !this.$element.hasClass(this.options.skin)) {
50          this.skinClassAdded = true;
51          this.$element.addClass(this.options.skin);
52        }
53      },
54
55      removeSkinClass: function () {
56        if (this.skinClassAdded)
57          this.$element.removeClass(this.options.skin);
58      },
59
60      addScrollBarComponents: function () {
61        this.assignViewPort();
62        if (this.$viewPort.length == 0) {
63          this.$element.wrapInner("<div class=\"viewport\" />");
64          this.assignViewPort();
65          this.viewPortAdded = true;
66        }
67        this.assignOverview();
68        if (this.$overview.length == 0) {
69          this.$viewPort.wrapInner("<div class=\"overview\" />");
70          this.assignOverview();
71          this.overviewAdded = true;
72        }
73        this.addScrollBar("vertical", "prepend");
74        this.addScrollBar("horizontal", "append");
75      },
76
77      removeScrollbarComponents: function () {
78        this.removeScrollbar("vertical");
79        this.removeScrollbar("horizontal");
80        if (this.overviewAdded)
81          this.$element.unwrap();
82        if (this.viewPortAdded)
83          this.$element.unwrap();
84      },
85
86      removeScrollbar: function (orientation) {
87        if (this[orientation + "ScrollbarAdded"])
88          this.$element.find(".scroll-bar." + orientation).remove();
89      },
90
91      assignViewPort: function () {
92        this.$viewPort = this.$element.find(".viewport");
93      },
94
95      assignOverview: function () {
96        this.$overview = this.$viewPort.find(".overview");
97      },
98
99      addScrollBar: function (orientation, fun) {
100        if (this.$element.find(".scroll-bar." + orientation).length == 0) {
101          this.$element[fun]("<div class='scroll-bar " + orientation + "'><div class='thumb'></div></div>")
102          this[orientation + "ScrollbarAdded"] = true;
103        }
104      },
105
106      resize: function (keepPosition) {
107        if (this.vScrollbar)
108          this.vScrollbar.resize(keepPosition);
109        if (this.hScrollbar)
110          this.hScrollbar.resize(keepPosition);
111      },
112
113      scrollTo: function (element) {
114        if (this.vScrollbar)
115          this.vScrollbar.scrollToElement(element);
116        if (this.hScrollbar)
117          this.hScrollbar.scrollToElement(element);
118      },
119
120      scrollToXY: function (x, y) {
121        this.scrollToX(x);
122        this.scrollToY(y);
123      },
124
125      scrollToX: function (x) {
126        if (this.hScrollbar)
127          this.hScrollbar.scrollOverviewTo(x, true);
128      },
129
130      scrollToY: function (y) {
131        if (this.vScrollbar)
132          this.vScrollbar.scrollOverviewTo(y, true);
133      },
134
135      scrollByX: function (x) {
136        if (this.hScrollbar)
137          this.scrollToX(this.hScrollbar.overviewPosition() + x);
138      },
139
140      scrollByY: function (y) {
141        if (this.vScrollbar)
142          this.scrollToY(this.vScrollbar.overviewPosition() + y);
143      },
144
145      remove: function () {
146        this.removeScrollableClass();
147        this.removeSkinClass();
148        this.removeScrollbarComponents();
149        this.$element.data("scrollable", null);
150        this.removeKeyboardScrolling();
151        if (this.vScrollbar)
152          this.vScrollbar.remove();
153        if (this.hScrollbar)
154          this.hScrollbar.remove();
155      },
156
157      setAnimationSpeed: function (speed) {
158        this.options.animationSpeed = speed;
159      },
160
161      isInside: function (element, wrappingElement) {
162        var $element = $(element);
163        var $wrappingElement = $(wrappingElement);
164        var elementOffset = $element.offset();
165        var wrappingElementOffset = $wrappingElement.offset();
166        return (elementOffset.top >= wrappingElementOffset.top) && (elementOffset.left >= wrappingElementOffset.left) &&
167          (elementOffset.top + $element.height() <= wrappingElementOffset.top + $wrappingElement.height()) &&
168          (elementOffset.left + $element.width() <= wrappingElementOffset.left + $wrappingElement.width())
169      },
170
171      initKeyboardScrolling: function () {
172        var _this = this;
173
174        this.elementKeydown = function (event) {
175          if (document.activeElement === _this.$element[0]) {
176            if (_this.vScrollbar)
177              _this.vScrollbar.keyScroll(event);
178            if (_this.hScrollbar)
179              _this.hScrollbar.keyScroll(event);
180          }
181        }
182
183        this.$element
184          .attr('tabindex', '-1')
185          .keydown(this.elementKeydown);
186      },
187
188      removeKeyboardScrolling: function () {
189        this.$element
190          .removeAttr('tabindex')
191          .unbind("keydown", this.elementKeydown);
192      },
193
194      bindEvents: function () {
195        if (this.options.onCustomScroll)
196          this.$element.on("customScroll", this.options.onCustomScroll);
197      }
198
199    }
200
201    var Scrollbar = function (scrollable, sizing) {
202      this.scrollable = scrollable;
203      this.sizing = sizing
204      this.$scrollBar = this.sizing.scrollBar(this.scrollable.$element);
205      this.$thumb = this.$scrollBar.find(".thumb");
206      this.setScrollPosition(0, 0);
207      this.resize();
208      this.initMouseMoveScrolling();
209      this.initMouseWheelScrolling();
210      this.initTouchScrolling();
211      this.initMouseClickScrolling();
212      this.initWindowResize();
213    }
214
215    Scrollbar.prototype = {
216
217      resize: function (keepPosition) {
218        this.overviewSize = this.sizing.size(this.scrollable.$overview);
219        this.calculateViewPortSize();
220        this.sizing.size(this.scrollable.$viewPort, this.viewPortSize);
221        this.ratio = this.viewPortSize / this.overviewSize;
222        this.sizing.size(this.$scrollBar, this.viewPortSize);
223        this.thumbSize = this.calculateThumbSize();
224        this.sizing.size(this.$thumb, this.thumbSize);
225        this.maxThumbPosition = this.calculateMaxThumbPosition();
226        this.maxOverviewPosition = this.calculateMaxOverviewPosition();
227        this.enabled = (this.overviewSize > this.viewPortSize);
228        if (this.scrollPercent === undefined)
229          this.scrollPercent = 0.0;
230        if (this.enabled)
231          this.rescroll(keepPosition);
232        else
233          this.setScrollPosition(0, 0);
234        this.$scrollBar.toggle(this.enabled);
235      },
236
237      calculateViewPortSize: function () {
238        var elementSize = this.sizing.size(this.scrollable.$element);
239        if (elementSize > 0 && !this.maxSizeUsed) {
240          this.viewPortSize = elementSize;
241          this.maxSizeUsed = false;
242        }
243        else {
244          var maxSize = this.sizing.maxSize(this.scrollable.$element);
245          this.viewPortSize = Math.min(maxSize, this.overviewSize);
246          this.maxSizeUsed = true;
247        }
248      },
249
250      calculateThumbSize: function () {
251        var fixedSize = this.sizing.fixedThumbSize(this.scrollable.options)
252        var size;
253        if (fixedSize)
254          size = fixedSize;
255        else
256          size = this.ratio * this.viewPortSize
257        return Math.max(size, this.sizing.minSize(this.$thumb));
258      },
259
260      initMouseMoveScrolling: function () {
261        var _this = this;
262        this.$thumb.mousedown(function (event) {
263          if (_this.enabled)
264            _this.startMouseMoveScrolling(event);
265        });
266        this.documentMouseup = function (event) {
267          _this.stopMouseMoveScrolling(event);
268        };
269        $(document).mouseup(this.documentMouseup);
270        this.documentMousemove = function (event) {
271          _this.mouseMoveScroll(event);
272        };
273        $(document).mousemove(this.documentMousemove);
274        this.$thumb.click(function (event) {
275          event.stopPropagation();
276        });
277      },
278
279      removeMouseMoveScrolling: function () {
280        this.$thumb.unbind();
281        $(document).unbind("mouseup", this.documentMouseup);
282        $(document).unbind("mousemove", this.documentMousemove);
283      },
284
285      initMouseWheelScrolling: function () {
286        var _this = this;
287        this.scrollable.$element.mousewheel(function (event, delta, deltaX, deltaY) {
288          if (_this.enabled) {
289            var scrolled = _this.mouseWheelScroll(deltaX, deltaY);
290            _this.stopEventConditionally(event, scrolled);
291          }
292        });
293      },
294
295      removeMouseWheelScrolling: function () {
296        this.scrollable.$element.unbind("mousewheel");
297      },
298
299      initTouchScrolling: function () {
300        if (document.addEventListener) {
301          var _this = this;
302          this.elementTouchstart = function (event) {
303            if (_this.enabled)
304              _this.startTouchScrolling(event);
305          }
306          this.scrollable.$element[0].addEventListener("touchstart", this.elementTouchstart);
307          this.documentTouchmove = function (event) {
308            _this.touchScroll(event);
309          }
310          this.scrollable.$element[0].addEventListener("touchmove", this.documentTouchmove);
311          this.elementTouchend = function (event) {
312            _this.stopTouchScrolling(event);
313          }
314          this.scrollable.$element[0].addEventListener("touchend", this.elementTouchend);
315        }
316      },
317
318      removeTouchScrolling: function () {
319        if (document.addEventListener) {
320          this.scrollable.$element[0].removeEventListener("touchstart", this.elementTouchstart);
321          document.removeEventListener("touchmove", this.documentTouchmove);
322          this.scrollable.$element[0].removeEventListener("touchend", this.elementTouchend);
323        }
324      },
325
326      initMouseClickScrolling: function () {
327        var _this = this;
328        this.scrollBarClick = function (event) {
329          _this.mouseClickScroll(event);
330        };
331        this.$scrollBar.click(this.scrollBarClick);
332      },
333
334      removeMouseClickScrolling: function () {
335        this.$scrollBar.unbind("click", this.scrollBarClick);
336      },
337
338      initWindowResize: function () {
339        if (this.scrollable.options.updateOnWindowResize) {
340          var _this = this;
341          this.windowResize = function () {
342            _this.resize();
343          };
344          $(window).resize(this.windowResize);
345        }
346      },
347
348      removeWindowResize: function () {
349        $(window).unbind("resize", this.windowResize);
350      },
351
352      isKeyScrolling: function (key) {
353        return this.keyScrollDelta(key) != null;
354      },
355
356      keyScrollDelta: function (key) {
357        for (var scrollingKey in this.sizing.scrollingKeys)
358          if (scrollingKey == key)
359            return this.sizing.scrollingKeys[key](this.viewPortSize);
360        return null;
361      },
362
363      startMouseMoveScrolling: function (event) {
364        this.mouseMoveScrolling = true;
365        $("body").addClass("not-selectable");
366        this.setUnselectable($("body"), "on");
367        this.setScrollEvent(event);
368        event.preventDefault();
369      },
370
371      stopMouseMoveScrolling: function (event) {
372        this.mouseMoveScrolling = false;
373        $("body").removeClass("not-selectable");
374        this.setUnselectable($("body"), null);
375      },
376
377      setUnselectable: function (element, value) {
378        if (element.attr("unselectable") != value) {
379          element.attr("unselectable", value);
380          element.find(':not(input)').attr('unselectable', value);
381        }
382      },
383
384      mouseMoveScroll: function (event) {
385        if (this.mouseMoveScrolling) {
386          var delta = this.sizing.mouseDelta(this.scrollEvent, event);
387          this.scrollThumbBy(delta);
388          this.setScrollEvent(event);
389        }
390      },
391
392      startTouchScrolling: function (event) {
393        if (event.touches && event.touches.length == 1) {
394          this.setScrollEvent(event.touches[0]);
395          this.touchScrolling = true;
396          event.stopPropagation();
397        }
398      },
399
400      touchScroll: function (event) {
401        if (this.touchScrolling && event.touches && event.touches.length == 1) {
402          var delta = -this.sizing.mouseDelta(this.scrollEvent, event.touches[0]) * this.scrollable.options.swipeSpeed;
403          var scrolled = this.scrollOverviewBy(delta);
404          if (scrolled)
405            this.setScrollEvent(event.touches[0]);
406          this.stopEventConditionally(event, scrolled);
407        }
408      },
409
410      stopTouchScrolling: function (event) {
411        this.touchScrolling = false;
412        event.stopPropagation();
413      },
414
415      mouseWheelScroll: function (deltaX, deltaY) {
416        var delta = -this.sizing.wheelDelta(deltaX, deltaY) * this.scrollable.options.wheelSpeed;
417        if (delta != 0)
418          return this.scrollOverviewBy(delta);
419      },
420
421      mouseClickScroll: function (event) {
422        var delta = this.viewPortSize - 20;
423        if (event["page" + this.sizing.scrollAxis()] < this.$thumb.offset()[this.sizing.offsetComponent()])
424        // mouse click over thumb
425          delta = -delta;
426        this.scrollOverviewBy(delta);
427      },
428
429      keyScroll: function (event) {
430        var keyDown = event.which;
431        if (this.enabled && this.isKeyScrolling(keyDown)) {
432          var scrolled = this.scrollOverviewBy(this.keyScrollDelta(keyDown));
433          this.stopEventConditionally(event, scrolled);
434        }
435      },
436
437      scrollThumbBy: function (delta) {
438        var thumbPosition = this.thumbPosition();
439        thumbPosition += delta;
440        thumbPosition = this.positionOrMax(thumbPosition, this.maxThumbPosition);
441        var oldScrollPercent = this.scrollPercent;
442        this.scrollPercent = thumbPosition / this.maxThumbPosition;
443        if (oldScrollPercent != this.scrollPercent) {
444          var overviewPosition = (thumbPosition * this.maxOverviewPosition) / this.maxThumbPosition;
445          this.setScrollPosition(overviewPosition, thumbPosition);
446          this.triggerCustomScroll(oldScrollPercent);
447          return true
448        }
449        else
450          return false;
451      },
452
453      thumbPosition: function () {
454        return this.$thumb.position()[this.sizing.offsetComponent()];
455      },
456
457      scrollOverviewBy: function (delta) {
458        var overviewPosition = this.overviewPosition() + delta;
459        return this.scrollOverviewTo(overviewPosition, false);
460      },
461
462      overviewPosition: function () {
463        return -this.scrollable.$overview.position()[this.sizing.offsetComponent()];
464      },
465
466      scrollOverviewTo: function (overviewPosition, animate) {
467        overviewPosition = this.positionOrMax(overviewPosition, this.maxOverviewPosition);
468        var oldScrollPercent = this.scrollPercent;
469        this.scrollPercent = overviewPosition / this.maxOverviewPosition;
470        if (oldScrollPercent != this.scrollPercent) {
471          var thumbPosition = this.scrollPercent * this.maxThumbPosition;
472          if (animate)
473            this.setScrollPositionWithAnimation(overviewPosition, thumbPosition);
474          else
475            this.setScrollPosition(overviewPosition, thumbPosition);
476          this.triggerCustomScroll(oldScrollPercent);
477          return true;
478        }
479        else
480          return false;
481      },
482
483      positionOrMax: function (p, max) {
484        if (p < 0)
485          return 0;
486        else if (p > max)
487          return max;
488        else
489          return p;
490      },
491
492      triggerCustomScroll: function (oldScrollPercent) {
493        this.scrollable.$element.trigger("customScroll", {
494            scrollAxis: this.sizing.scrollAxis(),
495            direction: this.sizing.scrollDirection(oldScrollPercent, this.scrollPercent),
496            scrollPercent: this.scrollPercent * 100
497          }
498        );
499      },
500
501      rescroll: function (keepPosition) {
502        if (keepPosition) {
503          var overviewPosition = this.positionOrMax(this.overviewPosition(), this.maxOverviewPosition);
504          this.scrollPercent = overviewPosition / this.maxOverviewPosition;
505          var thumbPosition = this.scrollPercent * this.maxThumbPosition;
506          this.setScrollPosition(overviewPosition, thumbPosition);
507        }
508        else {
509          var thumbPosition = this.scrollPercent * this.maxThumbPosition;
510          var overviewPosition = this.scrollPercent * this.maxOverviewPosition;
511          this.setScrollPosition(overviewPosition, thumbPosition);
512        }
513      },
514
515      setScrollPosition: function (overviewPosition, thumbPosition) {
516        this.$thumb.css(this.sizing.offsetComponent(), thumbPosition + "px");
517        this.scrollable.$overview.css(this.sizing.offsetComponent(), -overviewPosition + "px");
518      },
519
520      setScrollPositionWithAnimation: function (overviewPosition, thumbPosition) {
521        var thumbAnimationOpts = {};
522        var overviewAnimationOpts = {};
523        thumbAnimationOpts[this.sizing.offsetComponent()] = thumbPosition + "px";
524        this.$thumb.animate(thumbAnimationOpts, this.scrollable.options.animationSpeed);
525        overviewAnimationOpts[this.sizing.offsetComponent()] = -overviewPosition + "px";
526        this.scrollable.$overview.animate(overviewAnimationOpts, this.scrollable.options.animationSpeed);
527      },
528
529      calculateMaxThumbPosition: function () {
530        return Math.max(0, this.sizing.size(this.$scrollBar) - this.thumbSize);
531      },
532
533      calculateMaxOverviewPosition: function () {
534        return Math.max(0, this.sizing.size(this.scrollable.$overview) - this.sizing.size(this.scrollable.$viewPort));
535      },
536
537      setScrollEvent: function (event) {
538        var attr = "page" + this.sizing.scrollAxis();
539        if (!this.scrollEvent || this.scrollEvent[attr] != event[attr])
540          this.scrollEvent = {pageX: event.pageX, pageY: event.pageY};
541      },
542
543      scrollToElement: function (element) {
544        var $element = $(element);
545        if (this.sizing.isInside($element, this.scrollable.$overview) && !this.sizing.isInside($element, this.scrollable.$viewPort)) {
546          var elementOffset = $element.offset();
547          var overviewOffset = this.scrollable.$overview.offset();
548          var viewPortOffset = this.scrollable.$viewPort.offset();
549          this.scrollOverviewTo(elementOffset[this.sizing.offsetComponent()] - overviewOffset[this.sizing.offsetComponent()], true);
550        }
551      },
552
553      remove: function () {
554        this.removeMouseMoveScrolling();
555        this.removeMouseWheelScrolling();
556        this.removeTouchScrolling();
557        this.removeMouseClickScrolling();
558        this.removeWindowResize();
559      },
560
561      stopEventConditionally: function (event, condition) {
562        if (condition || this.scrollable.options.preventDefaultScroll) {
563          event.preventDefault();
564          event.stopPropagation();
565        }
566      }
567
568    }
569
570    var HSizing = function () {
571    }
572
573    HSizing.prototype = {
574      size: function ($el, arg) {
575        if (arg)
576          return $el.width(arg);
577        else
578          return $el.width();
579      },
580
581      minSize: function ($el) {
582        return parseInt($el.css("min-width")) || 0;
583      },
584
585      maxSize: function ($el) {
586        return parseInt($el.css("max-width")) || 0;
587      },
588
589      fixedThumbSize: function (options) {
590        return options.fixedThumbWidth;
591      },
592
593      scrollBar: function ($el) {
594        return $el.find(".scroll-bar.horizontal");
595      },
596
597      mouseDelta: function (event1, event2) {
598        return event2.pageX - event1.pageX;
599      },
600
601      offsetComponent: function () {
602        return "left";
603      },
604
605      wheelDelta: function (deltaX, deltaY) {
606        return deltaX;
607      },
608
609      scrollAxis: function () {
610        return "X";
611      },
612
613      scrollDirection: function (oldPercent, newPercent) {
614        return oldPercent < newPercent ? "right" : "left";
615      },
616
617      scrollingKeys: {
618        37: function (viewPortSize) {
619          return -10; //arrow left
620        },
621        39: function (viewPortSize) {
622          return 10; //arrow right
623        }
624      },
625
626      isInside: function (element, wrappingElement) {
627        var $element = $(element);
628        var $wrappingElement = $(wrappingElement);
629        var elementOffset = $element.offset();
630        var wrappingElementOffset = $wrappingElement.offset();
631        return (elementOffset.left >= wrappingElementOffset.left) &&
632          (elementOffset.left + $element.width() <= wrappingElementOffset.left + $wrappingElement.width());
633      }
634
635    }
636
637    var VSizing = function () {
638    }
639
640    VSizing.prototype = {
641
642      size: function ($el, arg) {
643        if (arg)
644          return $el.height(arg);
645        else
646          return $el.height();
647      },
648
649      minSize: function ($el) {
650        return parseInt($el.css("min-height")) || 0;
651      },
652
653      maxSize: function ($el) {
654        return parseInt($el.css("max-height")) || 0;
655      },
656
657      fixedThumbSize: function (options) {
658        return options.fixedThumbHeight;
659      },
660
661      scrollBar: function ($el) {
662        return $el.find(".scroll-bar.vertical");
663      },
664
665      mouseDelta: function (event1, event2) {
666        return event2.pageY - event1.pageY;
667      },
668
669      offsetComponent: function () {
670        return "top";
671      },
672
673      wheelDelta: function (deltaX, deltaY) {
674        return deltaY;
675      },
676
677      scrollAxis: function () {
678        return "Y";
679      },
680
681      scrollDirection: function (oldPercent, newPercent) {
682        return oldPercent < newPercent ? "down" : "up";
683      },
684
685      scrollingKeys: {
686        38: function (viewPortSize) {
687          return -10; //arrow up
688        },
689        40: function (viewPortSize) {
690          return 10; //arrow down
691        },
692        33: function (viewPortSize) {
693          return -(viewPortSize - 20); //page up
694        },
695        34: function (viewPortSize) {
696          return viewPortSize - 20; //page down
697        }
698      },
699
700      isInside: function (element, wrappingElement) {
701        var $element = $(element);
702        var $wrappingElement = $(wrappingElement);
703        var elementOffset = $element.offset();
704        var wrappingElementOffset = $wrappingElement.offset();
705        return (elementOffset.top >= wrappingElementOffset.top) &&
706          (elementOffset.top + $element.height() <= wrappingElementOffset.top + $wrappingElement.height());
707      }
708
709    }
710
711    return this.each(function () {
712      if (options == undefined)
713        options = defaultOptions;
714      if (typeof(options) == "string") {
715        var scrollable = $(this).data("scrollable");
716        if (scrollable)
717          scrollable[options](args);
718      }
719      else if (typeof(options) == "object") {
720        options = $.extend(defaultOptions, options);
721        new Scrollable($(this), options);
722      }
723      else
724        throw "Invalid type of options";
725    });
726
727  }
728  ;
729
730})
731  (jQuery);
732
733(function ($) {
734
735  var types = ['DOMMouseScroll', 'mousewheel'];
736
737  if ($.event.fixHooks) {
738    for (var i = types.length; i;) {
739      $.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
740    }
741  }
742
743  $.event.special.mousewheel = {
744    setup: function () {
745      if (this.addEventListener) {
746        for (var i = types.length; i;) {
747          this.addEventListener(types[--i], handler, false);
748        }
749      } else {
750        this.onmousewheel = handler;
751      }
752    },
753
754    teardown: function () {
755      if (this.removeEventListener) {
756        for (var i = types.length; i;) {
757          this.removeEventListener(types[--i], handler, false);
758        }
759      } else {
760        this.onmousewheel = null;
761      }
762    }
763  };
764
765  $.fn.extend({
766    mousewheel: function (fn) {
767      return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
768    },
769
770    unmousewheel: function (fn) {
771      return this.unbind("mousewheel", fn);
772    }
773  });
774
775
776  function handler(event) {
777    var orgEvent = event || window.event, args = [].slice.call(arguments, 1), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
778    event = $.event.fix(orgEvent);
779    event.type = "mousewheel";
780
781    // Old school scrollwheel delta
782    if (orgEvent.wheelDelta) {
783      delta = orgEvent.wheelDelta / 120;
784    }
785    if (orgEvent.detail) {
786      delta = -orgEvent.detail / 3;
787    }
788
789    // New school multidimensional scroll (touchpads) deltas
790    deltaY = delta;
791
792    // Gecko
793    if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) {
794      deltaY = 0;
795      deltaX = delta;
796    }
797
798    // Webkit
799    if (orgEvent.wheelDeltaY !== undefined) {
800      deltaY = orgEvent.wheelDeltaY / 120;
801    }
802    if (orgEvent.wheelDeltaX !== undefined) {
803      deltaX = orgEvent.wheelDeltaX / 120;
804    }
805
806    // Add event and delta to the front of the arguments
807    args.unshift(event, delta, deltaX, deltaY);
808
809    return ($.event.dispatch || $.event.handle).apply(this, args);
810  }
811
812})(jQuery);

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.