hyperhtml
Advanced tools
Comparing version 0.1.0 to 0.2.0
@@ -41,10 +41,9 @@ var hyperHTML = (function () {'use strict'; | ||
function update(values) { | ||
var html = [values[0]]; | ||
function update(statics) { | ||
for (var | ||
any, | ||
html = [values[0]], | ||
updates = this[EXPANDO], | ||
html = [statics[0]], | ||
updates = this[EXPANDO].u, | ||
i = 1, | ||
length = values.length; | ||
length = statics.length; | ||
i < length; i++ | ||
@@ -54,3 +53,3 @@ ) { | ||
updates[i - 1](any); | ||
html.push(any, values[i]); | ||
html.push(any, statics[i]); | ||
} | ||
@@ -60,15 +59,17 @@ return html.join(''); | ||
function upgrade(values) { | ||
function upgrade(statics) { | ||
for (var | ||
self = this, | ||
html = [values[0]], | ||
updates = [], | ||
html = [statics[0]], | ||
i = 1, | ||
length = values.length; | ||
length = statics.length; | ||
i < length; i++ | ||
) { | ||
html.push(uid, values[i]); | ||
html.push(uid, statics[i]); | ||
} | ||
self.innerHTML = html.join(''); | ||
lukeTreeWalker(self, (self[EXPANDO] = [])); | ||
return update.apply(this, arguments); | ||
lukeTreeWalker(self, updates); | ||
self[EXPANDO] = {s: statics, u: updates}; | ||
return update.apply(self, arguments); | ||
} | ||
@@ -82,5 +83,22 @@ | ||
function setHTMLContent(node) { | ||
function setAnyContent(node) { | ||
return function (value) { | ||
node.innerHTML = value; | ||
switch (typeof value) { | ||
// all primitives are considered html | ||
case 'string': | ||
case 'number': | ||
case 'boolean': | ||
node.innerHTML = value; | ||
break; | ||
default: | ||
if (node.firstChild !== value) { | ||
if (node.childNodes.length === 1) { | ||
node.replaceChild(value, node.firstChild); | ||
} else { | ||
node.textContent = ''; | ||
node.appendChild(value); | ||
} | ||
} | ||
break; | ||
} | ||
}; | ||
@@ -109,3 +127,3 @@ } | ||
) { | ||
actions.push(setHTMLContent(parent)); | ||
actions.push(setAnyContent(parent)); | ||
break; | ||
@@ -137,7 +155,8 @@ } else { | ||
return function hyperHTML() { | ||
return EXPANDO in this ? | ||
update.apply(this, arguments) : | ||
upgrade.apply(this, arguments); | ||
} | ||
return function hyperHTML(statics) { | ||
return EXPANDO in this && | ||
this[EXPANDO].s === statics ? | ||
update.apply(this, arguments) : | ||
upgrade.apply(this, arguments); | ||
}; | ||
@@ -144,0 +163,0 @@ }()); |
{ | ||
"name": "hyperhtml", | ||
"version": "0.1.0", | ||
"description": "DOM Mapped Template Strings", | ||
"version": "0.2.0", | ||
"description": "DOM Mapped Template Strings. A Light Virtual DOM Alternative", | ||
"main": "hyperhtml.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"build": "npm run minify && npm test && npm run size", | ||
"test": "node test/runner.js", | ||
"minify": "uglifyjs hyperhtml.js --comments=/^!/ --compress --mangle -o min.js", | ||
"size": "cat hyperhtml.js | wc -c;cat min.js | wc -c;gzip -c min.js | wc -c" | ||
}, | ||
@@ -25,3 +28,8 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/WebReflection/hyperhtml#readme" | ||
"homepage": "https://github.com/WebReflection/hyperhtml#readme", | ||
"devDependencies": { | ||
"jsdom": "^9.11.0", | ||
"tressa": "^0.3.1", | ||
"uglify-js": "^2.8.5" | ||
} | ||
} |
@@ -1,2 +0,93 @@ | ||
# hyperhtml | ||
DOM Mapped Template Strings | ||
# hyperHTML [![Build Status](https://travis-ci.org/WebReflection/hyperHTML.svg?branch=master)](https://travis-ci.org/WebReflection/hyperHTML) | ||
A Light Virtual DOM Alternative | ||
- - - | ||
The easiest way to describe `hyperHTML` is through [an example](https://webreflection.github.io/hyperHTML/test/tick.html). | ||
```js | ||
// this is React's first tick example | ||
// https://facebook.github.io/react/docs/state-and-lifecycle.html | ||
function tick() { | ||
const element = ( | ||
<div> | ||
<h1>Hello, world!</h1> | ||
<h2>It is {new Date().toLocaleTimeString()}.</h2> | ||
</div> | ||
); | ||
ReactDOM.render( | ||
element, | ||
document.getElementById('root') | ||
); | ||
} | ||
setInterval(tick, 1000); | ||
// this is hyperHTML | ||
function tick(render) { | ||
render` | ||
<div> | ||
<h1>Hello, world!</h1> | ||
<h2>It is ${new Date().toLocaleTimeString()}.</h2> | ||
</div> | ||
`; | ||
} | ||
setInterval(tick, 1000, | ||
hyperHTML.bind(document.getElementById('root')) | ||
); | ||
``` | ||
### ... wait, WAT? | ||
[ES6 Template literals](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals) come with a special feature that is not commonly used: prefixed transformers. | ||
Using such feature to map a template string to a generic DOM node, makes it possible to automatically target and update only the differences between to template invokes and with **no `innerHTML` involved**. | ||
Following [an example](https://webreflection.github.io/hyperHTML/test/article.html): | ||
```js | ||
function update(render, state) { | ||
return render ` | ||
<article data-magic=${state.magic}> | ||
<h3>${state.title}</h3> | ||
List of ${state.paragraphs.length} paragraphs: | ||
<ul>${ | ||
state.paragraphs | ||
.map(p => `<li>${p.title}</li>`) | ||
.join('') | ||
}</ul> | ||
</article> | ||
`; | ||
} | ||
update( | ||
hyperHTML.bind(articleElement), | ||
{ | ||
title: 'True story', | ||
paragraphs: [ | ||
{title: 'touching'}, | ||
{title: 'incredible'}, | ||
{title: 'doge'} | ||
] | ||
} | ||
); | ||
``` | ||
Since most of the time templates are 70% static text and 30% or less dynamic, `hyperHTML` passes through the resulting string only once, finds all attributes and content that is dynamic, and maps it 1:1 to the node to make updates as cheap as possible for both node attributes and node content. | ||
## Usage | ||
You have function that is suitable for parsing templates literals but it needs a DOM node context to operate. | ||
If you want to render many times the same template for a specific node, bind it once and boost up performance for free. | ||
### F.A.Q. and Caveats | ||
* _how can I differentiate between textContent only and HTML or DOM nodes?_ | ||
If there's any space or char around the value, that'd be a textContent. Other cases accept DOM nodes as well as html. | ||
```render`<p>This is: ${'text'}</p>`;``` for text, and ```render`<p>${'html' || node}</p>`;``` for everything else. | ||
* _can I use different renders for a single node?_ Sure thing. However, the best performance gain is reached with nodes that always use the same template string. If you have a very unpredictable conditional template, you might want to create two different nodes and apply `hyperHTML` with the same template for both of them, swapping them when necessary. In every other case, the new template will create new content and map it once per change. | ||
## Compatibility | ||
If your string literals are transpiled, this project is compatible with every browser, old to new. | ||
If you don't transpile string literals, check the [test page](https://webreflection.github.io/hyperHTML/test/) and wait 'till it's green. | ||
- - - | ||
(C) 2017 Andrea Giammarchi - MIT Style License |
Sorry, the diff of this file is not supported yet
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
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
10582
6
147
1
94
3