mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 14:03:30 +00:00 
			
		
		
		
	deps: Upgrade and move perfect-scrollbar from static/third to npm.
				
					
				
			- Remove `perfect-scrollbar` from `static/third` and fetch it from npm. - Upgrade `perfect-scrollbar` to 0.7.1. - Bump up the `PROVISION_VERSION` to 5.6. Changed `wheelSpeed` in "static/js/scroll_bar.js" to 0.5, because when it 20, the scrollbar scrolls very fast. Changed 'wheelSpeed' in "static/js/emoji_picker.js" from 25 to 0.68 (based on tabbott's testing of scrolling through the emoji list). Part of #1709.
This commit is contained in:
		@@ -158,10 +158,6 @@ Files: static/third/jquery-mousewheel/jquery.mousewheel.js
 | 
			
		||||
Copyright: 2011 Brandon Aaron
 | 
			
		||||
License: Expat
 | 
			
		||||
 | 
			
		||||
Files: static/third/jquery-perfect-scrollbar/*
 | 
			
		||||
Copyright: 2012 HyeonJe Jun
 | 
			
		||||
License: Expat
 | 
			
		||||
 | 
			
		||||
Files: static/third/jquery-throttle-debounce/*
 | 
			
		||||
Copyright: 2010 "Cowboy" Ben Alman
 | 
			
		||||
License: Expat or GPL
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,7 @@
 | 
			
		||||
    "katex": "0.7.1",
 | 
			
		||||
    "moment": "2.18.1",
 | 
			
		||||
    "moment-timezone": "0.5.12",
 | 
			
		||||
    "perfect-scrollbar": "0.7.1",
 | 
			
		||||
    "plotly.js": "1.19.2",
 | 
			
		||||
    "script-loader": "0.7.0",
 | 
			
		||||
    "source-map-loader": "0.2.1",
 | 
			
		||||
 
 | 
			
		||||
@@ -134,7 +134,8 @@ exports.toggle_emoji_popover = function (element, id) {
 | 
			
		||||
        $(".emoji-popover-emoji-map").perfectScrollbar({
 | 
			
		||||
            suppressScrollX: true,
 | 
			
		||||
            useKeyboard: false,
 | 
			
		||||
            wheelSpeed: 25,
 | 
			
		||||
            // Picked so that each mousewheel bump moves 1 emoji down.
 | 
			
		||||
            wheelSpeed: 0.68,
 | 
			
		||||
        });
 | 
			
		||||
        current_message_emoji_popover_elem = elt;
 | 
			
		||||
        exports.render_emoji_show_list();
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ $(function () {
 | 
			
		||||
    $("#stream-filters-container").perfectScrollbar({
 | 
			
		||||
        suppressScrollX: true,
 | 
			
		||||
        useKeyboard: false,
 | 
			
		||||
        wheelSpeed: 20,
 | 
			
		||||
        wheelSpeed: 0.5,
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,123 +0,0 @@
 | 
			
		||||
.ps-container .ps-scrollbar-x-rail {
 | 
			
		||||
    position: absolute; /* please don't change 'position' */
 | 
			
		||||
    bottom: 3px; /* there must be 'bottom' for ps-scrollbar-x-rail */
 | 
			
		||||
    height: 8px;
 | 
			
		||||
    -webkit-border-radius: 4px;
 | 
			
		||||
    -moz-border-radius: 4px;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
    filter: alpha(opacity = 0);
 | 
			
		||||
    -o-transition: background-color .2s linear, opacity .2s linear;
 | 
			
		||||
    -webkit-transition: background-color .2s linear, opacity .2s linear;
 | 
			
		||||
    -moz-transition: background-color .2s linear, opacity .2s linear;
 | 
			
		||||
    transition: background-color .2s linear, opacity .2s linear;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container:hover .ps-scrollbar-x-rail,
 | 
			
		||||
.ps-container.hover .ps-scrollbar-x-rail {
 | 
			
		||||
    opacity: 0.6;
 | 
			
		||||
    filter: alpha(opacity = 60);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container .ps-scrollbar-x-rail:hover,
 | 
			
		||||
.ps-container .ps-scrollbar-x-rail.hover {
 | 
			
		||||
    background-color: #eee;
 | 
			
		||||
    opacity: 0.9;
 | 
			
		||||
    filter: alpha(opacity = 90);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container .ps-scrollbar-x-rail.in-scrolling {
 | 
			
		||||
    opacity: 0.9;
 | 
			
		||||
    filter: alpha(opacity = 90);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container .ps-scrollbar-y-rail {
 | 
			
		||||
    position: absolute; /* please don't change 'position' */
 | 
			
		||||
    right: 3px; /* there must be 'right' for ps-scrollbar-y-rail */
 | 
			
		||||
    width: 8px;
 | 
			
		||||
    -webkit-border-radius: 4px;
 | 
			
		||||
    -moz-border-radius: 4px;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
    filter: alpha(opacity = 0);
 | 
			
		||||
    -o-transition: background-color .2s linear, opacity .2s linear;
 | 
			
		||||
    -webkit-transition: background-color .2s linear, opacity .2s linear;
 | 
			
		||||
    -moz-transition: background-color .2s linear, opacity .2s linear;
 | 
			
		||||
    transition: background-color .2s linear, opacity .2s linear;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container:hover .ps-scrollbar-y-rail,
 | 
			
		||||
.ps-container.hover .ps-scrollbar-y-rail {
 | 
			
		||||
    opacity: 0.6;
 | 
			
		||||
    filter: alpha(opacity = 60);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container .ps-scrollbar-y-rail:hover,
 | 
			
		||||
.ps-container .ps-scrollbar-y-rail.hover {
 | 
			
		||||
    background-color: #eee;
 | 
			
		||||
    opacity: 0.9;
 | 
			
		||||
    filter: alpha(opacity = 90);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container .ps-scrollbar-y-rail.in-scrolling {
 | 
			
		||||
    opacity: 0.9;
 | 
			
		||||
    filter: alpha(opacity = 90);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container .ps-scrollbar-x {
 | 
			
		||||
    position: absolute; /* please don't change 'position' */
 | 
			
		||||
    bottom: 0; /* there must be 'bottom' for ps-scrollbar-x */
 | 
			
		||||
    height: 8px;
 | 
			
		||||
    background-color: #aaa;
 | 
			
		||||
    -webkit-border-radius: 4px;
 | 
			
		||||
    -moz-border-radius: 4px;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    -o-transition: background-color .2s linear;
 | 
			
		||||
    -webkit-transition: background-color.2s linear;
 | 
			
		||||
    -moz-transition: background-color .2s linear;
 | 
			
		||||
    transition: background-color .2s linear;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container.ie6 .ps-scrollbar-x {
 | 
			
		||||
    font-size: 0; /* fixed scrollbar height in xp sp3 ie6 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container .ps-scrollbar-x-rail:hover .ps-scrollbar-x,
 | 
			
		||||
.ps-container .ps-scrollbar-x-rail.hover .ps-scrollbar-x {
 | 
			
		||||
    background-color: #999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container .ps-scrollbar-y {
 | 
			
		||||
    position: absolute; /* please don't change 'position' */
 | 
			
		||||
    right: 0; /* there must be 'right' for ps-scrollbar-y */
 | 
			
		||||
    width: 8px;
 | 
			
		||||
    background-color: #aaa;
 | 
			
		||||
    -webkit-border-radius: 4px;
 | 
			
		||||
    -moz-border-radius: 4px;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    -o-transition: background-color .2s linear;
 | 
			
		||||
    -webkit-transition: background-color.2s linear;
 | 
			
		||||
    -moz-transition: background-color .2s linear;
 | 
			
		||||
    transition: background-color .2s linear;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container.ie6 .ps-scrollbar-y {
 | 
			
		||||
    font-size: 0; /* fixed scrollbar height in xp sp3 ie6 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container .ps-scrollbar-y-rail:hover .ps-scrollbar-y,
 | 
			
		||||
.ps-container .ps-scrollbar-y-rail.hover .ps-scrollbar-y {
 | 
			
		||||
    background-color: #999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container.ie .ps-scrollbar-x,
 | 
			
		||||
.ps-container.ie .ps-scrollbar-y {
 | 
			
		||||
    visibility: hidden;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ps-container.ie:hover .ps-scrollbar-x,
 | 
			
		||||
.ps-container.ie:hover .ps-scrollbar-y,
 | 
			
		||||
.ps-container.ie.hover .ps-scrollbar-x,
 | 
			
		||||
.ps-container.ie.hover .ps-scrollbar-y {
 | 
			
		||||
    visibility: visible;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,591 +0,0 @@
 | 
			
		||||
/* Copyright (c) 2012 HyeonJe Jun (http://github.com/noraesae)
 | 
			
		||||
 * Licensed under the MIT License
 | 
			
		||||
 */
 | 
			
		||||
'use strict';
 | 
			
		||||
(function (factory) {
 | 
			
		||||
  if (typeof define === 'function' && define.amd) {
 | 
			
		||||
    // AMD. Register as an anonymous module.
 | 
			
		||||
    define(['jquery'], factory);
 | 
			
		||||
  } else {
 | 
			
		||||
    // Browser globals
 | 
			
		||||
    factory(jQuery);
 | 
			
		||||
  }
 | 
			
		||||
}(function ($) {
 | 
			
		||||
 | 
			
		||||
  // The default settings for the plugin
 | 
			
		||||
  var defaultSettings = {
 | 
			
		||||
    wheelSpeed: 10,
 | 
			
		||||
    wheelPropagation: false,
 | 
			
		||||
    minScrollbarLength: null,
 | 
			
		||||
    useBothWheelAxes: false,
 | 
			
		||||
    useKeyboard: true,
 | 
			
		||||
    suppressScrollX: false,
 | 
			
		||||
    suppressScrollY: false,
 | 
			
		||||
    scrollXMarginOffset: 0,
 | 
			
		||||
    scrollYMarginOffset: 0
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  var getEventClassName = (function () {
 | 
			
		||||
    var incrementingId = 0;
 | 
			
		||||
    return function () {
 | 
			
		||||
      var id = incrementingId;
 | 
			
		||||
      incrementingId += 1;
 | 
			
		||||
      return '.perfect-scrollbar-' + id;
 | 
			
		||||
    };
 | 
			
		||||
  }());
 | 
			
		||||
 | 
			
		||||
  $.fn.perfectScrollbar = function (suppliedSettings, option) {
 | 
			
		||||
 | 
			
		||||
    return this.each(function () {
 | 
			
		||||
      // Use the default settings
 | 
			
		||||
      var settings = $.extend(true, {}, defaultSettings),
 | 
			
		||||
          $this = $(this);
 | 
			
		||||
 | 
			
		||||
      if (typeof suppliedSettings === "object") {
 | 
			
		||||
        // But over-ride any supplied
 | 
			
		||||
        $.extend(true, settings, suppliedSettings);
 | 
			
		||||
      } else {
 | 
			
		||||
        // If no settings were supplied, then the first param must be the option
 | 
			
		||||
        option = suppliedSettings;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // Catch options
 | 
			
		||||
 | 
			
		||||
      if (option === 'update') {
 | 
			
		||||
        if ($this.data('perfect-scrollbar-update')) {
 | 
			
		||||
          $this.data('perfect-scrollbar-update')();
 | 
			
		||||
        }
 | 
			
		||||
        return $this;
 | 
			
		||||
      }
 | 
			
		||||
      else if (option === 'destroy') {
 | 
			
		||||
        if ($this.data('perfect-scrollbar-destroy')) {
 | 
			
		||||
          $this.data('perfect-scrollbar-destroy')();
 | 
			
		||||
        }
 | 
			
		||||
        return $this;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if ($this.data('perfect-scrollbar')) {
 | 
			
		||||
        // if there's already perfect-scrollbar
 | 
			
		||||
        return $this.data('perfect-scrollbar');
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
      // Or generate new perfectScrollbar
 | 
			
		||||
 | 
			
		||||
      // Set class to the container
 | 
			
		||||
      $this.addClass('ps-container');
 | 
			
		||||
 | 
			
		||||
      var $scrollbarXRail = $("<div class='ps-scrollbar-x-rail'></div>").appendTo($this),
 | 
			
		||||
          $scrollbarYRail = $("<div class='ps-scrollbar-y-rail'></div>").appendTo($this),
 | 
			
		||||
          $scrollbarX = $("<div class='ps-scrollbar-x'></div>").appendTo($scrollbarXRail),
 | 
			
		||||
          $scrollbarY = $("<div class='ps-scrollbar-y'></div>").appendTo($scrollbarYRail),
 | 
			
		||||
          scrollbarXActive,
 | 
			
		||||
          scrollbarYActive,
 | 
			
		||||
          containerWidth,
 | 
			
		||||
          containerHeight,
 | 
			
		||||
          contentWidth,
 | 
			
		||||
          contentHeight,
 | 
			
		||||
          scrollbarXWidth,
 | 
			
		||||
          scrollbarXLeft,
 | 
			
		||||
          scrollbarXBottom = parseInt($scrollbarXRail.css('bottom'), 10),
 | 
			
		||||
          scrollbarYHeight,
 | 
			
		||||
          scrollbarYTop,
 | 
			
		||||
          scrollbarYRight = parseInt($scrollbarYRail.css('right'), 10),
 | 
			
		||||
          eventClassName = getEventClassName();
 | 
			
		||||
 | 
			
		||||
      var updateContentScrollTop = function (currentTop, deltaY) {
 | 
			
		||||
        var newTop = currentTop + deltaY,
 | 
			
		||||
            maxTop = containerHeight - scrollbarYHeight;
 | 
			
		||||
 | 
			
		||||
        if (newTop < 0) {
 | 
			
		||||
          scrollbarYTop = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else if (newTop > maxTop) {
 | 
			
		||||
          scrollbarYTop = maxTop;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          scrollbarYTop = newTop;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var scrollTop = parseInt(scrollbarYTop * (contentHeight - containerHeight) / (containerHeight - scrollbarYHeight), 10);
 | 
			
		||||
        $this.scrollTop(scrollTop);
 | 
			
		||||
        $scrollbarXRail.css({bottom: scrollbarXBottom - scrollTop});
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var updateContentScrollLeft = function (currentLeft, deltaX) {
 | 
			
		||||
        var newLeft = currentLeft + deltaX,
 | 
			
		||||
            maxLeft = containerWidth - scrollbarXWidth;
 | 
			
		||||
 | 
			
		||||
        if (newLeft < 0) {
 | 
			
		||||
          scrollbarXLeft = 0;
 | 
			
		||||
        }
 | 
			
		||||
        else if (newLeft > maxLeft) {
 | 
			
		||||
          scrollbarXLeft = maxLeft;
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          scrollbarXLeft = newLeft;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var scrollLeft = parseInt(scrollbarXLeft * (contentWidth - containerWidth) / (containerWidth - scrollbarXWidth), 10);
 | 
			
		||||
        $this.scrollLeft(scrollLeft);
 | 
			
		||||
        $scrollbarYRail.css({right: scrollbarYRight - scrollLeft});
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var getSettingsAdjustedThumbSize = function (thumbSize) {
 | 
			
		||||
        if (settings.minScrollbarLength) {
 | 
			
		||||
          thumbSize = Math.max(thumbSize, settings.minScrollbarLength);
 | 
			
		||||
        }
 | 
			
		||||
        return thumbSize;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var updateScrollbarCss = function () {
 | 
			
		||||
        $scrollbarXRail.css({left: $this.scrollLeft(), bottom: scrollbarXBottom - $this.scrollTop(), width: containerWidth, display: scrollbarXActive ? "inherit": "none"});
 | 
			
		||||
        $scrollbarYRail.css({top: $this.scrollTop(), right: scrollbarYRight - $this.scrollLeft(), height: containerHeight, display: scrollbarYActive ? "inherit": "none"});
 | 
			
		||||
        $scrollbarX.css({left: scrollbarXLeft, width: scrollbarXWidth});
 | 
			
		||||
        $scrollbarY.css({top: scrollbarYTop, height: scrollbarYHeight});
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var updateBarSizeAndPosition = function () {
 | 
			
		||||
        containerWidth = $this.width();
 | 
			
		||||
        containerHeight = $this.height();
 | 
			
		||||
        contentWidth = $this.prop('scrollWidth');
 | 
			
		||||
        contentHeight = $this.prop('scrollHeight');
 | 
			
		||||
 | 
			
		||||
        if (!settings.suppressScrollX && containerWidth + settings.scrollXMarginOffset < contentWidth) {
 | 
			
		||||
          scrollbarXActive = true;
 | 
			
		||||
          scrollbarXWidth = getSettingsAdjustedThumbSize(parseInt(containerWidth * containerWidth / contentWidth, 10));
 | 
			
		||||
          scrollbarXLeft = parseInt($this.scrollLeft() * (containerWidth - scrollbarXWidth) / (contentWidth - containerWidth), 10);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          scrollbarXActive = false;
 | 
			
		||||
          scrollbarXWidth = 0;
 | 
			
		||||
          scrollbarXLeft = 0;
 | 
			
		||||
          $this.scrollLeft(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!settings.suppressScrollY && containerHeight + settings.scrollYMarginOffset < contentHeight) {
 | 
			
		||||
          scrollbarYActive = true;
 | 
			
		||||
          scrollbarYHeight = getSettingsAdjustedThumbSize(parseInt(containerHeight * containerHeight / contentHeight, 10));
 | 
			
		||||
          scrollbarYTop = parseInt($this.scrollTop() * (containerHeight - scrollbarYHeight) / (contentHeight - containerHeight), 10);
 | 
			
		||||
        }
 | 
			
		||||
        else {
 | 
			
		||||
          scrollbarYActive = false;
 | 
			
		||||
          scrollbarYHeight = 0;
 | 
			
		||||
          scrollbarYTop = 0;
 | 
			
		||||
          $this.scrollTop(0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (scrollbarYTop >= containerHeight - scrollbarYHeight) {
 | 
			
		||||
          scrollbarYTop = containerHeight - scrollbarYHeight;
 | 
			
		||||
        }
 | 
			
		||||
        if (scrollbarXLeft >= containerWidth - scrollbarXWidth) {
 | 
			
		||||
          scrollbarXLeft = containerWidth - scrollbarXWidth;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        updateScrollbarCss();
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var bindMouseScrollXHandler = function () {
 | 
			
		||||
        var currentLeft,
 | 
			
		||||
            currentPageX;
 | 
			
		||||
 | 
			
		||||
        $scrollbarX.bind('mousedown' + eventClassName, function (e) {
 | 
			
		||||
          currentPageX = e.pageX;
 | 
			
		||||
          currentLeft = $scrollbarX.position().left;
 | 
			
		||||
          $scrollbarXRail.addClass('in-scrolling');
 | 
			
		||||
          e.stopPropagation();
 | 
			
		||||
          e.preventDefault();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $(document).bind('mousemove' + eventClassName, function (e) {
 | 
			
		||||
          if ($scrollbarXRail.hasClass('in-scrolling')) {
 | 
			
		||||
            updateContentScrollLeft(currentLeft, e.pageX - currentPageX);
 | 
			
		||||
            e.stopPropagation();
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $(document).bind('mouseup' + eventClassName, function (e) {
 | 
			
		||||
          if ($scrollbarXRail.hasClass('in-scrolling')) {
 | 
			
		||||
            $scrollbarXRail.removeClass('in-scrolling');
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        currentLeft =
 | 
			
		||||
        currentPageX = null;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var bindMouseScrollYHandler = function () {
 | 
			
		||||
        var currentTop,
 | 
			
		||||
            currentPageY;
 | 
			
		||||
 | 
			
		||||
        $scrollbarY.bind('mousedown' + eventClassName, function (e) {
 | 
			
		||||
          currentPageY = e.pageY;
 | 
			
		||||
          currentTop = $scrollbarY.position().top;
 | 
			
		||||
          $scrollbarYRail.addClass('in-scrolling');
 | 
			
		||||
          e.stopPropagation();
 | 
			
		||||
          e.preventDefault();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $(document).bind('mousemove' + eventClassName, function (e) {
 | 
			
		||||
          if ($scrollbarYRail.hasClass('in-scrolling')) {
 | 
			
		||||
            updateContentScrollTop(currentTop, e.pageY - currentPageY);
 | 
			
		||||
            e.stopPropagation();
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $(document).bind('mouseup' + eventClassName, function (e) {
 | 
			
		||||
          if ($scrollbarYRail.hasClass('in-scrolling')) {
 | 
			
		||||
            $scrollbarYRail.removeClass('in-scrolling');
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        currentTop =
 | 
			
		||||
        currentPageY = null;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // check if the default scrolling should be prevented.
 | 
			
		||||
      var shouldPreventDefault = function (deltaX, deltaY) {
 | 
			
		||||
        var scrollTop = $this.scrollTop();
 | 
			
		||||
        if (deltaX === 0) {
 | 
			
		||||
          if (!scrollbarYActive) {
 | 
			
		||||
            return false;
 | 
			
		||||
          }
 | 
			
		||||
          if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= contentHeight - containerHeight && deltaY < 0)) {
 | 
			
		||||
            return !settings.wheelPropagation;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        var scrollLeft = $this.scrollLeft();
 | 
			
		||||
        if (deltaY === 0) {
 | 
			
		||||
          if (!scrollbarXActive) {
 | 
			
		||||
            return false;
 | 
			
		||||
          }
 | 
			
		||||
          if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= contentWidth - containerWidth && deltaX > 0)) {
 | 
			
		||||
            return !settings.wheelPropagation;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        return true;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // bind handlers
 | 
			
		||||
      var bindMouseWheelHandler = function () {
 | 
			
		||||
        var shouldPrevent = false;
 | 
			
		||||
        $this.bind('mousewheel' + eventClassName, function (e, deprecatedDelta, deprecatedDeltaX, deprecatedDeltaY) {
 | 
			
		||||
          var deltaX = e.deltaX ? e.deltaX / 10 : deprecatedDeltaX,
 | 
			
		||||
              deltaY = e.deltaY ? e.deltaY / 10 : deprecatedDeltaY;
 | 
			
		||||
 | 
			
		||||
          if (!settings.useBothWheelAxes) {
 | 
			
		||||
            // deltaX will only be used for horizontal scrolling and deltaY will
 | 
			
		||||
            // only be used for vertical scrolling - this is the default
 | 
			
		||||
            $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
 | 
			
		||||
            $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
 | 
			
		||||
          } else if (scrollbarYActive && !scrollbarXActive) {
 | 
			
		||||
            // only vertical scrollbar is active and useBothWheelAxes option is
 | 
			
		||||
            // active, so let's scroll vertical bar using both mouse wheel axes
 | 
			
		||||
            if (deltaY) {
 | 
			
		||||
              $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
 | 
			
		||||
            } else {
 | 
			
		||||
              $this.scrollTop($this.scrollTop() + (deltaX * settings.wheelSpeed));
 | 
			
		||||
            }
 | 
			
		||||
          } else if (scrollbarXActive && !scrollbarYActive) {
 | 
			
		||||
            // useBothWheelAxes and only horizontal bar is active, so use both
 | 
			
		||||
            // wheel axes for horizontal bar
 | 
			
		||||
            if (deltaX) {
 | 
			
		||||
              $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
 | 
			
		||||
            } else {
 | 
			
		||||
              $this.scrollLeft($this.scrollLeft() - (deltaY * settings.wheelSpeed));
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          // update bar position
 | 
			
		||||
          updateBarSizeAndPosition();
 | 
			
		||||
 | 
			
		||||
          shouldPrevent = shouldPreventDefault(deltaX, deltaY);
 | 
			
		||||
          if (shouldPrevent) {
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // fix Firefox scroll problem
 | 
			
		||||
        $this.bind('MozMousePixelScroll' + eventClassName, function (e) {
 | 
			
		||||
          if (shouldPrevent) {
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var bindKeyboardHandler = function () {
 | 
			
		||||
        var hovered = false;
 | 
			
		||||
        $this.bind('mouseenter' + eventClassName, function (e) {
 | 
			
		||||
          hovered = true;
 | 
			
		||||
        });
 | 
			
		||||
        $this.bind('mouseleave' + eventClassName, function (e) {
 | 
			
		||||
          hovered = false;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        var shouldPrevent = false;
 | 
			
		||||
        $(document).bind('keydown' + eventClassName, function (e) {
 | 
			
		||||
          if (!hovered || $(document.activeElement).is(":input,[contenteditable]")) {
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          var deltaX = 0,
 | 
			
		||||
              deltaY = 0;
 | 
			
		||||
 | 
			
		||||
          switch (e.which) {
 | 
			
		||||
          case 37: // left
 | 
			
		||||
            deltaX = -3;
 | 
			
		||||
            break;
 | 
			
		||||
          case 38: // up
 | 
			
		||||
            deltaY = 3;
 | 
			
		||||
            break;
 | 
			
		||||
          case 39: // right
 | 
			
		||||
            deltaX = 3;
 | 
			
		||||
            break;
 | 
			
		||||
          case 40: // down
 | 
			
		||||
            deltaY = -3;
 | 
			
		||||
            break;
 | 
			
		||||
          case 33: // page up
 | 
			
		||||
            deltaY = 9;
 | 
			
		||||
            break;
 | 
			
		||||
          case 32: // space bar
 | 
			
		||||
          case 34: // page down
 | 
			
		||||
            deltaY = -9;
 | 
			
		||||
            break;
 | 
			
		||||
          case 35: // end
 | 
			
		||||
            deltaY = -containerHeight;
 | 
			
		||||
            break;
 | 
			
		||||
          case 36: // home
 | 
			
		||||
            deltaY = containerHeight;
 | 
			
		||||
            break;
 | 
			
		||||
          default:
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          $this.scrollTop($this.scrollTop() - (deltaY * settings.wheelSpeed));
 | 
			
		||||
          $this.scrollLeft($this.scrollLeft() + (deltaX * settings.wheelSpeed));
 | 
			
		||||
 | 
			
		||||
          shouldPrevent = shouldPreventDefault(deltaX, deltaY);
 | 
			
		||||
          if (shouldPrevent) {
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var bindRailClickHandler = function () {
 | 
			
		||||
        var stopPropagation = function (e) { e.stopPropagation(); };
 | 
			
		||||
 | 
			
		||||
        $scrollbarY.bind('click' + eventClassName, stopPropagation);
 | 
			
		||||
        $scrollbarYRail.bind('click' + eventClassName, function (e) {
 | 
			
		||||
          var halfOfScrollbarLength = parseInt(scrollbarYHeight / 2, 10),
 | 
			
		||||
              positionTop = e.pageY - $scrollbarYRail.offset().top - halfOfScrollbarLength,
 | 
			
		||||
              maxPositionTop = containerHeight - scrollbarYHeight,
 | 
			
		||||
              positionRatio = positionTop / maxPositionTop;
 | 
			
		||||
 | 
			
		||||
          if (positionRatio < 0) {
 | 
			
		||||
            positionRatio = 0;
 | 
			
		||||
          } else if (positionRatio > 1) {
 | 
			
		||||
            positionRatio = 1;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          $this.scrollTop((contentHeight - containerHeight) * positionRatio);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $scrollbarX.bind('click' + eventClassName, stopPropagation);
 | 
			
		||||
        $scrollbarXRail.bind('click' + eventClassName, function (e) {
 | 
			
		||||
          var halfOfScrollbarLength = parseInt(scrollbarXWidth / 2, 10),
 | 
			
		||||
              positionLeft = e.pageX - $scrollbarXRail.offset().left - halfOfScrollbarLength,
 | 
			
		||||
              maxPositionLeft = containerWidth - scrollbarXWidth,
 | 
			
		||||
              positionRatio = positionLeft / maxPositionLeft;
 | 
			
		||||
 | 
			
		||||
          if (positionRatio < 0) {
 | 
			
		||||
            positionRatio = 0;
 | 
			
		||||
          } else if (positionRatio > 1) {
 | 
			
		||||
            positionRatio = 1;
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          $this.scrollLeft((contentWidth - containerWidth) * positionRatio);
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // bind mobile touch handler
 | 
			
		||||
      var bindMobileTouchHandler = function () {
 | 
			
		||||
        var applyTouchMove = function (differenceX, differenceY) {
 | 
			
		||||
          $this.scrollTop($this.scrollTop() - differenceY);
 | 
			
		||||
          $this.scrollLeft($this.scrollLeft() - differenceX);
 | 
			
		||||
 | 
			
		||||
          // update bar position
 | 
			
		||||
          updateBarSizeAndPosition();
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var startCoords = {},
 | 
			
		||||
            startTime = 0,
 | 
			
		||||
            speed = {},
 | 
			
		||||
            breakingProcess = null,
 | 
			
		||||
            inGlobalTouch = false;
 | 
			
		||||
 | 
			
		||||
        $(window).bind("touchstart" + eventClassName, function (e) {
 | 
			
		||||
          inGlobalTouch = true;
 | 
			
		||||
        });
 | 
			
		||||
        $(window).bind("touchend" + eventClassName, function (e) {
 | 
			
		||||
          inGlobalTouch = false;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $this.bind("touchstart" + eventClassName, function (e) {
 | 
			
		||||
          var touch = e.originalEvent.targetTouches[0];
 | 
			
		||||
 | 
			
		||||
          startCoords.pageX = touch.pageX;
 | 
			
		||||
          startCoords.pageY = touch.pageY;
 | 
			
		||||
 | 
			
		||||
          startTime = (new Date()).getTime();
 | 
			
		||||
 | 
			
		||||
          if (breakingProcess !== null) {
 | 
			
		||||
            clearInterval(breakingProcess);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          e.stopPropagation();
 | 
			
		||||
        });
 | 
			
		||||
        $this.bind("touchmove" + eventClassName, function (e) {
 | 
			
		||||
          if (!inGlobalTouch && e.originalEvent.targetTouches.length === 1) {
 | 
			
		||||
            var touch = e.originalEvent.targetTouches[0];
 | 
			
		||||
 | 
			
		||||
            var currentCoords = {};
 | 
			
		||||
            currentCoords.pageX = touch.pageX;
 | 
			
		||||
            currentCoords.pageY = touch.pageY;
 | 
			
		||||
 | 
			
		||||
            var differenceX = currentCoords.pageX - startCoords.pageX,
 | 
			
		||||
              differenceY = currentCoords.pageY - startCoords.pageY;
 | 
			
		||||
 | 
			
		||||
            applyTouchMove(differenceX, differenceY);
 | 
			
		||||
            startCoords = currentCoords;
 | 
			
		||||
 | 
			
		||||
            var currentTime = (new Date()).getTime();
 | 
			
		||||
 | 
			
		||||
            var timeGap = currentTime - startTime;
 | 
			
		||||
            if (timeGap > 0) {
 | 
			
		||||
              speed.x = differenceX / timeGap;
 | 
			
		||||
              speed.y = differenceY / timeGap;
 | 
			
		||||
              startTime = currentTime;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
        $this.bind("touchend" + eventClassName, function (e) {
 | 
			
		||||
          clearInterval(breakingProcess);
 | 
			
		||||
          breakingProcess = setInterval(function () {
 | 
			
		||||
            if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
 | 
			
		||||
              clearInterval(breakingProcess);
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            applyTouchMove(speed.x * 30, speed.y * 30);
 | 
			
		||||
 | 
			
		||||
            speed.x *= 0.8;
 | 
			
		||||
            speed.y *= 0.8;
 | 
			
		||||
          }, 10);
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var bindScrollHandler = function () {
 | 
			
		||||
        $this.bind('scroll' + eventClassName, function (e) {
 | 
			
		||||
          updateBarSizeAndPosition();
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var destroy = function () {
 | 
			
		||||
        $this.unbind(eventClassName);
 | 
			
		||||
        $(window).unbind(eventClassName);
 | 
			
		||||
        $(document).unbind(eventClassName);
 | 
			
		||||
        $this.data('perfect-scrollbar', null);
 | 
			
		||||
        $this.data('perfect-scrollbar-update', null);
 | 
			
		||||
        $this.data('perfect-scrollbar-destroy', null);
 | 
			
		||||
        $scrollbarX.remove();
 | 
			
		||||
        $scrollbarY.remove();
 | 
			
		||||
        $scrollbarXRail.remove();
 | 
			
		||||
        $scrollbarYRail.remove();
 | 
			
		||||
 | 
			
		||||
        // clean all variables
 | 
			
		||||
        $scrollbarX =
 | 
			
		||||
        $scrollbarY =
 | 
			
		||||
        containerWidth =
 | 
			
		||||
        containerHeight =
 | 
			
		||||
        contentWidth =
 | 
			
		||||
        contentHeight =
 | 
			
		||||
        scrollbarXWidth =
 | 
			
		||||
        scrollbarXLeft =
 | 
			
		||||
        scrollbarXBottom =
 | 
			
		||||
        scrollbarYHeight =
 | 
			
		||||
        scrollbarYTop =
 | 
			
		||||
        scrollbarYRight = null;
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var ieSupport = function (version) {
 | 
			
		||||
        $this.addClass('ie').addClass('ie' + version);
 | 
			
		||||
 | 
			
		||||
        var bindHoverHandlers = function () {
 | 
			
		||||
          var mouseenter = function () {
 | 
			
		||||
            $(this).addClass('hover');
 | 
			
		||||
          };
 | 
			
		||||
          var mouseleave = function () {
 | 
			
		||||
            $(this).removeClass('hover');
 | 
			
		||||
          };
 | 
			
		||||
          $this.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
 | 
			
		||||
          $scrollbarXRail.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
 | 
			
		||||
          $scrollbarYRail.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
 | 
			
		||||
          $scrollbarX.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
 | 
			
		||||
          $scrollbarY.bind('mouseenter' + eventClassName, mouseenter).bind('mouseleave' + eventClassName, mouseleave);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var fixIe6ScrollbarPosition = function () {
 | 
			
		||||
          updateScrollbarCss = function () {
 | 
			
		||||
            $scrollbarX.css({left: scrollbarXLeft + $this.scrollLeft(), bottom: scrollbarXBottom, width: scrollbarXWidth});
 | 
			
		||||
            $scrollbarY.css({top: scrollbarYTop + $this.scrollTop(), right: scrollbarYRight, height: scrollbarYHeight});
 | 
			
		||||
            $scrollbarX.hide().show();
 | 
			
		||||
            $scrollbarY.hide().show();
 | 
			
		||||
          };
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if (version === 6) {
 | 
			
		||||
          bindHoverHandlers();
 | 
			
		||||
          fixIe6ScrollbarPosition();
 | 
			
		||||
        }
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      var supportsTouch = (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);
 | 
			
		||||
 | 
			
		||||
      var initialize = function () {
 | 
			
		||||
        var ieMatch = navigator.userAgent.toLowerCase().match(/(msie) ([\w.]+)/);
 | 
			
		||||
        if (ieMatch && ieMatch[1] === 'msie') {
 | 
			
		||||
          // must be executed at first, because 'ieSupport' may addClass to the container
 | 
			
		||||
          ieSupport(parseInt(ieMatch[2], 10));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        updateBarSizeAndPosition();
 | 
			
		||||
        bindScrollHandler();
 | 
			
		||||
        bindMouseScrollXHandler();
 | 
			
		||||
        bindMouseScrollYHandler();
 | 
			
		||||
        bindRailClickHandler();
 | 
			
		||||
        if (supportsTouch) {
 | 
			
		||||
          bindMobileTouchHandler();
 | 
			
		||||
        }
 | 
			
		||||
        if ($this.mousewheel) {
 | 
			
		||||
          bindMouseWheelHandler();
 | 
			
		||||
        }
 | 
			
		||||
        if (settings.useKeyboard) {
 | 
			
		||||
          bindKeyboardHandler();
 | 
			
		||||
        }
 | 
			
		||||
        $this.data('perfect-scrollbar', $this);
 | 
			
		||||
        $this.data('perfect-scrollbar-update', updateBarSizeAndPosition);
 | 
			
		||||
        $this.data('perfect-scrollbar-destroy', destroy);
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // initialize
 | 
			
		||||
      initialize();
 | 
			
		||||
 | 
			
		||||
      return $this;
 | 
			
		||||
    });
 | 
			
		||||
  };
 | 
			
		||||
}));
 | 
			
		||||
@@ -1,2 +1,2 @@
 | 
			
		||||
ZULIP_VERSION = "1.6.0+git"
 | 
			
		||||
PROVISION_VERSION = '5.5'
 | 
			
		||||
PROVISION_VERSION = '5.6'
 | 
			
		||||
 
 | 
			
		||||
@@ -748,8 +748,8 @@ PIPELINE = {
 | 
			
		||||
                'third/bootstrap-notify/css/bootstrap-notify.css',
 | 
			
		||||
                'third/spectrum/spectrum.css',
 | 
			
		||||
                'third/thirdparty-fonts.css',
 | 
			
		||||
                'third/jquery-perfect-scrollbar/css/perfect-scrollbar.css',
 | 
			
		||||
                'node_modules/katex/dist/katex.css',
 | 
			
		||||
                'node_modules/perfect-scrollbar/dist/css/perfect-scrollbar.css',
 | 
			
		||||
                'styles/components.css',
 | 
			
		||||
                'styles/zulip.css',
 | 
			
		||||
                'styles/alerts.css',
 | 
			
		||||
@@ -859,7 +859,7 @@ JS_SPECS = {
 | 
			
		||||
            'third/jquery-throttle-debounce/jquery.ba-throttle-debounce.js',
 | 
			
		||||
            'third/jquery-idle/jquery.idle.js',
 | 
			
		||||
            'third/jquery-autosize/jquery.autosize.js',
 | 
			
		||||
            'third/jquery-perfect-scrollbar/js/perfect-scrollbar.js',
 | 
			
		||||
            'node_modules/perfect-scrollbar/dist/js/perfect-scrollbar.jquery.js',
 | 
			
		||||
            'third/lazyload/lazyload.js',
 | 
			
		||||
            'third/spectrum/spectrum.js',
 | 
			
		||||
            'third/sockjs/sockjs-0.3.4.js',
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user