EnVisageOnline/Main/Source/EnVisage/Scripts/Kendo/kendo.userevents.js

478 lines
22 KiB
JavaScript

/**
* Kendo UI v2016.1.226 (http://www.telerik.com/kendo-ui)
* Copyright 2016 Telerik AD. All rights reserved.
*
* Kendo UI commercial licenses may be obtained at
* http://www.telerik.com/purchase/license-agreement/kendo-ui-complete
* If you do not own a commercial license, this file shall be governed by the trial license terms.
*/
(function (f, define) {
define('kendo.userevents', ['kendo.core'], f);
}(function () {
var __meta__ = {
id: 'userevents',
name: 'User Events',
category: 'framework',
depends: ['core'],
hidden: true
};
(function ($, undefined) {
var kendo = window.kendo, support = kendo.support, document = window.document, Class = kendo.Class, Observable = kendo.Observable, now = $.now, extend = $.extend, OS = support.mobileOS, invalidZeroEvents = OS && OS.android, DEFAULT_MIN_HOLD = 800, DEFAULT_THRESHOLD = support.browser.msie ? 5 : 0, PRESS = 'press', HOLD = 'hold', SELECT = 'select', START = 'start', MOVE = 'move', END = 'end', CANCEL = 'cancel', TAP = 'tap', RELEASE = 'release', GESTURESTART = 'gesturestart', GESTURECHANGE = 'gesturechange', GESTUREEND = 'gestureend', GESTURETAP = 'gesturetap';
var THRESHOLD = {
'api': 0,
'touch': 0,
'mouse': 9,
'pointer': 9
};
var ENABLE_GLOBAL_SURFACE = !support.touch || support.mouseAndTouchPresent;
function touchDelta(touch1, touch2) {
var x1 = touch1.x.location, y1 = touch1.y.location, x2 = touch2.x.location, y2 = touch2.y.location, dx = x1 - x2, dy = y1 - y2;
return {
center: {
x: (x1 + x2) / 2,
y: (y1 + y2) / 2
},
distance: Math.sqrt(dx * dx + dy * dy)
};
}
function getTouches(e) {
var touches = [], originalEvent = e.originalEvent, currentTarget = e.currentTarget, idx = 0, length, changedTouches, touch;
if (e.api) {
touches.push({
id: 2,
event: e,
target: e.target,
currentTarget: e.target,
location: e,
type: 'api'
});
} else if (e.type.match(/touch/)) {
changedTouches = originalEvent ? originalEvent.changedTouches : [];
for (length = changedTouches.length; idx < length; idx++) {
touch = changedTouches[idx];
touches.push({
location: touch,
event: e,
target: touch.target,
currentTarget: currentTarget,
id: touch.identifier,
type: 'touch'
});
}
} else if (support.pointers || support.msPointers) {
touches.push({
location: originalEvent,
event: e,
target: e.target,
currentTarget: currentTarget,
id: originalEvent.pointerId,
type: 'pointer'
});
} else {
touches.push({
id: 1,
event: e,
target: e.target,
currentTarget: currentTarget,
location: e,
type: 'mouse'
});
}
return touches;
}
var TouchAxis = Class.extend({
init: function (axis, location) {
var that = this;
that.axis = axis;
that._updateLocationData(location);
that.startLocation = that.location;
that.velocity = that.delta = 0;
that.timeStamp = now();
},
move: function (location) {
var that = this, offset = location['page' + that.axis], timeStamp = now(), timeDelta = timeStamp - that.timeStamp || 1;
if (!offset && invalidZeroEvents) {
return;
}
that.delta = offset - that.location;
that._updateLocationData(location);
that.initialDelta = offset - that.startLocation;
that.velocity = that.delta / timeDelta;
that.timeStamp = timeStamp;
},
_updateLocationData: function (location) {
var that = this, axis = that.axis;
that.location = location['page' + axis];
that.client = location['client' + axis];
that.screen = location['screen' + axis];
}
});
var Touch = Class.extend({
init: function (userEvents, target, touchInfo) {
extend(this, {
x: new TouchAxis('X', touchInfo.location),
y: new TouchAxis('Y', touchInfo.location),
type: touchInfo.type,
useClickAsTap: userEvents.useClickAsTap,
threshold: userEvents.threshold || THRESHOLD[touchInfo.type],
userEvents: userEvents,
target: target,
currentTarget: touchInfo.currentTarget,
initialTouch: touchInfo.target,
id: touchInfo.id,
pressEvent: touchInfo,
_moved: false,
_finished: false
});
},
press: function () {
this._holdTimeout = setTimeout($.proxy(this, '_hold'), this.userEvents.minHold);
this._trigger(PRESS, this.pressEvent);
},
_hold: function () {
this._trigger(HOLD, this.pressEvent);
},
move: function (touchInfo) {
var that = this;
if (that._finished) {
return;
}
that.x.move(touchInfo.location);
that.y.move(touchInfo.location);
if (!that._moved) {
if (that._withinIgnoreThreshold()) {
return;
}
if (!UserEvents.current || UserEvents.current === that.userEvents) {
that._start(touchInfo);
} else {
return that.dispose();
}
}
if (!that._finished) {
that._trigger(MOVE, touchInfo);
}
},
end: function (touchInfo) {
this.endTime = now();
if (this._finished) {
return;
}
this._finished = true;
this._trigger(RELEASE, touchInfo);
if (this._moved) {
this._trigger(END, touchInfo);
} else {
if (!this.useClickAsTap) {
this._trigger(TAP, touchInfo);
}
}
clearTimeout(this._holdTimeout);
this.dispose();
},
dispose: function () {
var userEvents = this.userEvents, activeTouches = userEvents.touches;
this._finished = true;
this.pressEvent = null;
clearTimeout(this._holdTimeout);
activeTouches.splice($.inArray(this, activeTouches), 1);
},
skip: function () {
this.dispose();
},
cancel: function () {
this.dispose();
},
isMoved: function () {
return this._moved;
},
_start: function (touchInfo) {
clearTimeout(this._holdTimeout);
this.startTime = now();
this._moved = true;
this._trigger(START, touchInfo);
},
_trigger: function (name, touchInfo) {
var that = this, jQueryEvent = touchInfo.event, data = {
touch: that,
x: that.x,
y: that.y,
target: that.target,
event: jQueryEvent
};
if (that.userEvents.notify(name, data)) {
jQueryEvent.preventDefault();
}
},
_withinIgnoreThreshold: function () {
var xDelta = this.x.initialDelta, yDelta = this.y.initialDelta;
return Math.sqrt(xDelta * xDelta + yDelta * yDelta) <= this.threshold;
}
});
function withEachUpEvent(callback) {
var downEvents = kendo.eventMap.up.split(' '), idx = 0, length = downEvents.length;
for (; idx < length; idx++) {
callback(downEvents[idx]);
}
}
var UserEvents = Observable.extend({
init: function (element, options) {
var that = this, filter, ns = kendo.guid();
options = options || {};
filter = that.filter = options.filter;
that.threshold = options.threshold || DEFAULT_THRESHOLD;
that.minHold = options.minHold || DEFAULT_MIN_HOLD;
that.touches = [];
that._maxTouches = options.multiTouch ? 2 : 1;
that.allowSelection = options.allowSelection;
that.captureUpIfMoved = options.captureUpIfMoved;
that.useClickAsTap = !options.fastTap && !support.delayedClick();
that.eventNS = ns;
element = $(element).handler(that);
Observable.fn.init.call(that);
extend(that, {
element: element,
surface: options.global && ENABLE_GLOBAL_SURFACE ? $(document.documentElement) : $(options.surface || element),
stopPropagation: options.stopPropagation,
pressed: false
});
that.surface.handler(that).on(kendo.applyEventMap('move', ns), '_move').on(kendo.applyEventMap('up cancel', ns), '_end');
element.on(kendo.applyEventMap('down', ns), filter, '_start');
if (that.useClickAsTap) {
element.on(kendo.applyEventMap('click', ns), filter, '_click');
}
if (support.pointers || support.msPointers) {
if (support.browser.version < 11) {
element.css('-ms-touch-action', 'pinch-zoom double-tap-zoom');
} else {
element.css('touch-action', 'pan-y');
}
}
if (options.preventDragEvent) {
element.on(kendo.applyEventMap('dragstart', ns), kendo.preventDefault);
}
element.on(kendo.applyEventMap('mousedown', ns), filter, { root: element }, '_select');
if (that.captureUpIfMoved && support.eventCapture) {
var surfaceElement = that.surface[0], preventIfMovingProxy = $.proxy(that.preventIfMoving, that);
withEachUpEvent(function (eventName) {
surfaceElement.addEventListener(eventName, preventIfMovingProxy, true);
});
}
that.bind([
PRESS,
HOLD,
TAP,
START,
MOVE,
END,
RELEASE,
CANCEL,
GESTURESTART,
GESTURECHANGE,
GESTUREEND,
GESTURETAP,
SELECT
], options);
},
preventIfMoving: function (e) {
if (this._isMoved()) {
e.preventDefault();
}
},
destroy: function () {
var that = this;
if (that._destroyed) {
return;
}
that._destroyed = true;
if (that.captureUpIfMoved && support.eventCapture) {
var surfaceElement = that.surface[0];
withEachUpEvent(function (eventName) {
surfaceElement.removeEventListener(eventName, that.preventIfMoving);
});
}
that.element.kendoDestroy(that.eventNS);
that.surface.kendoDestroy(that.eventNS);
that.element.removeData('handler');
that.surface.removeData('handler');
that._disposeAll();
that.unbind();
delete that.surface;
delete that.element;
delete that.currentTarget;
},
capture: function () {
UserEvents.current = this;
},
cancel: function () {
this._disposeAll();
this.trigger(CANCEL);
},
notify: function (eventName, data) {
var that = this, touches = that.touches;
if (this._isMultiTouch()) {
switch (eventName) {
case MOVE:
eventName = GESTURECHANGE;
break;
case END:
eventName = GESTUREEND;
break;
case TAP:
eventName = GESTURETAP;
break;
}
extend(data, { touches: touches }, touchDelta(touches[0], touches[1]));
}
return this.trigger(eventName, extend(data, { type: eventName }));
},
press: function (x, y, target) {
this._apiCall('_start', x, y, target);
},
move: function (x, y) {
this._apiCall('_move', x, y);
},
end: function (x, y) {
this._apiCall('_end', x, y);
},
_isMultiTouch: function () {
return this.touches.length > 1;
},
_maxTouchesReached: function () {
return this.touches.length >= this._maxTouches;
},
_disposeAll: function () {
var touches = this.touches;
while (touches.length > 0) {
touches.pop().dispose();
}
},
_isMoved: function () {
return $.grep(this.touches, function (touch) {
return touch.isMoved();
}).length;
},
_select: function (e) {
if (!this.allowSelection || this.trigger(SELECT, { event: e })) {
e.preventDefault();
}
},
_start: function (e) {
var that = this, idx = 0, filter = that.filter, target, touches = getTouches(e), length = touches.length, touch, which = e.which;
if (which && which > 1 || that._maxTouchesReached()) {
return;
}
UserEvents.current = null;
that.currentTarget = e.currentTarget;
if (that.stopPropagation) {
e.stopPropagation();
}
for (; idx < length; idx++) {
if (that._maxTouchesReached()) {
break;
}
touch = touches[idx];
if (filter) {
target = $(touch.currentTarget);
} else {
target = that.element;
}
if (!target.length) {
continue;
}
touch = new Touch(that, target, touch);
that.touches.push(touch);
touch.press();
if (that._isMultiTouch()) {
that.notify('gesturestart', {});
}
}
},
_move: function (e) {
this._eachTouch('move', e);
},
_end: function (e) {
this._eachTouch('end', e);
},
_click: function (e) {
var data = {
touch: {
initialTouch: e.target,
target: $(e.currentTarget),
endTime: now(),
x: {
location: e.pageX,
client: e.clientX
},
y: {
location: e.pageY,
client: e.clientY
}
},
x: e.pageX,
y: e.pageY,
target: $(e.currentTarget),
event: e,
type: 'tap'
};
if (this.trigger('tap', data)) {
e.preventDefault();
}
},
_eachTouch: function (methodName, e) {
var that = this, dict = {}, touches = getTouches(e), activeTouches = that.touches, idx, touch, touchInfo, matchingTouch;
for (idx = 0; idx < activeTouches.length; idx++) {
touch = activeTouches[idx];
dict[touch.id] = touch;
}
for (idx = 0; idx < touches.length; idx++) {
touchInfo = touches[idx];
matchingTouch = dict[touchInfo.id];
if (matchingTouch) {
matchingTouch[methodName](touchInfo);
}
}
},
_apiCall: function (type, x, y, target) {
this[type]({
api: true,
pageX: x,
pageY: y,
clientX: x,
clientY: y,
target: $(target || this.element)[0],
stopPropagation: $.noop,
preventDefault: $.noop
});
}
});
UserEvents.defaultThreshold = function (value) {
DEFAULT_THRESHOLD = value;
};
UserEvents.minHold = function (value) {
DEFAULT_MIN_HOLD = value;
};
kendo.getTouches = getTouches;
kendo.touchDelta = touchDelta;
kendo.UserEvents = UserEvents;
}(window.kendo.jQuery));
return window.kendo;
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
(a3 || a2)();
}));