Comparing version 2.1.3 to 3.0.0
15
index.js
@@ -19,5 +19,5 @@ var assert = require('assert') | ||
// -> walk all child nodes and append to old node | ||
function nanomorph (newTree, oldTree) { | ||
function nanomorph (oldTree, newTree) { | ||
assert.equal(typeof oldTree, 'object', 'nanomorph: oldTree should be an object') | ||
assert.equal(typeof newTree, 'object', 'nanomorph: newTree should be an object') | ||
assert.equal(typeof oldTree, 'object', 'nanomorph: oldTree should be an object') | ||
var tree = walk(newTree, oldTree) | ||
@@ -36,11 +36,6 @@ return tree | ||
return oldNode | ||
} else if (newNode !== oldNode) { | ||
if (newNode.tagName !== oldNode.tagName) { | ||
return newNode | ||
} else { | ||
morph(newNode, oldNode) | ||
updateChildren(newNode, oldNode) | ||
return oldNode | ||
} | ||
} else if (newNode.tagName !== oldNode.tagName) { | ||
return newNode | ||
} else { | ||
morph(newNode, oldNode) | ||
updateChildren(newNode, oldNode) | ||
@@ -47,0 +42,0 @@ return oldNode |
@@ -70,5 +70,3 @@ var xtend = require('xtend') | ||
var kl = Object.keys(keys).length | ||
var i = 0 | ||
var prop | ||
for (i; i < kl; i++) { | ||
for (var i = 0, prop; i < kl; i++) { | ||
prop = keys[i] | ||
@@ -154,2 +152,1 @@ if (/^on/.test(prop)) { | ||
} | ||
{ | ||
"name": "nanomorph", | ||
"version": "2.1.3", | ||
"version": "3.0.0", | ||
"description": "Hyper fast diffing algorithm for real DOM nodes", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -13,4 +13,4 @@ # nanomorph [![stability][0]][1] | ||
var tree = html`<div>hello people</div>` | ||
tree = morph(html`<div>nanananana-na-no</div>`, tree) | ||
tree = morph(html`<div>teeny, tiny, tin bottle</div>`, tree) | ||
tree = morph(tree, html`<div>nanananana-na-no</div>`) | ||
tree = morph(tree, html`<div>teeny, tiny, tin bottle</div>`) | ||
``` | ||
@@ -35,4 +35,31 @@ | ||
## Caching DOM elements | ||
Sometimes we want to tell the algorithm to not evaluate certain nodes (and its | ||
children). This can be because we're sure they haven't changed, or perhaps | ||
because another piece of code is managing that part of the DOM tree. To achieve | ||
this `nanomorph` evaluates the `.isSameNode()` method on nodes to determine if | ||
they should be updated or not. | ||
```js | ||
var el = html`<div>node</div>` | ||
// tell nanomorph to not compare the DOM tree if they're both divs | ||
el.isSameNode = function (target) { | ||
return (target && target.nodeName && target.nodeName === 'DIV') | ||
} | ||
``` | ||
## Building your own | ||
Nanomorph was optimized for simplicity, but different situations might require | ||
different tradeoffs. So in order to allow folks to build their own | ||
implementation we expose our test suite as a function you can call. So | ||
regardless if you're doing it to solve a problem, or just for fun: you can use | ||
the same tests we use for your own implementation. Yay! :sparkles: | ||
```js | ||
var test = require('nanomorph/test') | ||
test(require('./my-morph-implementation')) | ||
``` | ||
## API | ||
### tree = nanomorph(newTree, oldTree) | ||
### tree = nanomorph(oldTree, newTree) | ||
Diff a tree of HTML elements against another tree of HTML elements and create | ||
@@ -39,0 +66,0 @@ a patched result that can be applied on the DOM. |
396
test.js
@@ -5,228 +5,241 @@ var test = require('tape') | ||
test('nanomorph', function (t) { | ||
t.test('should assert input types', function (t) { | ||
t.plan(2) | ||
t.throws(nanomorph, /newTree/) | ||
t.throws(nanomorph.bind(null, {}), /oldTree/) | ||
if (!module.parent) { | ||
specificTests(nanomorph) | ||
abstractMorph(nanomorph) | ||
} else { | ||
module.exports = abstractMorph | ||
} | ||
function specificTests (morph) { | ||
test('nanomorph', function (t) { | ||
t.test('should assert input types', function (t) { | ||
t.plan(2) | ||
t.throws(morph, /oldTree/) | ||
t.throws(morph.bind(null, {}), /newTree/) | ||
}) | ||
}) | ||
} | ||
t.test('root level', function (t) { | ||
t.test('should replace a node', function (t) { | ||
t.plan(1) | ||
function abstractMorph (morph) { | ||
test('abstract morph', function (t) { | ||
t.test('root level', function (t) { | ||
t.test('should replace a node', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<p>hello world</p>` | ||
var newTree = html`<div>hello world</div>` | ||
var oldTree = html`<p>hello world</p>` | ||
var newTree = html`<div>hello world</div>` | ||
var res = nanomorph(newTree, oldTree) | ||
var expected = '<div>hello world</div>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
var res = morph(oldTree, newTree) | ||
var expected = '<div>hello world</div>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
t.test('should morph a node', function (t) { | ||
t.plan(1) | ||
t.test('should morph a node', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<p>hello world</p>` | ||
var newTree = html`<p>hello you</p>` | ||
var oldTree = html`<p>hello world</p>` | ||
var newTree = html`<p>hello you</p>` | ||
var res = nanomorph(newTree, oldTree) | ||
var expected = '<p>hello you</p>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
var res = morph(oldTree, newTree) | ||
var expected = '<p>hello you</p>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
t.test('should morph a node with namespaced attribute', function (t) { | ||
t.plan(1) | ||
t.test('should morph a node with namespaced attribute', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<svg><use xlink:href="#heybooboo"></use></svg>` | ||
var newTree = html`<svg><use xlink:href="#boobear"></use></svg>` | ||
var oldTree = html`<svg><use xlink:href="#heybooboo"></use></svg>` | ||
var newTree = html`<svg><use xlink:href="#boobear"></use></svg>` | ||
var res = nanomorph(newTree, oldTree) | ||
var expected = '<svg><use xlink:href="#boobear"></use></svg>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
var res = morph(oldTree, newTree) | ||
var expected = '<svg><use xlink:href="#boobear"></use></svg>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
t.test('should ignore if node is same', function (t) { | ||
t.plan(1) | ||
t.test('should ignore if node is same', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<p>hello world</p>` | ||
var oldTree = html`<p>hello world</p>` | ||
var res = nanomorph(oldTree, oldTree) | ||
var expected = oldTree | ||
t.equal(res, expected, 'result was expected') | ||
var res = morph(oldTree, oldTree) | ||
var expected = oldTree | ||
t.equal(res, expected, 'result was expected') | ||
}) | ||
}) | ||
}) | ||
t.test('nested', function (t) { | ||
t.test('should replace a node', function (t) { | ||
t.plan(1) | ||
t.test('nested', function (t) { | ||
t.test('should replace a node', function (t) { | ||
t.plan(1) | ||
var oldTree = html` | ||
<main><p>hello world</p></main> | ||
` | ||
var newTree = html` | ||
<main><div>hello world</div></main> | ||
` | ||
var oldTree = html` | ||
<main><p>hello world</p></main> | ||
` | ||
var newTree = html` | ||
<main><div>hello world</div></main> | ||
` | ||
var res = nanomorph(newTree, oldTree) | ||
var expected = '<main><div>hello world</div></main>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
var res = morph(oldTree, newTree) | ||
var expected = '<main><div>hello world</div></main>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
t.test('should replace a node', function (t) { | ||
t.plan(1) | ||
t.test('should replace a node', function (t) { | ||
t.plan(1) | ||
var oldTree = html` | ||
<main><p>hello world</p></main> | ||
` | ||
var newTree = html` | ||
<main><p>hello you</p></main> | ||
` | ||
var oldTree = html` | ||
<main><p>hello world</p></main> | ||
` | ||
var newTree = html` | ||
<main><p>hello you</p></main> | ||
` | ||
var res = nanomorph(newTree, oldTree) | ||
var expected = '<main><p>hello you</p></main>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
var res = morph(oldTree, newTree) | ||
var expected = '<main><p>hello you</p></main>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
t.test('should replace a node', function (t) { | ||
t.plan(1) | ||
t.test('should replace a node', function (t) { | ||
t.plan(1) | ||
var oldTree = html` | ||
<main><p>hello world</p></main> | ||
` | ||
var oldTree = html` | ||
<main><p>hello world</p></main> | ||
` | ||
var res = nanomorph(oldTree, oldTree) | ||
var expected = oldTree | ||
t.equal(res, expected, 'result was expected') | ||
}) | ||
var res = morph(oldTree, oldTree) | ||
var expected = oldTree | ||
t.equal(res, expected, 'result was expected') | ||
}) | ||
t.test('should append a node', function (t) { | ||
t.plan(1) | ||
t.test('should append a node', function (t) { | ||
t.plan(1) | ||
var oldTree = html` | ||
<main></main> | ||
` | ||
var newTree = html` | ||
<main><p>hello you</p></main> | ||
` | ||
var oldTree = html` | ||
<main></main> | ||
` | ||
var newTree = html` | ||
<main><p>hello you</p></main> | ||
` | ||
var res = nanomorph(newTree, oldTree) | ||
var expected = '<main><p>hello you</p></main>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
var res = morph(oldTree, newTree) | ||
var expected = '<main><p>hello you</p></main>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
t.test('should remove a node', function (t) { | ||
t.plan(1) | ||
t.test('should remove a node', function (t) { | ||
t.plan(1) | ||
var oldTree = html` | ||
<main><p>hello you</p></main> | ||
` | ||
var oldTree = html` | ||
<main><p>hello you</p></main> | ||
` | ||
var newTree = html` | ||
<main></main> | ||
` | ||
var newTree = html` | ||
<main></main> | ||
` | ||
var res = nanomorph(newTree, oldTree) | ||
var expected = '<main></main>' | ||
t.equal(String(res), expected, 'result was expected') | ||
var res = morph(oldTree, newTree) | ||
var expected = '<main></main>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
}) | ||
}) | ||
t.test('events', function (t) { | ||
t.test('should copy onclick events', function (t) { | ||
t.plan(2) | ||
var oldTree = html` | ||
<button | ||
onclick=${function () { | ||
t.ok(true) | ||
}} | ||
> | ||
TEST | ||
</button>` | ||
var newTree = html`<button>UPDATED</button>` | ||
var res = nanomorph(newTree, oldTree) | ||
t.ok(typeof res.onclick === 'function') | ||
res.onclick() | ||
}) | ||
t.test('events', function (t) { | ||
t.test('should copy onclick events', function (t) { | ||
t.plan(2) | ||
var oldTree = html` | ||
<button | ||
onclick=${function () { | ||
t.ok(true) | ||
}} | ||
> | ||
TEST | ||
</button>` | ||
var newTree = html`<button>UPDATED</button>` | ||
var res = morph(oldTree, newTree) | ||
t.ok(typeof res.onclick === 'function') | ||
res.onclick() | ||
}) | ||
t.test('should copy onsubmit events', function (t) { | ||
var oldTree = html` | ||
<form | ||
onsubmit=${function () { t.ok(false) }} | ||
> | ||
<button>Sup</button> | ||
t.test('should copy onsubmit events', function (t) { | ||
var oldTree = html` | ||
<form | ||
onsubmit=${function () { t.ok(false) }} | ||
> | ||
<button>Sup</button> | ||
</form>` | ||
var newTree = html`<form> | ||
<button>Sup</button> | ||
</form>` | ||
var newTree = html`<form> | ||
<button>Sup</button> | ||
</form>` | ||
var res = nanomorph(newTree, oldTree) | ||
t.ok(typeof res.onsubmit === 'function') | ||
t.end() | ||
var res = morph(oldTree, newTree) | ||
t.ok(typeof res.onsubmit === 'function') | ||
t.end() | ||
}) | ||
}) | ||
}) | ||
t.test('values', function (t) { | ||
t.test('should be copied to new tree when it has no value', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<input type="text" />` | ||
oldTree.value = 'howdy' | ||
var newTree = html`<input type="text" />` | ||
var res = nanomorph(newTree, oldTree) | ||
t.equal(res.value, 'howdy') | ||
}) | ||
t.test('values', function (t) { | ||
t.test('should be copied to new tree when it has no value', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<input type="text" />` | ||
oldTree.value = 'howdy' | ||
var newTree = html`<input type="text" />` | ||
var res = morph(oldTree, newTree) | ||
t.equal(res.value, 'howdy') | ||
}) | ||
t.test('should be copied to old tree when new tree has a value', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<input type="text" />` | ||
oldTree.value = 'howdy' | ||
var newTree = html`<input type="text" />` | ||
newTree.value = 'hi' | ||
var res = nanomorph(newTree, oldTree) | ||
t.equal(res.value, 'hi') | ||
t.test('should be copied to old tree when new tree has a value', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<input type="text" />` | ||
oldTree.value = 'howdy' | ||
var newTree = html`<input type="text" />` | ||
newTree.value = 'hi' | ||
var res = morph(oldTree, newTree) | ||
t.equal(res.value, 'hi') | ||
}) | ||
}) | ||
}) | ||
t.test('isSameNode', function (t) { | ||
t.test('should return oldTree if true', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<div>YOLO</div>` | ||
var newTree = html`<div>FOMO</div>` | ||
newTree.isSameNode = function (el) { | ||
return true | ||
} | ||
var res = nanomorph(newTree, oldTree) | ||
t.equal(res.childNodes[0].data, 'YOLO') | ||
}) | ||
t.test('isSameNode', function (t) { | ||
t.test('should return oldTree if true', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<div>YOLO</div>` | ||
var newTree = html`<div>FOMO</div>` | ||
newTree.isSameNode = function (el) { | ||
return true | ||
} | ||
var res = morph(oldTree, newTree) | ||
t.equal(res.childNodes[0].data, 'YOLO') | ||
}) | ||
t.test('should return newTree if false', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<div>YOLO</div>` | ||
var newTree = html`<div>FOMO</div>` | ||
newTree.isSameNode = function (el) { | ||
return false | ||
} | ||
var res = nanomorph(newTree, oldTree) | ||
t.equal(res.childNodes[0].data, 'FOMO') | ||
t.test('should return newTree if false', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<div>YOLO</div>` | ||
var newTree = html`<div>FOMO</div>` | ||
newTree.isSameNode = function (el) { | ||
return false | ||
} | ||
var res = morph(oldTree, newTree) | ||
t.equal(res.childNodes[0].data, 'FOMO') | ||
}) | ||
}) | ||
}) | ||
t.test('lists', function (t) { | ||
t.test('should append nodes', function (t) { | ||
t.plan(1) | ||
t.test('lists', function (t) { | ||
t.test('should append nodes', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<ul></ul>` | ||
var newTree = html`<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>` | ||
var oldTree = html`<ul></ul>` | ||
var newTree = html`<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>` | ||
var res = nanomorph(newTree, oldTree) | ||
var expected = '<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
var res = morph(oldTree, newTree) | ||
var expected = '<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
t.test('should remove nodes', function (t) { | ||
t.plan(1) | ||
t.test('should remove nodes', function (t) { | ||
t.plan(1) | ||
var oldTree = html`<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>` | ||
var newTree = html`<ul></ul>` | ||
var oldTree = html`<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>` | ||
var newTree = html`<ul></ul>` | ||
var res = nanomorph(newTree, oldTree) | ||
var expected = '<ul></ul>' | ||
t.equal(String(res), expected, 'result was expected') | ||
var res = morph(oldTree, newTree) | ||
var expected = '<ul></ul>' | ||
t.equal(String(res), expected, 'result was expected') | ||
}) | ||
}) | ||
@@ -236,3 +249,3 @@ | ||
t.plan(1) | ||
var tree = html`<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>` | ||
var oldTree = html`<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>` | ||
@@ -242,6 +255,23 @@ var newTree = html`<ul><div>1</div><li>2</li><p>3</p><li>4</li><li>5</li></ul>` | ||
tree = nanomorph(newTree, tree) | ||
t.equal(String(tree), expected, 'result was expected') | ||
oldTree = nanomorph(oldTree, newTree) | ||
t.equal(String(oldTree), expected, 'result was expected') | ||
}) | ||
t.test('should replace nodes after multiple iterations', function (t) { | ||
t.plan(2) | ||
var oldTree = html`<ul></ul>` | ||
var newTree = html`<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>` | ||
var expected = '<ul><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>' | ||
oldTree = nanomorph(oldTree, newTree) | ||
t.equal(String(oldTree), expected, 'result was expected') | ||
newTree = html`<ul><div>1</div><li>2</li><p>3</p><li>4</li><li>5</li></ul>` | ||
expected = '<ul><div>1</div><li>2</li><p>3</p><li>4</li><li>5</li></ul>' | ||
oldTree = nanomorph(oldTree, newTree) | ||
t.equal(String(oldTree), expected, 'result was expected') | ||
}) | ||
}) | ||
}) | ||
} |
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
20946
440
120