/** * Dispatcher.js * * Copyright, Moxiecode Systems AB * Released under LGPL License. * * License: http://www.tinymce.com/license * Contributing: http://www.tinymce.com/contributing */ /** * This class is used to dispatch event to observers/listeners. * All internal events inside TinyMCE uses this class. * * @class tinymce.util.Dispatcher * @example * // Creates a custom event * this.onSomething = new tinymce.util.Dispatcher(this); * * // Dispatch/fire the event * this.onSomething.dispatch('some string'); */ tinymce.create('tinymce.util.Dispatcher', { scope : null, listeners : null, inDispatch: false, /** * Constructs a new event dispatcher object. * * @constructor * @method Dispatcher * @param {Object} scope Optional default execution scope for all observer functions. */ Dispatcher : function(scope) { this.scope = scope || this; this.listeners = []; }, /** * Add an observer function to be executed when a dispatch call is done. * * @method add * @param {function} callback Callback function to execute when a dispatch event occurs. * @param {Object} s Optional execution scope, defaults to the one specified in the class constructor. * @return {function} Returns the same function as the one passed on. */ add : function(callback, scope) { this.listeners.push({cb : callback, scope : scope || this.scope}); return callback; }, /** * Add an observer function to be executed to the top of the list of observers. * * @method addToTop * @param {function} callback Callback function to execute when a dispatch event occurs. * @param {Object} scope Optional execution scope, defaults to the one specified in the class constructor. * @return {function} Returns the same function as the one passed on. */ addToTop : function(callback, scope) { var self = this, listener = {cb : callback, scope : scope || self.scope}; // Create new listeners if addToTop is executed in a dispatch loop if (self.inDispatch) { self.listeners = [listener].concat(self.listeners); } else { self.listeners.unshift(listener); } return callback; }, /** * Removes an observer function. * * @method remove * @param {function} callback Observer function to remove. * @return {function} The same function that got passed in or null if it wasn't found. */ remove : function(callback) { var listeners = this.listeners, output = null; tinymce.each(listeners, function(listener, i) { if (callback == listener.cb) { output = listener; listeners.splice(i, 1); return false; } }); return output; }, /** * Dispatches an event to all observers/listeners. * * @method dispatch * @param {Object} .. Any number of arguments to dispatch. * @return {Object} Last observer functions return value. */ dispatch : function() { var self = this, returnValue, args = arguments, i, listeners = self.listeners, listener; self.inDispatch = true; // Needs to be a real loop since the listener count might change while looping // And this is also more efficient for (i = 0; i < listeners.length; i++) { listener = listeners[i]; returnValue = listener.cb.apply(listener.scope, args.length > 0 ? args : [listener.scope]); if (returnValue === false) break; } self.inDispatch = false; return returnValue; } /**#@-*/ });