| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | **********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //var DEBUG = DEBUG != null ? DEBUG : true
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | define(function(require){ var module = {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-09 18:54:53 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | // Actions
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Actions are an extension to the JavaScript object model tailored for
 | 
					
						
							|  |  |  | // a set of specific tasks.
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | // 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
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | // The main entities:
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | // 	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)
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | // 	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, 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | // 	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.
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | // 		- pre handlers are passed the same arguments the original actions
 | 
					
						
							|  |  |  | // 		  got when it was called.
 | 
					
						
							|  |  |  | // 		- post action handlers will get the root action result as first 
 | 
					
						
							|  |  |  | // 		  argument succeeded by the action arguments.
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | // 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(){ ... })
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | // 3) A mechanism to define and extend already defined actions
 | 
					
						
							|  |  |  | // 	This replaces / complements the standard JavaScript overloading 
 | 
					
						
							|  |  |  | // 	mechanisms (Action, Actions)
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | // 		// Actions...
 | 
					
						
							|  |  |  | // 		var X = Actions({
 | 
					
						
							|  |  |  | // 			m: [function(){ console.log('m') }]
 | 
					
						
							|  |  |  | // 		})
 | 
					
						
							|  |  |  | // 		var O = Actions(X, {
 | 
					
						
							|  |  |  | // 			m: [function(){
 | 
					
						
							|  |  |  | // 				console.log('pre')
 | 
					
						
							|  |  |  | // 				return function(){
 | 
					
						
							|  |  |  | // 					console.log('post')
 | 
					
						
							|  |  |  | // 				}
 | 
					
						
							|  |  |  | // 			}]
 | 
					
						
							|  |  |  | // 		})
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | //	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.
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | // helpers...
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // XXX
 | 
					
						
							| 
									
										
										
										
											2014-10-13 00:18:26 +04:00
										 |  |  | if(typeof(args2array) != 'function'){ | 
					
						
							|  |  |  | 	function args2array(args){ | 
					
						
							|  |  |  | 		return [].slice.call(args) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Construct an action object...
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | // Action function format:
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 		// pre event code...
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | // 		function(..){
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | //			... // pre code
 | 
					
						
							|  |  |  | // 		}
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | // 		// pre/post event code...
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | // 		function(..){
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | //			... // pre code
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | //			return function(<return>, ..){
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | //				... // post code
 | 
					
						
							|  |  |  | //			}
 | 
					
						
							|  |  |  | // 		}
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | // 		// same as above but using a deferred instead of a callback...
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | // 		function(..){
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | //			... // pre code
 | 
					
						
							|  |  |  | //			return $.Deferred()
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | //				.done(function(<return>, ..){
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | //					... // post code
 | 
					
						
							|  |  |  | //				})
 | 
					
						
							|  |  |  | // 		}
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-06 06:18:39 +04:00
										 |  |  | // 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
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | // 				NOTE: the signature if the post stage is the same as the
 | 
					
						
							|  |  |  | // 					action's with the added return value as first argument
 | 
					
						
							|  |  |  | // 					(the rest og the arguments are shifted by 1).
 | 
					
						
							| 
									
										
										
										
											2014-10-06 06:18:39 +04:00
										 |  |  | //
 | 
					
						
							|  |  |  | // 	- 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.
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-11-09 18:54:53 +03:00
										 |  |  | // 	- an action will return the deepest (root) action's return, if that 
 | 
					
						
							| 
									
										
										
										
											2015-07-29 15:22:49 +03:00
										 |  |  | // 	  return is undefined, then the action set is returned instead.
 | 
					
						
							| 
									
										
										
										
											2014-11-06 03:56:54 +03:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | // 	- action arguments are "threaded" through the action chain down and 
 | 
					
						
							|  |  |  | // 	  root action return value and arguments are threaded back up the 
 | 
					
						
							|  |  |  | // 	  action chain.
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2015-11-29 04:14:46 +03:00
										 |  |  | // NOTE: if the root handler is instance of Toggler (jli) and the action
 | 
					
						
							| 
									
										
										
										
											2014-11-09 18:54:53 +03:00
										 |  |  | // 		is called with '?' as argument, then the toggler will be called 
 | 
					
						
							|  |  |  | // 		with the argument and return the result bypassing the handlers.
 | 
					
						
							| 
									
										
										
										
											2014-10-06 16:32:15 +04:00
										 |  |  | // 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??
 | 
					
						
							| 
									
										
										
										
											2014-10-06 06:18:39 +04:00
										 |  |  | // NOTE: by default an action will return 'this', i.e. the action set
 | 
					
						
							|  |  |  | // 		object the action was called from.
 | 
					
						
							| 
									
										
										
										
											2014-10-06 16:32:15 +04:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-11 17:08:17 +04:00
										 |  |  | // XXX add more metadata/docs:
 | 
					
						
							|  |  |  | // 		.section
 | 
					
						
							|  |  |  | // 		.category
 | 
					
						
							|  |  |  | // 		...
 | 
					
						
							| 
									
										
										
										
											2014-11-17 04:24:07 +03:00
										 |  |  | // XXX might be a good idea to add an option to return the full results...
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 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 args = args2array(arguments) | 
					
						
							| 
									
										
										
										
											2014-12-16 04:50:34 +03:00
										 |  |  | 		var that = this | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 16:32:15 +04:00
										 |  |  | 		var getHandlers = this.getHandlers | 
					
						
							|  |  |  | 		getHandlers = getHandlers == null ? MetaActions.getHandlers : getHandlers | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-16 04:50:34 +03:00
										 |  |  | 		// get handlers...
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | 		//
 | 
					
						
							|  |  |  | 		// 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...
 | 
					
						
							| 
									
										
										
										
											2014-10-11 06:33:49 +04:00
										 |  |  | 		var handlers = getHandlers.call(this, name) | 
					
						
							| 
									
										
										
										
											2014-11-09 18:54:53 +03:00
										 |  |  | 		//	.map(function(h){ return h.apply(that, args) })
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// special case: if the root handler is a toggler and we call 
 | 
					
						
							|  |  |  | 		// it with '?' then do not call the handlers...
 | 
					
						
							|  |  |  | 		// XXX might be good to make this modular/configurable...
 | 
					
						
							|  |  |  | 		if(handlers.slice(-1)[0] instanceof Toggler  | 
					
						
							|  |  |  | 				&& args.length == 1  | 
					
						
							|  |  |  | 				&& args[0] == '?'){ | 
					
						
							|  |  |  | 			return handlers.slice(-1)[0].apply(this, args) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-16 04:50:34 +03:00
										 |  |  | 		// call handlers -- pre phase...
 | 
					
						
							| 
									
										
										
										
											2014-11-09 18:54:53 +03:00
										 |  |  | 		handlers = handlers | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 			.map(function(h){ return h.apply(that, args) }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 		// NOTE: this action will get included and called by the code 
 | 
					
						
							| 
									
										
										
										
											2014-10-13 00:18:26 +04:00
										 |  |  | 		// 		above and below, so no need to explicitly call func...
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 		// call handlers -- post phase...
 | 
					
						
							|  |  |  | 		// NOTE: post handlers need to get called last run pre first run post...
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | 		var results = [] | 
					
						
							|  |  |  | 		handlers.reverse().forEach(function(h, i){  | 
					
						
							|  |  |  | 			var res = h | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 			// function...
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 			if(h instanceof Function){ | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | 				//res = h.apply(that, args)
 | 
					
						
							|  |  |  | 				res = h.apply(that, | 
					
						
							|  |  |  | 					[results[0] !== undefined ? | 
					
						
							| 
									
										
										
										
											2015-12-06 06:21:37 +03:00
										 |  |  | 						results[0]  | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | 						: that].concat(args)) | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 			// deferred...
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 			} else if(h != null && h.resolve instanceof Function){ | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | 				//res = h.resolve()
 | 
					
						
							|  |  |  | 				res = h.resolve.apply(h, | 
					
						
							|  |  |  | 					[results[0] !== undefined ?  | 
					
						
							|  |  |  | 						results[0]  | 
					
						
							|  |  |  | 						: that].concat(args)) | 
					
						
							| 
									
										
										
										
											2014-11-17 04:24:07 +03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | 			results.push(res) | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-17 04:24:07 +03:00
										 |  |  | 		// XXX might be a good idea to add an option to return the full
 | 
					
						
							|  |  |  | 		// 		results...
 | 
					
						
							|  |  |  | 		return results[0] !== undefined ? results[0] : this | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	meth.__proto__ = this.__proto__ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// populate the action attributes...
 | 
					
						
							|  |  |  | 	meth.name = name | 
					
						
							|  |  |  | 	meth.doc = doc | 
					
						
							|  |  |  | 	meth.long_doc = ldoc | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 	meth.func = func | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 	return meth | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-20 06:52:13 +04:00
										 |  |  | // this will make action instances behave like real functions...
 | 
					
						
							|  |  |  | Action.prototype.__proto__ = Function | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 06:18:39 +04:00
										 |  |  | // A base action-set object...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This will define a set of action-set specific methods and helpers.
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | // XXX .off(...) needs more work...
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | var MetaActions = | 
					
						
							|  |  |  | module.MetaActions = { | 
					
						
							|  |  |  | 	// List actions...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-10-06 16:32:15 +04:00
										 |  |  | 	get actions(){ | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 		var res = [] | 
					
						
							|  |  |  | 		for(var k in this){ | 
					
						
							| 
									
										
										
										
											2014-10-11 06:33:49 +04:00
										 |  |  | 			// avoid recursion...
 | 
					
						
							|  |  |  | 			if(k == 'actions' || k == 'length'){ | 
					
						
							|  |  |  | 				continue | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 			// get only actions...
 | 
					
						
							| 
									
										
										
										
											2014-10-06 16:32:15 +04:00
										 |  |  | 			if(this[k] instanceof Action){ | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 				res.push(k) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return res | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Number of defined actions...
 | 
					
						
							| 
									
										
										
										
											2014-10-06 16:32:15 +04:00
										 |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 	get length(){ | 
					
						
							|  |  |  | 		return this.actions.length | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 16:32:15 +04:00
										 |  |  | 	// Get action documentation...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:52:20 +04:00
										 |  |  | 	getDoc: function(actions){ | 
					
						
							|  |  |  | 		var res = {} | 
					
						
							|  |  |  | 		var that = this | 
					
						
							| 
									
										
										
										
											2014-10-11 06:33:49 +04:00
										 |  |  | 		actions = actions == null ? this.actions | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | 			: arguments.length > 1 ? args2array(arguments) | 
					
						
							| 
									
										
										
										
											2014-10-06 03:52:20 +04:00
										 |  |  | 			: typeof(actions) == typeof('str') ? [actions] | 
					
						
							|  |  |  | 			: actions | 
					
						
							| 
									
										
										
										
											2015-09-08 01:01:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:52:20 +04:00
										 |  |  | 		// get the first defined set of docs in the inheritance chain...
 | 
					
						
							|  |  |  | 		actions.forEach(function(n){ | 
					
						
							|  |  |  | 			var cur = that | 
					
						
							| 
									
										
										
										
											2014-10-11 06:33:49 +04:00
										 |  |  | 			res[n] = [] | 
					
						
							| 
									
										
										
										
											2015-09-08 01:01:06 +03:00
										 |  |  | 			// go up the proto chain...
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:52:20 +04:00
										 |  |  | 			while(cur.__proto__ != null){ | 
					
						
							| 
									
										
										
										
											2014-10-11 06:33:49 +04:00
										 |  |  | 				if(cur[n] != null && cur[n].doc != null){ | 
					
						
							| 
									
										
										
										
											2014-10-06 03:52:20 +04:00
										 |  |  | 					res[n] = [ cur[n].doc, cur[n].long_doc ] | 
					
						
							|  |  |  | 					break | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				cur = cur.__proto__ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		return res | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-08 01:01:06 +03:00
										 |  |  | 	getPath: 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 | 
					
						
							|  |  |  | 			// go up the proto chain...
 | 
					
						
							|  |  |  | 			while(cur.__proto__ != null){ | 
					
						
							|  |  |  | 				if(cur[n] != null && cur[n].doc != null){ | 
					
						
							|  |  |  | 					var doc = cur[n].doc | 
					
						
							|  |  |  | 					var long_doc = cur[n].long_doc | 
					
						
							|  |  |  | 					break | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				cur = cur.__proto__ | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			res[(doc && doc.replace(/[\\\/]$/, '/'+n)) || n] = [n, doc, long_doc] | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 		return res | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | 	// 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.
 | 
					
						
							| 
									
										
										
										
											2014-10-06 16:32:15 +04:00
										 |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-10-08 04:52:41 +04:00
										 |  |  | 	// For more docs on handler sequencing and definition see: .on(..)
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:52:20 +04:00
										 |  |  | 	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 | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 16:32:15 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 	// Register an action callback...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//	Register a post action callback
 | 
					
						
							| 
									
										
										
										
											2014-10-13 17:32:19 +04:00
										 |  |  | 	// 	.on('action', [<tag>, ]<function>)
 | 
					
						
							|  |  |  | 	// 	.on('action.post', [<tag>, ]<function>)
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 	// 		-> <action-set>
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// 	Register a pre action callback
 | 
					
						
							| 
									
										
										
										
											2014-10-13 17:32:19 +04:00
										 |  |  | 	// 	.on('action.pre', [<tag>, ]<function>)
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 	// 		-> <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.
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2015-12-05 04:38:15 +03:00
										 |  |  | 	// Handler Arguments:
 | 
					
						
							|  |  |  | 	// 	'pre'		- the handler will get the same arguments as the main
 | 
					
						
							|  |  |  | 	// 					action when called.
 | 
					
						
							|  |  |  | 	// 	'post'		- the handler will get the action return value followed
 | 
					
						
							|  |  |  | 	// 					by action arguments.
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-10-13 17:32:19 +04:00
										 |  |  | 	// The optional tag marks the handler to enable group removal via 
 | 
					
						
							|  |  |  | 	// .off(..)
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | 	// NOTE: 'post' mode is the default.
 | 
					
						
							| 
									
										
										
										
											2014-10-13 17:32:19 +04:00
										 |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-10-29 18:50:04 +03:00
										 |  |  | 	// XXX should we have multiple tags per handler???
 | 
					
						
							| 
									
										
										
										
											2014-10-25 03:06:05 +04:00
										 |  |  | 	on: function(actions, b, c){ | 
					
						
							| 
									
										
										
										
											2014-10-13 17:32:19 +04:00
										 |  |  | 		var handler = typeof(c) == 'function' ? c : b | 
					
						
							|  |  |  | 		var tag = typeof(c) == 'function' ? b : c | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-25 12:01:08 +04:00
										 |  |  | 		actions = typeof(actions) == 'string' ? actions.split(' ') : actions | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-25 03:06:05 +04:00
										 |  |  | 		var that = this | 
					
						
							| 
									
										
										
										
											2014-10-25 12:01:08 +04:00
										 |  |  | 		actions.forEach(function(action){ | 
					
						
							| 
									
										
										
										
											2014-10-25 03:06:05 +04:00
										 |  |  | 			// prepare the handler...
 | 
					
						
							|  |  |  | 			var mode = action.split('.') | 
					
						
							|  |  |  | 			action = mode[0] | 
					
						
							|  |  |  | 			mode = mode[1] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-02 00:15:27 +03:00
										 |  |  | 			// keep the original handler for future use...
 | 
					
						
							|  |  |  | 			var a_handler = handler | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-25 03:06:05 +04:00
										 |  |  | 			// a post handler (default)...
 | 
					
						
							|  |  |  | 			if(mode == null || mode == 'post'){ | 
					
						
							| 
									
										
										
										
											2014-11-02 00:15:27 +03:00
										 |  |  | 				var old_handler = a_handler | 
					
						
							|  |  |  | 				a_handler = function(){ return old_handler } | 
					
						
							| 
									
										
										
										
											2014-10-25 03:06:05 +04:00
										 |  |  | 				// NOTE: this is set so as to identify the handler for removal
 | 
					
						
							|  |  |  | 				// 		via. .off(..)
 | 
					
						
							| 
									
										
										
										
											2014-11-02 00:15:27 +03:00
										 |  |  | 				a_handler.orig_handler = old_handler.orig_handler || old_handler | 
					
						
							| 
									
										
										
										
											2014-10-25 03:06:05 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// mot pre mode...
 | 
					
						
							|  |  |  | 			} else if(mode != 'pre') { | 
					
						
							|  |  |  | 				// XXX
 | 
					
						
							|  |  |  | 				throw 'Unknown action mode: '+action+'.'+mode | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-02 00:15:27 +03:00
										 |  |  | 			a_handler.tag = tag | 
					
						
							| 
									
										
										
										
											2014-10-25 03:06:05 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// 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...
 | 
					
						
							| 
									
										
										
										
											2014-11-02 00:15:27 +03:00
										 |  |  | 			if(that._action_handlers[action].indexOf(a_handler) < 0){ | 
					
						
							| 
									
										
										
										
											2014-10-25 03:06:05 +04:00
										 |  |  | 				// NOTE: last registered is first...
 | 
					
						
							| 
									
										
										
										
											2014-11-02 00:15:27 +03:00
										 |  |  | 				that._action_handlers[action].splice(0, 0, a_handler) | 
					
						
							| 
									
										
										
										
											2014-10-25 03:06:05 +04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							| 
									
										
										
										
											2014-10-13 17:32:19 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 		return this | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Remove an action callback...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-10-29 18:50:04 +03:00
										 |  |  | 	//	Remove all handlers from action:
 | 
					
						
							|  |  |  | 	//	.off('action')
 | 
					
						
							|  |  |  | 	//	.off('action', '*')
 | 
					
						
							|  |  |  | 	//	.off('action', 'all')
 | 
					
						
							|  |  |  | 	// 		-> <action-set>
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//	Remove specific handler from action:
 | 
					
						
							|  |  |  | 	//	.off('action', <handler>)
 | 
					
						
							|  |  |  | 	// 		-> <action-set>
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	//	Remove handlers from action by tag:
 | 
					
						
							|  |  |  | 	//	.off('action', <tag>)
 | 
					
						
							|  |  |  | 	// 		-> <action-set>
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: the handler passed to .off(..) for removal must be the same
 | 
					
						
							|  |  |  | 	// 		as the handler passed to .on(..) / .one(..)
 | 
					
						
							| 
									
										
										
										
											2014-10-25 12:01:08 +04:00
										 |  |  | 	off: function(actions, handler){ | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 		if(this.hasOwnProperty('_action_handlers')){ | 
					
						
							| 
									
										
										
										
											2014-10-25 12:01:08 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			actions = actions == '*' ? Object.keys(this._action_handlers) | 
					
						
							| 
									
										
										
										
											2014-10-29 18:50:04 +03:00
										 |  |  | 				: typeof(actions) == 'string' ?  actions.split(' ') | 
					
						
							| 
									
										
										
										
											2014-10-25 12:01:08 +04:00
										 |  |  | 				: actions | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-13 17:32:19 +04:00
										 |  |  | 			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) | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-13 17:32:19 +04:00
										 |  |  | 					// NOTE: unknown modes are skipped...
 | 
					
						
							|  |  |  | 					if(i >= 0){ | 
					
						
							|  |  |  | 						h.splice(i, 1) | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-29 18:50:04 +03:00
										 |  |  | 				// remove all handlers...
 | 
					
						
							|  |  |  | 				} else if(handler == null || handler == 'all' || handler == '*'){ | 
					
						
							|  |  |  | 					h.splice(0, h.length) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-13 17:32:19 +04:00
										 |  |  | 				// 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 }))) | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}) | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-10-29 18:50:04 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return this | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Register an action callback that will only fire once per event...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// This is signature compatible with .on(..)
 | 
					
						
							|  |  |  | 	one: function(actions, b, c){ | 
					
						
							|  |  |  | 		var handler = typeof(c) == 'function' ? c : b | 
					
						
							|  |  |  | 		var tag = typeof(c) == 'function' ? b : c | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		actions = typeof(actions) == 'string' ? actions.split(' ') : actions | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var that = this | 
					
						
							|  |  |  | 		actions.forEach(function(action){ | 
					
						
							|  |  |  | 			var _handler = function(){ | 
					
						
							|  |  |  | 				// remove handler... 
 | 
					
						
							|  |  |  | 				that.off(action, handler) | 
					
						
							|  |  |  | 				return handler.apply(this, arguments) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			_handler.orig_handler = handler | 
					
						
							|  |  |  | 			that.on(action, tag, _handler) | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 		return this | 
					
						
							|  |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2014-10-25 12:01:08 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-30 03:45:38 +03:00
										 |  |  | 	// Get mixin object in inheritance chain...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: if pre is true this will return the chain item before the 
 | 
					
						
							|  |  |  | 	// 		mixin, this is useful, for example, to remove mixins, see 
 | 
					
						
							|  |  |  | 	// 		.mixout(..) for an example...
 | 
					
						
							|  |  |  | 	getMixin: function(from, pre){ | 
					
						
							|  |  |  | 		var cur = this | 
					
						
							|  |  |  | 		var proto = this.__proto__ | 
					
						
							|  |  |  | 		while(proto != null){ | 
					
						
							| 
									
										
										
										
											2014-11-30 03:47:21 +03:00
										 |  |  | 			// we have a hit...
 | 
					
						
							| 
									
										
										
										
											2014-11-30 03:45:38 +03:00
										 |  |  | 			if(proto.hasOwnProperty('__mixin_source')  | 
					
						
							|  |  |  | 					&& proto.__mixin_source === from){ | 
					
						
							|  |  |  | 				return pre ? cur : proto | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// go to next item in chain...
 | 
					
						
							|  |  |  | 			cur = proto | 
					
						
							|  |  |  | 			proto = cur.__proto__ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return null | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2014-10-28 14:20:10 +03:00
										 |  |  | 	// Mixin a set of actions into this...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-10-25 12:01:08 +04:00
										 |  |  | 	// NOTE: if 'all' is set them mixin all the actions available, 
 | 
					
						
							|  |  |  | 	// 		otherwise only mixin local actions...
 | 
					
						
							| 
									
										
										
										
											2014-11-30 03:45:38 +03:00
										 |  |  | 	// NOTE: this will override existing own attributes.
 | 
					
						
							|  |  |  | 	inlineMmixin: function(from, all, descriptors, all_attr_types){ | 
					
						
							| 
									
										
										
										
											2014-11-21 17:11:13 +03:00
										 |  |  | 		// defaults...
 | 
					
						
							|  |  |  | 		descriptors = descriptors || true | 
					
						
							|  |  |  | 		all_attr_types = all_attr_types || false | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 03:37:37 +03:00
										 |  |  | 		if(all){ | 
					
						
							|  |  |  | 			var keys = [] | 
					
						
							|  |  |  | 			for(var k in from){ | 
					
						
							|  |  |  | 				keys.push(k) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			var keys = Object.keys(from) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var that = this | 
					
						
							|  |  |  | 		keys.forEach(function(k){ | 
					
						
							| 
									
										
										
										
											2014-11-30 03:45:38 +03:00
										 |  |  | 			/* | 
					
						
							|  |  |  | 			// XXX is this the right way to go???
 | 
					
						
							|  |  |  | 			// check if we are not overwriting anything...
 | 
					
						
							|  |  |  | 			if(that.hasOwnProperty(k)){ | 
					
						
							|  |  |  | 				console.warn('WARNING:', that,'already has attribute', k, '- skipping...') | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-21 17:11:13 +03:00
										 |  |  | 			// properties....
 | 
					
						
							|  |  |  | 			var prop = Object.getOwnPropertyDescriptor(from, k) | 
					
						
							|  |  |  | 			if(descriptors && prop.get != null){ | 
					
						
							|  |  |  | 				// NOTE: so as to be able to delete this on mixout...
 | 
					
						
							|  |  |  | 				prop.configurable = true | 
					
						
							|  |  |  | 				Object.defineProperty(that, k, prop) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// actions and other attributes...
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				var attr = from[k] | 
					
						
							|  |  |  | 				if(all_attr_types || attr instanceof Action){ | 
					
						
							|  |  |  | 					that[k] = attr | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-10-28 03:37:37 +03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return this | 
					
						
							| 
									
										
										
										
											2014-10-25 12:01:08 +04:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2014-10-28 14:20:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-30 03:45:38 +03:00
										 |  |  | 	// Same as .inlineMmixin(..) but isolates a mixin in a seporate object
 | 
					
						
							| 
									
										
										
										
											2015-11-09 22:48:13 +03:00
										 |  |  | 	// in the inheritance chain...
 | 
					
						
							| 
									
										
										
										
											2014-11-30 03:45:38 +03:00
										 |  |  | 	//
 | 
					
						
							|  |  |  | 	mixin: function(from, all, descriptors, all_attr_types){ | 
					
						
							|  |  |  | 		var proto = Object.create(this.__proto__) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// mixinto an empty object
 | 
					
						
							|  |  |  | 		proto.inlineMmixin(from, all, descriptors, all_attr_types) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// mark the mixin for simpler removal...
 | 
					
						
							|  |  |  | 		proto.__mixin_source = from | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		this.__proto__ = proto | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return this | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 14:20:10 +03:00
										 |  |  | 	// Mixin a set of local actions into an object...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:24:06 +03:00
										 |  |  | 	// XXX this will not work on non-actions...
 | 
					
						
							| 
									
										
										
										
											2014-11-24 04:02:01 +03:00
										 |  |  | 	mixinTo: function(to, all, descriptors, all_attr_types){ | 
					
						
							|  |  |  | 		return this.mixin.call(to, this, all, descriptors, all_attr_types) | 
					
						
							| 
									
										
										
										
											2014-10-25 12:01:08 +04:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2014-10-28 14:20:10 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Remove mixed in actions from this...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: this will only remove local actions, inherited actions will
 | 
					
						
							|  |  |  | 	// 		not be affected...
 | 
					
						
							|  |  |  | 	// NOTE: this will not affect event handlers, they should be removed
 | 
					
						
							|  |  |  | 	// 		manually if needed...
 | 
					
						
							| 
									
										
										
										
											2014-11-30 03:45:38 +03:00
										 |  |  | 	inlineMixout: function(from, all, descriptors, all_attr_types){ | 
					
						
							| 
									
										
										
										
											2014-11-21 17:11:13 +03:00
										 |  |  | 		// defaults...
 | 
					
						
							|  |  |  | 		descriptors = descriptors || true | 
					
						
							|  |  |  | 		all_attr_types = all_attr_types || false | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 14:20:10 +03:00
										 |  |  | 		if(all){ | 
					
						
							|  |  |  | 			var keys = [] | 
					
						
							|  |  |  | 			for(var k in from){ | 
					
						
							|  |  |  | 				keys.push(k) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			var keys = Object.keys(from) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		var locals = Object.keys(this) | 
					
						
							|  |  |  | 		var that = this | 
					
						
							|  |  |  | 		keys.forEach(function(k){ | 
					
						
							| 
									
										
										
										
											2014-11-21 17:11:13 +03:00
										 |  |  | 			var prop = Object.getOwnPropertyDescriptor(from, k) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// descriptor...
 | 
					
						
							|  |  |  | 			if(descriptors && prop.get != null){ | 
					
						
							|  |  |  | 				if(prop.get === Object.getOwnPropertyDescriptor(that, k).get){ | 
					
						
							|  |  |  | 					delete that[k] | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// actions and other attrs...
 | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				var attr = from[k] | 
					
						
							|  |  |  | 				if((all_attr_types || attr instanceof Action)  | 
					
						
							|  |  |  | 						// remove only local attrs...
 | 
					
						
							|  |  |  | 						&& locals.indexOf(k) >= 0){ | 
					
						
							|  |  |  | 					delete that[k] | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-10-28 14:20:10 +03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return this | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-30 03:45:38 +03:00
										 |  |  | 	// This is similare in effect but different in mechanics to .inlineMixout(..)
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// This will find and remove a mixin object from the inheritance chian.
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: this will remove only the first occurance of a mixin.
 | 
					
						
							|  |  |  | 	mixout: function(from){ | 
					
						
							|  |  |  | 		var o = this.getMixin(from, true) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// pop the mixin off the chain...
 | 
					
						
							|  |  |  | 		if(o != null){ | 
					
						
							|  |  |  | 			o.__proto__ = o.__proto__.__proto__ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return this | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-28 14:20:10 +03:00
										 |  |  | 	// Remove a set of local mixed in actions from object...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2014-11-24 04:02:01 +03:00
										 |  |  | 	mixoutFrom: function(to, all, descriptors, all_attr_types){ | 
					
						
							|  |  |  | 		return this.mixout.call(to, this, all, descriptors, all_attr_types) | 
					
						
							| 
									
										
										
										
											2014-10-28 14:20:10 +03:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2015-12-08 05:24:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-08 08:27:44 +03:00
										 |  |  | 	// Create a child object...
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							|  |  |  | 	// NOTE: this will create a .config in the instance that inherits from
 | 
					
						
							|  |  |  | 	// 		this.config...
 | 
					
						
							|  |  |  | 	// NOTE: this will not copy/clone any data.
 | 
					
						
							|  |  |  | 	//
 | 
					
						
							| 
									
										
										
										
											2015-12-08 05:24:06 +03:00
										 |  |  | 	// XXX is this correct???
 | 
					
						
							|  |  |  | 	clone: function(){ | 
					
						
							| 
									
										
										
										
											2015-12-08 08:27:44 +03:00
										 |  |  | 		var o = Object.create(this) | 
					
						
							|  |  |  | 		o.config = Object.create(this.config) | 
					
						
							|  |  |  | 		return o | 
					
						
							| 
									
										
										
										
											2015-12-08 05:24:06 +03:00
										 |  |  | 	}, | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 06:18:39 +04:00
										 |  |  | // An action set...
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | //
 | 
					
						
							|  |  |  | //	Actions(<object>)
 | 
					
						
							|  |  |  | //	Actions(<prototype>, <object>)
 | 
					
						
							|  |  |  | //		-> actions
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This will pre-process an object to setup the action mechanics.
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-11-28 03:57:10 +03:00
										 |  |  | // If the this and prototype both contain a .config attribute then this
 | 
					
						
							|  |  |  | // will make set <actions>.config.__proto__ = <prototype>.config 
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | //
 | 
					
						
							|  |  |  | // The action format:
 | 
					
						
							|  |  |  | // 	{
 | 
					
						
							|  |  |  | // 		// full format...
 | 
					
						
							|  |  |  | // 		<name> : [
 | 
					
						
							|  |  |  | // 			<doc>,
 | 
					
						
							|  |  |  | // 			<long-doc>,
 | 
					
						
							|  |  |  | // 			<function>
 | 
					
						
							|  |  |  | // 		],
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 		// short doc only...
 | 
					
						
							|  |  |  | // 		<name> : [
 | 
					
						
							|  |  |  | // 			<doc>,
 | 
					
						
							|  |  |  | // 			<function>
 | 
					
						
							|  |  |  | // 		],
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 		// only the code...
 | 
					
						
							|  |  |  | // 		<name> : [
 | 
					
						
							|  |  |  | // 			<function>
 | 
					
						
							|  |  |  | // 		],
 | 
					
						
							|  |  |  | // 		...
 | 
					
						
							|  |  |  | // 	}
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2015-07-29 15:22:49 +03:00
										 |  |  | // NOTE: the action function is always last.
 | 
					
						
							| 
									
										
										
										
											2014-10-06 06:18:39 +04:00
										 |  |  | // NOTE: if <prototype> is not given, MetaActions will be used as default.
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-10-06 06:18:39 +04:00
										 |  |  | // For more documentation see: Action(..).
 | 
					
						
							| 
									
										
										
										
											2014-10-29 18:50:04 +03:00
										 |  |  | //
 | 
					
						
							|  |  |  | // XXX add doc, ldoc, tags and save them to each action...
 | 
					
						
							| 
									
										
										
										
											2014-11-28 03:57:10 +03:00
										 |  |  | // XXX is .config processing correct here???
 | 
					
						
							| 
									
										
										
										
											2015-11-07 19:44:52 +03:00
										 |  |  | // XXX should this be a full fledged object???
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | var Actions = | 
					
						
							|  |  |  | module.Actions = | 
					
						
							|  |  |  | function Actions(a, b){ | 
					
						
							|  |  |  | 	var obj = b == null ? a : b | 
					
						
							|  |  |  | 	var proto = b == null ? MetaActions : a | 
					
						
							| 
									
										
										
										
											2015-11-07 19:44:52 +03:00
										 |  |  | 	obj = obj || {} | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// NOTE: this is intentionally done only for own attributes...
 | 
					
						
							|  |  |  | 	Object.keys(obj).forEach(function(k){ | 
					
						
							|  |  |  | 		var args = obj[k] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// skip non-arrays...
 | 
					
						
							| 
									
										
										
										
											2014-10-11 17:08:17 +04:00
										 |  |  | 		if(args == null  | 
					
						
							|  |  |  | 				|| args.constructor !== Array  | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 				// 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...
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 		obj[k] = new Action(k, args[0], args[1], func) | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if(proto != null){ | 
					
						
							|  |  |  | 		obj.__proto__ = proto | 
					
						
							| 
									
										
										
										
											2014-11-28 03:57:10 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		// XXX is this the right way to go???
 | 
					
						
							|  |  |  | 		if(obj.config != null && proto.config != null){ | 
					
						
							|  |  |  | 			obj.config.__proto__ = proto.config | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return obj | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var test = | 
					
						
							|  |  |  | module.test = | 
					
						
							|  |  |  | function test(){ | 
					
						
							|  |  |  | 	var TestActions =  | 
					
						
							|  |  |  | 	module.TestActions =  | 
					
						
							|  |  |  | 	Actions({ | 
					
						
							|  |  |  | 		testActionGen1: ['baisc test action...', | 
					
						
							|  |  |  | 			'some extra info', | 
					
						
							|  |  |  | 			function(){ | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 				console.log('  test 1!') | 
					
						
							|  |  |  | 				return function(){ | 
					
						
							|  |  |  | 					console.log('  test 2!') | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 			}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		testActionGen2: ['baisc 2\'nd gen test action...', | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 			// no extra info...
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 			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...
 | 
					
						
							| 
									
										
										
										
											2014-10-13 00:18:26 +04:00
										 |  |  | 		testActionGen1: [ | 
					
						
							|  |  |  | 			function(){ | 
					
						
							|  |  |  | 				console.log('  pre callback!') | 
					
						
							|  |  |  | 				return function(){ | 
					
						
							|  |  |  | 					console.log('  post callback!') | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			}], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		testAction2: ['this is an action', | 
					
						
							|  |  |  | 			function(){ | 
					
						
							|  |  |  | 				console.log('testAction2 args:', arguments) | 
					
						
							|  |  |  | 			}], | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-06 02:25:57 +04:00
										 |  |  | 	// 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
 | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 	*/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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...
 | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | 	TestActions2.on('testActionGen1.post',  | 
					
						
							|  |  |  | 			function(){ console.log('  post handler! (first defined)') }) | 
					
						
							|  |  |  | 	TestActions2.on('testActionGen1',  | 
					
						
							|  |  |  | 			function(){ console.log('  post handler! (last defined)') }) | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	console.log('TestActions2.testActionGen1()') | 
					
						
							|  |  |  | 	TestActions2.testActionGen1() | 
					
						
							| 
									
										
										
										
											2014-10-06 03:14:11 +04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	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() | 
					
						
							| 
									
										
										
										
											2014-10-04 01:39:05 +04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                                                */ | 
					
						
							|  |  |  | return module }) |