UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

235 lines (181 loc) • 6.91 kB
"use strict"; var $ = require("../../core/renderer"), eventsEngine = require("../../events/core/events_engine"), devices = require("../../core/devices"), styleUtils = require("../../core/utils/style"), callOnce = require("../../core/utils/call_once"), browser = require("../../core/utils/browser"), domUtils = require("../../core/utils/dom"), readyCallbacks = require("../../core/utils/ready_callbacks"), ready = readyCallbacks.add, mathUtils = require("../../core/utils/math"), noop = require("../../core/utils/common").noop, isDefined = require("../../core/utils/type").isDefined, eventUtils = require("../utils"), Emitter = require("../core/emitter"), sign = mathUtils.sign, abs = Math.abs; var SLEEP = 0, INITED = 1, STARTED = 2, TOUCH_BOUNDARY = 10, IMMEDIATE_TOUCH_BOUNDARY = 0, IMMEDIATE_TIMEOUT = 180; var isMouseWheelEvent = function isMouseWheelEvent(e) { return e && e.type === "dxmousewheel"; }; var supportPointerEvents = function supportPointerEvents() { var cssSupport = styleUtils.styleProp("pointer-events"); var msieLess11 = browser.msie && parseInt(browser.version, 10) < 11; return cssSupport && !msieLess11; }; var setGestureCover = callOnce(function () { var GESTURE_COVER_CLASS = "dx-gesture-cover"; var isDesktop = devices.real().platform === "generic"; if (!supportPointerEvents() || !isDesktop) { return noop; } var $cover = $("<div>").addClass(GESTURE_COVER_CLASS).css("pointerEvents", "none"); eventsEngine.subscribeGlobal($cover, "dxmousewheel", function (e) { e.preventDefault(); }); ready(function () { $cover.appendTo("body"); }); return function (toggle, cursor) { $cover.css("pointerEvents", toggle ? "all" : "none"); toggle && $cover.css("cursor", cursor); }; }); var gestureCover = function gestureCover(toggle, cursor) { var gestureCoverStrategy = setGestureCover(); gestureCoverStrategy(toggle, cursor); }; var GestureEmitter = Emitter.inherit({ gesture: true, configure: function configure(data) { this.getElement().css("msTouchAction", data.immediate ? "pinch-zoom" : ""); this.callBase(data); }, allowInterruptionByMouseWheel: function allowInterruptionByMouseWheel() { return this._stage !== STARTED; }, getDirection: function getDirection() { return this.direction; }, _cancel: function _cancel() { this.callBase.apply(this, arguments); this._toggleGestureCover(false); this._stage = SLEEP; }, start: function start(e) { if (eventUtils.needSkipEvent(e)) { this._cancel(e); return; } this._startEvent = eventUtils.createEvent(e); this._startEventData = eventUtils.eventData(e); this._stage = INITED; this._init(e); this._setupImmediateTimer(); }, _setupImmediateTimer: function _setupImmediateTimer() { clearTimeout(this._immediateTimer); this._immediateAccepted = false; if (!this.immediate) { return; } this._immediateTimer = setTimeout(function () { this._immediateAccepted = true; }.bind(this), IMMEDIATE_TIMEOUT); }, move: function move(e) { if (this._stage === INITED && this._directionConfirmed(e)) { this._stage = STARTED; this._resetActiveElement(); this._toggleGestureCover(true); this._clearSelection(e); this._adjustStartEvent(e); this._start(this._startEvent); if (this._stage === SLEEP) { return; } this._requestAccept(e); this._move(e); this._forgetAccept(); } else if (this._stage === STARTED) { this._clearSelection(e); this._move(e); } }, _directionConfirmed: function _directionConfirmed(e) { var touchBoundary = this._getTouchBoundary(e), delta = eventUtils.eventDelta(this._startEventData, eventUtils.eventData(e)), deltaX = abs(delta.x), deltaY = abs(delta.y); var horizontalMove = this._validateMove(touchBoundary, deltaX, deltaY), verticalMove = this._validateMove(touchBoundary, deltaY, deltaX); var direction = this.getDirection(e), bothAccepted = direction === "both" && (horizontalMove || verticalMove), horizontalAccepted = direction === "horizontal" && horizontalMove, verticalAccepted = direction === "vertical" && verticalMove; return bothAccepted || horizontalAccepted || verticalAccepted || this._immediateAccepted; }, _validateMove: function _validateMove(touchBoundary, mainAxis, crossAxis) { return mainAxis && mainAxis >= touchBoundary && (this.immediate ? mainAxis >= crossAxis : true); }, _getTouchBoundary: function _getTouchBoundary(e) { return this.immediate || isMouseWheelEvent(e) ? IMMEDIATE_TOUCH_BOUNDARY : TOUCH_BOUNDARY; }, _adjustStartEvent: function _adjustStartEvent(e) { var touchBoundary = this._getTouchBoundary(e), delta = eventUtils.eventDelta(this._startEventData, eventUtils.eventData(e)); this._startEvent.pageX += sign(delta.x) * touchBoundary; this._startEvent.pageY += sign(delta.y) * touchBoundary; }, _resetActiveElement: function _resetActiveElement() { if (devices.real().platform === "ios" && this.getElement().find(":focus").length) { domUtils.resetActiveElement(); } }, _toggleGestureCover: function _toggleGestureCover(toggle) { var isStarted = this._stage === STARTED; if (isStarted) { gestureCover(toggle, this.getElement().css("cursor")); } }, _clearSelection: function _clearSelection(e) { if (isMouseWheelEvent(e) || eventUtils.isTouchEvent(e)) { return; } domUtils.clearSelection(); }, end: function end(e) { this._toggleGestureCover(false); if (this._stage === STARTED) { this._end(e); } else if (this._stage === INITED) { this._stop(e); } this._stage = SLEEP; }, dispose: function dispose() { clearTimeout(this._immediateTimer); this.callBase.apply(this, arguments); this._toggleGestureCover(false); }, _init: noop, _start: noop, _move: noop, _stop: noop, _end: noop }); GestureEmitter.initialTouchBoundary = TOUCH_BOUNDARY; GestureEmitter.touchBoundary = function (newBoundary) { if (isDefined(newBoundary)) { TOUCH_BOUNDARY = newBoundary; return; } return TOUCH_BOUNDARY; }; module.exports = GestureEmitter;