Add `patch`-hook, `update`-hook and short circuiting

pull/2/head
paldepind 10 years ago
parent f5d2b0f861
commit 1eb19f827e

@ -178,12 +178,18 @@ function init(modules) {
function patchVnode(oldVnode, vnode) {
var i, elm = vnode.elm = oldVnode.elm, oldCh = oldVnode.children, ch = vnode.children;
if (!isUndef(i = vnode.data) && !isUndef(i = i.hook) && !isUndef(i = i.patch)) {
i(oldVnode, vnode);
}
if (oldVnode === vnode) return;
if (!isUndef(vnode.data)) {
for (i = 0; i < updateCbs.length; ++i) updateCbs[i](oldVnode, vnode);
i = vnode.data.hook;
if (!isUndef(i) && !isUndef(i = i.update)) i(vnode);
}
if (isUndef(vnode.text)) {
if (!isUndef(oldCh) && !isUndef(ch)) {
updateChildren(elm, oldCh, ch);
if (oldCh !== ch) updateChildren(elm, oldCh, ch);
} else if (!isUndef(ch)) {
addVnodes(elm, undefined, ch, 0, ch.length - 1);
} else if (!isUndef(oldCh)) {

@ -382,6 +382,7 @@ describe('snabbdom', function() {
assert.deepEqual(map(inner, elm.children), ['Three', 'One', 'Two']);
});
});
});
describe('event handling', function() {
it('attaches click event handler to element', function() {
var result = [];
@ -433,7 +434,8 @@ describe('snabbdom', function() {
assert.deepEqual(result, [1, 2]);
});
});
describe('lifecycle vnode hooks', function() {
describe('hooks', function() {
describe('element hooks', function() {
it('calls `create` listener before inserted into parent but after children', function() {
var result = [];
function cb(vnode) {
@ -472,6 +474,54 @@ describe('snabbdom', function() {
patch(vnode0, vnode1);
assert.equal(1, result.length);
});
it('calls `patch` listener', function() {
var result = [];
function cb(oldVnode, vnode) {
assert.strictEqual(oldVnode, vnode1.children[1]);
assert.strictEqual(vnode, vnode2.children[1]);
result.push(vnode);
}
var vnode1 = h('div', [
h('span', 'First sibling'),
h('div', {hook: {patch: cb}}, [
h('span', 'Child 1'),
h('span', 'Child 2'),
]),
]);
var vnode2 = h('div', [
h('span', 'First sibling'),
h('div', {hook: {patch: cb}}, [
h('span', 'Child 1'),
h('span', 'Child 2'),
]),
]);
patch(vnode0, vnode1);
patch(vnode1, vnode2);
assert.equal(result.length, 1);
});
it('calls `update` listener', function() {
var result = [];
function cb(vnode, rm) {
result.push(vnode);
}
var vnode1 = h('div', [
h('span', 'First sibling'),
h('div', {hook: {update: cb}}, [
h('span', 'Child 1'),
h('span', {hook: {update: cb}}, 'Child 2'),
]),
]);
var vnode2 = h('div', [
h('span', 'First sibling'),
h('div', {hook: {update: cb}}, [
h('span', 'Child 1'),
h('span', {hook: {update: cb}}, 'Child 2'),
]),
]);
patch(vnode0, vnode1);
patch(vnode1, vnode2);
assert.equal(result.length, 2);
});
it('calls `remove` listener', function() {
var result = [];
function cb(vnode, rm) {
@ -515,6 +565,8 @@ describe('snabbdom', function() {
rm2();
assert.equal(elm.children.length, 0);
});
});
describe('module hooks', function() {
it('invokes `pre` and `post` hook', function() {
var result = [];
var patch = snabbdom.init([
@ -560,4 +612,30 @@ describe('snabbdom', function() {
});
});
});
describe('short circuiting', function() {
it('does not update strictly equal vnodes', function() {
var result = [];
function cb(vnode) { result.push(vnode); }
var vnode1 = h('div', [
h('span', {hook: {update: cb}}, 'Hello'),
h('span', 'there'),
]);
patch(vnode0, vnode1);
patch(vnode1, vnode1);
assert.equal(result.length, 0);
});
it('does not update strictly equal children', function() {
var result = [];
function cb(vnode) { result.push(vnode); }
var vnode1 = h('div', [
h('span', {hook: {patch: cb}}, 'Hello'),
h('span', 'there'),
]);
var vnode2 = h('div');
vnode2.children = vnode1.children;
patch(vnode0, vnode1);
patch(vnode1, vnode2);
assert.equal(result.length, 0);
});
});
});

Loading…
Cancel
Save