Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
language: node_js
node_js:
- '4'
- "6"
- "8"
- "9"
before_script:
- export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start
7 changes: 7 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Copyright 2018 Choo Contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
263 changes: 105 additions & 158 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,186 +1,133 @@
# [bel](https://en.wikipedia.org/wiki/Bel_(mythology))
# nanohtml
[![npm version][2]][3] [![build status][4]][5]
[![downloads][8]][9] [![js-standard-style][10]][11]

[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Downloads][downloads-image]][downloads-url]
[![js-standard-style][standard-image]][standard-url]
![experimental][experimental-image]
HTML template strings for the Browser with support for Server Side
Rendering in Node.

A simple library for composable DOM elements using [tagged template strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals).

If you're looking for a higher level front end framework, try
[yo-yo](https://github.com/maxogden/yo-yo). Or even higher than that, try
[choo](https://github.com/yoshuawuyts/choo).

## usage

For a more in depth tutorial on getting started, please [check out the wiki](https://github.com/shama/bel/wiki).

### A Simple Element

Create an element:

```js
// list.js
var bel = require('bel')

module.exports = function (items) {
return bel`<ul>
${items.map(function (item) {
return bel`<li>${item}</li>`
})}
</ul>`
}
## Installation
```sh
$ npm install nanohtml
```

Then pass data to it and add to the DOM:

## Usage
```js
// app.js
var createList = require('./list.js')
var list = createList([
'grizzly',
'polar',
'brown'
])
document.body.appendChild(list)
```
var html = require('nanohtml')

### Data Down, Actions Up
var el = html`
<body>
<h1>Hello planet</h1>
</body>
`

```js
// list.js
var bel = require('bel')

// The DOM is built by the data passed in
module.exports = function (items, onselected) {
function render () {
return bel`<ul>
${items.map(function (item) {
return bel`<li>${button(item.id, item.label)}</li>`
})}
</ul>`
}
function button (id, label) {
return bel`<button onclick=${function () {
// Then action gets sent up
onselected(id)
}}>${label}</button>`
}
var element = render()
return element
}
document.body.appendChild(el)
```

```js
// app.js
var bel = require('bel')
var morphdom = require('morphdom')
var list = require('./list.js')

module.exports = function (bears) {
function onselected (id) {
// When a bear is selected, rerender with the newly selected item
// This will use DOM diffing to render, sending the data back down again
morphdom(element, render(id))
}
function render (selected) {
return bel`<div className="app">
<h1>Selected: ${selected}</h1>
${list(bears, onselected)}
</div>`
}
// On first render, we haven't selected anything
var element = render('none')
return element
}
```

### use with/without [hyperx](https://www.npmjs.com/package/hyperx)

`hyperx` is built into `bel` but there may be times when you wish to use your
own version or implementation of `hyperx`. Or if you prefer to create elements
using `bel` without using tagged template literals:
## Node
Node doesn't have a DOM available. So in order to render HTML we use string
concatenation instead. This has the fun benefit of being quite efficient, which
in turn means it's great for server rendering!

```js
var createElement = require('bel').createElement
var hyperx = require('hyperx')
var bel = hyperx(createElement)

var element = bel`<div class="heading">Hello!</div>`
var html = require('nanohtml')

// ...
var el = html`
<body>
<h1>Hello planet</h1>
</body>
`

var sameElement = createElement('div', { className: 'heading' }, ['Hello!'])
console.log(el.toString())
```

### use yo-yoify to build

Transform bel template strings into pure and fast document calls with browserify.

e.g. `browserify entry.js -g yo-yoify -o bundle.js`

[See also](https://github.com/shama/yo-yoify#how-this-works)


## note

Please use [yo-yoify](https://github.com/shama/yo-yoify) which will transform any `Function.caller` into plain strings until an alternative solution to identify element creators is implemented.
## Interpolating unescaped HTML
By default all content inside template strings is escaped. This is great for
strings, but not ideal if you want to insert HTML that's been returned from
another function (for example: a markdown renderer). Use `nanohtml/raw` for
to interpolate HTML directly.

yo-yoify can resolve the error like below:

`TypeError: Function.caller used to retrieve strict caller`
```js
var raw = require('nanohtml/raw')
var html = require('nanohtml')

or
var string = '<h1>This a regular string.'
var el = html`
<body>
${raw(string)}
</body>
`

`TypeError: access to strict mode caller function is censored`
document.body.appendChild(el)
```

## Static optimizations
Parsing HTML has significant overhead. Being able to parse HTML statically,
ahead of time can speed up rendering to be about twice as fast.

## security
### Browserify

bel sets attributes with `element.setAttribute()` and `element.setAttributeNS()`, and creates text nodes with `document.createTextNode()`. These approaches mitigate some [Cross-Site Scripting (XSS)](https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29) attacks. You should still code carefully every time you put content from users in the DOM.
#### From the command line
```sh
$ browserify -t nanohtml index.js > bundle.js
```

## unescaping
#### Programmatically
```js
var browserify = require('browserify')
var nanohtml = require('nanohtml')
var path = require('path')

bel escapes `${values}` within template literals. Sometimes that is not desirable; for instance, when parsing a string with markdown, which returns HTML.
var b = browserify(path.join(__dirname, 'index.js'))
.transform(nanohtml)

To unescape values, use the `raw` method:
b.bundle().pipe(process.stdout)
```

```js
var bel = require('bel')
var raw = require('bel/raw')

function example () {
var output = '<strong>hello there</strong>'
return bel`
<div>${raw(output)}</div>
`
#### In package.json
```json
{
"name": "my-app",
"private": true,
"browserify": {
"transform": [
"nanohtml"
]
},
"dependencies": {
"nanohtml": "^1.0.0"
}
}

```

Make sure that you are sticking to the security suggestions above, and sanitize any input for malicious code before using `raw`.

## similar projects

* [vel](https://github.com/yoshuawuyts/vel)
minimal virtual-dom library
* [base-element](https://github.com/shama/base-element)
An element authoring library for creating standalone and performant elements
* [virtual-dom](https://github.com/Matt-Esch/virtual-dom)
A Virtual DOM and diffing algorithm
* [hyperscript](https://github.com/dominictarr/hyperscript)
Create HyperText with JavaScript.

# license
(c) 2016 Kyle Robinson Young. MIT License

[npm-image]: https://img.shields.io/npm/v/bel.svg?style=flat-square
[npm-url]: https://npmjs.org/package/bel
[travis-image]: https://img.shields.io/travis/shama/bel/master.svg?style=flat-square
[travis-url]: https://travis-ci.org/shama/bel
[downloads-image]: http://img.shields.io/npm/dm/bel.svg?style=flat-square
[downloads-url]: https://npmjs.org/package/bel
[standard-image]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square
[standard-url]: https://github.com/feross/standard
[experimental-image]: https://img.shields.io/badge/stability-experimental-orange.svg?style=flat-square
### Webpack
At the time of writing there's no Webpack loader yet. We'd love a contribution!

### Parcel
At the time of writing there's no Parcel plugin yet. We'd love a contribution!

## Attributions
Shout out to [Shama](https://github.com/shama) and
[Shuhei](https://github.com/shuhei) for their contributions to
[Bel](https://github.com/shama/html),
[yo-yoify](https://github.com/shama/yo-yoify) and
[pelo](https://github.com/shuhei/pelo). This module is based on their work, and
wouldn't have been possible otherwise!

## See Also
- [choojs/nanomorph](https://github.com/choojs/nanomorph)

## License
[MIT](./LICENSE)

[0]: https://img.shields.io/badge/stability-experimental-orange.svg?style=flat-square
[1]: https://nodejs.org/api/documentation.html#documentation_stability_index
[2]: https://img.shields.io/npm/v/nanohtml.svg?style=flat-square
[3]: https://npmjs.org/package/nanohtml
[4]: https://img.shields.io/travis/choojs/nanohtml/master.svg?style=flat-square
[5]: https://travis-ci.org/choojs/nanohtml
[6]: https://img.shields.io/codecov/c/github/choojs/nanohtml/master.svg?style=flat-square
[7]: https://codecov.io/github/choojs/nanohtml
[8]: http://img.shields.io/npm/dm/nanohtml.svg?style=flat-square
[9]: https://npmjs.org/package/nanohtml
[10]: https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square
[11]: https://github.com/feross/standard
11 changes: 0 additions & 11 deletions bench/bench.js

This file was deleted.

13 changes: 13 additions & 0 deletions bench/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
var nanobench = require('nanobench')

var nanoHtml = require('../')
var createApp = require('./fixtures/app')

nanobench('nanohtml browser 10000 iterations', function (b) {
var app = createApp(nanoHtml)
for (var i = 0; i < 100; i++) app.render().toString()

b.start()
for (i = 0; i < 10000; i++) app.render().toString()
b.end()
})
53 changes: 0 additions & 53 deletions bench/create-trees.js

This file was deleted.

Loading