2010-06-17 14:00:47 +00:00
|
|
|
(function (global) {
|
|
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
}
|
|
|
|
|
var getUniqueId = (function () {
|
|
|
|
|
if (typeof document.documentElement.uniqueID !== 'undefined') {
|
|
|
|
|
return function (element) {
|
|
|
|
|
return element.uniqueID;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
var uid = 0;
|
|
|
|
|
return function (element) {
|
|
|
|
|
return element.__uniqueID || (element.__uniqueID = 'uniqueID__' + uid++);
|
|
|
|
|
};
|
|
|
|
|
})();
|
2010-10-15 16:55:53 +00:00
|
|
|
|
|
|
|
|
/** @ignore */
|
2010-06-17 14:00:47 +00:00
|
|
|
var getElement, setElement;
|
|
|
|
|
|
|
|
|
|
(function () {
|
|
|
|
|
var elements = { };
|
2010-10-15 16:55:53 +00:00
|
|
|
/** @ignore */
|
2010-06-17 14:00:47 +00:00
|
|
|
getElement = function (uid) {
|
|
|
|
|
return elements[uid];
|
|
|
|
|
};
|
2010-10-15 16:55:53 +00:00
|
|
|
/** @ignore */
|
2010-06-17 14:00:47 +00:00
|
|
|
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 || 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 || window.event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var shouldUseAddListenerRemoveListener = (
|
|
|
|
|
areHostMethods(document.documentElement, 'addEventListener', 'removeEventListener') &&
|
|
|
|
|
areHostMethods(window, 'addEventListener', 'removeEventListener')),
|
|
|
|
|
|
|
|
|
|
shouldUseAttachEventDetachEvent = (
|
|
|
|
|
areHostMethods(document.documentElement, 'attachEvent', 'detachEvent') &&
|
|
|
|
|
areHostMethods(window, 'attachEvent', 'detachEvent')),
|
|
|
|
|
|
|
|
|
|
// IE branch
|
|
|
|
|
listeners = { },
|
|
|
|
|
|
|
|
|
|
// DOM L0 branch
|
2010-10-15 02:16:24 +00:00
|
|
|
handlers = { },
|
|
|
|
|
|
|
|
|
|
addListener, removeListener;
|
2010-06-17 14:00:47 +00:00
|
|
|
|
|
|
|
|
if (shouldUseAddListenerRemoveListener) {
|
2010-10-15 02:16:24 +00:00
|
|
|
/** @ignore */
|
2010-06-17 14:00:47 +00:00
|
|
|
addListener = function (element, eventName, handler) {
|
|
|
|
|
element.addEventListener(eventName, handler, false);
|
|
|
|
|
};
|
2010-10-15 02:16:24 +00:00
|
|
|
/** @ignore */
|
2010-06-17 14:00:47 +00:00
|
|
|
removeListener = function (element, eventName, handler) {
|
|
|
|
|
element.removeEventListener(eventName, handler, false);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (shouldUseAttachEventDetachEvent) {
|
2010-10-15 02:16:24 +00:00
|
|
|
/** @ignore */
|
2010-06-17 14:00:47 +00:00
|
|
|
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);
|
|
|
|
|
};
|
2010-10-15 02:16:24 +00:00
|
|
|
/** @ignore */
|
2010-06-17 14:00:47 +00:00
|
|
|
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 {
|
2010-10-15 02:16:24 +00:00
|
|
|
/** @ignore */
|
2010-06-17 14:00:47 +00:00
|
|
|
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);
|
|
|
|
|
};
|
2010-10-15 02:16:24 +00:00
|
|
|
/** @ignore */
|
2010-06-17 14:00:47 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-15 02:16:24 +00:00
|
|
|
/**
|
|
|
|
|
* Adds an event listener to an element
|
|
|
|
|
* @mthod addListener
|
|
|
|
|
* @memberOf fabric.util
|
|
|
|
|
* @function
|
|
|
|
|
* @param {HTMLElement} element
|
|
|
|
|
* @param {String} eventName
|
|
|
|
|
* @param {Function} handler
|
|
|
|
|
*/
|
2010-07-10 01:50:13 +00:00
|
|
|
fabric.util.addListener = addListener;
|
2010-10-15 02:16:24 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Removes an event listener from an element
|
|
|
|
|
* @mthod removeListener
|
|
|
|
|
* @memberOf fabric.util
|
|
|
|
|
* @function
|
|
|
|
|
* @param {HTMLElement} element
|
|
|
|
|
* @param {String} eventName
|
|
|
|
|
* @param {Function} handler
|
|
|
|
|
*/
|
2010-07-10 01:50:13 +00:00
|
|
|
fabric.util.removeListener = removeListener;
|
2010-06-17 14:00:47 +00:00
|
|
|
|
2010-10-15 02:16:24 +00:00
|
|
|
/**
|
|
|
|
|
* Cross-browser wrapper for getting event's coordinates
|
|
|
|
|
* @method getPointer
|
|
|
|
|
* @memberOf fabric.util
|
|
|
|
|
* @param {Event} event
|
|
|
|
|
*/
|
2010-06-17 14:00:47 +00:00
|
|
|
function getPointer(event) {
|
2010-10-15 02:16:24 +00:00
|
|
|
// TODO (kangax): this method needs fixing
|
2010-06-17 14:00:47 +00:00
|
|
|
return { x: pointerX(event), y: pointerY(event) };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function pointerX(event) {
|
|
|
|
|
var docElement = document.documentElement,
|
|
|
|
|
body = document.body || { scrollLeft: 0 };
|
2010-08-27 16:27:49 +00:00
|
|
|
|
|
|
|
|
// looks like in IE (<9) clientX at certain point (apparently when mouseup fires on VML element)
|
|
|
|
|
// is represented as COM object, with all the consequences, like "unknown" type and error on [[Get]]
|
|
|
|
|
// need to investigate later
|
|
|
|
|
return event.pageX || ((typeof event.clientX != 'unknown' ? event.clientX : 0) +
|
2010-06-17 14:00:47 +00:00
|
|
|
(docElement.scrollLeft || body.scrollLeft) -
|
|
|
|
|
(docElement.clientLeft || 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function pointerY(event) {
|
|
|
|
|
var docElement = document.documentElement,
|
|
|
|
|
body = document.body || { scrollTop: 0 };
|
|
|
|
|
|
2010-08-27 16:27:49 +00:00
|
|
|
return event.pageY || ((typeof event.clientY != 'unknown' ? event.clientY : 0) +
|
2010-06-17 14:00:47 +00:00
|
|
|
(docElement.scrollTop || body.scrollTop) -
|
|
|
|
|
(docElement.clientTop || 0));
|
|
|
|
|
}
|
|
|
|
|
|
2010-07-10 01:50:13 +00:00
|
|
|
fabric.util.getPointer = getPointer;
|
2011-06-27 22:25:45 +00:00
|
|
|
|
|
|
|
|
fabric.util.object.extend(fabric.util, fabric.Observable);
|
|
|
|
|
|
2010-06-17 14:00:47 +00:00
|
|
|
})(this);
|