<html>\r
<head>\r
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> \r
<title>The source code</title>\r
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
me.events = e || {};
};
-EXTUTIL.Observable.prototype = function(){
- var filterOptRe = /^(?:scope|delay|buffer|single)$/, toLower = function(s){
- return s.toLowerCase();
- };
-
- return {
- <div id="method-Ext.util.Observable-fireEvent"></div>/**
- * <p>Fires the specified event with the passed parameters (minus the event name).</p>
- * <p>An event may be set to bubble up an Observable parent hierarchy (See {@link Ext.Component#getBubbleTarget})
- * by calling {@link #enableBubble}.</p>
- * @param {String} eventName The name of the event to fire.
- * @param {Object...} args Variable number of parameters are passed to handlers.
- * @return {Boolean} returns false if any of the handlers return false otherwise it returns true.
- */
-
- fireEvent : function(){
- var a = TOARRAY(arguments),
- ename = toLower(a[0]),
- me = this,
- ret = TRUE,
- ce = me.events[ename],
- q,
- c;
- if (me.eventsSuspended === TRUE) {
- if (q = me.suspendedEventsQueue) {
- q.push(a);
- }
+EXTUTIL.Observable.prototype = {
+ // private
+ filterOptRe : /^(?:scope|delay|buffer|single)$/,
+
+ <div id="method-Ext.util.Observable-fireEvent"></div>/**
+ * <p>Fires the specified event with the passed parameters (minus the event name).</p>
+ * <p>An event may be set to bubble up an Observable parent hierarchy (See {@link Ext.Component#getBubbleTarget})
+ * by calling {@link #enableBubble}.</p>
+ * @param {String} eventName The name of the event to fire.
+ * @param {Object...} args Variable number of parameters are passed to handlers.
+ * @return {Boolean} returns false if any of the handlers return false otherwise it returns true.
+ */
+ fireEvent : function(){
+ var a = TOARRAY(arguments),
+ ename = a[0].toLowerCase(),
+ me = this,
+ ret = TRUE,
+ ce = me.events[ename],
+ q,
+ c;
+ if (me.eventsSuspended === TRUE) {
+ if (q = me.eventQueue) {
+ q.push(a);
}
- else if(ISOBJECT(ce) && ce.bubble){
- if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
- return FALSE;
- }
- c = me.getBubbleTarget && me.getBubbleTarget();
- if(c && c.enableBubble) {
+ }
+ else if(ISOBJECT(ce) && ce.bubble){
+ if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
+ return FALSE;
+ }
+ c = me.getBubbleTarget && me.getBubbleTarget();
+ if(c && c.enableBubble) {
+ if(!c.events[ename] || !Ext.isObject(c.events[ename]) || !c.events[ename].bubble) {
c.enableBubble(ename);
- return c.fireEvent.apply(c, a);
}
+ return c.fireEvent.apply(c, a);
}
- else {
- if (ISOBJECT(ce)) {
- a.shift();
- ret = ce.fire.apply(ce, a);
- }
+ }
+ else {
+ if (ISOBJECT(ce)) {
+ a.shift();
+ ret = ce.fire.apply(ce, a);
}
- return ret;
- },
-
- <div id="method-Ext.util.Observable-addListener"></div>/**
- * Appends an event handler to this object.
- * @param {String} eventName The name of the event to listen for.
- * @param {Function} handler The method the event invokes.
- * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the handler function is executed.
- * <b>If omitted, defaults to the object which fired the event.</b>
- * @param {Object} options (optional) An object containing handler configuration.
- * properties. This may contain any of the following properties:<ul>
- * <li><b>scope</b> : Object<div class="sub-desc">The scope (<code><b>this</b></code> reference) in which the handler function is executed.
- * <b>If omitted, defaults to the object which fired the event.</b></div></li>
- * <li><b>delay</b> : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after the event fires.</div></li>
- * <li><b>single</b> : Boolean<div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
- * <li><b>buffer</b> : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
- * by the specified number of milliseconds. If the event fires again within that time, the original
- * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
- * <li><b>target</b> : Observable<div class="sub-desc">Only call the handler if the event was fired on the target Observable, <i>not</i>
- * if the event was bubbled up from a child Observable.</div></li>
- * </ul><br>
- * <p>
- * <b>Combining Options</b><br>
- * Using the options argument, it is possible to combine different types of listeners:<br>
- * <br>
- * A delayed, one-time listener.
- * <pre><code>
-myDataView.on('click', this.onClick, this, {
- single: true,
- delay: 100
-});</code></pre>
- * <p>
- * <b>Attaching multiple handlers in 1 call</b><br>
- * The method also allows for a single argument to be passed which is a config object containing properties
- * which specify multiple handlers.
- * <p>
- * <pre><code>
-myGridPanel.on({
- 'click' : {
- fn: this.onClick,
- scope: this,
- delay: 100
- },
- 'mouseover' : {
- fn: this.onMouseOver,
- scope: this
+ }
+ return ret;
},
- 'mouseout' : {
- fn: this.onMouseOut,
- scope: this
- }
+
+ <div id="method-Ext.util.Observable-addListener"></div>/**
+ * Appends an event handler to this object.
+ * @param {String} eventName The name of the event to listen for.
+ * @param {Function} handler The method the event invokes.
+ * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the handler function is executed.
+ * <b>If omitted, defaults to the object which fired the event.</b>
+ * @param {Object} options (optional) An object containing handler configuration.
+ * properties. This may contain any of the following properties:<ul>
+ * <li><b>scope</b> : Object<div class="sub-desc">The scope (<code><b>this</b></code> reference) in which the handler function is executed.
+ * <b>If omitted, defaults to the object which fired the event.</b></div></li>
+ * <li><b>delay</b> : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after the event fires.</div></li>
+ * <li><b>single</b> : Boolean<div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
+ * <li><b>buffer</b> : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
+ * by the specified number of milliseconds. If the event fires again within that time, the original
+ * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
+ * <li><b>target</b> : Observable<div class="sub-desc">Only call the handler if the event was fired on the target Observable, <i>not</i>
+ * if the event was bubbled up from a child Observable.</div></li>
+ * </ul><br>
+ * <p>
+ * <b>Combining Options</b><br>
+ * Using the options argument, it is possible to combine different types of listeners:<br>
+ * <br>
+ * A delayed, one-time listener.
+ * <pre><code>
+myDataView.on('click', this.onClick, this, {
+single: true,
+delay: 100
});</code></pre>
* <p>
- * Or a shorthand syntax:<br>
+ * <b>Attaching multiple handlers in 1 call</b><br>
+ * The method also allows for a single argument to be passed which is a config object containing properties
+ * which specify multiple handlers.
+ * <p>
* <pre><code>
myGridPanel.on({
- 'click' : this.onClick,
- 'mouseover' : this.onMouseOver,
- 'mouseout' : this.onMouseOut,
- scope: this
+'click' : {
+ fn: this.onClick,
+ scope: this,
+ delay: 100
+},
+'mouseover' : {
+ fn: this.onMouseOver,
+ scope: this
+},
+'mouseout' : {
+ fn: this.onMouseOut,
+ scope: this
+}
});</code></pre>
- */
- addListener : function(eventName, fn, scope, o){
- var me = this,
- e,
- oe,
- isF,
- ce;
- if (ISOBJECT(eventName)) {
- o = eventName;
- for (e in o){
- oe = o[e];
- if (!filterOptRe.test(e)) {
- me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
- }
- }
- } else {
- eventName = toLower(eventName);
- ce = me.events[eventName] || TRUE;
- if (typeof ce == "boolean") {
- me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
+ * <p>
+ * Or a shorthand syntax:<br>
+ * <pre><code>
+myGridPanel.on({
+'click' : this.onClick,
+'mouseover' : this.onMouseOver,
+'mouseout' : this.onMouseOut,
+ scope: this
+});</code></pre>
+ */
+ addListener : function(eventName, fn, scope, o){
+ var me = this,
+ e,
+ oe,
+ isF,
+ ce;
+ if (ISOBJECT(eventName)) {
+ o = eventName;
+ for (e in o){
+ oe = o[e];
+ if (!me.filterOptRe.test(e)) {
+ me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
}
- ce.addListener(fn, scope, ISOBJECT(o) ? o : {});
- }
- },
-
- <div id="method-Ext.util.Observable-removeListener"></div>/**
- * Removes an event handler.
- * @param {String} eventName The type of event the handler was associated with.
- * @param {Function} handler The handler to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
- * @param {Object} scope (optional) The scope originally specified for the handler.
- */
- removeListener : function(eventName, fn, scope){
- var ce = this.events[toLower(eventName)];
- if (ISOBJECT(ce)) {
- ce.removeListener(fn, scope);
}
- },
-
- <div id="method-Ext.util.Observable-purgeListeners"></div>/**
- * Removes all listeners for this object
- */
- purgeListeners : function(){
- var events = this.events,
- evt,
- key;
- for(key in events){
- evt = events[key];
- if(ISOBJECT(evt)){
- evt.clearListeners();
- }
+ } else {
+ eventName = eventName.toLowerCase();
+ ce = me.events[eventName] || TRUE;
+ if (Ext.isBoolean(ce)) {
+ me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
}
- },
-
- <div id="method-Ext.util.Observable-addEvents"></div>/**
- * Used to define events on this Observable
- * @param {Object} object The object with the events defined
- */
- addEvents : function(o){
- var me = this;
- me.events = me.events || {};
- if (typeof o == 'string') {
- EACH(arguments, function(a) {
- me.events[a] = me.events[a] || TRUE;
- });
- } else {
- Ext.applyIf(me.events, o);
+ ce.addListener(fn, scope, ISOBJECT(o) ? o : {});
+ }
+ },
+
+ <div id="method-Ext.util.Observable-removeListener"></div>/**
+ * Removes an event handler.
+ * @param {String} eventName The type of event the handler was associated with.
+ * @param {Function} handler The handler to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
+ * @param {Object} scope (optional) The scope originally specified for the handler.
+ */
+ removeListener : function(eventName, fn, scope){
+ var ce = this.events[eventName.toLowerCase()];
+ if (ISOBJECT(ce)) {
+ ce.removeListener(fn, scope);
+ }
+ },
+
+ <div id="method-Ext.util.Observable-purgeListeners"></div>/**
+ * Removes all listeners for this object
+ */
+ purgeListeners : function(){
+ var events = this.events,
+ evt,
+ key;
+ for(key in events){
+ evt = events[key];
+ if(ISOBJECT(evt)){
+ evt.clearListeners();
}
- },
-
- <div id="method-Ext.util.Observable-hasListener"></div>/**
- * Checks to see if this object has any listeners for a specified event
- * @param {String} eventName The name of the event to check for
- * @return {Boolean} True if the event is being listened for, else false
- */
- hasListener : function(eventName){
- var e = this.events[eventName];
- return ISOBJECT(e) && e.listeners.length > 0;
- },
-
- <div id="method-Ext.util.Observable-suspendEvents"></div>/**
- * Suspend the firing of all events. (see {@link #resumeEvents})
- * @param {Boolean} queueSuspended Pass as true to queue up suspended events to be fired
- * after the {@link #resumeEvents} call instead of discarding all suspended events;
- */
- suspendEvents : function(queueSuspended){
- this.eventsSuspended = TRUE;
- if (queueSuspended){
- this.suspendedEventsQueue = [];
+ }
+ },
+
+ <div id="method-Ext.util.Observable-addEvents"></div>/**
+ * Adds the specified events to the list of events which this Observable may fire.
+ * @param {Object|String} o Either an object with event names as properties with a value of <code>true</code>
+ * or the first event name string if multiple event names are being passed as separate parameters.
+ * @param {string} Optional. Event name if multiple event names are being passed as separate parameters.
+ * Usage:<pre><code>
+this.addEvents('storeloaded', 'storecleared');
+</code></pre>
+ */
+ addEvents : function(o){
+ var me = this;
+ me.events = me.events || {};
+ if (Ext.isString(o)) {
+ var a = arguments,
+ i = a.length;
+ while(i--) {
+ me.events[a[i]] = me.events[a[i]] || TRUE;
}
- },
-
- <div id="method-Ext.util.Observable-resumeEvents"></div>/**
- * Resume firing events. (see {@link #suspendEvents})
- * If events were suspended using the <tt><b>queueSuspended</b></tt> parameter, then all
- * events fired during event suspension will be sent to any listeners now.
- */
- resumeEvents : function(){
- var me = this;
- me.eventsSuspended = !delete me.suspendedEventQueue;
- EACH(me.suspendedEventsQueue, function(e) {
- me.fireEvent.apply(me, e);
- });
+ } else {
+ Ext.applyIf(me.events, o);
+ }
+ },
+
+ <div id="method-Ext.util.Observable-hasListener"></div>/**
+ * Checks to see if this object has any listeners for a specified event
+ * @param {String} eventName The name of the event to check for
+ * @return {Boolean} True if the event is being listened for, else false
+ */
+ hasListener : function(eventName){
+ var e = this.events[eventName];
+ return ISOBJECT(e) && e.listeners.length > 0;
+ },
+
+ <div id="method-Ext.util.Observable-suspendEvents"></div>/**
+ * Suspend the firing of all events. (see {@link #resumeEvents})
+ * @param {Boolean} queueSuspended Pass as true to queue up suspended events to be fired
+ * after the {@link #resumeEvents} call instead of discarding all suspended events;
+ */
+ suspendEvents : function(queueSuspended){
+ this.eventsSuspended = TRUE;
+ if(queueSuspended && !this.eventQueue){
+ this.eventQueue = [];
}
+ },
+
+ <div id="method-Ext.util.Observable-resumeEvents"></div>/**
+ * Resume firing events. (see {@link #suspendEvents})
+ * If events were suspended using the <tt><b>queueSuspended</b></tt> parameter, then all
+ * events fired during event suspension will be sent to any listeners now.
+ */
+ resumeEvents : function(){
+ var me = this,
+ queued = me.eventQueue || [];
+ me.eventsSuspended = FALSE;
+ delete me.eventQueue;
+ EACH(queued, function(e) {
+ me.fireEvent.apply(me, e);
+ });
}
-}();
+};
var OBSERVABLE = EXTUTIL.Observable.prototype;
<div id="method-Ext.util.Observable-on"></div>/**
};
};
-function createBuffered(h, o, scope){
- var task = new EXTUTIL.DelayedTask();
+function createBuffered(h, o, fn, scope){
+ fn.task = new EXTUTIL.DelayedTask();
return function(){
- task.delay(o.buffer, h, scope, TOARRAY(arguments));
+ fn.task.delay(o.buffer, h, scope, TOARRAY(arguments));
};
}
};
}
-function createDelayed(h, o, scope){
+function createDelayed(h, o, fn, scope){
return function(){
- var args = TOARRAY(arguments);
- (function(){
- h.apply(scope, args);
- }).defer(o.delay || 10);
+ var task = new EXTUTIL.DelayedTask();
+ if(!fn.tasks) {
+ fn.tasks = [];
+ }
+ fn.tasks.push(task);
+ task.delay(o.delay || 10, h, scope, TOARRAY(arguments));
};
};
h = createTargeted(h, o, scope);
}
if(o.delay){
- h = createDelayed(h, o, scope);
+ h = createDelayed(h, o, fn, scope);
}
if(o.single){
h = createSingle(h, this, fn, scope);
}
if(o.buffer){
- h = createBuffered(h, o, scope);
+ h = createBuffered(h, o, fn, scope);
}
l.fireFn = h;
return l;
},
findListener : function(fn, scope){
- var s, ret = -1;
- EACH(this.listeners, function(l, i) {
- s = l.scope;
- if(l.fn == fn && (s == scope || s == this.obj)){
- ret = i;
- return FALSE;
+ var list = this.listeners,
+ i = list.length,
+ l,
+ s;
+ while(i--) {
+ l = list[i];
+ if(l) {
+ s = l.scope;
+ if(l.fn == fn && (s == scope || s == this.obj)){
+ return i;
+ }
}
- },
- this);
- return ret;
+ }
+ return -1;
},
isListening : function(fn, scope){
removeListener : function(fn, scope){
var index,
+ l,
+ k,
me = this,
ret = FALSE;
if((index = me.findListener(fn, scope)) != -1){
if (me.firing) {
me.listeners = me.listeners.slice(0);
}
+ l = me.listeners[index].fn;
+ // Cancel buffered tasks
+ if(l.task) {
+ l.task.cancel();
+ delete l.task;
+ }
+ // Cancel delayed tasks
+ k = l.tasks && l.tasks.length;
+ if(k) {
+ while(k--) {
+ l.tasks[k].cancel();
+ }
+ delete l.tasks;
+ }
me.listeners.splice(index, 1);
ret = TRUE;
}
return ret;
},
+ // Iterate to stop any buffered/delayed events
clearListeners : function(){
- this.listeners = [];
+ var me = this,
+ l = me.listeners,
+ i = l.length;
+ while(i--) {
+ me.removeListener(l[i].fn, l[i].scope);
+ }
},
fire : function(){
var me = this,
args = TOARRAY(arguments),
- ret = TRUE;
+ listeners = me.listeners,
+ len = listeners.length,
+ i = 0,
+ l;
- EACH(me.listeners, function(l) {
+ if(len > 0){
me.firing = TRUE;
- if (l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
- return ret = me.firing = FALSE;
+ for (; i < len; i++) {
+ l = listeners[i];
+ if(l && l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
+ return (me.firing = FALSE);
+ }
}
- });
+ }
me.firing = FALSE;
- return ret;
+ return TRUE;
}
};
})();</pre> \r