UNPKG

@v4fire/client

Version:

V4Fire client core library

105 lines (84 loc) 2.6 kB
/*! * V4Fire Client Core * https://github.com/V4Fire/Client * * Released under the MIT license * https://github.com/V4Fire/Client/blob/master/LICENSE */ import symbolGenerator from 'core/symbol'; import Async from 'core/async'; import { ID_ATTRIBUTE } from 'core/component/directives/update-on/const'; import type { ComponentInterface } from 'core/component'; import type { DirectiveValue } from 'core/component/directives/update-on/interface'; export const $$ = symbolGenerator(); export default { /** * Attaches a listener to the specified element * * @param el * @param params * @param ctx - context of the tied component */ add(el: Element, params: DirectiveValue, ctx: ComponentInterface): void { let id = Math.random().toString().slice(2); if (Object.isTruly(params.group)) { id = `${params.group}:${id}`; } const $a = this.getAsync(el, ctx), group = {group: id}; const handler = (...args) => (params.listener ?? params.handler)(el, ...args), errorHandler = (err) => params.errorHandler != null ? params.errorHandler(el, err) : stderr(err); const emitter = Object.isFunction(params.emitter) ? params.emitter() : params.emitter; el.setAttribute(ID_ATTRIBUTE, id); if (Object.isPromise(emitter)) { $a.promise(emitter, group).then(handler, errorHandler); } else if (Object.isString(emitter)) { const // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition unsafe = ctx.unsafe ?? ctx; const watcher = params.options != null ? unsafe.$watch(emitter, params.options, handler) : unsafe.$watch(emitter, handler); $a.worker(watcher, group); } else if (emitter != null) { if (params.event == null) { throw new Error('An event to listen is not specified'); } $a[params.single ?? params.once ? 'once' : 'on'](emitter, params.event, handler, { options: params.options, ...group }); } }, /** * Removes listeners from the specified element * * @param el * @param ctx - context of the tied component */ remove(el: Element, ctx: ComponentInterface | object): void { const group = el.getAttribute(ID_ATTRIBUTE); if (group != null) { this.getAsync(el, ctx).clearAll({group}); } }, /** * Returns an async instance of the specified element * * @param el * @param ctx - context of the tied component */ getAsync(el: Element, ctx: ComponentInterface | object): Async<ComponentInterface> { if ('$async' in ctx) { return ctx.unsafe.$async; } const $a = ctx[$$.async] ?? new Async(ctx); ctx[$$.async] = $a; return $a; } };