1 /* ************************************************************************
3 qooxdoo - the new era of web development
8 2004-2006 by 1&1 Internet AG, Germany, http://www.1and1.org
11 LGPL 2.1: http://www.gnu.org/licenses/lgpl.html
14 * Sebastian Werner (wpbasti)
15 * Andreas Ecker (ecker)
17 ************************************************************************ */
19 /* ************************************************************************
23 ************************************************************************ */
26 * This is the main constructor for all objects that need to be connected to qx.event.type.Event objects.
28 * In objects created with this constructor, you find functions to addEventListener or
29 * removeEventListener to or from the created object. Each event to connect to has a type in
30 * form of an identification string. This type could be the name of a regular dom event like "click" or
31 * something self-defined like "ready".
33 * @param vAutoDispose {boolean ? true} wether the object should be disposed automatically by qooxdoo
35 qx.OO.defineClass("qx.core.Target", qx.core.Object,
36 function(vAutoDispose) {
37 qx.core.Object.call(this, vAutoDispose);
43 qx.Class.EVENTPREFIX = "evt";
49 ---------------------------------------------------------------------------
51 ---------------------------------------------------------------------------
55 * Add event listener to an object.
57 * @param vType {string} name of the event type
58 * @param vFunction {Function} event callback function
59 * @param vObject {object ? window} reference to the 'this' variable inside the callback
61 qx.Proto.addEventListener = function(vType, vFunction, vObject)
67 if(typeof vFunction !== "function") {
68 throw new Error("qx.core.Target: addEventListener(" + vType + "): '" + vFunction + "' is not a function!");
71 // If this is the first event of given type, we need to create a subobject
72 // that contains all the actions that will be assigned to this type
73 if (typeof this._listeners === "undefined")
76 this._listeners[vType] = {};
78 else if(typeof this._listeners[vType] === "undefined")
80 this._listeners[vType] = {};
83 // Create a special vKey string to allow identification of each bound action
84 var vKey = qx.core.Target.EVENTPREFIX + qx.core.Object.toHashCode(vFunction) + (vObject ? "_" + qx.core.Object.toHashCode(vObject) : "");
86 // Finally set up the listeners object
87 this._listeners[vType][vKey] =
96 * Remove event listener from object
98 * @param vType {string} name of the event type
99 * @param vFunction {Function} event callback function
100 * @param vObject {object ? window} reference to the 'this' variable inside the callback
102 qx.Proto.removeEventListener = function(vType, vFunction, vObject)
108 var vListeners = this._listeners;
109 if (!vListeners || typeof vListeners[vType] === "undefined") {
113 if(typeof vFunction !== "function") {
114 throw new Error("qx.core.Target: removeEventListener(" + vType + "): '" + vFunction + "' is not a function!");
117 // Create a special vKey string to allow identification of each bound action
118 var vKey = qx.core.Target.EVENTPREFIX + qx.core.Object.toHashCode(vFunction) + (vObject ? "_" + qx.core.Object.toHashCode(vObject) : "");
120 // Delete object entry for this action
121 delete this._listeners[vType][vKey];
127 ---------------------------------------------------------------------------
128 EVENT CONNECTION UTILITIES
129 ---------------------------------------------------------------------------
133 * Check if there are one or more listeners for an event type.
135 * @param vType {string} name of the event type
137 qx.Proto.hasEventListeners = function(vType) {
138 return this._listeners && typeof this._listeners[vType] !== "undefined" && !qx.lang.Object.isEmpty(this._listeners[vType]);
143 * Checks if the event is registered. If so it creates an event object and dispatches it.
145 * @param vType {string} name of the event type
147 qx.Proto.createDispatchEvent = function(vType)
149 if (this.hasEventListeners(vType)) {
150 this.dispatchEvent(new qx.event.type.Event(vType), true);
156 * Checks if the event is registered. If so it creates an event object and dispatches it.
158 * @param vType {string} name of the event type
159 * @param vData {Object} user defined data attached to the event object
161 qx.Proto.createDispatchDataEvent = function(vType, vData)
163 if (this.hasEventListeners(vType)) {
164 this.dispatchEvent(new qx.event.type.DataEvent(vType, vData), true);
171 ---------------------------------------------------------------------------
173 ---------------------------------------------------------------------------
179 * @param vEvent {qx.event.type.Event} event to dispatch
180 * @param vEnableDispose {boolean} wether the event object should be disposed after all event handlers run.
181 * @return {boolean} wether the event default was prevented or not. Returns true, when the event was NOT prevented.
183 qx.Proto.dispatchEvent = function(vEvent, vEnableDispose)
185 // Ignore event if eventTarget is disposed
186 if(this.getDisposed() && this.getEnabled()) {
190 if (vEvent.getTarget() == null) {
191 vEvent.setTarget(this);
194 if (vEvent.getCurrentTarget() == null) {
195 vEvent.setCurrentTarget(this);
199 this._dispatchEvent(vEvent, vEnableDispose);
201 // Read default prevented
202 var defaultPrevented = vEvent._defaultPrevented;
204 // enable dispose for event?
205 vEnableDispose && vEvent.dispose();
207 return !defaultPrevented;
212 * Internal event dispatch method
214 * @param vEvent {qx.event.type.Event} event to dispatch
216 qx.Proto._dispatchEvent = function(vEvent)
218 var vListeners = this._listeners;
221 // Setup current target
222 vEvent.setCurrentTarget(this);
224 // Shortcut for listener data
225 var vTypeListeners = vListeners[vEvent.getType()];
229 var vFunction, vObject;
231 // Handle all events for the specified type
232 for (var vHashCode in vTypeListeners)
234 // Shortcuts for handler and object
235 vFunction = vTypeListeners[vHashCode].handler;
236 vObject = vTypeListeners[vHashCode].object;
238 // Call object function
241 if(typeof vFunction === "function") {
242 vFunction.call(qx.util.Validation.isValid(vObject) ? vObject : this, vEvent);
247 this.error("Could not dispatch event of type \"" + vEvent.getType() + "\"", ex);
253 // Bubble event to parents
254 // TODO: Move this to Parent or Widget?
255 if(vEvent.getBubbles() && !vEvent.getPropagationStopped() && this.getParent)
257 var vParent = this.getParent();
258 if (vParent && !vParent.getDisposed() && vParent.getEnabled()) {
259 vParent._dispatchEvent(vEvent);
268 ---------------------------------------------------------------------------
270 ---------------------------------------------------------------------------
276 qx.Proto.dispose = function()
278 if(this.getDisposed()) {
282 if (typeof this._listeners === "object")
284 for (var vType in this._listeners)
286 var listener = this._listeners[vType];
287 for (var vKey in listener)
289 listener[vKey] = null;
292 this._listeners[vType] = null;
296 this._listeners = null;
298 return qx.core.Object.prototype.dispose.call(this);