function invokeHandler(handler, vnode, event) { if (typeof handler === "function") { // call function handler handler.call(vnode, event, vnode); } else if (typeof handler === "object") { // call handler with arguments if (typeof handler[0] === "function") { // special case for single argument for performance if (handler.length === 2) { handler[0].call(vnode, handler[1], event, vnode); } else { var args = handler.slice(1); args.push(event); args.push(vnode); handler[0].apply(vnode, args); } } else { // call multiple handlers for (var i = 0; i < handler.length; i++) { invokeHandler(handler[i]); } } } } function handleEvent(event, vnode) { var name = event.type, on = vnode.data.on; // call event handler(s) if exists if (on && on[name]) { invokeHandler(on[name], vnode, event); } } function createListener() { return function handler(event) { handleEvent(event, handler.vnode); } } function updateEventListeners(oldVnode, vnode) { var oldOn = oldVnode.data.on, oldListener = oldVnode.listener, oldElm = oldVnode.elm, on = vnode && vnode.data.on, elm = vnode && vnode.elm, name; // optimization for reused immutable handlers if (oldOn === on) { return; } // remove existing listeners which no longer used if (oldOn && oldListener) { // if element changed or deleted we remove all existing listeners unconditionally if (!on) { for (name in oldOn) { // remove listener if element was changed or existing listeners removed oldElm.removeEventListener(name, oldListener, false); } } else { for (name in oldOn) { // remove listener if existing listener removed if (!on[name]) { oldElm.removeEventListener(name, oldListener, false); } } } } // add new listeners which has not already attached if (on) { // reuse existing listener or create new var listener = vnode.listener = oldVnode.listener || createListener(); // update vnode for listener listener.vnode = vnode; // if element changed or added we add all needed listeners unconditionally if (!oldOn) { for (name in on) { // add listener if element was changed or new listeners added elm.addEventListener(name, listener, false); } } else { for (name in on) { // add listener if new listener added if (!oldOn[name]) { elm.addEventListener(name, listener, false); } } } } } module.exports = { create: updateEventListeners, update: updateEventListeners, destroy: updateEventListeners };