trigger(eventName, edata) {
        if (arguments.length == 1) {
            edata = eventName
        } else {
            edata.type = eventName
            edata.target = edata.target ?? this
        }
        if (w2utils.isPlainObject(edata) && edata.phase == 'after') {
            // find event
            edata = this.activeEvents.find(event => {
                if (event.type == edata.type && event.target == edata.target) {
                    return true
                }
                return false
            })
            if (!edata) {
                console.log(`ERROR: Cannot find even handler for "${edata.type}" on "${edata.target}".`)
                return
            }
            console.log('NOTICE: This syntax "edata.trigger({ phase: \'after\' })" is outdated. Use edata.finish() instead.')
        } else if (!(edata instanceof w2event)) {
            edata = new w2event(this, edata)
            this.activeEvents.push(edata)
        }
        let args, fun, tmp
        if (!Array.isArray(this.listeners)) this.listeners = []
        if (this.debug) {
            console.log(`w2base: trigger "${edata.type}:${edata.phase}"`, edata)
        }
        // process events in REVERSE order
        for (let h = this.listeners.length-1; h >= 0; h--) {
            let item = this.listeners[h]
            if (item != null && (item.edata.type === edata.type || item.edata.type === '*') &&
                (item.edata.target === edata.target || item.edata.target == null) &&
                (item.edata.execute === edata.phase || item.edata.execute === '*' || item.edata.phase === '*'))
            {
                // add extra params if there
                Object.keys(item.edata).forEach(key => {
                    if (edata[key] == null && item.edata[key] != null) {
                        edata[key] = item.edata[key]
                    }
                })
                // check handler arguments
                args = []
                tmp  = new RegExp(/\((.*?)\)/).exec(String(item.handler).split('=>')[0])
                if (tmp) args = tmp[1].split(/\s*,\s*/)
                if (args.length === 2) {
                    item.handler.call(this, edata.target, edata) // old way for back compatibility
                    if (this.debug) console.log(' - call (old)', item.handler)
                } else {
                    item.handler.call(this, edata) // new way
                    if (this.debug) console.log(' - call', item.handler)
                }
                if (edata.isStopped === true || edata.stop === true) return edata // back compatibility edata.stop === true
            }
        }
        // main object events
        let funName = 'on' + edata.type.substr(0,1).toUpperCase() + edata.type.substr(1)
        if (edata.phase === 'before' && typeof this[funName] === 'function') {
            fun = this[funName]
            // check handler arguments
            args = []
            tmp  = new RegExp(/\((.*?)\)/).exec(String(fun).split('=>')[0])
            if (tmp) args = tmp[1].split(/\s*,\s*/)
            if (args.length === 2) {
                fun.call(this, edata.target, edata) // old way for back compatibility
                if (this.debug) console.log(' - call: on[Event] (old)', fun)
            } else {
                fun.call(this, edata) // new way
                if (this.debug) console.log(' - call: on[Event]', fun)
            }
            if (edata.isStopped === true || edata.stop === true) return edata // back compatibility edata.stop === true
        }
        // item object events
        if (edata.object != null && edata.phase === 'before' && typeof edata.object[funName] === 'function') {
            fun = edata.object[funName]
            // check handler arguments
            args = []
            tmp  = new RegExp(/\((.*?)\)/).exec(String(fun).split('=>')[0])
            if (tmp) args = tmp[1].split(/\s*,\s*/)
            if (args.length === 2) {
                fun.call(this, edata.target, edata) // old way for back compatibility
                if (this.debug) console.log(' - call: edata.object (old)', fun)
            } else {
                fun.call(this, edata) // new way
                if (this.debug) console.log(' - call: edata.object', fun)
            }
            if (edata.isStopped === true || edata.stop === true) return edata
        }
        // execute onComplete
        if (edata.phase === 'after') {
            if (typeof edata.onComplete === 'function') edata.onComplete.call(this, edata)
            for (let i = 0; i < edata.listeners.length; i++) {
                if (typeof edata.listeners[i] === 'function') {
                    edata.listeners[i].call(this, edata)
                    if (this.debug) console.log(' - call: done', fun)
                }
            }
            edata._resolve(edata)
            if (this.debug) {
                console.log(`w2base: trigger "${edata.type}:${edata.phase}"`, edata)
            }
        }
        return edata
    }
Triggers even listeners for a specific event, loops through this.listeners

@param {Object} edata - Object
@returns modified edata