Add attachTo module

pull/8/head
paldepind 10 years ago
parent f1ee781962
commit 24206f430a

@ -120,16 +120,19 @@ var vnode = h('div', {style: {color: '#000'}}, [
### Hooks
#### Overview
| Name | Triggered when | Arguments to callback |
| --------- | -------------- | --------------------- |
| `pre` | the patch process begins. | |
| `create` | a DOM element has been created based on a VNode. | `emptyVNode, createdVnode` |
| `insert` | an element has been inserted into the DOM. | `insertedVnode` |
| `patch` | an element is about to be patched. | `oldVnode, newVnode` |
| `update` | an element is being updated. | `oldVnode, newVnode` |
| `pre` | the patch process begins. | none |
| `create` | a DOM element has been created based on a VNode. | `emptyVNode, vnode` |
| `insert` | an element has been inserted into the DOM. | `vnode` |
| `patch` | an element is about to be patched. | `oldVnode, vnode` |
| `update` | an element is being updated. | `oldVnode, vnode` |
| `remove` | an element is directly being removed from the DOM. | `vnode, removeCallback` |
| `destroy` | an element is begin removed from the DOM or it's parent is. | `vnode` |
| `post` | the patch process is done. | |
| `destroy` | an element is being removed from the DOM or it's parent is. | `vnode` |
| `post` | the patch process is done. | none |
## Modules documentation

@ -0,0 +1,34 @@
function insert(vnode) {
// Placeholder has been inserted, reset the vnodes
// element to the actual element so that updates will
// be made to the proper element
var attach = vnode.data.attachTo;
vnode.elm = attach.elm;
}
function attach(_, vnode) {
var data = vnode.data, target = data.attachTo;
if (target === undefined) return;
var elm = vnode.elm;
var placeholder = document.createElement('span');
// Replace actual element with dummy placeholder
// Snabbdom will then insert placeholder instead
vnode.elm = placeholder;
target.appendChild(elm);
if (vnode.data.hook === undefined) vnode.data.hook = {};
data.attachTo = {target: target, placeholder: placeholder, elm: elm};
var hook = vnode.data.hook;
hook.insert = insert;
}
function destroy(vnode) {
var attach = vnode.data.attachTo;
if (attach === undefined) return;
// Manually remove the actual element from where it was inserted
attach.target.removeChild(attach.elm);
// Replace actual element with the dummy
// placeholder so that Snabbdom removes it
vnode.elm = attach.placeholder;
}
module.exports = {create: attach, destroy: destroy};

@ -79,7 +79,7 @@ function init(modules) {
} else {
elm = vnode.elm = document.createTextNode(vnode.text);
}
return elm;
return vnode.elm;
}
function addVnodes(parentElm, before, vnodes, startIdx, endIdx) {
@ -103,10 +103,10 @@ function init(modules) {
for (; startIdx <= endIdx; ++startIdx) {
var i, listeners, rm, ch = vnodes[startIdx];
if (!isUndef(ch)) {
invokeDestroyHook(ch);
listeners = cbs.remove.length + 1;
rm = createRmCb(parentElm, ch.elm, listeners);
for (i = 0; i < cbs.remove.length; ++i) cbs.remove[i](ch, rm);
invokeDestroyHook(ch);
if (!isUndef(i = ch.data) && !isUndef(i = i.hook) && !isUndef(i = i.remove)) {
i(ch, rm);
} else {

@ -0,0 +1,60 @@
var assert = require('assert');
var snabbdom = require('../snabbdom');
var patch = snabbdom.init([
require('../modules/attachto'),
]);
var h = require('../h');
describe('attachTo', function() {
var elm, vnode0;
beforeEach(function() {
elm = document.createElement('div');
vnode0 = elm;
});
it('adds element to target', function() {
patch(vnode0, h('div', [
h('div#wrapper', [
h('div', 'Some element'),
h('div#attached', {attachTo: elm}, 'Test'),
]),
]));
console.log(elm.children);
assert.equal(elm.children.length, 2);
});
it('updates element at target', function() {
var vnode1 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
h('div#attached', {attachTo: elm}, 'First text'),
]),
]);
var vnode2 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
h('div#attached', {attachTo: elm}, 'New text'),
]),
]);
patch(vnode0, vnode1);
assert.equal(elm.children[0].innerHTML, 'First text');
patch(vnode1, vnode2);
assert.equal(elm.children[0].innerHTML, 'New text');
});
it('removes element at target', function() {
var vnode1 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
h('div#attached', {attachTo: elm}, 'First text'),
]),
]);
var vnode2 = h('div', [
h('div#wrapper', [
h('div', 'Some element'),
]),
]);
patch(vnode0, vnode1);
assert.equal(elm.children[0].innerHTML, 'First text');
patch(vnode1, vnode2);
assert.equal(elm.children.length, 1);
});
});

@ -588,8 +588,8 @@ describe('snabbdom', function() {
it('removes element when all remove listeners are done', function() {
var rm1, rm2, rm3;
var patch = snabbdom.init([
{remove: function(_, rm) { rm1 = rm; }},
{remove: function(_, rm) { rm2 = rm; }},
{remove: function(_, rm) { rm1 = rm; }},
{remove: function(_, rm) { rm2 = rm; }},
]);
var vnode1 = h('div', [h('a', {hook: {remove: function(_, rm) { rm3 = rm; }}})]);
patch(vnode0, vnode1);
@ -608,14 +608,14 @@ describe('snabbdom', function() {
it('invokes `pre` and `post` hook', function() {
var result = [];
var patch = snabbdom.init([
{pre: function() { result.push('pre'); }},
{post: function() { result.push('post'); }},
{pre: function() { result.push('pre'); }},
{post: function() { result.push('post'); }},
]);
var vnode1 = h('div');
patch(vnode0, vnode1);
assert.deepEqual(result, ['pre', 'post']);
});
it('invokes `destroy` hook for all removed children', function() {
it('invokes global `destroy` hook for all removed children', function() {
var result = [];
function cb(vnode) { result.push(vnode); }
var vnode1 = h('div', [

@ -1,3 +1,4 @@
require('./core');
require('./style');
require('./attachto');
require('./thunk');

Loading…
Cancel
Save