<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>The source code</title> <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="../resources/prettify/prettify.js"></script> <style type="text/css"> .highlight { display: block; background-color: #ddd; } </style> <script type="text/javascript"> function highlight() { document.getElementById(location.hash.replace(/#/, "")).className = "highlight"; } </script> </head> <body onload="prettyPrint(); highlight();"> <pre class="prettyprint lang-js">Ext.require('Ext.util.DelayedTask', function() { <span id='Ext-util-Event'> /** </span> * Represents single event type that an Observable object listens to. * All actual listeners are tracked inside here. When the event fires, * it calls all the registered listener functions. * * @private */ Ext.util.Event = Ext.extend(Object, (function() { var noOptions = {}; function createTargeted(handler, listener, o, scope){ return function(){ if (o.target === arguments[0]){ handler.apply(scope, arguments); } }; } function createBuffered(handler, listener, o, scope) { listener.task = new Ext.util.DelayedTask(); return function() { listener.task.delay(o.buffer, handler, scope, Ext.Array.toArray(arguments)); }; } function createDelayed(handler, listener, o, scope) { return function() { var task = new Ext.util.DelayedTask(); if (!listener.tasks) { listener.tasks = []; } listener.tasks.push(task); task.delay(o.delay || 10, handler, scope, Ext.Array.toArray(arguments)); }; } function createSingle(handler, listener, o, scope) { return function() { var event = listener.ev; if (event.removeListener(listener.fn, scope) && event.observable) { // Removing from a regular Observable-owned, named event (not an anonymous // event such as Ext's readyEvent): Decrement the listeners count event.observable.hasListeners[event.name]--; } return handler.apply(scope, arguments); }; } return { <span id='Ext-util-Event-property-isEvent'> /** </span> * @property {Boolean} isEvent * `true` in this class to identify an object as an instantiated Event, or subclass thereof. */ isEvent: true, constructor: function(observable, name) { this.name = name; this.observable = observable; this.listeners = []; }, addListener: function(fn, scope, options) { var me = this, listener; scope = scope || me.observable; //<debug error> if (!fn) { Ext.Error.raise({ sourceClass: Ext.getClassName(this.observable), sourceMethod: "addListener", msg: "The specified callback function is undefined" }); } //</debug> if (!me.isListening(fn, scope)) { listener = me.createListener(fn, scope, options); if (me.firing) { // if we are currently firing this event, don't disturb the listener loop me.listeners = me.listeners.slice(0); } me.listeners.push(listener); } }, createListener: function(fn, scope, options) { options = options || noOptions; scope = scope || this.observable; var listener = { fn: fn, scope: scope, o: options, ev: this }, handler = fn; // The order is important. The 'single' wrapper must be wrapped by the 'buffer' and 'delayed' wrapper // because the event removal that the single listener does destroys the listener's DelayedTask(s) if (options.single) { handler = createSingle(handler, listener, options, scope); } if (options.target) { handler = createTargeted(handler, listener, options, scope); } if (options.delay) { handler = createDelayed(handler, listener, options, scope); } if (options.buffer) { handler = createBuffered(handler, listener, options, scope); } listener.fireFn = handler; return listener; }, findListener: function(fn, scope) { var listeners = this.listeners, i = listeners.length, listener, s; while (i--) { listener = listeners[i]; if (listener) { s = listener.scope; // Compare the listener's scope with *JUST THE PASSED SCOPE* if one is passed, and only fall back to the owning Observable if none is passed. // We cannot use the test (s == scope || s == this.observable) // Otherwise, if the Observable itself adds Ext.emptyFn as a listener, and then Ext.emptyFn is added under another scope, there will be a false match. if (listener.fn == fn && (s == (scope || this.observable))) { return i; } } } return - 1; }, isListening: function(fn, scope) { return this.findListener(fn, scope) !== -1; }, removeListener: function(fn, scope) { var me = this, index, listener, k; index = me.findListener(fn, scope); if (index != -1) { listener = me.listeners[index]; if (me.firing) { me.listeners = me.listeners.slice(0); } // cancel and remove a buffered handler that hasn't fired yet if (listener.task) { listener.task.cancel(); delete listener.task; } // cancel and remove all delayed handlers that haven't fired yet k = listener.tasks && listener.tasks.length; if (k) { while (k--) { listener.tasks[k].cancel(); } delete listener.tasks; } // remove this listener from the listeners array Ext.Array.erase(me.listeners, index, 1); return true; } return false; }, // Iterate to stop any buffered/delayed events clearListeners: function() { var listeners = this.listeners, i = listeners.length; while (i--) { this.removeListener(listeners[i].fn, listeners[i].scope); } }, fire: function() { var me = this, listeners = me.listeners, count = listeners.length, i, args, listener; if (count > 0) { me.firing = true; for (i = 0; i < count; i++) { listener = listeners[i]; args = arguments.length ? Array.prototype.slice.call(arguments, 0) : []; if (listener.o) { args.push(listener.o); } if (listener && listener.fireFn.apply(listener.scope || me.observable, args) === false) { return (me.firing = false); } } } me.firing = false; return true; } }; }())); }); </pre> </body> </html>