devextreme
Version:
HTML5 JavaScript Component Suite for Responsive Web Development
266 lines (264 loc) • 9.18 kB
JavaScript
/**
* DevExtreme (cjs/__internal/events/gesture/m_emitter.gesture.scroll.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 _frame = require("../../../common/core/animation/frame");
var _emitter_registrator = _interopRequireDefault(require("../../../common/core/events/core/emitter_registrator"));
var _events_engine = _interopRequireDefault(require("../../../common/core/events/core/events_engine"));
var _emitter = _interopRequireDefault(require("../../../common/core/events/gesture/emitter.gesture"));
var _index = require("../../../common/core/events/utils/index");
var _class = _interopRequireDefault(require("../../../core/class"));
var _m_devices = _interopRequireDefault(require("../../core/m_devices"));
function _interopRequireDefault(e) {
return e && e.__esModule ? e : {
default: e
}
}
const {
abstract: abstract
} = _class.default;
const realDevice = _m_devices.default.real();
const SCROLL_EVENT = "scroll";
const SCROLL_INIT_EVENT = "dxscrollinit";
const SCROLL_START_EVENT = "dxscrollstart";
const SCROLL_MOVE_EVENT = "dxscroll";
const SCROLL_END_EVENT = "dxscrollend";
const SCROLL_STOP_EVENT = "dxscrollstop";
const SCROLL_CANCEL_EVENT = "dxscrollcancel";
const Locker = _class.default.inherit(function() {
const NAMESPACED_SCROLL_EVENT = (0, _index.addNamespace)("scroll", "dxScrollEmitter");
return {
ctor(element) {
this._element = element;
this._locked = false;
this._proxiedScroll = e => {
if (!this._disposed) {
this._scroll(e)
}
};
_events_engine.default.on(this._element, NAMESPACED_SCROLL_EVENT, this._proxiedScroll)
},
_scroll: abstract,
check(e, callback) {
if (this._locked) {
callback()
}
},
dispose() {
this._disposed = true;
_events_engine.default.off(this._element, NAMESPACED_SCROLL_EVENT, this._proxiedScroll)
}
}
}());
const TimeoutLocker = Locker.inherit({
ctor(element, timeout) {
this.callBase(element);
this._timeout = timeout
},
_scroll() {
this._prepare();
this._forget()
},
_prepare() {
if (this._timer) {
this._clearTimer()
}
this._locked = true
},
_clearTimer() {
clearTimeout(this._timer);
this._locked = false;
this._timer = null
},
_forget() {
const that = this;
this._timer = setTimeout((() => {
that._clearTimer()
}), this._timeout)
},
dispose() {
this.callBase();
this._clearTimer()
}
});
const WheelLocker = TimeoutLocker.inherit({
ctor(element) {
this.callBase(element, 400);
this._lastWheelDirection = null
},
check(e, callback) {
this._checkDirectionChanged(e);
this.callBase(e, callback)
},
_checkDirectionChanged(e) {
if (!(0, _index.isDxMouseWheelEvent)(e)) {
this._lastWheelDirection = null;
return
}
const direction = e.shiftKey || false;
const directionChange = null !== this._lastWheelDirection && direction !== this._lastWheelDirection;
this._lastWheelDirection = direction;
this._locked = this._locked && !directionChange
}
});
let PointerLocker = TimeoutLocker.inherit({
ctor(element) {
this.callBase(element, 400)
}
});
! function() {
const {
ios: isIos,
android: isAndroid
} = realDevice;
if (!(isIos || isAndroid)) {
return
}
PointerLocker = Locker.inherit({
_scroll() {
this._locked = true;
const that = this;
(0, _frame.cancelAnimationFrame)(this._scrollFrame);
this._scrollFrame = (0, _frame.requestAnimationFrame)((() => {
that._locked = false
}))
},
check(e, callback) {
(0, _frame.cancelAnimationFrame)(this._scrollFrame);
(0, _frame.cancelAnimationFrame)(this._checkFrame);
const that = this;
const {
callBase: callBase
} = this;
this._checkFrame = (0, _frame.requestAnimationFrame)((() => {
callBase.call(that, e, callback);
that._locked = false
}))
},
dispose() {
this.callBase();
(0, _frame.cancelAnimationFrame)(this._scrollFrame);
(0, _frame.cancelAnimationFrame)(this._checkFrame)
}
})
}();
const ScrollEmitter = _emitter.default.inherit(function() {
const FRAME_DURATION = Math.round(1e3 / 60);
return {
ctor(element) {
this.callBase.apply(this, arguments);
this.direction = "both";
this._pointerLocker = new PointerLocker(element);
this._wheelLocker = new WheelLocker(element)
},
validate: () => true,
configure(data) {
if (data.scrollTarget) {
this._pointerLocker.dispose();
this._wheelLocker.dispose();
this._pointerLocker = new PointerLocker(data.scrollTarget);
this._wheelLocker = new WheelLocker(data.scrollTarget)
}
this.callBase(data)
},
_init(e) {
this._wheelLocker.check(e, (() => {
if ((0, _index.isDxMouseWheelEvent)(e)) {
this._accept(e)
}
}));
this._pointerLocker.check(e, (() => {
const skipCheck = this.isNative && (0, _index.isMouseEvent)(e);
if (!(0, _index.isDxMouseWheelEvent)(e) && !skipCheck) {
this._accept(e)
}
}));
this._fireEvent("dxscrollinit", e);
this._prevEventData = (0, _index.eventData)(e)
},
move(e) {
this.callBase.apply(this, arguments);
e.isScrollingEvent = this.isNative || e.isScrollingEvent
},
_start(e) {
this._savedEventData = (0, _index.eventData)(e);
this._fireEvent("dxscrollstart", e);
this._prevEventData = (0, _index.eventData)(e)
},
_move(e) {
const currentEventData = (0, _index.eventData)(e);
this._fireEvent("dxscroll", e, {
delta: (0, _index.eventDelta)(this._prevEventData, currentEventData)
});
const delta = (0, _index.eventDelta)(this._savedEventData, currentEventData);
if (delta.time > 200) {
this._savedEventData = this._prevEventData
}
this._prevEventData = (0, _index.eventData)(e)
},
_end(e) {
const endEventDelta = (0, _index.eventDelta)(this._prevEventData, (0, _index.eventData)(e));
let velocity = {
x: 0,
y: 0
};
if (!(0, _index.isDxMouseWheelEvent)(e) && endEventDelta.time < 100) {
const delta = (0, _index.eventDelta)(this._savedEventData, this._prevEventData);
const velocityMultiplier = FRAME_DURATION / delta.time;
velocity = {
x: delta.x * velocityMultiplier,
y: delta.y * velocityMultiplier
}
}
this._fireEvent("dxscrollend", e, {
velocity: velocity
})
},
_stop(e) {
this._fireEvent("dxscrollstop", e)
},
cancel(e) {
this.callBase.apply(this, arguments);
this._fireEvent("dxscrollcancel", e)
},
dispose() {
this.callBase.apply(this, arguments);
this._pointerLocker.dispose();
this._wheelLocker.dispose()
},
_clearSelection() {
if (this.isNative) {
return
}
return this.callBase.apply(this, arguments)
},
_toggleGestureCover() {
if (this.isNative) {
return
}
return this.callBase.apply(this, arguments)
}
}
}());
(0, _emitter_registrator.default)({
emitter: ScrollEmitter,
events: ["dxscrollinit", "dxscrollstart", "dxscroll", "dxscrollend", "dxscrollstop", "dxscrollcancel"]
});
var _default = exports.default = {
init: "dxscrollinit",
start: "dxscrollstart",
move: "dxscroll",
end: "dxscrollend",
stop: "dxscrollstop",
cancel: "dxscrollcancel",
scroll: "scroll"
};