Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nanomorph

Package Overview
Dependencies
Maintainers
2
Versions
33
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nanomorph - npm Package Compare versions

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.

@@ -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')
})
})
})
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc