ui.scrollbar.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. /**
  2. * DevExtreme (ui/scroll_view/ui.scrollbar.js)
  3. * Version: 19.1.16
  4. * Build date: Tue Oct 18 2022
  5. *
  6. * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
  7. * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
  8. */
  9. "use strict";
  10. var _renderer = require("../../core/renderer");
  11. var _renderer2 = _interopRequireDefault(_renderer);
  12. var _dom_adapter = require("../../core/dom_adapter");
  13. var _dom_adapter2 = _interopRequireDefault(_dom_adapter);
  14. var _events_engine = require("../../events/core/events_engine");
  15. var _events_engine2 = _interopRequireDefault(_events_engine);
  16. var _ready_callbacks = require("../../core/utils/ready_callbacks");
  17. var _ready_callbacks2 = _interopRequireDefault(_ready_callbacks);
  18. var _translator = require("../../animation/translator");
  19. var _translator2 = _interopRequireDefault(_translator);
  20. var _ui = require("../widget/ui.widget");
  21. var _ui2 = _interopRequireDefault(_ui);
  22. var _utils = require("../../events/utils");
  23. var _utils2 = _interopRequireDefault(_utils);
  24. var _common = require("../../core/utils/common");
  25. var _common2 = _interopRequireDefault(_common);
  26. var _type = require("../../core/utils/type");
  27. var _extend = require("../../core/utils/extend");
  28. var _pointer = require("../../events/pointer");
  29. var _pointer2 = _interopRequireDefault(_pointer);
  30. function _interopRequireDefault(obj) {
  31. return obj && obj.__esModule ? obj : {
  32. "default": obj
  33. }
  34. }
  35. var SCROLLBAR = "dxScrollbar";
  36. var SCROLLABLE_SCROLLBAR_CLASS = "dx-scrollable-scrollbar";
  37. var SCROLLABLE_SCROLLBAR_ACTIVE_CLASS = "".concat(SCROLLABLE_SCROLLBAR_CLASS, "-active");
  38. var SCROLLABLE_SCROLL_CLASS = "dx-scrollable-scroll";
  39. var SCROLLABLE_SCROLL_CONTENT_CLASS = "dx-scrollable-scroll-content";
  40. var HOVER_ENABLED_STATE = "dx-scrollbar-hoverable";
  41. var HORIZONTAL = "horizontal";
  42. var THUMB_MIN_SIZE = 15;
  43. var SCROLLBAR_VISIBLE = {
  44. onScroll: "onScroll",
  45. onHover: "onHover",
  46. always: "always",
  47. never: "never"
  48. };
  49. var Scrollbar = _ui2.default.inherit({
  50. _getDefaultOptions: function() {
  51. return (0, _extend.extend)(this.callBase(), {
  52. direction: null,
  53. visible: false,
  54. activeStateEnabled: false,
  55. visibilityMode: SCROLLBAR_VISIBLE.onScroll,
  56. containerSize: 0,
  57. contentSize: 0,
  58. expandable: true,
  59. scaleRatio: 1
  60. })
  61. },
  62. _init: function() {
  63. this.callBase();
  64. this._isHovered = false
  65. },
  66. _initMarkup: function() {
  67. this._renderThumb();
  68. this.callBase()
  69. },
  70. _render: function() {
  71. this.callBase();
  72. this._renderDirection();
  73. this._update();
  74. this._attachPointerDownHandler();
  75. this.option("hoverStateEnabled", this._isHoverMode());
  76. this.$element().toggleClass(HOVER_ENABLED_STATE, this.option("hoverStateEnabled"))
  77. },
  78. _renderThumb: function() {
  79. this._$thumb = (0, _renderer2.default)("<div>").addClass(SCROLLABLE_SCROLL_CLASS);
  80. (0, _renderer2.default)("<div>").addClass(SCROLLABLE_SCROLL_CONTENT_CLASS).appendTo(this._$thumb);
  81. this.$element().addClass(SCROLLABLE_SCROLLBAR_CLASS).append(this._$thumb)
  82. },
  83. isThumb: function($element) {
  84. return !!this.$element().find($element).length
  85. },
  86. _isHoverMode: function() {
  87. var visibilityMode = this.option("visibilityMode");
  88. return (visibilityMode === SCROLLBAR_VISIBLE.onHover || visibilityMode === SCROLLBAR_VISIBLE.always) && this.option("expandable")
  89. },
  90. _renderDirection: function() {
  91. var direction = this.option("direction");
  92. this.$element().addClass("dx-scrollbar-" + direction);
  93. this._dimension = direction === HORIZONTAL ? "width" : "height";
  94. this._prop = direction === HORIZONTAL ? "left" : "top"
  95. },
  96. _attachPointerDownHandler: function() {
  97. _events_engine2.default.on(this._$thumb, _utils2.default.addNamespace(_pointer2.default.down, SCROLLBAR), this.feedbackOn.bind(this))
  98. },
  99. feedbackOn: function() {
  100. this.$element().addClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS);
  101. activeScrollbar = this
  102. },
  103. feedbackOff: function() {
  104. this.$element().removeClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS);
  105. activeScrollbar = null
  106. },
  107. cursorEnter: function() {
  108. this._isHovered = true;
  109. if (this._needScrollbar()) {
  110. this.option("visible", true)
  111. }
  112. },
  113. cursorLeave: function() {
  114. this._isHovered = false;
  115. this.option("visible", false)
  116. },
  117. _renderDimensions: function() {
  118. this._$thumb.css({
  119. width: this.option("width"),
  120. height: this.option("height")
  121. })
  122. },
  123. _toggleVisibility: function(visible) {
  124. if (this.option("visibilityMode") === SCROLLBAR_VISIBLE.onScroll) {
  125. this._$thumb.css("opacity")
  126. }
  127. visible = this._adjustVisibility(visible);
  128. this.option().visible = visible;
  129. this._$thumb.toggleClass("dx-state-invisible", !visible)
  130. },
  131. _adjustVisibility: function(visible) {
  132. if (this._baseContainerToContentRatio && !this._needScrollbar()) {
  133. return false
  134. }
  135. switch (this.option("visibilityMode")) {
  136. case SCROLLBAR_VISIBLE.onScroll:
  137. break;
  138. case SCROLLBAR_VISIBLE.onHover:
  139. visible = visible || !!this._isHovered;
  140. break;
  141. case SCROLLBAR_VISIBLE.never:
  142. visible = false;
  143. break;
  144. case SCROLLBAR_VISIBLE.always:
  145. visible = true
  146. }
  147. return visible
  148. },
  149. moveTo: function(location) {
  150. if (this._isHidden()) {
  151. return
  152. }
  153. if ((0, _type.isPlainObject)(location)) {
  154. location = location[this._prop] || 0
  155. }
  156. var scrollBarLocation = {};
  157. scrollBarLocation[this._prop] = this._calculateScrollBarPosition(location);
  158. _translator2.default.move(this._$thumb, scrollBarLocation)
  159. },
  160. _calculateScrollBarPosition: function(location) {
  161. return -location * this._thumbRatio
  162. },
  163. _update: function() {
  164. var containerSize = Math.round(this.option("containerSize"));
  165. var contentSize = Math.round(this.option("contentSize"));
  166. var baseContainerSize = Math.round(this.option("baseContainerSize"));
  167. var baseContentSize = Math.round(this.option("baseContentSize"));
  168. if (isNaN(baseContainerSize)) {
  169. baseContainerSize = containerSize;
  170. baseContentSize = contentSize
  171. }
  172. this._baseContainerToContentRatio = baseContentSize ? baseContainerSize / baseContentSize : baseContainerSize;
  173. this._realContainerToContentRatio = contentSize ? containerSize / contentSize : containerSize;
  174. var thumbSize = Math.round(Math.max(Math.round(containerSize * this._realContainerToContentRatio), THUMB_MIN_SIZE));
  175. this._thumbRatio = (containerSize - thumbSize) / (this.option("scaleRatio") * (contentSize - containerSize));
  176. this.option(this._dimension, thumbSize / this.option("scaleRatio"));
  177. this.$element().css("display", this._needScrollbar() ? "" : "none")
  178. },
  179. _isHidden: function() {
  180. return this.option("visibilityMode") === SCROLLBAR_VISIBLE.never
  181. },
  182. _needScrollbar: function() {
  183. return !this._isHidden() && this._baseContainerToContentRatio < 1
  184. },
  185. containerToContentRatio: function() {
  186. return this._realContainerToContentRatio
  187. },
  188. _normalizeSize: function(size) {
  189. return (0, _type.isPlainObject)(size) ? size[this._dimension] || 0 : size
  190. },
  191. _clean: function() {
  192. this.callBase();
  193. if (this === activeScrollbar) {
  194. activeScrollbar = null
  195. }
  196. _events_engine2.default.off(this._$thumb, "." + SCROLLBAR)
  197. },
  198. _optionChanged: function(args) {
  199. if (this._isHidden()) {
  200. return
  201. }
  202. switch (args.name) {
  203. case "containerSize":
  204. case "contentSize":
  205. this.option()[args.name] = this._normalizeSize(args.value);
  206. this._update();
  207. break;
  208. case "baseContentSize":
  209. case "baseContainerSize":
  210. this._update();
  211. break;
  212. case "visibilityMode":
  213. case "direction":
  214. this._invalidate();
  215. break;
  216. case "scaleRatio":
  217. this._update();
  218. break;
  219. default:
  220. this.callBase.apply(this, arguments)
  221. }
  222. },
  223. update: _common2.default.deferRenderer(function() {
  224. this._adjustVisibility() && this.option("visible", true)
  225. })
  226. });
  227. var activeScrollbar = null;
  228. _ready_callbacks2.default.add(function() {
  229. _events_engine2.default.subscribeGlobal(_dom_adapter2.default.getDocument(), _utils2.default.addNamespace(_pointer2.default.up, SCROLLBAR), function() {
  230. if (activeScrollbar) {
  231. activeScrollbar.feedbackOff()
  232. }
  233. })
  234. });
  235. module.exports = Scrollbar;