Comparing version 0.5.1 to 0.5.2
@@ -1,57 +0,92 @@ | ||
var is = require('../is'); | ||
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 arrInvoker(arr) { | ||
return function() { | ||
if (!arr.length) return; | ||
// Special case when length is two, for performance | ||
arr.length === 2 ? arr[0](arr[1]) : arr[0].apply(undefined, arr.slice(1)); | ||
}; | ||
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 fnInvoker(o) { | ||
return function(ev) { | ||
if (o.fn === null) return; | ||
o.fn(ev); | ||
}; | ||
function createListener() { | ||
return function handler(event) { | ||
handleEvent(event, handler.vnode); | ||
} | ||
} | ||
function updateEventListeners(oldVnode, vnode) { | ||
var name, cur, old, elm = vnode.elm, | ||
oldOn = oldVnode.data.on, on = vnode.data.on; | ||
var oldOn = oldVnode.data.on, | ||
oldListener = oldVnode.listener, | ||
oldElm = oldVnode.elm, | ||
on = vnode && vnode.data.on, | ||
elm = vnode && vnode.elm, | ||
name; | ||
if (!on && !oldOn) return; | ||
on = on || {}; | ||
oldOn = oldOn || {}; | ||
// optimization for reused immutable handlers | ||
if (oldOn === on) { | ||
return; | ||
} | ||
for (name in on) { | ||
cur = on[name]; | ||
old = oldOn[name]; | ||
if (old === undefined) { | ||
if (is.array(cur)) { | ||
elm.addEventListener(name, arrInvoker(cur)); | ||
} else { | ||
cur = {fn: cur}; | ||
on[name] = cur; | ||
elm.addEventListener(name, fnInvoker(cur)); | ||
// 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 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; | ||
for (name in oldOn) { | ||
// remove listener if existing listener removed | ||
if (!on[name]) { | ||
oldElm.removeEventListener(name, oldListener, false); | ||
} | ||
} | ||
} | ||
} | ||
if (oldOn) { | ||
for (name in oldOn) { | ||
if (on[name] === undefined) { | ||
var old = oldOn[name]; | ||
if (is.array(old)) { | ||
old.length = 0; | ||
// 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); | ||
} | ||
else { | ||
old.fn = null; | ||
} | ||
} | ||
@@ -62,2 +97,6 @@ } | ||
module.exports = {create: updateEventListeners, update: updateEventListeners}; | ||
module.exports = { | ||
create: updateEventListeners, | ||
update: updateEventListeners, | ||
destroy: updateEventListeners | ||
}; |
{ | ||
"name": "snabbdom", | ||
"version": "0.5.1", | ||
"version": "0.5.2", | ||
"description": "A virtual DOM library with focus on simplicity, modularity, powerful features and performance.", | ||
@@ -5,0 +5,0 @@ "main": "snabbdom.js", |
@@ -468,2 +468,20 @@ # Snabbdom | ||
#### Using Classes | ||
Due to a bug in certain browsers like IE 11 and below and UC Browser, SVG Objects in these browsers do not support classlist property. Hence, the classes module (which uses classlist property internally) will not work for these browsers. | ||
Also, using snabbdom/h to create an element by passing a className along with the element type will not work as className property is read-only for SVG elements. | ||
You can add classes to SVG elements for both of these cases by using the attributes module as shown below:- | ||
```javascript | ||
h('text', { | ||
attrs: { | ||
x: xPos, | ||
y: yPos, | ||
dy: "5", | ||
class: 'text_class' | ||
}}, | ||
text | ||
); | ||
``` | ||
### Thunks | ||
@@ -470,0 +488,0 @@ |
@@ -72,3 +72,3 @@ var assert = require('assert'); | ||
var result = []; | ||
function clicked() { result.push([].slice.call(arguments)); } | ||
function clicked() { result.push([].slice.call(arguments, 0, arguments.length-2)); } | ||
var vnode1 = h('div', {on: {click: [clicked, 1, 2, 3]}}, [ | ||
@@ -91,2 +91,84 @@ h('a', 'Click my parent'), | ||
}); | ||
it('detach attached click event handler to element', function() { | ||
var result = []; | ||
function clicked(ev) { result.push(ev); } | ||
var vnode1 = h('div', {on: {click: clicked}}, [ | ||
h('a', 'Click my parent'), | ||
]); | ||
elm = patch(vnode0, vnode1).elm; | ||
elm.click(); | ||
assert.equal(1, result.length); | ||
var vnode2 = h('div', {on: {}}, [ | ||
h('a', 'Click my parent'), | ||
]); | ||
elm = patch(vnode1, vnode2).elm; | ||
elm.click(); | ||
assert.equal(1, result.length); | ||
}); | ||
it('multiple event handlers for same event on same element', function() { | ||
var result = []; | ||
function clicked(ev) { result.push(ev); } | ||
var vnode1 = h('div', {on: {click: [[clicked], [clicked], [clicked]]}}, [ | ||
h('a', 'Click my parent'), | ||
]); | ||
elm = patch(vnode0, vnode1).elm; | ||
elm.click(); | ||
assert.equal(3, result.length); | ||
var vnode2 = h('div', {on: {click: [[clicked], [clicked]]}}, [ | ||
h('a', 'Click my parent'), | ||
]); | ||
elm = patch(vnode1, vnode2).elm; | ||
elm.click(); | ||
assert.equal(5, result.length); | ||
}); | ||
it('access to virtual node in event handler', function() { | ||
var result = []; | ||
function clicked(ev, vnode) { result.push(this); result.push(vnode); } | ||
var vnode1 = h('div', {on: {click: clicked }}, [ | ||
h('a', 'Click my parent'), | ||
]); | ||
elm = patch(vnode0, vnode1).elm; | ||
elm.click(); | ||
assert.equal(2, result.length); | ||
assert.equal(vnode1, result[0]); | ||
assert.equal(vnode1, result[1]); | ||
}), | ||
it('access to virtual node in event handler with argument', function() { | ||
var result = []; | ||
function clicked(arg, ev, vnode) { result.push(this); result.push(vnode); } | ||
var vnode1 = h('div', {on: {click: [clicked, 1] }}, [ | ||
h('a', 'Click my parent'), | ||
]); | ||
elm = patch(vnode0, vnode1).elm; | ||
elm.click(); | ||
assert.equal(2, result.length); | ||
assert.equal(vnode1, result[0]); | ||
assert.equal(vnode1, result[1]); | ||
}), | ||
it('access to virtual node in event handler with arguments', function() { | ||
var result = []; | ||
function clicked(arg1, arg2, ev, vnode) { result.push(this); result.push(vnode); } | ||
var vnode1 = h('div', {on: {click: [clicked, 1, "2"] }}, [ | ||
h('a', 'Click my parent'), | ||
]); | ||
elm = patch(vnode0, vnode1).elm; | ||
elm.click(); | ||
assert.equal(2, result.length); | ||
assert.equal(vnode1, result[0]); | ||
assert.equal(vnode1, result[1]); | ||
}); | ||
it('shared handlers in parent and child nodes', function() { | ||
var result = []; | ||
var sharedHandlers = { | ||
click: function(ev) { result.push(ev); } | ||
}; | ||
var vnode1 = h('div', {on: sharedHandlers}, [ | ||
h('a', {on: sharedHandlers}, 'Click my parent'), | ||
]); | ||
elm = patch(vnode0, vnode1).elm; | ||
elm.click(); | ||
assert.equal(1, result.length); | ||
elm.firstChild.click(); | ||
assert.equal(3, result.length); | ||
}); | ||
}); |
@@ -8,7 +8,7 @@ { | ||
"serve_files": [ | ||
"test/browserified.js" | ||
"browserified.js" | ||
], | ||
"before_tests": "browserify -d test/index.js -o test/browserified.js", | ||
"on_exit": "rm test/browserified.js", | ||
"before_tests": "browserify -d test/index.js -o browserified.js", | ||
"on_exit": "rm browserified.js", | ||
"launch_in_dev": [ "firefox", "chromium" ] | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
515586
9528
638