From 11cf6c3cdcffffa7cad0f6846329c6da75f5eedc Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Thu, 12 Nov 2020 17:35:41 +0300 Subject: [PATCH] adding basic event framework... Signed-off-by: Alex A. Naanou --- event.js | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++ generator.js | 7 +-- package.json | 2 +- 3 files changed, 164 insertions(+), 5 deletions(-) create mode 100644 event.js diff --git a/event.js b/event.js new file mode 100644 index 0000000..c5d91f6 --- /dev/null +++ b/event.js @@ -0,0 +1,160 @@ +/********************************************************************** +* +* +* +**********************************************/ /* 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') + + + +/*********************************************************************/ + +var bareEventMethod = function(name, func, options={}){ + var hidden + var method + + options = typeof(func) != 'function' ? + func + : options + + return object.mixinFlat( + method = function(func, mode){ + var handlers = + // hidden... + options.handlerLocation == 'hidden' ? + (hidden = hidden || []) + // function... + : options.handlerLocation == 'method' ? + (method.__event_handlers__ = method.__event_handlers__ || []) + // context (default)... + : ((this.__event_handlers__ = this.__event_handlers__ || {})[name] = + this.__event_handlers__[name] || []) + + var args = [...arguments] + var handle = function(){ + handlers + .forEach(function(handler){ + handler(...args) }) } + var res + func ? + (res = func.call(this, handle, ...args)) + : handle(...args) + + return res }, + { + __event__: true, + get __event_handler_location__(){ + return ['hidden', 'method'].includes(options.handlerLocation) ? + options.handlerLocation + : 'context' }, + // XXX revise nameing... + __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)... + : ((this.__event_handlers__ = this.__event_handlers__ || {})[name] = + this.__event_handlers__[name] || []) + // add handler... + handlers.push(args[1]) + return this }, + __event_handler_remove__: function(context, func){ + var handlers = + (options.handlerLocation == 'hidden' ? + hidden + : options.handlerLocation == 'method' ? + method.__event_handlers__ + : (context.__event_handlers__ || {})[name]) || [] + handlers.splice(handlers.indexOf(func), 1) + return this }, + toString: function(){ + return func.toString() + .replace(/^(function[^(]*\()[^,)]*, ?/, '$1') }, + }) } + + +// +// eventMethod(name, func) +// -> method +// eventMethod(name, func) +// -> method +// +// +// Bind handler... +// method(handler) +// -> this +// +// Unbind handler... +// method(handler, false) +// -> this +// +// Trigger handlers... +// method(...args) +// -> this +// +// +// func(handle, ...args) +// +// +var eventMethod = function(name, func, options={}){ + var method + options = typeof(func) != 'function' ? + func + : options + + return Object.assign( + method = bareEventMethod(name, + function(handle, ...args){ + // add handler... + // XXX handle handler tags... + if(typeof(args[0]) == 'function'){ + method.__event_handler_add__(this, args[0]) + + // call the action... + } else { + func.call(handle, ...args) } + + return this }, + options), + { + // NOTE: this is a copy of bareEventMethod's .toString() as we + // still need to base the doc on the user's func... + toString: function(){ + return func.toString() + .replace(/^(function[^(]*\()[^,)]*, ?/, '$1') }, + }) } + + +var EventHandlerMixin = { + // XXX add option to force global??? + on: function(evt, func){ + // event... + if(evt in this){ + this[evt].__event_handler_add__ + && this[evt].__event_handler_add__(this, func) + // non-event... + } else { + ;((this.__event_handlers__ = this.__event_handlers__ || {})[evt] = + this.__event_handlers__[evt] || []) + .push(func) } + return this }, + off: function(event, func){ + }, + trigger: function(event, ...args){ + // XXX trigger both the context and the method event handlers... + }, +} + + + + +/********************************************************************** +* vim:set ts=4 sw=4 : */ return module }) diff --git a/generator.js b/generator.js index 7a02d17..26a61c2 100644 --- a/generator.js +++ b/generator.js @@ -63,9 +63,9 @@ module.Generator = // generic generator wrapper... var iter = module.iter = -function*(lst=[]){ - for(var e of lst){ - yield e } } + function*(lst=[]){ + for(var e of lst){ + yield e } } @@ -248,6 +248,5 @@ GeneratorPrototype.prototype.finally = function(func){ - /********************************************************************** * vim:set ts=4 sw=4 : */ return module }) diff --git a/package.json b/package.json index def09eb..cb3fc8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ig-types", - "version": "3.5.2", + "version": "3.6.0", "description": "Generic JavaScript types and type extensions...", "main": "main.js", "scripts": {