FaC: Das alte Flag von Terminen, die in die Zeiterfassung übernommen worden sind, wird ebenfalls berücksichtigt.
166 lines
4.1 KiB
JavaScript
166 lines
4.1 KiB
JavaScript
var promise = require('./promise')
|
|
, flatten = require('./flatten')
|
|
, def = require('./def')
|
|
, noop = function(){}
|
|
|
|
module.exports = function emitterify(body, hooks) {
|
|
body = body || {}
|
|
hooks = hooks || {}
|
|
def(body, 'emit', emit, 1)
|
|
def(body, 'once', once, 1)
|
|
def(body, 'off', off, 1)
|
|
def(body, 'on', on, 1)
|
|
body.on['*'] = body.on['*'] || []
|
|
return body
|
|
|
|
function emit(type, pm, filter) {
|
|
var li = body.on[type.split('.')[0]] || []
|
|
, results = []
|
|
|
|
for (var i = 0; i < li.length; i++)
|
|
if (!li[i].ns || !filter || filter(li[i].ns))
|
|
results.push(call(li[i].isOnce ? li.splice(i--, 1)[0] : li[i], pm))
|
|
|
|
for (var i = 0; i < body.on['*'].length; i++)
|
|
results.push(call(body.on['*'][i], [type, pm]))
|
|
|
|
return results.reduce(flatten, [])
|
|
}
|
|
|
|
function call(cb, pm){
|
|
return cb.next ? cb.next(pm)
|
|
: pm instanceof Array ? cb.apply(body, pm)
|
|
: cb.call(body, pm)
|
|
}
|
|
|
|
function on(type, opts, isOnce) {
|
|
var id = type.split('.')[0]
|
|
, ns = type.split('.')[1]
|
|
, li = body.on[id] = body.on[id] || []
|
|
, cb = typeof opts == 'function' ? opts : 0
|
|
|
|
return !cb && ns ? (cb = body.on[id]['$'+ns]) ? cb : push(observable(body, opts))
|
|
: !cb && !ns ? push(observable(body, opts))
|
|
: cb && ns ? push((remove(li, body.on[id]['$'+ns] || -1), cb))
|
|
: cb && !ns ? push(cb)
|
|
: false
|
|
|
|
function push(cb){
|
|
cb.isOnce = isOnce
|
|
cb.type = id
|
|
if (ns) body.on[id]['$'+(cb.ns = ns)] = cb
|
|
li.push(cb)
|
|
;(hooks.on || noop)(cb)
|
|
return cb.next ? cb : body
|
|
}
|
|
}
|
|
|
|
function once(type, callback){
|
|
return body.on(type, callback, true)
|
|
}
|
|
|
|
function remove(li, cb) {
|
|
var i = li.length
|
|
while (~--i)
|
|
if (cb == li[i] || cb == li[i].fn || !cb)
|
|
(hooks.off || noop)(li.splice(i, 1)[0])
|
|
}
|
|
|
|
function off(type, cb) {
|
|
remove((body.on[type] || []), cb)
|
|
if (cb && cb.ns) delete body.on[type]['$'+cb.ns]
|
|
return body
|
|
}
|
|
|
|
function observable(parent, opts) {
|
|
opts = opts || {}
|
|
var o = emitterify(opts.base || promise())
|
|
o.i = 0
|
|
o.li = []
|
|
o.fn = opts.fn
|
|
o.parent = parent
|
|
o.source = opts.fn ? o.parent.source : o
|
|
|
|
o.on('stop', function(reason){
|
|
o.type
|
|
? o.parent.off(o.type, o)
|
|
: o.parent.off(o)
|
|
return o.reason = reason
|
|
})
|
|
|
|
o.each = function(fn) {
|
|
var n = fn.next ? fn : observable(o, { fn: fn })
|
|
o.li.push(n)
|
|
return n
|
|
}
|
|
|
|
o.pipe = function(fn) {
|
|
return fn(o)
|
|
}
|
|
|
|
o.map = function(fn){
|
|
return o.each(function(d, i, n){ return n.next(fn(d, i, n)) })
|
|
}
|
|
|
|
o.filter = function(fn){
|
|
return o.each(function(d, i, n){ return fn(d, i, n) && n.next(d) })
|
|
}
|
|
|
|
o.reduce = function(fn, acc) {
|
|
return o.each(function(d, i, n){ return n.next(acc = fn(acc, d, i, n)) })
|
|
}
|
|
|
|
o.unpromise = function(){
|
|
var n = observable(o, { base: {}, fn: function(d){ return n.next(d) } })
|
|
o.li.push(n)
|
|
return n
|
|
}
|
|
|
|
o.next = function(value) {
|
|
o.resolve && o.resolve(value)
|
|
return o.li.length
|
|
? o.li.map(function(n){ return n.fn(value, n.i++, n) })
|
|
: value
|
|
}
|
|
|
|
o.until = function(stop){
|
|
return !stop ? 0
|
|
: stop.each ? stop.each(o.stop) // TODO: check clean up on stop too
|
|
: stop.then ? stop.then(o.stop)
|
|
: stop.call ? o.filter(stop).map(o.stop)
|
|
: 0
|
|
}
|
|
|
|
o.off = function(fn){
|
|
return remove(o.li, fn), o
|
|
}
|
|
|
|
o.start = function(stop){
|
|
o.until(stop)
|
|
o.source.emit('start')
|
|
return o
|
|
}
|
|
|
|
o.stop = function(reason){
|
|
return o.source.emit('stop', reason)
|
|
}
|
|
|
|
o[Symbol.asyncIterator] = function(){
|
|
return {
|
|
next: function(){
|
|
return o.wait = new Promise(function(resolve){
|
|
o.wait = true
|
|
o.map(function(d, i, n){
|
|
delete o.wait
|
|
o.off(n)
|
|
resolve({ value: d, done: false })
|
|
})
|
|
o.emit('pull', o)
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
return o
|
|
}
|
|
} |