// code taken from KineticJS morpheus.Events = function () { }; morpheus.Events.prototype = { /** * Pass in a string of events delimmited by a space to bind multiple events * at once such as 'mousedown mouseup mousemove'. Include a namespace to * bind an event by name such as 'click.foobar'. * * @param {String} * evtStr e.g. 'click', 'mousedown touchstart', 'mousedown.foo * touchstart.foo' * @param {Function} * handler The handler function is passed an event object */ on: function (evtStr, handler) { if (!handler) { throw Error('Handler not specified'); } if (!this.eventListeners) { this.eventListeners = {}; } var events = evtStr.split(' '), len = events.length, n, event, parts, baseEvent, name; /* * loop through types and attach event listeners to each one. eg. 'click * mouseover.namespace mouseout' will create three event bindings */ for (n = 0; n < len; n++) { event = events[n]; parts = event.split('.'); baseEvent = parts[0]; name = parts[1] || ''; // create events array if it doesn't exist if (!this.eventListeners[baseEvent]) { this.eventListeners[baseEvent] = []; } this.eventListeners[baseEvent].push({ name: name, handler: handler }); } return this; }, getListeners: function () { if (!this.eventListeners) { this.eventListeners = {}; } return this.eventListeners; }, setListeners: function (eventListeners) { this.eventListeners = eventListeners; }, /** * Fire an event. * * @param eventType * @param evt */ trigger: function (eventType, evt) { if (!this.eventListeners) { this.eventListeners = {}; } if (!evt) { evt = {}; } evt.type = eventType; if (!evt.source) { evt.source = this; } var events = this.eventListeners[eventType]; if (events) { var len = events.length; for (var i = 0; i < len; i++) { events[i].handler.apply(this, [evt]); } } return this; }, /** * Remove event bindings. Pass in a string of event types delimmited by a * space to remove multiple event bindings at once such as 'mousedown * mouseup mousemove'. include a namespace to remove an event binding by * name such as 'click.foobar'. If you only give a name like '.foobar', all * events in that namespace will be removed. * * @param {String} * evtStr e.g. 'click', 'mousedown.foo touchstart', '.foobar' */ off: function (evtStr, handler) { if (!this.eventListeners) { this.eventListeners = {}; } var events = (evtStr || '').split(' '), len = events.length, n, t, event, parts, baseEvent, name; if (!evtStr) { // remove all events for (t in this.eventListeners) { this._off(t, null, handler); } } for (n = 0; n < len; n++) { event = events[n]; parts = event.split('.'); baseEvent = parts[0]; name = parts[1]; if (baseEvent) { if (this.eventListeners[baseEvent]) { this._off(baseEvent, name, handler); } } else { for (t in this.eventListeners) { this._off(t, name, handler); } } } return this; }, _off: function (type, name, handler) { var evtListeners = this.eventListeners[type], i, evtName; for (i = 0; i < evtListeners.length; i++) { evtName = evtListeners[i].name; // check if an event name is not specified, or if one is specified, // it matches the current event name if ((!name || evtName === name) && (handler == null || handler == evtListeners[i].handler)) { evtListeners.splice(i, 1); if (evtListeners.length === 0) { delete this.eventListeners[type]; break; } i--; } } } };