UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

297 lines (232 loc) • 9.53 kB
"use strict"; var $ = require("../../core/renderer"), readyCallbacks = require("../../core/utils/ready_callbacks"), domAdapter = require("../../core/dom_adapter"), eventsEngine = require("../../events/core/events_engine"), dataUtils = require("../../core/element_data"), Class = require("../../core/class"), extend = require("../../core/utils/extend").extend, inArray = require("../../core/utils/array").inArray, each = require("../../core/utils/iterator").each, registerEvent = require("./event_registrator"), eventUtils = require("../utils"), pointerEvents = require("../pointer"), wheelEvent = require("./wheel"); var MANAGER_EVENT = "dxEventManager", EMITTER_DATA = "dxEmitter"; var EventManager = Class.inherit({ ctor: function ctor() { this._attachHandlers(); this.reset(); this._proxiedCancelHandler = this._cancelHandler.bind(this); this._proxiedAcceptHandler = this._acceptHandler.bind(this); }, _attachHandlers: function _attachHandlers() { readyCallbacks.add(function () { var document = domAdapter.getDocument(); eventsEngine.subscribeGlobal(document, eventUtils.addNamespace(pointerEvents.down, MANAGER_EVENT), this._pointerDownHandler.bind(this)); eventsEngine.subscribeGlobal(document, eventUtils.addNamespace(pointerEvents.move, MANAGER_EVENT), this._pointerMoveHandler.bind(this)); eventsEngine.subscribeGlobal(document, eventUtils.addNamespace([pointerEvents.up, pointerEvents.cancel].join(" "), MANAGER_EVENT), this._pointerUpHandler.bind(this)); eventsEngine.subscribeGlobal(document, eventUtils.addNamespace(wheelEvent.name, MANAGER_EVENT), this._mouseWheelHandler.bind(this)); }.bind(this)); }, _eachEmitter: function _eachEmitter(callback) { var activeEmitters = this._activeEmitters || []; var i = 0; while (activeEmitters.length > i) { var emitter = activeEmitters[i]; if (callback(emitter) === false) { break; } if (activeEmitters[i] === emitter) { i++; } } }, _applyToEmitters: function _applyToEmitters(method, arg) { this._eachEmitter(function (emitter) { emitter[method].call(emitter, arg); }); }, reset: function reset() { this._eachEmitter(this._proxiedCancelHandler); this._activeEmitters = []; }, resetEmitter: function resetEmitter(emitter) { this._proxiedCancelHandler(emitter); }, _pointerDownHandler: function _pointerDownHandler(e) { if (eventUtils.isMouseEvent(e) && e.which > 1) { return; } this._updateEmitters(e); }, _updateEmitters: function _updateEmitters(e) { if (!this._isSetChanged(e)) { return; } this._cleanEmitters(e); this._fetchEmitters(e); }, _isSetChanged: function _isSetChanged(e) { var currentSet = this._closestEmitter(e); var previousSet = this._emittersSet || []; var setChanged = currentSet.length !== previousSet.length; each(currentSet, function (index, emitter) { setChanged = setChanged || previousSet[index] !== emitter; return !setChanged; }); this._emittersSet = currentSet; return setChanged; }, _closestEmitter: function _closestEmitter(e) { var that = this, result = [], $element = $(e.target); function handleEmitter(_, emitter) { if (!!emitter && emitter.validatePointers(e) && emitter.validate(e)) { emitter.addCancelCallback(that._proxiedCancelHandler); emitter.addAcceptCallback(that._proxiedAcceptHandler); result.push(emitter); } } while ($element.length) { var emitters = dataUtils.data($element.get(0), EMITTER_DATA) || []; each(emitters, handleEmitter); $element = $element.parent(); } return result; }, _acceptHandler: function _acceptHandler(acceptedEmitter, e) { var that = this; this._eachEmitter(function (emitter) { if (emitter !== acceptedEmitter) { that._cancelEmitter(emitter, e); } }); }, _cancelHandler: function _cancelHandler(canceledEmitter, e) { this._cancelEmitter(canceledEmitter, e); }, _cancelEmitter: function _cancelEmitter(emitter, e) { var activeEmitters = this._activeEmitters; if (e) { emitter.cancel(e); } else { emitter.reset(); } emitter.removeCancelCallback(); emitter.removeAcceptCallback(); var emitterIndex = inArray(emitter, activeEmitters); if (emitterIndex > -1) { activeEmitters.splice(emitterIndex, 1); } }, _cleanEmitters: function _cleanEmitters(e) { this._applyToEmitters("end", e); this.reset(e); }, _fetchEmitters: function _fetchEmitters(e) { this._activeEmitters = this._emittersSet.slice(); this._applyToEmitters("start", e); }, _pointerMoveHandler: function _pointerMoveHandler(e) { this._applyToEmitters("move", e); }, _pointerUpHandler: function _pointerUpHandler(e) { this._updateEmitters(e); }, _mouseWheelHandler: function _mouseWheelHandler(e) { if (!this._allowInterruptionByMouseWheel()) { return; } e.pointers = [null]; this._pointerDownHandler(e); this._adjustWheelEvent(e); this._pointerMoveHandler(e); e.pointers = []; this._pointerUpHandler(e); }, _allowInterruptionByMouseWheel: function _allowInterruptionByMouseWheel() { var allowInterruption = true; this._eachEmitter(function (emitter) { allowInterruption = emitter.allowInterruptionByMouseWheel() && allowInterruption; return allowInterruption; }); return allowInterruption; }, _adjustWheelEvent: function _adjustWheelEvent(e) { var closestGestureEmitter = null; this._eachEmitter(function (emitter) { if (!emitter.gesture) { return; } var direction = emitter.getDirection(e); if (direction !== "horizontal" && !e.shiftKey || direction !== "vertical" && e.shiftKey) { closestGestureEmitter = emitter; return false; } }); if (!closestGestureEmitter) { return; } var direction = closestGestureEmitter.getDirection(e), verticalGestureDirection = direction === "both" && !e.shiftKey || direction === "vertical", prop = verticalGestureDirection ? "pageY" : "pageX"; e[prop] += e.delta; }, isActive: function isActive(element) { var result = false; this._eachEmitter(function (emitter) { result = result || emitter.getElement().is(element); }); return result; } }); var eventManager = new EventManager(); var EMITTER_SUBSCRIPTION_DATA = "dxEmitterSubscription"; var registerEmitter = function registerEmitter(emitterConfig) { var emitterClass = emitterConfig.emitter, emitterName = emitterConfig.events[0], emitterEvents = emitterConfig.events; each(emitterEvents, function (_, eventName) { registerEvent(eventName, { noBubble: !emitterConfig.bubble, setup: function setup(element) { var subscriptions = dataUtils.data(element, EMITTER_SUBSCRIPTION_DATA) || {}, emitters = dataUtils.data(element, EMITTER_DATA) || {}, emitter = emitters[emitterName] || new emitterClass(element); subscriptions[eventName] = true; emitters[emitterName] = emitter; dataUtils.data(element, EMITTER_DATA, emitters); dataUtils.data(element, EMITTER_SUBSCRIPTION_DATA, subscriptions); }, add: function add(element, handleObj) { var emitters = dataUtils.data(element, EMITTER_DATA), emitter = emitters[emitterName]; emitter.configure(extend({ delegateSelector: handleObj.selector }, handleObj.data), handleObj.type); }, teardown: function teardown(element) { var subscriptions = dataUtils.data(element, EMITTER_SUBSCRIPTION_DATA), emitters = dataUtils.data(element, EMITTER_DATA), emitter = emitters[emitterName]; delete subscriptions[eventName]; var disposeEmitter = true; each(emitterEvents, function (_, eventName) { disposeEmitter = disposeEmitter && !subscriptions[eventName]; return disposeEmitter; }); if (disposeEmitter) { if (eventManager.isActive(element)) { eventManager.resetEmitter(emitter); } emitter && emitter.dispose(); delete emitters[emitterName]; } } }); }); }; module.exports = registerEmitter;