Comparing version 2.0.0 to 2.1.0
56
index.js
@@ -5,2 +5,4 @@ /* global MutationObserver */ | ||
var watch = [] | ||
var KEY_ID = 'onloadid' + (new Date() % 9e6).toString(36) | ||
var INDEX = 0 | ||
@@ -10,28 +12,42 @@ if (window && window.MutationObserver) { | ||
for (var i = 0; i < mutations.length; i++) { | ||
var mutation = mutations[i] | ||
var x, y | ||
for (x = 0; x < mutation.addedNodes.length; x++) { | ||
for (y = 0; y < watch.length; y++) { | ||
if (watch[y][0] === mutation.addedNodes[x]) { | ||
watch[y][1]() | ||
} | ||
eachMutation(mutations[i].removedNodes, function (index) { | ||
if (watch[index][2]) { | ||
watch[index][2]() | ||
// TODO: Do we need clean up here? | ||
} | ||
} | ||
for (x = 0; x < mutation.removedNodes.length; x++) { | ||
for (y = 0; y < watch.length; y++) { | ||
if (watch[y][0] === mutation.removedNodes[x]) { | ||
watch[y][2]() | ||
watch.splice(y, 1) | ||
} | ||
}) | ||
eachMutation(mutations[i].addedNodes, function (index) { | ||
if (watch[index][1]) { | ||
watch[index][1]() | ||
} | ||
} | ||
}) | ||
} | ||
}) | ||
observer.observe(document.body, {childList: true, subtree: true}) | ||
observer.observe(document.body, { | ||
childList: true, | ||
subtree: true | ||
}) | ||
} | ||
module.exports = function onload (el, l, u) { | ||
l = l || function () {} | ||
u = u || function () {} | ||
watch.push([el, l, u]) | ||
module.exports = function onload (el, on, off) { | ||
on = on || function () {} | ||
off = off || function () {} | ||
el.dataset[KEY_ID] = INDEX | ||
watch.push([INDEX.toString(), on, off]) | ||
INDEX += 1 | ||
} | ||
function eachMutation (nodes, fn) { | ||
for (var i = 0; i < nodes.length; i++) { | ||
if (nodes[i] && nodes[i].dataset && nodes[i].dataset[KEY_ID]) { | ||
for (var j = 0; j < watch.length; j++) { | ||
if (watch[j][0] === nodes[i].dataset[KEY_ID]) { | ||
fn(j) | ||
} | ||
} | ||
} | ||
if (nodes[i].childNodes.length > 0) { | ||
eachMutation(nodes[i].childNodes, fn) | ||
} | ||
} | ||
} |
{ | ||
"name": "on-load", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "On load/unload events for DOM elements using a MutationObserver", | ||
@@ -36,4 +36,5 @@ "main": "index.js", | ||
"testron": "^1.2.0", | ||
"wzrd": "^1.3.1" | ||
"wzrd": "^1.3.1", | ||
"yo-yo": "^1.2.1" | ||
} | ||
} |
148
test.js
var onload = require('./') | ||
var test = require('tape') | ||
var yo = require('yo-yo') | ||
@@ -37,1 +38,148 @@ test('onload/onunload', function (t) { | ||
}) | ||
test('complex', function (t) { | ||
t.plan(4) | ||
var state = [] | ||
function button () { | ||
var el = yo`<button>click</button>` | ||
onload(el, function () { | ||
state.push('on') | ||
}, function () { | ||
state.push('off') | ||
}) | ||
return el | ||
} | ||
var root = yo`<div> | ||
${button()} | ||
</div>` | ||
document.body.appendChild(root) | ||
runops([ | ||
function () { | ||
t.deepEqual(state, ['on'], 'turn on') | ||
state = [] | ||
root = yo.update(root, yo`<p>${button()}</p>`) | ||
}, | ||
function () { | ||
t.deepEqual(state, ['off', 'on'], 'turn off/on') | ||
state = [] | ||
root = yo.update(root, yo`<p>removed</p>`) | ||
}, | ||
function () { | ||
t.deepEqual(state, ['off'], 'turn off') | ||
state = [] | ||
var btn = button() | ||
root = yo.update(root, yo`<p><div>${btn}</div></p>`) | ||
root = yo.update(root, yo`<p> | ||
<div>Updated</div> | ||
<div>${btn}</div> | ||
</p>`) | ||
}, | ||
function () { | ||
t.deepEqual(state, ['off', 'on'], 'turn off/on') | ||
} | ||
], function () { | ||
root.parentNode.removeChild(root) | ||
t.end() | ||
}) | ||
}) | ||
test('complex nested', function (t) { | ||
t.plan(8) | ||
var state = [] | ||
function button () { | ||
var el = yo`<button>click</button>` | ||
onload(el, function () { | ||
state.push('on') | ||
}, function () { | ||
state.push('off') | ||
}) | ||
return el | ||
} | ||
function app (page) { | ||
return yo`<div class="app"> | ||
<h1>Hello</h1> | ||
${page} | ||
</div>` | ||
} | ||
var root = app(yo`<div>Loading...</div>`) | ||
document.body.appendChild(root) | ||
runops([ | ||
function () { | ||
t.deepEqual(state, [], 'did nothing') | ||
state = [] | ||
root = yo.update(root, app(yo`<div class="page"> | ||
${button()} | ||
</div>`)) | ||
}, | ||
function () { | ||
t.deepEqual(state, ['on'], 'turn on') | ||
state = [] | ||
root = yo.update(root, app(yo`<div class="page"> | ||
<h3>Another Page</h3> | ||
</div>`)) | ||
}, | ||
function () { | ||
t.deepEqual(state, ['off'], 'turn off') | ||
state = [] | ||
root = yo.update(root, app(yo`<div class="page"> | ||
${button()} | ||
${button()} | ||
</div>`)) | ||
}, | ||
function () { | ||
t.deepEqual(state, ['on', 'on'], 'turn 2 on') | ||
state = [] | ||
root = yo.update(root, app(yo`<div class="page"> | ||
${button()} | ||
${button()} | ||
</div>`)) | ||
}, | ||
function () { | ||
t.deepEqual(state, [], 'do nothing') | ||
state = [] | ||
root = yo.update(root, app(yo`<div class="page"> | ||
${button()} | ||
<p>removed</p> | ||
</div>`)) | ||
}, | ||
function () { | ||
t.deepEqual(state, ['off'], 'turn 1 off') | ||
state = [] | ||
root = yo.update(root, app(yo`Loading...`)) | ||
}, | ||
function () { | ||
t.deepEqual(state, ['off'], 'turn off') | ||
state = [] | ||
root = yo.update(root, app(yo`<div> | ||
<ul> | ||
<li><div><p>${button()}</p></div></li> | ||
</ul> | ||
</div>`)) | ||
}, | ||
function () { | ||
t.deepEqual(state, ['on'], 'turn on') | ||
} | ||
], function () { | ||
root.parentNode.removeChild(root) | ||
t.end() | ||
}) | ||
}) | ||
function runops (ops, done) { | ||
function loop () { | ||
var next = ops.shift() | ||
if (next) { | ||
next() | ||
setTimeout(loop, 10) | ||
} else { | ||
done() | ||
} | ||
} | ||
setTimeout(loop, 10) | ||
} |
7601
220
7