mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-03-16 22:10:32 +00:00
223 lines
6.4 KiB
JavaScript
223 lines
6.4 KiB
JavaScript
(function () {
|
|
|
|
var unknown = 'unknown';
|
|
|
|
/* EVENT HANDLING */
|
|
|
|
function areHostMethods(object) {
|
|
var methodNames = Array.prototype.slice.call(arguments, 1),
|
|
t, i, len = methodNames.length;
|
|
for (i = 0; i < len; i++) {
|
|
t = typeof object[methodNames[i]];
|
|
if (!(/^(?:function|object|unknown)$/).test(t)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/** @ignore */
|
|
var getElement,
|
|
setElement,
|
|
getUniqueId = (function () {
|
|
var uid = 0;
|
|
return function (element) {
|
|
return element.__uniqueID || (element.__uniqueID = 'uniqueID__' + uid++);
|
|
};
|
|
})();
|
|
|
|
(function () {
|
|
var elements = { };
|
|
/** @ignore */
|
|
getElement = function (uid) {
|
|
return elements[uid];
|
|
};
|
|
/** @ignore */
|
|
setElement = function (uid, element) {
|
|
elements[uid] = element;
|
|
};
|
|
})();
|
|
|
|
function createListener(uid, handler) {
|
|
return {
|
|
handler: handler,
|
|
wrappedHandler: createWrappedHandler(uid, handler)
|
|
};
|
|
}
|
|
|
|
function createWrappedHandler(uid, handler) {
|
|
return function (e) {
|
|
handler.call(getElement(uid), e || fabric.window.event);
|
|
};
|
|
}
|
|
|
|
function createDispatcher(uid, eventName) {
|
|
return function (e) {
|
|
if (handlers[uid] && handlers[uid][eventName]) {
|
|
var handlersForEvent = handlers[uid][eventName];
|
|
for (var i = 0, len = handlersForEvent.length; i < len; i++) {
|
|
handlersForEvent[i].call(this, e || fabric.window.event);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
var shouldUseAddListenerRemoveListener = (
|
|
areHostMethods(fabric.document.documentElement, 'addEventListener', 'removeEventListener') &&
|
|
areHostMethods(fabric.window, 'addEventListener', 'removeEventListener')),
|
|
|
|
shouldUseAttachEventDetachEvent = (
|
|
areHostMethods(fabric.document.documentElement, 'attachEvent', 'detachEvent') &&
|
|
areHostMethods(fabric.window, 'attachEvent', 'detachEvent')),
|
|
|
|
// IE branch
|
|
listeners = { },
|
|
|
|
// DOM L0 branch
|
|
handlers = { },
|
|
|
|
addListener, removeListener;
|
|
|
|
if (shouldUseAddListenerRemoveListener) {
|
|
/** @ignore */
|
|
addListener = function (element, eventName, handler, options) {
|
|
// since ie10 or ie9 can use addEventListener but they do not support options, i need to check
|
|
element.addEventListener(eventName, handler, shouldUseAttachEventDetachEvent ? false : options);
|
|
};
|
|
/** @ignore */
|
|
removeListener = function (element, eventName, handler, options) {
|
|
element.removeEventListener(eventName, handler, shouldUseAttachEventDetachEvent ? false : options);
|
|
};
|
|
}
|
|
|
|
else if (shouldUseAttachEventDetachEvent) {
|
|
/** @ignore */
|
|
addListener = function (element, eventName, handler) {
|
|
var uid = getUniqueId(element);
|
|
setElement(uid, element);
|
|
if (!listeners[uid]) {
|
|
listeners[uid] = { };
|
|
}
|
|
if (!listeners[uid][eventName]) {
|
|
listeners[uid][eventName] = [];
|
|
|
|
}
|
|
var listener = createListener(uid, handler);
|
|
listeners[uid][eventName].push(listener);
|
|
element.attachEvent('on' + eventName, listener.wrappedHandler);
|
|
};
|
|
/** @ignore */
|
|
removeListener = function (element, eventName, handler) {
|
|
var uid = getUniqueId(element), listener;
|
|
if (listeners[uid] && listeners[uid][eventName]) {
|
|
for (var i = 0, len = listeners[uid][eventName].length; i < len; i++) {
|
|
listener = listeners[uid][eventName][i];
|
|
if (listener && listener.handler === handler) {
|
|
element.detachEvent('on' + eventName, listener.wrappedHandler);
|
|
listeners[uid][eventName][i] = null;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
else {
|
|
/** @ignore */
|
|
addListener = function (element, eventName, handler) {
|
|
var uid = getUniqueId(element);
|
|
if (!handlers[uid]) {
|
|
handlers[uid] = { };
|
|
}
|
|
if (!handlers[uid][eventName]) {
|
|
handlers[uid][eventName] = [];
|
|
var existingHandler = element['on' + eventName];
|
|
if (existingHandler) {
|
|
handlers[uid][eventName].push(existingHandler);
|
|
}
|
|
element['on' + eventName] = createDispatcher(uid, eventName);
|
|
}
|
|
handlers[uid][eventName].push(handler);
|
|
};
|
|
/** @ignore */
|
|
removeListener = function (element, eventName, handler) {
|
|
var uid = getUniqueId(element);
|
|
if (handlers[uid] && handlers[uid][eventName]) {
|
|
var handlersForEvent = handlers[uid][eventName];
|
|
for (var i = 0, len = handlersForEvent.length; i < len; i++) {
|
|
if (handlersForEvent[i] === handler) {
|
|
handlersForEvent.splice(i, 1);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Adds an event listener to an element
|
|
* @function
|
|
* @memberOf fabric.util
|
|
* @param {HTMLElement} element
|
|
* @param {String} eventName
|
|
* @param {Function} handler
|
|
*/
|
|
fabric.util.addListener = addListener;
|
|
|
|
/**
|
|
* Removes an event listener from an element
|
|
* @function
|
|
* @memberOf fabric.util
|
|
* @param {HTMLElement} element
|
|
* @param {String} eventName
|
|
* @param {Function} handler
|
|
*/
|
|
fabric.util.removeListener = removeListener;
|
|
|
|
/**
|
|
* Cross-browser wrapper for getting event's coordinates
|
|
* @memberOf fabric.util
|
|
* @param {Event} event Event object
|
|
*/
|
|
function getPointer(event) {
|
|
event || (event = fabric.window.event);
|
|
|
|
var element = event.target ||
|
|
(typeof event.srcElement !== unknown ? event.srcElement : null),
|
|
|
|
scroll = fabric.util.getScrollLeftTop(element);
|
|
|
|
return {
|
|
x: pointerX(event) + scroll.left,
|
|
y: pointerY(event) + scroll.top
|
|
};
|
|
}
|
|
|
|
var pointerX = function(event) {
|
|
return event.clientX;
|
|
},
|
|
|
|
pointerY = function(event) {
|
|
return event.clientY;
|
|
};
|
|
|
|
function _getPointer(event, pageProp, clientProp) {
|
|
var touchProp = event.type === 'touchend' ? 'changedTouches' : 'touches';
|
|
|
|
return (event[touchProp] && event[touchProp][0]
|
|
? (event[touchProp][0][pageProp] - (event[touchProp][0][pageProp] - event[touchProp][0][clientProp]))
|
|
|| event[clientProp]
|
|
: event[clientProp]);
|
|
}
|
|
|
|
if (fabric.isTouchSupported) {
|
|
pointerX = function(event) {
|
|
return _getPointer(event, 'pageX', 'clientX');
|
|
};
|
|
pointerY = function(event) {
|
|
return _getPointer(event, 'pageY', 'clientY');
|
|
};
|
|
}
|
|
|
|
fabric.util.getPointer = getPointer;
|
|
|
|
fabric.util.object.extend(fabric.util, fabric.Observable);
|
|
|
|
})();
|