UNPKG

@v4fire/client

Version:

V4Fire client core library

121 lines (95 loc) 2.39 kB
/*! * V4Fire Client Core * https://github.com/V4Fire/Client * * Released under the MIT license * https://github.com/V4Fire/Client/blob/master/LICENSE */ /** * [[include:super/i-block/directives/event/README.md]] * @packageDocumentation */ import Component, { VNode, VNodeDirective, ComponentElement } from 'core/component'; import type iBlock from 'super/i-block/i-block'; import { cache, commaRgxp, keyValRgxp } from 'super/i-block/directives/event/const'; function bind( node: ComponentElement<iBlock>, p: VNodeDirective, vNode: VNode & {context?: iBlock}, oldVNode?: VNode ): void { if (!vNode.context) { return; } if (p.arg == null || p.arg === '') { throw new Error('An event type is not defined'); } const m = p.modifiers ?? {}, obj = vNode.context.unsafe.async, raw = Object.cast<{rawName: string}>(p).rawName; const isObj = Object.isPlainObject(p.value), group = isObj && p.value.group || `v-e:${p.arg}`, handler = isObj ? p.value.fn : p.value, cacheList = oldVNode && cache.get(oldVNode); if (oldVNode != null && cacheList != null) { for (let i = 0; i < cacheList.length; i++) { cacheList[i].off({group}); } } cache.set( vNode, Array.concat([], cache.get(vNode), group) ); if (p.arg === 'dnd') { obj.dnd(node, {group, ...p.value}); } else { obj.on(node, p.arg.replace(commaRgxp, ' '), fn, {group, ...isObj && p.value}, Boolean(m.capture)); } const keys = {}; if (m.key) { const res = keyValRgxp.exec(raw); if (res?.[1] != null) { const list = res[1].split(commaRgxp); for (let i = 0; i < list.length; i++) { keys[list[i].toLowerCase()] = true; } } } function fn(this: unknown, e: KeyboardEvent, ...args: unknown[]): void { const key = m.key && e.key; if ( m.alt && !e.altKey || m.shift && !e.shiftKey || m.ctrl && !e.ctrlKey || m.meta && !e.metaKey || Object.isTruly(key) && keys[String(key).toLowerCase()] == null ) { return; } if (m.prevent) { e.preventDefault(); } if (m.stop) { e.stopPropagation(); } if (m.stopImmediate) { e.stopImmediatePropagation(); } const handlers = Array.concat([], handler); for (let i = 0; i < handlers.length; i++) { const fn = handlers[i]; if (Object.isFunction(fn)) { fn.apply(this, args); } } } } Component.directive('e', {bind: Object.cast(bind)});