New implementation of eventlisteners module
parent
fd539435f6
commit
8ca33c916b
@ -1,62 +1,79 @@
|
|||||||
var is = require('../is');
|
function invokeHandler(handler, vnode, event) {
|
||||||
|
if (typeof handler === "function") {
|
||||||
function arrInvoker(arr) {
|
// call function handler
|
||||||
return function() {
|
handler.call(vnode, event);
|
||||||
if (!arr.length) return;
|
} else if (typeof handler === "object") {
|
||||||
// Special case when length is two, for performance
|
// call handler with arguments
|
||||||
arr.length === 2 ? arr[0](arr[1]) : arr[0].apply(undefined, arr.slice(1));
|
if (typeof handler[0] === "function") {
|
||||||
};
|
// special case for single argument for performance
|
||||||
|
handler.length === 2 ?
|
||||||
|
handler[0].call(vnode, handler[1], event) :
|
||||||
|
handler[0].apply(vnode, handler.slice(1).concat(event));
|
||||||
|
} else {
|
||||||
|
// call multiple handlers
|
||||||
|
for (var i = 0; i < handler.length; i++) {
|
||||||
|
invokeHandler(handler[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fnInvoker(o) {
|
function handleEvent(event, vnode) {
|
||||||
return function(ev) {
|
var name = event.type,
|
||||||
if (o.fn === null) return;
|
on = vnode.data.on;
|
||||||
o.fn(ev);
|
|
||||||
};
|
// 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) {
|
function updateEventListeners(oldVnode, vnode) {
|
||||||
var name, cur, old, elm = vnode.elm,
|
var oldOn = oldVnode.data.on,
|
||||||
oldOn = oldVnode.data.on, on = vnode.data.on;
|
oldListener = oldVnode.listener,
|
||||||
|
oldElm = oldVnode.elm,
|
||||||
if (!on && !oldOn) return;
|
on = vnode && vnode.data.on,
|
||||||
on = on || {};
|
elm = vnode && vnode.elm;
|
||||||
oldOn = oldOn || {};
|
|
||||||
|
// improvement for immutable handlers
|
||||||
for (name in on) {
|
if (oldElm === elm && oldOn === on) {
|
||||||
cur = on[name];
|
return;
|
||||||
old = oldOn[name];
|
}
|
||||||
if (old === undefined) {
|
|
||||||
if (is.array(cur)) {
|
// remove existing listeners which no longer used
|
||||||
elm.addEventListener(name, arrInvoker(cur));
|
if (oldOn && oldListener) {
|
||||||
} else {
|
for (var _name in oldOn) {
|
||||||
cur = {fn: cur};
|
// remove listener if element was changed or existing listener(s) removed
|
||||||
on[name] = cur;
|
if (elm !== oldElm || !on || !on[_name]) {
|
||||||
elm.addEventListener(name, fnInvoker(cur));
|
oldElm.removeEventListener(_name, oldListener, false);
|
||||||
}
|
}
|
||||||
} else if (is.array(old)) {
|
|
||||||
// Deliberately modify old array since it's captured in closure created with `arrInvoker`
|
|
||||||
old.length = cur.length;
|
|
||||||
for (var i = 0; i < old.length; ++i) old[i] = cur[i];
|
|
||||||
on[name] = old;
|
|
||||||
} else {
|
|
||||||
old.fn = cur;
|
|
||||||
on[name] = old;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (oldOn) {
|
|
||||||
for (name in oldOn) {
|
// add new listeners which has not already attached
|
||||||
if (on[name] === undefined) {
|
if (on) {
|
||||||
var old = oldOn[name];
|
// reuse existing listener or create new
|
||||||
if (is.array(old)) {
|
var listener = vnode.listener = oldVnode.listener || createListener();
|
||||||
old.length = 0;
|
// update vnode for listener
|
||||||
}
|
listener.vnode = vnode;
|
||||||
else {
|
|
||||||
old.fn = null;
|
for (var name in on) {
|
||||||
}
|
// add listener if element was changed or new listener(s) added
|
||||||
|
if (elm !== oldElm || !oldOn || !oldOn[name]) {
|
||||||
|
elm.addEventListener(name, listener, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {create: updateEventListeners, update: updateEventListeners};
|
module.exports = {
|
||||||
|
create: updateEventListeners,
|
||||||
|
update: updateEventListeners,
|
||||||
|
destroy: updateEventListeners
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue