UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

280 lines (278 loc) • 10.6 kB
/** * DevExtreme (cjs/__internal/ui/scroll_view/m_scrollable.native.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _events_engine = _interopRequireDefault(require("../../../common/core/events/core/events_engine")); var _index = require("../../../common/core/events/utils/index"); var _class = _interopRequireDefault(require("../../../core/class")); var _devices = _interopRequireDefault(require("../../../core/devices")); var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _iterator = require("../../../core/utils/iterator"); var _size = require("../../../core/utils/size"); var _m_scrollbar = _interopRequireDefault(require("./m_scrollbar")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } const SCROLLABLE_NATIVE = "dxNativeScrollable"; const SCROLLABLE_NATIVE_CLASS = "dx-scrollable-native"; const SCROLLABLE_SCROLLBAR_SIMULATED = "dx-scrollable-scrollbar-simulated"; const SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden"; const VERTICAL = "vertical"; const HORIZONTAL = "horizontal"; const HIDE_SCROLLBAR_TIMEOUT = 500; class NativeStrategy extends(_class.default.inherit({})) { ctor(scrollable) { this._init(scrollable) } _init(scrollable) { this._component = scrollable; this._$element = scrollable.$element(); this._$container = (0, _renderer.default)(scrollable.container()); this._$content = scrollable.$content(); const { direction: direction, useSimulatedScrollbar: useSimulatedScrollbar } = scrollable.option(); this._direction = direction; this._useSimulatedScrollbar = useSimulatedScrollbar; this.option = scrollable.option.bind(scrollable); this._createActionByOption = scrollable._createActionByOption.bind(scrollable); this._isLocked = scrollable._isLocked.bind(scrollable); this._isDirection = scrollable._isDirection.bind(scrollable); this._allowedDirection = scrollable._allowedDirection.bind(scrollable); this._getMaxOffset = scrollable._getMaxOffset.bind(scrollable); this._isRtlNativeStrategy = scrollable._isRtlNativeStrategy.bind(scrollable) } render() { const device = _devices.default.real(); const deviceType = device.platform; this._$element.addClass("dx-scrollable-native").addClass(`dx-scrollable-native-${deviceType}`).toggleClass(SCROLLABLE_SCROLLBARS_HIDDEN, !this._isScrollbarVisible()); if (this._isScrollbarVisible() && this._useSimulatedScrollbar) { this._renderScrollbars() } } updateRtlPosition(isFirstRender) { if (isFirstRender && this.option("rtlEnabled")) { if (this._isScrollbarVisible() && this._useSimulatedScrollbar) { this._moveScrollbars() } } } _renderScrollbars() { this._scrollbars = {}; this._hideScrollbarTimeout = 0; this._$element.addClass(SCROLLABLE_SCROLLBAR_SIMULATED); this._renderScrollbar(VERTICAL); this._renderScrollbar(HORIZONTAL) } _renderScrollbar(direction) { if (!this._isDirection(direction)) { return } this._scrollbars[direction] = new _m_scrollbar.default((0, _renderer.default)("<div>").appendTo(this._$element), { direction: direction, expandable: this._component.option("scrollByThumb") }) } handleInit(e) {} handleStart() {} handleMove(e) { if (this._isLocked()) { e.cancel = true; return } if (this._allowedDirection()) { e.originalEvent.isScrollingEvent = true } } handleEnd() {} handleCancel() {} handleStop() {} _eachScrollbar(callback) { callback = callback.bind(this); (0, _iterator.each)(this._scrollbars || {}, ((direction, scrollbar) => { callback(scrollbar, direction) })) } createActions() { this._scrollAction = this._createActionByOption("onScroll"); this._updateAction = this._createActionByOption("onUpdated") } _createActionArgs() { const { left: left, top: top } = this.location(); return { event: this._eventForUserAction, scrollOffset: this._getScrollOffset(), reachedLeft: this._isRtlNativeStrategy() ? this._isReachedRight(-left) : this._isReachedLeft(left), reachedRight: this._isRtlNativeStrategy() ? this._isReachedLeft(-Math.abs(left)) : this._isReachedRight(left), reachedTop: this._isDirection(VERTICAL) ? Math.round(top) >= 0 : void 0, reachedBottom: this._isDirection(VERTICAL) ? Math.round(Math.abs(top) - this._getMaxOffset().top) >= 0 : void 0 } } _getScrollOffset() { const { top: top, left: left } = this.location(); return { top: -top, left: this._normalizeOffsetLeft(-left) } } _normalizeOffsetLeft(scrollLeft) { if (this._isRtlNativeStrategy()) { return this._getMaxOffset().left + scrollLeft } return scrollLeft } _isReachedLeft(left) { return this._isDirection(HORIZONTAL) ? Math.round(left) >= 0 : void 0 } _isReachedRight(left) { return this._isDirection(HORIZONTAL) ? Math.round(Math.abs(left) - this._getMaxOffset().left) >= 0 : void 0 } _isScrollbarVisible() { const { showScrollbar: showScrollbar } = this.option(); return "never" !== showScrollbar && false !== showScrollbar } handleScroll(e) { var _this$_scrollAction; this._eventForUserAction = e; this._moveScrollbars(); null === (_this$_scrollAction = this._scrollAction) || void 0 === _this$_scrollAction || _this$_scrollAction.call(this, this._createActionArgs()) } _moveScrollbars() { const { top: top, left: left } = this._getScrollOffset(); this._eachScrollbar((scrollbar => { scrollbar.moveTo({ top: -top, left: -left }); scrollbar.option("visible", true) })); this._hideScrollbars() } _hideScrollbars() { clearTimeout(this._hideScrollbarTimeout); this._hideScrollbarTimeout = setTimeout((() => { this._eachScrollbar((scrollbar => { scrollbar.option("visible", false) })) }), 500) } location() { return { left: -this._$container.scrollLeft(), top: -this._$container.scrollTop() } } disabledChanged() {} update() { this._update(); this._updateAction(this._createActionArgs()) } _update() { this._updateDimensions(); this._updateScrollbars() } _updateDimensions() { this._containerSize = { height: (0, _size.getHeight)(this._$container), width: (0, _size.getWidth)(this._$container) }; this._componentContentSize = { height: (0, _size.getHeight)(this._component.$content()), width: (0, _size.getWidth)(this._component.$content()) }; this._contentSize = { height: (0, _size.getHeight)(this._$content), width: (0, _size.getWidth)(this._$content) } } _updateScrollbars() { this._eachScrollbar((function(scrollbar, direction) { const dimension = direction === VERTICAL ? "height" : "width"; scrollbar.option({ containerSize: this._containerSize[dimension], contentSize: this._componentContentSize[dimension] }); scrollbar.update() })) } _allowedDirections() { return { vertical: this._isDirection(VERTICAL) && this._contentSize.height > this._containerSize.height, horizontal: this._isDirection(HORIZONTAL) && this._contentSize.width > this._containerSize.width } } dispose() { const { className: className } = this._$element.get(0); const scrollableNativeRegexp = new RegExp("dx-scrollable-native\\S*", "g"); if (scrollableNativeRegexp.test(className)) { this._$element.removeClass(className.match(scrollableNativeRegexp).join(" ")) } _events_engine.default.off(this._$element, `.${SCROLLABLE_NATIVE}`); _events_engine.default.off(this._$container, `.${SCROLLABLE_NATIVE}`); this._removeScrollbars(); clearTimeout(this._hideScrollbarTimeout) } _removeScrollbars() { this._eachScrollbar((scrollbar => { scrollbar.$element().remove() })) } scrollBy(distance) { const location = this.location(); this._$container.scrollTop(Math.round(-location.top - distance.top)); this._$container.scrollLeft(Math.round(-location.left - distance.left)) } validate(e) { const { disabled: disabled } = this.option(); if (disabled) { return false } if ((0, _index.isDxMouseWheelEvent)(e) && this._isScrolledInMaxDirection(e)) { return false } return !!this._allowedDirection() } _isScrolledInMaxDirection(e) { const container = this._$container.get(0); let result; if (e.delta > 0) { result = e.shiftKey ? !container.scrollLeft : !container.scrollTop } else if (e.shiftKey) { result = container.scrollLeft >= this._getMaxOffset().left } else { result = container.scrollTop >= this._getMaxOffset().top } return result } getDirection() { return this._allowedDirection() } } var _default = exports.default = NativeStrategy;