| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | /********************************************************************** | 
					
						
							|  |  |  | *  | 
					
						
							|  |  |  | * | 
					
						
							|  |  |  | * | 
					
						
							| 
									
										
										
										
											2020-11-26 22:56:23 +03:00
										 |  |  | * XXX need ability to extend event to implement proxy events... | 
					
						
							|  |  |  | * 		...i.e. .on(..) / ... get called on one object but the handler | 
					
						
							|  |  |  | * 		bound on a different object via a proxy event method... | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | * XXX is types/events the right place for this??? | 
					
						
							| 
									
										
										
										
											2020-11-13 13:37:10 +03:00
										 |  |  | * XXX should we have .pre/.post events??? | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | * XXX should we propogate event handling to parent/overloaded events??? | 
					
						
							| 
									
										
										
										
											2020-11-13 13:37:10 +03:00
										 |  |  | * | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | **********************************************/  /* c8 ignore next 2 */ | 
					
						
							|  |  |  | ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) | 
					
						
							|  |  |  | (function(require){ var module={} // make module AMD/node compatible...
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var object = require('ig-object') | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*********************************************************************/ | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | // Event method wrappers...
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | var EventCommand =  | 
					
						
							|  |  |  | module.EventCommand =  | 
					
						
							|  |  |  | object.Constructor('EventCommand', { | 
					
						
							|  |  |  | 	name: null, | 
					
						
							|  |  |  | 	__init__: function(name, data={}){ | 
					
						
							|  |  |  | 		Object.assign(this, data, {name}) }, | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | // Create an "eventfull" method...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // The resulting method can be either called directly or via .trigger(..).
 | 
					
						
							|  |  |  | // Handlrs can be bound to it via .on(..) and unbound via .off(..) and 
 | 
					
						
							|  |  |  | // calling it will trigger the handlers either after the user func(..)
 | 
					
						
							|  |  |  | // return or when the user calles the passed handler(..) function.
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2020-11-15 03:12:33 +03:00
										 |  |  | // 	Eventfull(name[, options])
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | // 		-> method
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2020-11-15 03:12:33 +03:00
										 |  |  | // 	Eventfull(name, func[, options])
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | // 		-> method
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | //	Trigger the event...
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | //	method(...args)
 | 
					
						
							|  |  |  | //		-> ..
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 	func(handle, ...args)
 | 
					
						
							|  |  |  | // 		-> ..
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | //	trigger event handlers...
 | 
					
						
							|  |  |  | //	handle()
 | 
					
						
							|  |  |  | //	handle(true)
 | 
					
						
							|  |  |  | //		-> true
 | 
					
						
							|  |  |  | //		-> false
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //	prevent event handlers from triggering...
 | 
					
						
							|  |  |  | //	handle(false)
 | 
					
						
							|  |  |  | //		-> undefined
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Special case: EventCommand...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //	EventCommand instance can be passed as the first argument of method, 
 | 
					
						
							|  |  |  | //	in this case the event function will get it but the event handlers 
 | 
					
						
							|  |  |  | //	will not...
 | 
					
						
							|  |  |  | //	This is done to be able to externally pass commands to event methods
 | 
					
						
							|  |  |  | //	that get handled in a special way by the function but not passed to 
 | 
					
						
							|  |  |  | //	the event handlers...
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 		method(<event-command>, ...args)
 | 
					
						
							|  |  |  | // 			-> ..
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // 		func(handle, <event-command>, ...args)
 | 
					
						
							|  |  |  | // 			-> ..
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | // NOTE: calling handle(false) will exiplicitly disable calling the 
 | 
					
						
							|  |  |  | // 		handlers for that call...
 | 
					
						
							| 
									
										
										
										
											2020-11-15 03:12:33 +03:00
										 |  |  | var Eventfull =  | 
					
						
							|  |  |  | module.Eventfull = | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | function(name, func, options={}){ | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 	var hidden | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 	options = func && typeof(func) != 'function' ? | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 		func | 
					
						
							|  |  |  | 		: options | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 05:48:54 +03:00
										 |  |  | 	var method = object.mixin( | 
					
						
							|  |  |  | 		function(...args){ | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 			var handlers =  | 
					
						
							|  |  |  | 				// hidden...
 | 
					
						
							|  |  |  | 				options.handlerLocation == 'hidden' ? | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 					(hidden || []) | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 				// function...
 | 
					
						
							|  |  |  | 				: options.handlerLocation == 'method' ? | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 					(method.__event_handlers__ || []) | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 				// context (default)...
 | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 				: ((this.__event_handlers__ || {})[name] || []) | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 			// NOTE: this will stop event handling if one of the handlers 
 | 
					
						
							|  |  |  | 			// 		explicitly returns false...
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | 			// NOTE: if the user does not call handle() it will be called 
 | 
					
						
							|  |  |  | 			// 		after the event action is done but before it returns...
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:27:20 +03:00
										 |  |  | 			// NOTE: to explicitly disable calling the handlers func must 
 | 
					
						
							|  |  |  | 			// 		call handle(false)
 | 
					
						
							|  |  |  | 			var did_handle = false | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | 			var handle = function(run=true){ | 
					
						
							|  |  |  | 				did_handle = run === false | 
					
						
							|  |  |  | 				var a = args[0] instanceof EventCommand ? | 
					
						
							|  |  |  | 					args.slice(1) | 
					
						
							|  |  |  | 					: args | 
					
						
							|  |  |  | 				return run ? | 
					
						
							|  |  |  | 					handlers | 
					
						
							| 
									
										
										
										
											2020-11-15 02:27:20 +03:00
										 |  |  | 						.reduce(function(res, handler){  | 
					
						
							|  |  |  | 							return res === true  | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | 								&& handler(name, ...a) !== false }, true)  | 
					
						
							|  |  |  | 					: undefined }  | 
					
						
							| 
									
										
										
										
											2020-11-15 02:27:20 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			var res = func ? | 
					
						
							|  |  |  | 				func.call(this, handle, ...args) | 
					
						
							|  |  |  | 				: undefined | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | 			// call the handlers if the user either didn't call handle()
 | 
					
						
							|  |  |  | 			// or explicitly called handle(false)...
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:27:20 +03:00
										 |  |  | 			!did_handle | 
					
						
							|  |  |  | 				&& handle() | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			return res }, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 			__event__: 'bare', | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 			get __event_handler_location__(){ | 
					
						
							|  |  |  | 				return ['hidden', 'method'].includes(options.handlerLocation) ? | 
					
						
							|  |  |  | 					options.handlerLocation | 
					
						
							|  |  |  | 					: 'context' }, | 
					
						
							|  |  |  | 			__event_handler_add__: function(context, func){ | 
					
						
							|  |  |  | 				var handlers =  | 
					
						
							|  |  |  | 					// hidden...
 | 
					
						
							|  |  |  | 					options.handlerLocation == 'hidden' ? | 
					
						
							|  |  |  | 						(hidden = hidden || []) | 
					
						
							|  |  |  | 					// function...
 | 
					
						
							|  |  |  | 					: options.handlerLocation == 'method' ? | 
					
						
							|  |  |  | 						(method.__event_handlers__ = method.__event_handlers__ || []) | 
					
						
							|  |  |  | 					// context (default)...
 | 
					
						
							| 
									
										
										
										
											2020-11-24 05:48:54 +03:00
										 |  |  | 					: (context.__event_handlers__ == null ? | 
					
						
							|  |  |  | 						Object.defineProperty(context, '__event_handlers__', { | 
					
						
							|  |  |  | 								value: {[name]: (handlers = [])}, | 
					
						
							|  |  |  | 								enumerable: false, | 
					
						
							|  |  |  | 							})  | 
					
						
							|  |  |  | 							&& handlers | 
					
						
							|  |  |  | 						: (context.__event_handlers__[name] =  | 
					
						
							|  |  |  | 							context.__event_handlers__[name] || [])) | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 				// add handler...
 | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 				handlers.push(func) | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 				return this }, | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 			// XXX should this support the 'all' key -- remove all handlers???
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 			__event_handler_remove__: function(context, func){ | 
					
						
							|  |  |  | 				var handlers =  | 
					
						
							|  |  |  | 					(options.handlerLocation == 'hidden' ?  | 
					
						
							|  |  |  | 						hidden | 
					
						
							|  |  |  | 					: options.handlerLocation == 'method' ? | 
					
						
							|  |  |  | 						method.__event_handlers__ | 
					
						
							|  |  |  | 					: (context.__event_handlers__ || {})[name]) || [] | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | 				handlers.splice(0, handlers.length, | 
					
						
							|  |  |  | 					...handlers.filter(function(h){ | 
					
						
							|  |  |  | 						return h !== func | 
					
						
							|  |  |  | 							&& h.__event_original_handler__ !== func })) | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 				return this }, | 
					
						
							| 
									
										
										
										
											2020-11-25 20:50:38 +03:00
										 |  |  | 			// remove the handle from the arguments...
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 			toString: function(){ | 
					
						
							| 
									
										
										
										
											2020-11-25 20:50:38 +03:00
										 |  |  | 				return 'Eventfull ' | 
					
						
							|  |  |  | 					+(func.toString() | 
					
						
							|  |  |  | 						.replace(/^(function[^(]*\()[^,)]*, ?/, '$1')) }, | 
					
						
							| 
									
										
										
										
											2020-11-24 05:48:54 +03:00
										 |  |  | 		})  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Object.defineProperty(method, 'name', { | 
					
						
							|  |  |  | 		value: name, | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return method }  | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | module.TRIGGER = module.EventCommand('TRIGGER') | 
					
						
							| 
									
										
										
										
											2020-11-15 05:59:19 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 03:12:33 +03:00
										 |  |  | // Extends Eventfull(..) adding ability to bind events via the 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | // resulting method directly by passing it a function...
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2020-11-15 03:12:33 +03:00
										 |  |  | //	Event(name[, options])
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | //		-> method
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | //
 | 
					
						
							| 
									
										
										
										
											2020-11-15 03:12:33 +03:00
										 |  |  | //	Event(name, func[, options])
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | //		-> method
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //	Bind handler...
 | 
					
						
							|  |  |  | //	method(handler)
 | 
					
						
							|  |  |  | //		-> this
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //	Unbind handler...
 | 
					
						
							|  |  |  | //	method(handler, false)
 | 
					
						
							|  |  |  | //		-> this
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //	Trigger handlers...
 | 
					
						
							|  |  |  | //	method(...args)
 | 
					
						
							|  |  |  | //		-> this
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //	func(handle, ...args)
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2020-11-15 05:59:19 +03:00
										 |  |  | // Special case:
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | //	Force trigger event...
 | 
					
						
							|  |  |  | //	method(TRIGGER, ...args)
 | 
					
						
							|  |  |  | //		-> this
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This will pass args to the event action regardless whether the first 
 | 
					
						
							|  |  |  | // arg is a function or not...
 | 
					
						
							|  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2020-11-15 03:12:33 +03:00
										 |  |  | var Event =  | 
					
						
							|  |  |  | module.Event = | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | function(name, func, options={}){ | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 	var method | 
					
						
							|  |  |  | 	options = typeof(func) != 'function' ? | 
					
						
							|  |  |  | 		func | 
					
						
							|  |  |  | 		: options | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-24 05:48:54 +03:00
										 |  |  | 	//return Object.assign(
 | 
					
						
							|  |  |  | 	return object.mixin( | 
					
						
							| 
									
										
										
										
											2020-11-15 03:12:33 +03:00
										 |  |  | 		method = Eventfull(name,  | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 			function(handle, ...args){ | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | 				// NOTE: when the first arg is an event command this will
 | 
					
						
							|  |  |  | 				// 		fall through to calling the action...
 | 
					
						
							|  |  |  | 				typeof(args[0]) == 'function' ? | 
					
						
							|  |  |  | 					// add handler...
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 					method.__event_handler_add__(this, args[0]) | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | 					// call the action...
 | 
					
						
							|  |  |  | 					: (func | 
					
						
							|  |  |  | 						&& func.call(this, handle, ...args)) | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 				return this },  | 
					
						
							|  |  |  | 			options), | 
					
						
							|  |  |  |    		{ | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 			__event__: 'full', | 
					
						
							| 
									
										
										
										
											2020-11-15 03:12:33 +03:00
										 |  |  | 			// NOTE: this is a copy of Eventfull's .toString() as we 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 			// 		still need to base the doc on the user's func...
 | 
					
						
							|  |  |  | 			toString: function(){ | 
					
						
							| 
									
										
										
										
											2020-11-24 05:48:54 +03:00
										 |  |  | 				return func ? | 
					
						
							| 
									
										
										
										
											2020-11-25 20:50:38 +03:00
										 |  |  | 					'Event ' | 
					
						
							|  |  |  | 						+func.toString() | 
					
						
							|  |  |  | 							.replace(/^(function[^(]*\()[^,)]*, ?/, '$1') | 
					
						
							|  |  |  | 		   			: `Event function ${name}(){}`}, | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 		}) } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | // Like Event(..) but produces an event that can only be triggered via 
 | 
					
						
							|  |  |  | // .trigger(name, ...), calling this is a no-op...
 | 
					
						
							|  |  |  | var PureEvent = | 
					
						
							|  |  |  | module.PureEvent = | 
					
						
							|  |  |  | function(name, options={}){ | 
					
						
							| 
									
										
										
										
											2020-11-25 20:50:38 +03:00
										 |  |  | 	return object.mixin( | 
					
						
							|  |  |  | 		Event(name, function(handle, trigger){  | 
					
						
							|  |  |  | 			trigger === module.TRIGGER  | 
					
						
							|  |  |  | 				|| handle(false) }, options), | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			toString: function(){ | 
					
						
							|  |  |  | 				return `PureEvent ${name}(){}`}, | 
					
						
							|  |  |  | 		}) } | 
					
						
							| 
									
										
										
										
											2020-11-25 20:39:55 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-26 22:56:23 +03:00
										 |  |  | // XXX
 | 
					
						
							|  |  |  | var ProxyEvent = | 
					
						
							|  |  |  | module.ProxyEvent = | 
					
						
							|  |  |  | function(name, target, options={}){ | 
					
						
							|  |  |  | 	// XXX
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | //---------------------------------------------------------------------
 | 
					
						
							|  |  |  | // Mixins...
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | // XXX might be nice to add support to pre/post handlers...
 | 
					
						
							|  |  |  | // XXX still not sure about the builtin-local event control flow...
 | 
					
						
							| 
									
										
										
										
											2020-11-15 02:53:05 +03:00
										 |  |  | // XXX do we need to be able to force global handler???
 | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | var EventHandlerMixin =  | 
					
						
							| 
									
										
										
										
											2020-11-19 02:24:09 +03:00
										 |  |  | module.EventHandlerMixin = object.Mixin('EventHandlerMixin', { | 
					
						
							| 
									
										
										
										
											2020-11-24 05:48:54 +03:00
										 |  |  | 	//__event_handlers__: null,
 | 
					
						
							| 
									
										
										
										
											2020-11-13 13:37:10 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 	on: function(evt, func){ | 
					
						
							|  |  |  | 		// event...
 | 
					
						
							| 
									
										
										
										
											2020-11-13 13:37:10 +03:00
										 |  |  | 		if(evt in this  | 
					
						
							|  |  |  | 				&& this[evt].__event_handler_add__){ | 
					
						
							|  |  |  | 			this[evt].__event_handler_add__(this, func) | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 		// non-event...
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2020-11-24 05:48:54 +03:00
										 |  |  | 			this.__event_handlers__ == null | 
					
						
							|  |  |  | 				&& Object.defineProperty(this, '__event_handlers__', { | 
					
						
							|  |  |  | 					value: {}, | 
					
						
							|  |  |  | 					enumerable: false, | 
					
						
							|  |  |  | 				}) | 
					
						
							|  |  |  | 			;(this.__event_handlers__[evt] =  | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 					this.__event_handlers__[evt] || []) | 
					
						
							|  |  |  | 				.push(func) } | 
					
						
							|  |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | 	one: function(evt, func){ | 
					
						
							|  |  |  | 		var handler | 
					
						
							|  |  |  | 		this.on(evt,  | 
					
						
							| 
									
										
										
										
											2020-11-15 05:13:35 +03:00
										 |  |  | 			handler = Object.assign( | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | 				function(handle, ...args){ | 
					
						
							|  |  |  | 					this.off(evt, handler) | 
					
						
							| 
									
										
										
										
											2020-11-15 05:13:35 +03:00
										 |  |  | 					return func.call(this, handle, ...args) }.bind(this), | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | 				{__event_original_handler__: func})) | 
					
						
							|  |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 	// XXX do we need .off(evt, 'all')
 | 
					
						
							| 
									
										
										
										
											2020-11-13 13:37:10 +03:00
										 |  |  | 	off: function(evt, func){ | 
					
						
							|  |  |  | 		// event...
 | 
					
						
							|  |  |  | 		if(evt in this  | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | 				&& this[evt].__event_handler_remove__){ | 
					
						
							| 
									
										
										
										
											2020-11-13 13:37:10 +03:00
										 |  |  | 			this[evt].__event_handler_remove__(this, func) | 
					
						
							|  |  |  | 		// non-event...
 | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 			var handlers = this.__event_handlers__ | 
					
						
							|  |  |  | 				&& (this.__event_handlers__[evt] || []) | 
					
						
							|  |  |  | 			handlers | 
					
						
							| 
									
										
										
										
											2020-11-15 02:50:39 +03:00
										 |  |  | 				&& handlers.splice(0, handlers.length, | 
					
						
							|  |  |  | 					...handlers.filter(function(h){ | 
					
						
							|  |  |  | 						return h !== func  | 
					
						
							|  |  |  | 							&& h.__event_original_handler__ !== func })) } | 
					
						
							| 
									
										
										
										
											2020-11-13 13:37:10 +03:00
										 |  |  | 		return this }, | 
					
						
							|  |  |  | 	trigger: function(evt, ...args){ | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 		// local handler...
 | 
					
						
							|  |  |  | 		evt in this | 
					
						
							| 
									
										
										
										
											2020-11-15 05:59:19 +03:00
										 |  |  | 			&& this[evt](module.TRIGGER, ...args) | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 		// global events...
 | 
					
						
							|  |  |  | 		this.__event_handlers__ | 
					
						
							|  |  |  | 			&& (this.__event_handlers__[evt] || []) | 
					
						
							|  |  |  | 				.forEach(function(h){ h(evt, ...args) })  | 
					
						
							|  |  |  | 		return this }, | 
					
						
							| 
									
										
										
										
											2020-11-19 02:24:09 +03:00
										 |  |  | }) | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | // NOTE: this can't be added via Object.assign(..), use object.mixinFlat(..) 
 | 
					
						
							|  |  |  | // 		instead...
 | 
					
						
							|  |  |  | var EventDocMixin =  | 
					
						
							| 
									
										
										
										
											2020-11-19 02:24:09 +03:00
										 |  |  | module.EventDocMixin = object.Mixin('EventDocMixin', { | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 	get eventfull(){ | 
					
						
							|  |  |  | 		return object.deepKeys(this) | 
					
						
							|  |  |  | 			.filter(function(n){  | 
					
						
							|  |  |  | 				// avoid triggering props...
 | 
					
						
							|  |  |  | 				return !object.values(this, n, function(){ return object.STOP }, true)[0].get | 
					
						
							|  |  |  | 					&& (this[n] || {}).__event__ == 'bare'}.bind(this)) }, | 
					
						
							|  |  |  | 	get events(){ | 
					
						
							|  |  |  | 		return object.deepKeys(this) | 
					
						
							|  |  |  | 			.filter(function(n){  | 
					
						
							|  |  |  | 				// avoid triggering props...
 | 
					
						
							|  |  |  | 				return !object.values(this, n, function(){ return object.STOP }, true)[0].get | 
					
						
							|  |  |  | 					&& (this[n] || {}).__event__ == 'full' }.bind(this)) }, | 
					
						
							| 
									
										
										
										
											2020-11-19 02:24:09 +03:00
										 |  |  | }) | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var EventMixin =  | 
					
						
							| 
									
										
										
										
											2020-11-19 02:24:09 +03:00
										 |  |  | module.EventMixin =  | 
					
						
							|  |  |  | object.Mixin('EventMixin',  | 
					
						
							|  |  |  | 	EventHandlerMixin, | 
					
						
							|  |  |  | 	EventDocMixin) | 
					
						
							| 
									
										
										
										
											2020-11-15 00:24:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-12 17:35:41 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /********************************************************************** | 
					
						
							|  |  |  | * vim:set ts=4 sw=4 :                               */ return module }) |