From 76e8d610d07481c18db431f35a9431a98e003d89 Mon Sep 17 00:00:00 2001 From: "Rochmar Nicolas (DevExpress)" Date: Wed, 24 Jul 2024 08:45:05 +0800 Subject: [PATCH] Migrate events modules to TypeScript --- .../devextreme/js/__internal/.eslintrc.js | 1 + .../events/core/m_emitter_registrator.ts | 456 +++++++++--------- .../__internal/events/core/m_events_engine.ts | 1 - .../js/events/core/emitter_registrator.js | 1 + 4 files changed, 230 insertions(+), 229 deletions(-) create mode 100644 packages/devextreme/js/events/core/emitter_registrator.js diff --git a/packages/devextreme/js/__internal/.eslintrc.js b/packages/devextreme/js/__internal/.eslintrc.js index 0b4a9f632995..7e5daea6c821 100644 --- a/packages/devextreme/js/__internal/.eslintrc.js +++ b/packages/devextreme/js/__internal/.eslintrc.js @@ -72,6 +72,7 @@ module.exports = { '@typescript-eslint/no-unsafe-return': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-dynamic-delete': 'off', } }, // Rules for a new TS files. diff --git a/packages/devextreme/js/__internal/events/core/m_emitter_registrator.ts b/packages/devextreme/js/__internal/events/core/m_emitter_registrator.ts index ccfbbfb4797f..99f9ba67e1fc 100644 --- a/packages/devextreme/js/__internal/events/core/m_emitter_registrator.ts +++ b/packages/devextreme/js/__internal/events/core/m_emitter_registrator.ts @@ -1,297 +1,297 @@ -import $ from '../../core/renderer'; -import readyCallbacks from '../../core/utils/ready_callbacks'; -import domAdapter from '../../core/dom_adapter'; -import eventsEngine from '../../events/core/events_engine'; -import { data as elementData } from '../../core/element_data'; -import Class from '../../core/class'; -import { extend } from '../../core/utils/extend'; -import { each } from '../../core/utils/iterator'; -import registerEvent from './event_registrator'; -import { addNamespace, isMouseEvent } from '../utils/index'; -import pointerEvents from '../pointer'; -import { name as wheelEventName } from './wheel'; +import Class from '@js/core/class'; +import domAdapter from '@js/core/dom_adapter'; +import { data as elementData } from '@js/core/element_data'; +import $ from '@js/core/renderer'; +import { extend } from '@js/core/utils/extend'; +import { each } from '@js/core/utils/iterator'; +import readyCallbacks from '@js/core/utils/ready_callbacks'; +import registerEvent from '@js/events/core/event_registrator'; +import eventsEngine from '@js/events/core/events_engine'; +import { name as wheelEventName } from '@js/events/core/wheel'; +import pointerEvents from '@js/events/pointer'; +import { addNamespace, isMouseEvent } from '@js/events/utils/index'; const MANAGER_EVENT = 'dxEventManager'; const EMITTER_DATA = 'dxEmitter'; const EventManager = Class.inherit({ - ctor: function() { - this._attachHandlers(); - this.reset(); - - this._proxiedCancelHandler = this._cancelHandler.bind(this); - this._proxiedAcceptHandler = this._acceptHandler.bind(this); - }, - - _attachHandlers: function() { - readyCallbacks.add(function() { - const document = domAdapter.getDocument(); - eventsEngine.subscribeGlobal(document, addNamespace(pointerEvents.down, MANAGER_EVENT), this._pointerDownHandler.bind(this)); - eventsEngine.subscribeGlobal(document, addNamespace(pointerEvents.move, MANAGER_EVENT), this._pointerMoveHandler.bind(this)); - eventsEngine.subscribeGlobal(document, addNamespace([pointerEvents.up, pointerEvents.cancel].join(' '), MANAGER_EVENT), this._pointerUpHandler.bind(this)); - eventsEngine.subscribeGlobal(document, addNamespace(wheelEventName, MANAGER_EVENT), this._mouseWheelHandler.bind(this)); - }.bind(this)); - }, - - _eachEmitter: function(callback) { - const activeEmitters = this._activeEmitters || []; - let i = 0; - - while(activeEmitters.length > i) { - const emitter = activeEmitters[i]; - if(callback(emitter) === false) { - break; - } - - if(activeEmitters[i] === emitter) { - i++; - } - } - }, + ctor() { + this._attachHandlers(); + this.reset(); + + this._proxiedCancelHandler = this._cancelHandler.bind(this); + this._proxiedAcceptHandler = this._acceptHandler.bind(this); + }, + + _attachHandlers() { + readyCallbacks.add(() => { + const document = domAdapter.getDocument(); + (eventsEngine as any).subscribeGlobal(document, addNamespace(pointerEvents.down, MANAGER_EVENT), this._pointerDownHandler.bind(this)); + (eventsEngine as any).subscribeGlobal(document, addNamespace(pointerEvents.move, MANAGER_EVENT), this._pointerMoveHandler.bind(this)); + (eventsEngine as any).subscribeGlobal(document, addNamespace([pointerEvents.up, pointerEvents.cancel].join(' '), MANAGER_EVENT), this._pointerUpHandler.bind(this)); + (eventsEngine as any).subscribeGlobal(document, addNamespace(wheelEventName, MANAGER_EVENT), this._mouseWheelHandler.bind(this)); + }); + }, - _applyToEmitters: function(method, arg) { - this._eachEmitter(function(emitter) { - emitter[method].call(emitter, arg); - }); - }, + _eachEmitter(callback) { + const activeEmitters = this._activeEmitters || []; + let i = 0; - reset: function() { - this._eachEmitter(this._proxiedCancelHandler); - this._activeEmitters = []; - }, + while (activeEmitters.length > i) { + const emitter = activeEmitters[i]; + if (callback(emitter) === false) { + break; + } - resetEmitter: function(emitter) { - this._proxiedCancelHandler(emitter); - }, + if (activeEmitters[i] === emitter) { + i++; + } + } + }, - _pointerDownHandler: function(e) { - if(isMouseEvent(e) && e.which > 1) { - return; - } + _applyToEmitters(method, arg) { + this._eachEmitter((emitter) => { + emitter[method].call(emitter, arg); + }); + }, - this._updateEmitters(e); - }, + reset() { + this._eachEmitter(this._proxiedCancelHandler); + this._activeEmitters = []; + }, - _updateEmitters: function(e) { - if(!this._isSetChanged(e)) { - return; - } + resetEmitter(emitter) { + this._proxiedCancelHandler(emitter); + }, - this._cleanEmitters(e); - this._fetchEmitters(e); - }, + _pointerDownHandler(e) { + if (isMouseEvent(e) && e.which > 1) { + return; + } - _isSetChanged: function(e) { - const currentSet = this._closestEmitter(e); - const previousSet = this._emittersSet || []; + this._updateEmitters(e); + }, - let setChanged = currentSet.length !== previousSet.length; + _updateEmitters(e) { + if (!this._isSetChanged(e)) { + return; + } - each(currentSet, function(index, emitter) { - setChanged = setChanged || previousSet[index] !== emitter; - return !setChanged; - }); + this._cleanEmitters(e); + this._fetchEmitters(e); + }, - this._emittersSet = currentSet; + _isSetChanged(e) { + const currentSet = this._closestEmitter(e); + const previousSet = this._emittersSet || []; - return setChanged; - }, + let setChanged = currentSet.length !== previousSet.length; - _closestEmitter: function(e) { - const that = this; + each(currentSet, (index, emitter) => { + setChanged = setChanged || previousSet[index] !== emitter; + return !setChanged; + }); - const result = []; - let $element = $(e.target); + this._emittersSet = currentSet; - function handleEmitter(_, emitter) { - if(!!emitter && emitter.validatePointers(e) && emitter.validate(e)) { - emitter.addCancelCallback(that._proxiedCancelHandler); - emitter.addAcceptCallback(that._proxiedAcceptHandler); - result.push(emitter); - } - } + return setChanged; + }, - while($element.length) { - const emitters = elementData($element.get(0), EMITTER_DATA) || []; - each(emitters, handleEmitter); - $element = $element.parent(); - } + _closestEmitter(e) { + const that = this; - return result; - }, + const result: any = []; + let $element = $(e.target); - _acceptHandler: function(acceptedEmitter, e) { - const that = this; + function handleEmitter(_, emitter) { + if (!!emitter && emitter.validatePointers(e) && emitter.validate(e)) { + emitter.addCancelCallback(that._proxiedCancelHandler); + emitter.addAcceptCallback(that._proxiedAcceptHandler); + result.push(emitter); + } + } - this._eachEmitter(function(emitter) { - if(emitter !== acceptedEmitter) { - that._cancelEmitter(emitter, e); - } - }); - }, + while ($element.length) { + const emitters = elementData($element.get(0), EMITTER_DATA) || []; + each(emitters, handleEmitter); + $element = $element.parent(); + } - _cancelHandler: function(canceledEmitter, e) { - this._cancelEmitter(canceledEmitter, e); - }, + return result; + }, - _cancelEmitter: function(emitter, e) { - const activeEmitters = this._activeEmitters; + _acceptHandler(acceptedEmitter, e) { + const that = this; - if(e) { - emitter.cancel(e); - } else { - emitter.reset(); - } + this._eachEmitter((emitter) => { + if (emitter !== acceptedEmitter) { + that._cancelEmitter(emitter, e); + } + }); + }, - emitter.removeCancelCallback(); - emitter.removeAcceptCallback(); + _cancelHandler(canceledEmitter, e) { + this._cancelEmitter(canceledEmitter, e); + }, - const emitterIndex = activeEmitters.indexOf(emitter); - if(emitterIndex > -1) { - activeEmitters.splice(emitterIndex, 1); - } - }, + _cancelEmitter(emitter, e) { + const activeEmitters = this._activeEmitters; - _cleanEmitters: function(e) { - this._applyToEmitters('end', e); - this.reset(e); - }, + if (e) { + emitter.cancel(e); + } else { + emitter.reset(); + } - _fetchEmitters: function(e) { - this._activeEmitters = this._emittersSet.slice(); - this._applyToEmitters('start', e); - }, + emitter.removeCancelCallback(); + emitter.removeAcceptCallback(); - _pointerMoveHandler: function(e) { - this._applyToEmitters('move', e); - }, + const emitterIndex = activeEmitters.indexOf(emitter); + if (emitterIndex > -1) { + activeEmitters.splice(emitterIndex, 1); + } + }, - _pointerUpHandler: function(e) { - this._updateEmitters(e); - }, + _cleanEmitters(e) { + this._applyToEmitters('end', e); + this.reset(e); + }, - _mouseWheelHandler: function(e) { - if(!this._allowInterruptionByMouseWheel()) { - return; - } + _fetchEmitters(e) { + this._activeEmitters = this._emittersSet.slice(); + this._applyToEmitters('start', e); + }, - e.pointers = [null]; - this._pointerDownHandler(e); + _pointerMoveHandler(e) { + this._applyToEmitters('move', e); + }, - this._adjustWheelEvent(e); + _pointerUpHandler(e) { + this._updateEmitters(e); + }, - this._pointerMoveHandler(e); - e.pointers = []; - this._pointerUpHandler(e); - }, + _mouseWheelHandler(e) { + if (!this._allowInterruptionByMouseWheel()) { + return; + } - _allowInterruptionByMouseWheel: function() { - let allowInterruption = true; - this._eachEmitter(function(emitter) { - allowInterruption = emitter.allowInterruptionByMouseWheel() && allowInterruption; - return allowInterruption; - }); - return allowInterruption; - }, - - _adjustWheelEvent: function(e) { - let closestGestureEmitter = null; - - this._eachEmitter(function(emitter) { - if(!(emitter.gesture)) { - return; - } - - const direction = emitter.getDirection(e); - if(direction !== 'horizontal' && !e.shiftKey || direction !== 'vertical' && e.shiftKey) { - closestGestureEmitter = emitter; - return false; - } - }); + e.pointers = [null]; + this._pointerDownHandler(e); - if(!closestGestureEmitter) { - return; - } + this._adjustWheelEvent(e); - const direction = closestGestureEmitter.getDirection(e); - const verticalGestureDirection = direction === 'both' && !e.shiftKey || direction === 'vertical'; - const prop = verticalGestureDirection ? 'pageY' : 'pageX'; + this._pointerMoveHandler(e); + e.pointers = []; + this._pointerUpHandler(e); + }, - e[prop] += e.delta; - }, + _allowInterruptionByMouseWheel() { + let allowInterruption = true; + this._eachEmitter((emitter) => { + allowInterruption = emitter.allowInterruptionByMouseWheel() && allowInterruption; + return allowInterruption; + }); + return allowInterruption; + }, + + _adjustWheelEvent(e) { + let closestGestureEmitter: any = null; + // @ts-expect-error + this._eachEmitter((emitter) => { + if (!emitter.gesture) { + return; + } + + const direction = emitter.getDirection(e); + if (direction !== 'horizontal' && !e.shiftKey || direction !== 'vertical' && e.shiftKey) { + closestGestureEmitter = emitter; + return false; + } + }); - isActive: function(element) { - let result = false; - this._eachEmitter(function(emitter) { - result = result || emitter.getElement().is(element); - }); - return result; + if (!closestGestureEmitter) { + return; } + + const direction = closestGestureEmitter.getDirection(e); + const verticalGestureDirection = direction === 'both' && !e.shiftKey || direction === 'vertical'; + const prop = verticalGestureDirection ? 'pageY' : 'pageX'; + + e[prop] += e.delta; + }, + + isActive(element) { + let result = false; + this._eachEmitter((emitter) => { + result = result || emitter.getElement().is(element); + }); + return result; + }, }); const eventManager = new EventManager(); const EMITTER_SUBSCRIPTION_DATA = 'dxEmitterSubscription'; -const registerEmitter = function(emitterConfig) { - const emitterClass = emitterConfig.emitter; - const emitterName = emitterConfig.events[0]; - const emitterEvents = emitterConfig.events; +const registerEmitter = function (emitterConfig) { + const EmitterClass = emitterConfig.emitter; + const emitterName = emitterConfig.events[0]; + const emitterEvents = emitterConfig.events; - each(emitterEvents, function(_, eventName) { - registerEvent(eventName, { + each(emitterEvents, (_, eventName) => { + registerEvent(eventName, { - noBubble: !emitterConfig.bubble, + noBubble: !emitterConfig.bubble, - setup: function(element) { - const subscriptions = elementData(element, EMITTER_SUBSCRIPTION_DATA) || {}; + setup(element) { + const subscriptions = elementData(element, EMITTER_SUBSCRIPTION_DATA) || {}; - const emitters = elementData(element, EMITTER_DATA) || {}; - const emitter = emitters[emitterName] || new emitterClass(element); + const emitters = elementData(element, EMITTER_DATA) || {}; + const emitter = emitters[emitterName] || new EmitterClass(element); - subscriptions[eventName] = true; - emitters[emitterName] = emitter; + subscriptions[eventName] = true; + emitters[emitterName] = emitter; - elementData(element, EMITTER_DATA, emitters); - elementData(element, EMITTER_SUBSCRIPTION_DATA, subscriptions); - }, + elementData(element, EMITTER_DATA, emitters); + elementData(element, EMITTER_SUBSCRIPTION_DATA, subscriptions); + }, - add: function(element, handleObj) { - const emitters = elementData(element, EMITTER_DATA); - const emitter = emitters[emitterName]; + add(element, handleObj) { + const emitters = elementData(element, EMITTER_DATA); + const emitter = emitters[emitterName]; - emitter.configure(extend({ - delegateSelector: handleObj.selector - }, handleObj.data), handleObj.type); - }, + emitter.configure(extend({ + delegateSelector: handleObj.selector, + }, handleObj.data), handleObj.type); + }, - teardown: function(element) { - const subscriptions = elementData(element, EMITTER_SUBSCRIPTION_DATA); + teardown(element) { + const subscriptions = elementData(element, EMITTER_SUBSCRIPTION_DATA); - const emitters = elementData(element, EMITTER_DATA); - const emitter = emitters[emitterName]; + const emitters = elementData(element, EMITTER_DATA); + const emitter = emitters[emitterName]; - delete subscriptions[eventName]; + delete subscriptions[eventName]; - let disposeEmitter = true; - each(emitterEvents, function(_, eventName) { - disposeEmitter = disposeEmitter && !subscriptions[eventName]; - return disposeEmitter; - }); + let disposeEmitter = true; + each(emitterEvents, (_, eventName) => { + disposeEmitter = disposeEmitter && !subscriptions[eventName]; + return disposeEmitter; + }); - if(disposeEmitter) { - if(eventManager.isActive(element)) { - eventManager.resetEmitter(emitter); - } + if (disposeEmitter) { + if ((eventManager as any).isActive(element)) { + (eventManager as any).resetEmitter(emitter); + } - emitter && emitter.dispose(); - delete emitters[emitterName]; - } - } + emitter && emitter.dispose(); + delete emitters[emitterName]; + } + }, - }); }); + }); }; export default registerEmitter; diff --git a/packages/devextreme/js/__internal/events/core/m_events_engine.ts b/packages/devextreme/js/__internal/events/core/m_events_engine.ts index aac8eadaef55..ea89ad34137b 100644 --- a/packages/devextreme/js/__internal/events/core/m_events_engine.ts +++ b/packages/devextreme/js/__internal/events/core/m_events_engine.ts @@ -1,6 +1,5 @@ /* eslint-disable guard-for-in */ /* eslint-disable no-restricted-syntax */ -/* eslint-disable @typescript-eslint/no-dynamic-delete */ import domAdapter from '@js/core/dom_adapter'; import errors from '@js/core/errors'; import callOnce from '@js/core/utils/call_once'; diff --git a/packages/devextreme/js/events/core/emitter_registrator.js b/packages/devextreme/js/events/core/emitter_registrator.js new file mode 100644 index 000000000000..c9f061241a98 --- /dev/null +++ b/packages/devextreme/js/events/core/emitter_registrator.js @@ -0,0 +1 @@ +export { default } from '../../__internal/events/core/m_emitter_registrator';