mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 03:10:07 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			635 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			635 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			JavaScript
		
	
	
		
			Executable File
		
	
	
	
	
| /**********************************************************************
 | |
| * 
 | |
| *
 | |
| *
 | |
| **********************************************************************/
 | |
| 
 | |
| //var DEBUG = DEBUG != null ? DEBUG : true
 | |
| 
 | |
| define(function(require){ var module = {}
 | |
| 
 | |
| 
 | |
| /*********************************************************************/
 | |
| // Actions
 | |
| //
 | |
| // Actions are an extension to the JavaScript object model tailored for
 | |
| // a set of specific tasks.
 | |
| //
 | |
| // Goals:
 | |
| // 	- provide a unified mechanism to define and manage user API's for 
 | |
| // 	  use in UI-hooks, keyboard mappings, scripting, ...
 | |
| // 	- a means to generate configuration UI's
 | |
| // 	- a means to generate documentation
 | |
| //
 | |
| //
 | |
| // The main entities:
 | |
| //
 | |
| // 	Action set
 | |
| // 		- an object containing a number of actions,
 | |
| // 		- optionally, directly or indirectly inherited from MetaActions
 | |
| // 		  and/or other action sets,
 | |
| // 		- the action handlers are bound relative to it (._action_handlers)
 | |
| //
 | |
| // 	Action
 | |
| // 		- a method, created by Action(..),
 | |
| // 		- calls all the shadowed actions in the inheritance chain in 
 | |
| // 		  sequence implicitly,
 | |
| // 		  NOTE: there is no way to prevent an action in the chain from
 | |
| // 		  		running, this is by design, i.e. no way to full shadow.
 | |
| // 		- returns the action set (for call chaining),
 | |
| // 		- can consist of two parts: the first is called before the 
 | |
| // 		  shadowed action (pre-callback) and the second after (post-callback).
 | |
| // 		- can be bound to, a-la an event, calling the handlers when it is 
 | |
| // 		  called, 
 | |
| //
 | |
| // 	Action (event) handler
 | |
| //  	- a function,
 | |
| // 		- can be bound to run before and/or after the action itself,
 | |
| // 		- is local to an action set it was bound via,
 | |
| // 		- when an action is triggered from an action set, all the pre 
 | |
| // 		  handlers in its inheritance chain will be called before the 
 | |
| // 		  respective actions they are bound to and all the post handlers
 | |
| // 		  are called directly after.
 | |
| //
 | |
| //
 | |
| //
 | |
| // The action system provides three components:
 | |
| //
 | |
| // 1) Documentation generation and introspection (MetaActions)
 | |
| //
 | |
| // 		<action-set>.getDoc()
 | |
| // 		<action-set>.getDoc(<action-name>[, ..])
 | |
| // 				-> dict of action-name, doc
 | |
| //
 | |
| // 		<action-set>.actions
 | |
| // 				-> list of action names
 | |
| // 	
 | |
| //
 | |
| // 2) Event-like callbacks for actions (MetaActions, Action)
 | |
| //
 | |
| // 		<action-set>.on('action', function(){ ... })
 | |
| // 		<action-set>.on('action.post', function(){ ... })
 | |
| //
 | |
| // 		<action-set>.on('action.pre', function(){ ... })
 | |
| //
 | |
| //
 | |
| // 3) A mechanism to define and extend already defined actions
 | |
| // 	This replaces / complements the standard JavaScript overloading 
 | |
| // 	mechanisms (Action, Actions)
 | |
| //
 | |
| // 		// Actions...
 | |
| // 		var X = Actions({
 | |
| // 			m: [function(){ console.log('m') }]
 | |
| // 		})
 | |
| // 		var O = Actions(X, {
 | |
| // 			m: [function(){
 | |
| // 				console.log('pre')
 | |
| // 				return function(){
 | |
| // 					console.log('post')
 | |
| // 				}
 | |
| // 			}]
 | |
| // 		})
 | |
| //
 | |
| //	NOTE: what is done here is similar to calling O.__proto__.m.call(..)
 | |
| //		but is implicit, and not dependant on the original containing 
 | |
| //		object name/reference ('O'), thus enabling an action to be 
 | |
| //		referenced and called from any object and still chain correctly.
 | |
| //
 | |
| //
 | |
| //
 | |
| /*********************************************************************/
 | |
| // helpers...
 | |
| 
 | |
| // XXX
 | |
| if(typeof(args2array) != 'function'){
 | |
| 	function args2array(args){
 | |
| 		return [].slice.call(args)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /*********************************************************************/
 | |
| 
 | |
| // Construct an action object...
 | |
| //
 | |
| // Action function format:
 | |
| //
 | |
| // 		// pre event code...
 | |
| // 		function(){
 | |
| //			... // pre code
 | |
| // 		}
 | |
| //
 | |
| // 		// pre/post event code...
 | |
| // 		function(){
 | |
| //			... // pre code
 | |
| //			return function(){
 | |
| //				... // post code
 | |
| //			}
 | |
| // 		}
 | |
| //
 | |
| // 		// same as above but using a deferred instead of a callback...
 | |
| // 		function(){
 | |
| //			... // pre code
 | |
| //			return $.Deferred()
 | |
| //				.done(function(){
 | |
| //					... // post code
 | |
| //				})
 | |
| // 		}
 | |
| //
 | |
| //
 | |
| // An action is essentially a method with several additional features:
 | |
| //
 | |
| // 	- actions are split into two stages:
 | |
| // 		pre: 	the code of the method is executed before the action 
 | |
| // 				event is fired
 | |
| // 		post:	if the action returns a callback function or a deferred
 | |
| // 				object it will be executed after the event is fired
 | |
| //
 | |
| // 	- actions automatically call the shadowed action, the pre stage is
 | |
| // 	  executed down-up while the post stage is run in reverse order, 
 | |
| // 	  i.e. the pre is going down and the post is going up.
 | |
| //
 | |
| // 	- actions provide an event-like mechanism to register handlers or 
 | |
| // 	  callbacks. These callbacks are local to a specific object and will
 | |
| // 	  be fired on action event/call starting from the current action 
 | |
| // 	  caller and down the inheritance chain, i.e. all event handlers 
 | |
| // 	  registered from the current object and up to the base action set
 | |
| // 	  will be fired.
 | |
| //
 | |
| // NOTE: actions once defined do not depend on the inheritance hierarchy, 
 | |
| // 		other than the .getHandlers(..) method. If this method is not 
 | |
| // 		found in the inheritance chain (i.e. the link to MetaActions)
 | |
| // 		was severed, then the default will be used: 
 | |
| // 			MetaActions.getHandlers(..)
 | |
| // 		This makes it possible to redefine the method if needed but 
 | |
| // 		prevents the system from breaking when an action set gets 
 | |
| // 		disconnected from MetaActions. This can be useful, for example,
 | |
| // 		to remove .on(..) / .off(..) handler functionality.
 | |
| // 		XXX is this correct??
 | |
| // NOTE: by default an action will return 'this', i.e. the action set
 | |
| // 		object the action was called from.
 | |
| //
 | |
| // XXX do we need to return something from an action ever?
 | |
| // XXX add more metadata/docs:
 | |
| // 		.section
 | |
| // 		.category
 | |
| // 		...
 | |
| var Action =
 | |
| module.Action =
 | |
| function Action(name, doc, ldoc, func){
 | |
| 	// we got called without a 'new'...
 | |
| 	if(this == null || this.constructor !== Action){
 | |
| 		// XXX using something like .apply(.., arguemnts) would be more
 | |
| 		// 		generel but have no time to figure out how to pass it 
 | |
| 		// 		to new without the later complaining...
 | |
| 		return new Action(name, doc, ldoc, func)
 | |
| 	}
 | |
| 
 | |
| 	// prevent action overloading...
 | |
| 	if(this[name] != null){
 | |
| 		throw 'action "'+name+'" already exists.'
 | |
| 	}
 | |
| 
 | |
| 	// create the actual instance we will be returning...
 | |
| 	var meth = function(){
 | |
| 		var that = this
 | |
| 		var args = args2array(arguments)
 | |
| 
 | |
| 		var getHandlers = this.getHandlers
 | |
| 		getHandlers = getHandlers == null ? MetaActions.getHandlers : getHandlers
 | |
| 
 | |
| 		// get and call handlers -- pre phase...
 | |
| 		//
 | |
| 		// NOTE: using CLASS.__proto__[name].call(this, ...) here is not
 | |
| 		// 		possible as there is no reliable way to get the "class" 
 | |
| 		// 		the current method is referenced from.
 | |
| 		// 		...searching the inheritance chain is not reliable as a
 | |
| 		// 		method can be referenced more than once, both with the 
 | |
| 		// 		same as well as under different names...
 | |
| 		var handlers = getHandlers.call(this, name)
 | |
| 			.map(function(h){ return h.apply(that, args) })
 | |
| 
 | |
| 		// NOTE: this action will get included and called by the code 
 | |
| 		// 		above and below, so no need to explicitly call func...
 | |
| 
 | |
| 		// call handlers -- post phase...
 | |
| 		// NOTE: post handlers need to get called last run pre first run post...
 | |
| 		handlers.reverse().forEach(function(h){ 
 | |
| 			// function...
 | |
| 			if(h instanceof Function){
 | |
| 				//h.call(that, res)
 | |
| 				h.call(that)
 | |
| 
 | |
| 			// deferred...
 | |
| 			} else if(h != null && h.resolve instanceof Function){
 | |
| 				//h.resolve(res)
 | |
| 				h.resolve()
 | |
| 			} 
 | |
| 		})
 | |
| 
 | |
| 		//return res
 | |
| 		return this
 | |
| 	}
 | |
| 	meth.__proto__ = this.__proto__
 | |
| 
 | |
| 	// populate the action attributes...
 | |
| 	meth.name = name
 | |
| 	meth.doc = doc
 | |
| 	meth.long_doc = ldoc
 | |
| 
 | |
| 	meth.func = func
 | |
| 
 | |
| 	return meth
 | |
| }
 | |
| // this will make action instances behave like real functions...
 | |
| Action.prototype.__proto__ = Function
 | |
| 
 | |
| 
 | |
| // A base action-set object...
 | |
| //
 | |
| // This will define a set of action-set specific methods and helpers.
 | |
| //
 | |
| // XXX .off(...) needs more work...
 | |
| var MetaActions =
 | |
| module.MetaActions = {
 | |
| 	// List actions...
 | |
| 	//
 | |
| 	get actions(){
 | |
| 		var res = []
 | |
| 		for(var k in this){
 | |
| 			// avoid recursion...
 | |
| 			if(k == 'actions' || k == 'length'){
 | |
| 				continue
 | |
| 			}
 | |
| 			// get only actions...
 | |
| 			if(this[k] instanceof Action){
 | |
| 				res.push(k)
 | |
| 			}
 | |
| 		}
 | |
| 		return res
 | |
| 	},
 | |
| 
 | |
| 	// Number of defined actions...
 | |
| 	//
 | |
| 	get length(){
 | |
| 		return this.actions.length
 | |
| 	},
 | |
| 
 | |
| 	// Get action documentation...
 | |
| 	//
 | |
| 	getDoc: function(actions){
 | |
| 		var res = {}
 | |
| 		var that = this
 | |
| 		actions = actions == null ? this.actions
 | |
| 			: arguments.length > 1 ? args2array(arguments)
 | |
| 			: typeof(actions) == typeof('str') ? [actions]
 | |
| 			: actions
 | |
| 		// get the first defined set of docs in the inheritance chain...
 | |
| 		actions.forEach(function(n){
 | |
| 			var cur = that
 | |
| 			res[n] = []
 | |
| 			while(cur.__proto__ != null){
 | |
| 				if(cur[n] != null && cur[n].doc != null){
 | |
| 					res[n] = [ cur[n].doc, cur[n].long_doc ]
 | |
| 					break
 | |
| 				}
 | |
| 				cur = cur.__proto__
 | |
| 			}
 | |
| 		})
 | |
| 		return res
 | |
| 	},
 | |
| 
 | |
| 	// Get action handlers from the inheritance chain...
 | |
| 	//
 | |
| 	// NOTE: this collects both the event handlers (in order of hierarchy,
 | |
| 	// 		then order of definition) and actions (in order of hierarchy)
 | |
| 	// NOTE: this is the correct order for 'pre' calling, but is the 
 | |
| 	// 		reverse of how the 'post' handlers must be called.
 | |
| 	//
 | |
| 	// For more docs on handler sequencing and definition see: .on(..)
 | |
| 	getHandlers: function(name){
 | |
| 		var handlers = []
 | |
| 		var cur = this
 | |
| 		while(cur.__proto__ != null){
 | |
| 			// get action "event" handlers...
 | |
| 			if(cur.hasOwnProperty('_action_handlers') 
 | |
| 					&& name in cur._action_handlers){
 | |
| 				handlers.splice.apply(handlers,
 | |
| 						[handlers.length, 0].concat(cur._action_handlers[name]))
 | |
| 			}
 | |
| 
 | |
| 			// get the overloading action...
 | |
| 			// NOTE: this will get all the handlers including the root 
 | |
| 			// 		and the current handlers...
 | |
| 			// NOTE: this will ignore "shadows" that are not actions...
 | |
| 			if(cur.hasOwnProperty(name) && cur[name] instanceof Action){
 | |
| 				handlers.push(cur[name].func)
 | |
| 			}
 | |
| 
 | |
| 			cur = cur.__proto__
 | |
| 		}
 | |
| 		return handlers
 | |
| 	},
 | |
| 
 | |
| 
 | |
| 	// Register an action callback...
 | |
| 	//
 | |
| 	//	Register a post action callback
 | |
| 	// 	.on('action', [<tag>, ]<function>)
 | |
| 	// 	.on('action.post', [<tag>, ]<function>)
 | |
| 	// 		-> <action-set>
 | |
| 	//
 | |
| 	// 	Register a pre action callback
 | |
| 	// 	.on('action.pre', [<tag>, ]<function>)
 | |
| 	// 		-> <action-set>
 | |
| 	//
 | |
| 	// Modes:
 | |
| 	// 	'pre'		- the handler is fired before the action is triggered,
 | |
| 	// 					and if the handler returns a deferred or a function
 | |
| 	// 					then that will get resolved, called resp. after
 | |
| 	// 					the action is done.
 | |
| 	// 	'post'		- the handler is fired after the action is finished.
 | |
| 	// 					this is the default.
 | |
| 	//
 | |
| 	// The optional tag marks the handler to enable group removal via 
 | |
| 	// .off(..)
 | |
| 	//
 | |
| 	// NOTE: 'post' mode is the default.
 | |
| 	//
 | |
| 	// XXX add something like text tags to events (extra arg) to enable
 | |
| 	// 		simple and fast handler removal...
 | |
| 	on: function(actions, b, c){
 | |
| 		var handler = typeof(c) == 'function' ? c : b
 | |
| 		var tag = typeof(c) == 'function' ? b : c
 | |
| 
 | |
| 		var that = this
 | |
| 		actions.split(' ').forEach(function(action){
 | |
| 			// prepare the handler...
 | |
| 			var mode = action.split('.')
 | |
| 			action = mode[0]
 | |
| 			mode = mode[1]
 | |
| 
 | |
| 			// a post handler (default)...
 | |
| 			if(mode == null || mode == 'post'){
 | |
| 				var old_handler = handler
 | |
| 				handler = function(){ return old_handler }
 | |
| 				// NOTE: this is set so as to identify the handler for removal
 | |
| 				// 		via. .off(..)
 | |
| 				handler.orig_handler = old_handler
 | |
| 
 | |
| 			// mot pre mode...
 | |
| 			} else if(mode != 'pre') {
 | |
| 				// XXX
 | |
| 				throw 'Unknown action mode: '+action+'.'+mode
 | |
| 			}
 | |
| 
 | |
| 			handler.tag = tag
 | |
| 
 | |
| 			// register handlers locally only...
 | |
| 			if(!that.hasOwnProperty('_action_handlers')){
 | |
| 				that._action_handlers = {}
 | |
| 			}
 | |
| 			if(!(action in that._action_handlers)){
 | |
| 				that._action_handlers[action] = []
 | |
| 			}
 | |
| 			// register a handler only once...
 | |
| 			if(that._action_handlers[action].indexOf(handler) < 0){
 | |
| 				// NOTE: last registered is first...
 | |
| 				that._action_handlers[action].splice(0, 0, handler)
 | |
| 			}
 | |
| 		})
 | |
| 
 | |
| 		return this
 | |
| 	},
 | |
| 
 | |
| 	// Remove an action callback...
 | |
| 	//
 | |
| 	// XXX needs more testing...
 | |
| 	off: function(action, handler){
 | |
| 		if(this.hasOwnProperty('_action_handlers')){
 | |
| 			if(action == '*'){
 | |
| 				var actions = Object.keys(this._action_handlers)
 | |
| 			} else {
 | |
| 				var actions = action.split(' ')
 | |
| 			}
 | |
| 			var that = this
 | |
| 			actions.forEach(function(action){
 | |
| 				var mode = action.split('.')
 | |
| 				action = mode[0]
 | |
| 				mode = mode[1]
 | |
| 
 | |
| 				// get the handlers...
 | |
| 				var h = that._action_handlers[action]
 | |
| 
 | |
| 				// remove explicit handler...
 | |
| 				if(typeof(handler) == 'function'){
 | |
| 					var i = -1
 | |
| 					if(mode == null || mode == 'post'){
 | |
| 						// XXX find via e.orig_handler == handler && e.mode == 'post'
 | |
| 						h.forEach(function(e, j){
 | |
| 							// NOTE: we will only get the first match...
 | |
| 							if(e.orig_handler === handler && i == -1){
 | |
| 								i = j
 | |
| 							}
 | |
| 						})
 | |
| 
 | |
| 					} else if(mode == 'pre'){
 | |
| 						i = h.indexOf(handler)
 | |
| 					}
 | |
| 
 | |
| 					// NOTE: unknown modes are skipped...
 | |
| 					if(i >= 0){
 | |
| 						h.splice(i, 1)
 | |
| 					}
 | |
| 
 | |
| 				// remove handlers by tag...
 | |
| 				} else {
 | |
| 					// filter out everything that mathches a tag in-place...
 | |
| 					h.splice.apply(h, 
 | |
| 							[0, h.length]
 | |
| 								.concat(h.filter(function(e){ 
 | |
| 									return e.tag != handler })))
 | |
| 				}
 | |
| 			})
 | |
| 		}
 | |
| 		return this
 | |
| 	},
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| // An action set...
 | |
| //
 | |
| //	Actions(<object>)
 | |
| //	Actions(<prototype>, <object>)
 | |
| //		-> actions
 | |
| //
 | |
| // This will pre-process an object to setup the action mechanics.
 | |
| //
 | |
| //
 | |
| // The action format:
 | |
| // 	{
 | |
| // 		// full format...
 | |
| // 		<name> : [
 | |
| // 			<doc>,
 | |
| // 			<long-doc>,
 | |
| // 			<function>
 | |
| // 		],
 | |
| //
 | |
| // 		// short doc only...
 | |
| // 		<name> : [
 | |
| // 			<doc>,
 | |
| // 			<function>
 | |
| // 		],
 | |
| //
 | |
| // 		// only the code...
 | |
| // 		<name> : [
 | |
| // 			<function>
 | |
| // 		],
 | |
| // 		...
 | |
| // 	}
 | |
| //
 | |
| //
 | |
| // NOTE: if <prototype> is not given, MetaActions will be used as default.
 | |
| //
 | |
| // For more documentation see: Action(..).
 | |
| var Actions =
 | |
| module.Actions =
 | |
| function Actions(a, b){
 | |
| 	var obj = b == null ? a : b
 | |
| 	var proto = b == null ? MetaActions : a
 | |
| 
 | |
| 	// NOTE: this is intentionally done only for own attributes...
 | |
| 	Object.keys(obj).forEach(function(k){
 | |
| 		var args = obj[k]
 | |
| 
 | |
| 		// skip non-arrays...
 | |
| 		if(args == null 
 | |
| 				|| args.constructor !== Array 
 | |
| 				// and arrays the last element of which is not a function...
 | |
| 				|| !(args[args.length-1] instanceof Function)){
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		var func = args.pop()
 | |
| 
 | |
| 		// create a new action...
 | |
| 		obj[k] = new Action(k, args[0], args[1], func)
 | |
| 	})
 | |
| 
 | |
| 	if(proto != null){
 | |
| 		obj.__proto__ = proto
 | |
| 	}
 | |
| 
 | |
| 	return obj
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /*********************************************************************/
 | |
| 
 | |
| var test =
 | |
| module.test =
 | |
| function test(){
 | |
| 	var TestActions = 
 | |
| 	module.TestActions = 
 | |
| 	Actions({
 | |
| 		testActionGen1: ['baisc test action...',
 | |
| 			'some extra info',
 | |
| 			function(){
 | |
| 				console.log('  test 1!')
 | |
| 				return function(){
 | |
| 					console.log('  test 2!')
 | |
| 				}
 | |
| 			}],
 | |
| 
 | |
| 		testActionGen2: ['baisc 2\'nd gen test action...',
 | |
| 			// no extra info...
 | |
| 			function(){
 | |
| 				console.log('  test gen 2!')
 | |
| 				this.testActionGen1()
 | |
| 			}],
 | |
| 	})
 | |
| 
 | |
| 	var TestActions2 = 
 | |
| 	module.TestActions2 = 
 | |
| 	Actions(TestActions, {
 | |
| 		// NOTE: this looks like an action and feels like an action but 
 | |
| 		// 		actually this is a callback as an action with this name 
 | |
| 		// 		already exists...
 | |
| 		testActionGen1: [
 | |
| 			function(){
 | |
| 				console.log('  pre callback!')
 | |
| 				return function(){
 | |
| 					console.log('  post callback!')
 | |
| 				}
 | |
| 			}],
 | |
| 
 | |
| 		testAction2: ['this is an action',
 | |
| 			function(){
 | |
| 				console.log('testAction2 args:', arguments)
 | |
| 			}],
 | |
| 
 | |
| 	})
 | |
| 
 | |
| 	// XXX the main question here is that there is no way to know if a 
 | |
| 	// 		particular action is going to be a root action or an action
 | |
| 	// 		callback because we do not know if the action in the parent 
 | |
| 	// 		will be available at mix time or not, and the two models 
 | |
| 	// 		are different...
 | |
| 	// 		XXX one way to do this is to make all code a callback and 
 | |
| 	// 			just use the root as an event trigger...
 | |
| 	//
 | |
| 	// 			...but this effectively means we are implementing 
 | |
| 	// 			inheritance ourselves as the traditional name resolution
 | |
| 	// 			will no longer be used, and as in the case we implement
 | |
| 	// 			MRO why not go the whole way and implement multiple 
 | |
| 	// 			inheritance in the first place...
 | |
| 	//
 | |
| 	// 			...let's try and avoid this...
 | |
| 	/*
 | |
| 	var TestActionMixin =
 | |
| 	module.TestActionMixin = 
 | |
| 	ActionMixin({
 | |
| 		// XXX
 | |
| 	})
 | |
| 	*/
 | |
| 
 | |
| 
 | |
| 	console.log('TestActions.testActionGen1()')
 | |
| 	TestActions.testActionGen1()
 | |
| 	console.log('TestActions.testActionGen2()')
 | |
| 	TestActions.testActionGen2()
 | |
| 
 | |
| 		
 | |
| 	// both of these should cet a callback...
 | |
| 	console.log('TestActions2.testActionGen1()')
 | |
| 	TestActions2.testActionGen1()
 | |
| 	console.log('TestActions2.testActionGen2()')
 | |
| 	TestActions2.testActionGen2()
 | |
| 
 | |
| 	// and an event-like handler...
 | |
| 	TestActions2.on('testActionGen1.post', 
 | |
| 			function(){ console.log('  post handler! (first defined)') })
 | |
| 	TestActions2.on('testActionGen1', 
 | |
| 			function(){ console.log('  post handler! (last defined)') })
 | |
| 
 | |
| 	console.log('TestActions2.testActionGen1()')
 | |
| 	TestActions2.testActionGen1()
 | |
| 
 | |
| 	TestActions2.on('testActionGen2.pre', 
 | |
| 			function(){ console.log('  pre handler! (first defined)') })
 | |
| 	TestActions2.on('testActionGen2.pre', 
 | |
| 			function(){ console.log('  pre handler! (last defined)') })
 | |
| 
 | |
| 	console.log('TestActions2.testActionGen2()')
 | |
| 	TestActions2.testActionGen2()
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| /**********************************************************************
 | |
| * vim:set ts=4 sw=4 :                                                */
 | |
| return module })
 |