nouilles/EventojLancilo.js

98 lines
2.8 KiB
JavaScript

var Event = Event || class Event { constructor(type){this.type=type} }
// eventoj lancilo = events launcher
var EventojLancilo = function( obj )
{
obj = this instanceof EventojLancilo ? this : obj
obj = obj instanceof Function ? obj.prototype : obj
let has = {
add: obj.addEventListener || obj.on
, rem: obj.removeEventListener || obj.off
, emit: obj.dispatchEvent || obj.emit || obj.fire || obj.fireEvent
}
// console.log(has)
if( !has.add )
obj[Symbol.Eventoj] = {}
// obj.on = tplOrCall(add) tpl?
// obj.on('a',cb) n ok
// obj.on('a',cb,opt) n ok
// obj.on('a b',cb) n ok
// obj.on(['a','b'],cb) y ko
// obj.on(['a','b'],cb,opt) n ok
// obj.on(['a','b','c'],cb,{}) y ko
// obj.on({a:cba,b:cb2,c:cb3}) n ok
// obj.on('a')(cb) n ko
// obj.on(['a'])(cb) y ok
// obj.on`a`(cb) y ok
// obj.on`${str}change`(cb) y ok
function tplOrCall( fn )
{
return function( ss, ...pp )
{
let isTpl = Array.isArray( ss ) && ss.every( o=> typeof o == 'string' ) && ss.length == pp.length + 1
return isTpl
? (...a)=> fn.bind(this)( String.merge(ss,...pp), ...a )
: fn.bind(this)( ss, ...pp )
}
}
// obj.on(['a','b'],cb,opt)
// obj.on({a:cba,b:cb2,c:cb3},opt)
// obj.on('a b',cb,opt)
function multi( fn )
{
return ( ev, ...args )=>
Array.isArray( ev )
? ev.map( e=> fn(e,...args) )
: typeof ev == 'object'
? Object.keys( ev ).map( e=> fn(e,ev[e],...args) )
: fn(ev,...args)
}
function on( event, handler, options )
{
let evs = this[Symbol.Eventoj][event] = this[Symbol.Eventoj][event] || []
!evs.includes( handler )
&& evs.push( handler )
return this
}
function one( event, handler, options )
{
return on( event, (...args)=> off(handler) && handler(...args) )
}
function off( event, handler )
{
let evs = obj[Symbol.Eventoj][event] = obj[Symbol.Eventoj][event] || []
evs.includes( handler )
&& evs.splice( evs.indexOf(handler), 1 )
return obj
}
function fire( event, ...args )
{
event = typeof event == 'string'
? new Event( event )
: event
event.target = obj
event.details = args
event.type in obj[Symbol.Eventoj]
&& obj[Symbol.Eventoj][event.type].map( h=> h.call(obj, event, ...args) )
return event
}
Object.defineProperties( obj, {
on: { value: tplOrCall(has.add ? has.add : on) }
, off: { value: tplOrCall(has.rem ? has.rem : off) }
, fire: { value: tplOrCall(has.emit ? has.emit : fire) }
, one: { value: tplOrCall(has.add ? has.add : one) }
, once: { value: tplOrCall(has.add ? has.add : one) }
, addEventListener: { value: tplOrCall(has.add ? has.add : on) }
, removeEventListener: { value: tplOrCall(has.rem ? has.rem : off) }
, dispatchEvent: { value: tplOrCall(has.emit ? has.emit : fire) }
, emit: { value: tplOrCall(has.emit ? has.emit : fire) }
})
}
Symbol.Eventoj = Symbol`Eventoj`
export { Event, EventojLancilo }