UNPKG

auto-events

Version:

Small Vanilla JS utility for binding events between DOMNode and a simple controller.

64 lines (53 loc) 1.77 kB
/** * # AutoEvents * * Auto bind events on DOM nodes with methods from a controller. * */ /* eslint curly:0, no-param-reassign:0 */ import functionCallParser from 'elenpi-simple-function-call-parser/src/index'; const debug = require('debug'); const eventAttributeMatcher = /^data-ev-(\w+)/i; const autoEvents = { devMode: false }; function isAllowedMethod(name, ctrl) { if (!ctrl[name]) throw new Error('method not found on component : ', name); return true; } function parseCallAndCheck(value, parsed, ctrl) { parsed = functionCallParser.parse(value); isAllowedMethod(parsed.method, ctrl); return parsed; } function checkAttribute(node, ctrl, attrib) { const matched = eventAttributeMatcher.exec(attrib.name); if (matched) { const eventType = matched[1]; let parsed; debug('bind event (%s) with : %s : on : ', eventType, attrib.value, ctrl); if (!parsed && autoEvents.devMode) // immediate parsing and check of events parsed = parseCallAndCheck(attrib.value, parsed, ctrl); node.addEventListener(eventType, e => { if (!parsed && !autoEvents.devMode) // lazzy parsing and check of events parsed = parseCallAndCheck(attrib.value, parsed, ctrl); debug('binded event : %s ! : ', eventType, parsed.method, parsed.arguments); ctrl[parsed.method](e, ...parsed.arguments); }); } } function bindEvents(node, ctrl) { if (typeof node === 'string') node = document.querySelector(node); [].slice.call(node.attributes) .forEach(attrib => checkAttribute(node, ctrl, attrib)); } autoEvents.bindEvents = bindEvents; autoEvents.install = function($ = window.$) { $.fn.autoEvents = function autoEvents(ctrl) { this.get().forEach(node => bindEvents(node, ctrl)); return this; }; }; module.exports = autoEvents;