diff --git a/bench/loop.js b/bench/loop.js index 0cf09eb..fd911d8 100644 --- a/bench/loop.js +++ b/bench/loop.js @@ -1,6 +1,8 @@ -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) function render (state) { return hx`
diff --git a/bench/raw.js b/bench/raw.js index 6d656d9..826ca2d 100644 --- a/bench/raw.js +++ b/bench/raw.js @@ -1,4 +1,6 @@ -var vdom = require('virtual-dom') +import vdom from 'virtual-dom' + + var h = vdom.h function render (state) { diff --git a/index.js b/index.js index 95fc8ee..7f8b120 100644 --- a/index.js +++ b/index.js @@ -1,25 +1,23 @@ -var attrToProp = require('hyperscript-attribute-to-property') +import attrToProp from 'hyperscript-attribute-to-property' -var VAR = 0, TEXT = 1, OPEN = 2, CLOSE = 3, ATTR = 4 -var ATTR_KEY = 5, ATTR_KEY_W = 6 -var ATTR_VALUE_W = 7, ATTR_VALUE = 8 -var ATTR_VALUE_SQ = 9, ATTR_VALUE_DQ = 10 -var ATTR_EQ = 11, ATTR_BREAK = 12 -var COMMENT = 13 +const VAR = 0, TEXT = 1, OPEN = 2, CLOSE = 3, ATTR = 4 +const ATTR_KEY = 5, ATTR_KEY_W = 6 +const ATTR_VALUE_W = 7, ATTR_VALUE = 8 +const ATTR_VALUE_SQ = 9, ATTR_VALUE_DQ = 10 +const ATTR_EQ = 11, ATTR_BREAK = 12 +const COMMENT = 13 -module.exports = function (h, opts) { - if (!opts) opts = { } - - var concat = opts.concat || function (a, b) { +export default function hyperx (h, opts={}) { + + const concat = opts.concat || function (a, b) { return String(a) + String(b) } if (opts.attrToProp !== false) h = attrToProp(h) - return function (strings) { var state = TEXT, reg = '', isSelfClosing = false @@ -347,21 +345,24 @@ module.exports = function (h, opts) { } } + function quot (state) { return state === ATTR_VALUE_SQ || state === ATTR_VALUE_DQ } + //area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr -var voidCloseRE = RegExp('^(' + [ +const voidCloseRE = RegExp('^(' + [ 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr' ].join('|') + ')(?:[\.#][a-zA-Z0-9\u007F-\uFFFF_:-]+)*$') + function selfClosingVoid (tag) { return voidCloseRE.test(tag) } /* -var closeRE = RegExp('^(' + [ +const closeRE = RegExp('^(' + [ 'area', 'base', 'basefont', 'bgsound', 'br', 'col', 'command', 'embed', 'frame', 'hr', 'img', 'input', 'isindex', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr', '!--', diff --git a/package.json b/package.json index 8f719af..c739859 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "3.0.0", "description": "tagged template string virtual dom builder", "main": "index.js", + "type": "module", "scripts": { "test": "tape test/*.js", "coverage": "covert test/*.js" @@ -34,10 +35,10 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/mreinstein/hyperx.git" + "url": "git+https://github.com/choojs/hyperx.git" }, "bugs": { - "url": "https://github.com/mreinstein/hyperx/issues" + "url": "https://github.com/choojs/hyperx/issues" }, - "homepage": "https://github.com/mreinstein/hyperx#readme" + "homepage": "https://github.com/choojs/hyperx#readme" } diff --git a/readme.markdown b/readme.markdown index ffd0898..a667125 100644 --- a/readme.markdown +++ b/readme.markdown @@ -18,6 +18,7 @@ parser down the wire. [2]: https://npmjs.com/package/hyperxify + # compatibility [Template strings][1] are available in: @@ -27,18 +28,20 @@ If you're targeting these platforms, there's no need to use a transpiler! [1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/template_strings + # examples ## virtual-dom node example ``` js -var vdom = require('virtual-dom') -var hyperx = require('hyperx') -var hx = hyperx(vdom.h) +import vdom from 'virtual-dom' +import hyperx from 'hyperx' + +const hx = hyperx(vdom.h) -var title = 'world' -var wow = [1,2,3] -var tree = hx`
+const title = 'world' +const wow = [ 1, 2, 3 ] +const tree = hx`

hello ${title}!

${hx`cool`} wow @@ -46,6 +49,7 @@ var tree = hx`
return hx`${w}\n` })}
` + console.log(vdom.create(tree).toString()) ``` @@ -64,10 +68,11 @@ $ node vdom.js ## react node example ``` js -var React = require('react') -var toString = require('react-dom/server').renderToString -var hyperx = require('hyperx') -var hx = hyperx(function createElement (component, properties, children) { +import React from 'react' +import { renderToString } from 'react-dom/server' +import hyperx from 'hyperx' + +const hx = hyperx(function createElement (component, properties, children) { // Pass children as separate arguments to avoid key warnings return React.createElement.apply(null, [component, properties].concat(children)) }, { @@ -76,13 +81,14 @@ var hx = hyperx(function createElement (component, properties, children) { } }) -var title = 'world' -var wow = [1,2,3] -var frag = hx` +const title = 'world' +const wow = [ 1, 2, 3 ] +const frag = hx` row1 row2 ` -var tree = hx`
+ +const tree = hx`

hello ${title}!

${hx`cool`} wow @@ -92,19 +98,21 @@ var tree = hx`
${frag}
` -console.log(toString(tree)) + +console.log(renderToString(tree)) ``` ## hyperscript node example ``` js -var h = require('hyperscript') -var hyperx = require('hyperx') -var hx = hyperx(h) +import h from 'hyperscript' +import hyperx from 'hyperx' + +const hx = hyperx(h) -var title = 'world' -var wow = [1,2,3] -var tree = hx`
+const title = 'world' +const wow = [1,2,3] +const tree = hx`

hello ${title}!

${hx`cool`} wow @@ -112,18 +120,20 @@ var tree = hx`
return hx`${w}\n` })}
` + console.log(tree.outerHTML) ``` ## virtual-dom/main-loop browser example ``` js -var vdom = require('virtual-dom') -var hyperx = require('hyperx') -var hx = hyperx(vdom.h) +import vdom from 'virtual-dom' +import hyperx from 'hyperx' +import main from 'main-loop' + +const hx = hyperx(vdom.h) -var main = require('main-loop') -var loop = main({ times: 0 }, render, vdom) +const loop = main({ times: 0 }, render, vdom) document.querySelector('#content').appendChild(loop.target) function render (state) { @@ -141,12 +151,13 @@ function render (state) { ## react browser example ``` js -var React = require('react') -var render = require('react-dom').render -var hyperx = require('hyperx') -var hx = hyperx(React.createElement) +import React from 'react' +import { render } from 'react-dom' +import hyperx from 'hyperx' -var App = React.createClass({ +const hx = hyperx(React.createElement) + +const App = React.createClass({ getInitialState: function () { return { n: 0 } }, render: function () { return hx`
@@ -158,15 +169,16 @@ var App = React.createClass({ this.setState({ n: this.state.n + 1 }) } }) + render(React.createElement(App), document.querySelector('#content')) ``` ## console.log example ``` js -var hyperx = require('hyperx') +import hyperx from 'hyperx' -var convertTaggedTemplateOutputToDomBuilder = hyperx(function (tagName, attrs, children) { +const convertTaggedTemplateOutputToDomBuilder = hyperx(function (tagName, attrs, children) { console.log(tagName, attrs, children) }) @@ -178,11 +190,11 @@ convertTaggedTemplateOutputToDomBuilder`

hello world

` # api -``` -var hyperx = require('hyperx') +```js +import hyperx from 'hyperx' ``` -## var hx = hyperx(h, opts={}) +## const hx = hyperx(h, opts={}) Return a tagged template function `hx` from a hyperscript-style factory function `h`. @@ -205,17 +217,13 @@ hyperx syntax. will be provided as an array to this function. the return value will then be returned by the template literal + # prior art * http://www.2ality.com/2014/07/jsx-template-strings.html?m=1 * http://facebook.github.io/jsx/#why-not-template-literals (respectfully disagree) + # license BSD - -# install - -``` -npm install hyperx -``` diff --git a/test/attr.js b/test/attr.js index d4c94c7..8c2fd72 100644 --- a/test/attr.js +++ b/test/attr.js @@ -1,112 +1,114 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) test('class', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), '
') t.end() }) test('boolean attribute', function (t) { - var tree = hx`` + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('boolean attribute followed by normal attribute', function (t) { - var tree = hx`` + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('boolean attribute preceded by normal attribute', function (t) { - var tree = hx`` + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('unquoted attribute', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), '
') t.end() }) test('unquoted attribute preceded by boolean attribute', function (t) { - var tree = hx`` + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('unquoted attribute succeeded by boolean attribute', function (t) { - var tree = hx`` + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('unquoted attribute preceded by normal attribute', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), '
') t.end() }) test('unquoted attribute succeeded by normal attribute', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), '
') t.end() }) test('consecutive unquoted attributes', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), '
') t.end() }) test('strange leading character attributes', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), '
') t.end() }) test('strange inbetween character attributes', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), `
`) t.end() }) test('null and undefined attributes', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), `
`) t.end() }) test('undefined (with quotes) attribute value is evaluated', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), `
`) t.end() }) test('null (with quotes) attribute value is evaluated', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), `
`) t.end() }) test('undefined (without quotes) attribute value is evaluated', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), `
`) t.end() }) test('null (without quotes) attribute value is evaluated', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), `
`) t.end() }) test('null is ignored and adjacent attribute is evaluated', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(vdom.create(tree).toString(), `
`) t.end() }) diff --git a/test/attr_to_prop.js b/test/attr_to_prop.js index 831fa85..ae9bb7f 100644 --- a/test/attr_to_prop.js +++ b/test/attr_to_prop.js @@ -1,29 +1,31 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) test('class to className', function (t) { - var tree = hx`
` + const tree = hx`
` t.deepEqual(tree.properties, { className: 'wow' }) t.end() }) test('for to htmlFor', function (t) { - var tree = hx`
` + const tree = hx`
` t.deepEqual(tree.properties, { htmlFor: 'wow' }) t.end() }) test('http-equiv to httpEquiv', function (t) { - var tree = hx`` + const tree = hx`` t.deepEqual(tree.properties, { content: '30', httpEquiv: 'refresh' }) t.end() }) test('no transform', t => { - var hx = hyperx(vdom.h, { attrToProp: false }) - var tree = hx`
` + const hx = hyperx(vdom.h, { attrToProp: false }) + const tree = hx`
` t.deepEqual(tree.properties, { class: 'wow' }) t.end() }) diff --git a/test/br.js b/test/br.js index b2f437e..5ca7ceb 100644 --- a/test/br.js +++ b/test/br.js @@ -1,10 +1,12 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) test('self closing tags without a space', function (t) { - var tree = hx`
a
b
` + const tree = hx`
a
b
` t.equal(vdom.create(tree).toString(), '
a
b
') t.end() }) diff --git a/test/children.js b/test/children.js index 654f368..850181e 100644 --- a/test/children.js +++ b/test/children.js @@ -1,22 +1,24 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) test('1 child', function (t) { - var tree = hx`
foobar
` + const tree = hx`
foobar
` t.equal(vdom.create(tree).toString(), '
foobar
') t.end() }) test('no children', function (t) { - var tree = hx`` + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('multiple children', function (t) { - var html = `
+ const html = `

title

    @@ -26,7 +28,7 @@ test('multiple children', function (t) {
` - var tree = hx` + const tree = hx`

title

diff --git a/test/comment.js b/test/comment.js index 1f8da46..f93f251 100644 --- a/test/comment.js +++ b/test/comment.js @@ -1,7 +1,9 @@ -var test = require('tape') -var hyperx = require('../') -var hx = hyperx(createElement) -var hxc = hyperx(createElement, {comments: true}) +import hyperx from '../index.js' +import test from 'tape' + + +const hx = hyperx(createElement) +const hxc = hyperx(createElement, {comments: true}) function createElement(tag, props, children) { if (tag === '!--') { @@ -11,30 +13,30 @@ function createElement(tag, props, children) { } test('1 comment', function (t) { - var tree = hxc`` + const tree = hxc`` t.equal(tree, '') t.end() }) test('with crazy characters', function (t) { - var tree = hxc`` + const tree = hxc`` t.equal(tree, '') t.end() }) test('as child', function (t) { - var tree = hxc`
` + const tree = hxc`
` t.equal(tree, '
') t.end() }) test('many comments', function (t) { - var html = `
+ const html = `
bar
` - var tree = hxc` + const tree = hxc`
bar @@ -45,18 +47,18 @@ test('many comments', function (t) { }) test('excluded by default', function (t) { - var tree = hx`
` + const tree = hx`
` t.equal(tree, '
') t.end() }) test('template parts in comment, discard comments', function (t) { - var child = 'something' - var objectChild = { + const child = 'something' + const objectChild = { type: 'div', children: ['something'] } - var tree = hx`
` + let tree = hx`
` t.equal(tree, '
') tree = hx`
` t.equal(tree, '
') @@ -64,12 +66,12 @@ test('template parts in comment, discard comments', function (t) { }) test('template parts in comment, keep comments', function (t) { - var child = 'something' - var objectChild = { + const child = 'something' + const objectChild = { type: 'div', children: ['something'] } - var tree = hxc`
` + let tree = hxc`
` t.equal(tree, '
') tree = hxc`
` t.equal(tree, '
', 'stringifies comment contents') diff --git a/test/concat.js b/test/concat.js index b8b25d3..c8a6a26 100644 --- a/test/concat.js +++ b/test/concat.js @@ -1,7 +1,9 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(function (tagName, opts, children) { +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(function (tagName, opts, children) { return { expr: 'h(' + JSON.stringify(tagName) + ',' + JSON.stringify(opts) @@ -17,7 +19,7 @@ var hx = hyperx(function (tagName, opts, children) { function concat (a, b) { if (!a.expr && !b.expr) return String(a) + String(b) - var aexpr, bexpr + let aexpr, bexpr if (a.expr) aexpr = '(' + a.expr + ')' else aexpr = JSON.stringify(a) if (b.expr) bexpr = '(' + b.expr + ')' @@ -25,7 +27,7 @@ function concat (a, b) { return { expr: aexpr + '+' + bexpr } } -var expected = `
+const expected = `

hello world!

cool wow @@ -33,9 +35,9 @@ var expected = `
` test('vdom', function (t) { - var title = 'world' - var wow = [1,2,3] - var str = hx`
+ const title = 'world' + const wow = [1,2,3] + const str = hx`

hello ${title}!

${hx`cool`} wow @@ -43,7 +45,7 @@ test('vdom', function (t) { return hx`${w}\n` })}
`.expr - var tree = Function(['h'],'return ' + str)(vdom.h) + const tree = Function(['h'],'return ' + str)(vdom.h) t.equal(vdom.create(tree).toString(), expected) t.end() }) diff --git a/test/esc.js b/test/esc.js index 65be7e2..74f488e 100644 --- a/test/esc.js +++ b/test/esc.js @@ -1,11 +1,13 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) test('escape double quotes', function (t) { - var value = '">' - var tree = hx`` + const value = '">' + const tree = hx`` t.equal( vdom.create(tree).toString(), `` @@ -14,8 +16,8 @@ test('escape double quotes', function (t) { }) test('escape single quotes', function (t) { - var value = "'>" - var tree = hx`` + const value = "'>" + const tree = hx`` t.equal( vdom.create(tree).toString(), `` diff --git a/test/fragments.js b/test/fragments.js index f6770cc..2c7f9a6 100644 --- a/test/fragments.js +++ b/test/fragments.js @@ -1,14 +1,16 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h, {createFragment: createFragment}) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h, {createFragment: createFragment}) function createFragment (nodes) { return nodes } test('mutliple root, fragments as array', function (t) { - var list = hx`
  • 1
  • 2
    _
  • ` + const list = hx`
  • 1
  • 2
    _
  • ` t.equal(list.length, 3, '3 elements') t.equal(vdom.create(list[0]).toString(), '
  • 1
  • ') t.equal(list[1], ' ') diff --git a/test/ignore_surounding_whitespace.js b/test/ignore_surounding_whitespace.js index b54cc06..b4d3c90 100644 --- a/test/ignore_surounding_whitespace.js +++ b/test/ignore_surounding_whitespace.js @@ -1,10 +1,12 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) test('ignore whitespace surrounding an element', function (t) { - var tree = hx`
    `; + let tree = hx`
    `; t.equal(vdom.create(tree).toString(), '
    ') tree = hx`
    `; diff --git a/test/key.js b/test/key.js index b60cb60..0802282 100644 --- a/test/key.js +++ b/test/key.js @@ -1,72 +1,74 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) test('key', function (t) { - var key = 'type' - var value = 'text' - var tree = hx`` + const key = 'type' + const value = 'text' + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('pre key', function (t) { - var key = 'ype' - var value = 'text' - var tree = hx`` + const key = 'ype' + const value = 'text' + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('post key', function (t) { - var key = 'typ' - var value = 'text' - var tree = hx`` + const key = 'typ' + const value = 'text' + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('pre post key', function (t) { - var key = 'yp' - var value = 'text' - var tree = hx`` + const key = 'yp' + const value = 'text' + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('boolean key', function (t) { - var key = 'checked' - var tree = hx`` + const key = 'checked' + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('multiple keys', function (t) { - var props = { + const props = { type: 'text', 'data-special': 'true' } - var key = 'data-' - var value = 'bar' - var tree = hx`` + const key = 'data-' + const value = 'bar' + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) test('multiple keys dont overwrite existing ones', function (t) { - var props = { + const props = { type: 'text' } - var tree = hx`` + const tree = hx`` t.equal(vdom.create(tree).toString(), '') t.end() }) // https://github.com/choojs/hyperx/issues/55 test('unquoted key does not make void element eat adjacent elements', function (t) { - var tree = hx`sometext` + const tree = hx`sometext` t.equal(vdom.create(tree).toString(), 'sometext') t.end() }) diff --git a/test/multi_elem_error.js b/test/multi_elem_error.js index a8834cc..568d227 100644 --- a/test/multi_elem_error.js +++ b/test/multi_elem_error.js @@ -1,12 +1,14 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) test('multiple element error', function (t) { t.plan(1) t.throws(function () { - var tree = hx`
    one
    two
    ` + const tree = hx`
    one
    two
    ` }, 'exception') t.end() }) diff --git a/test/style.js b/test/style.js index 14cd390..62d7e0e 100644 --- a/test/style.js +++ b/test/style.js @@ -1,12 +1,14 @@ -var test = require('tape') -var vdom = require('virtual-dom') -var hyperx = require('../') -var hx = hyperx(vdom.h) +import hyperx from '../index.js' +import test from 'tape' +import vdom from 'virtual-dom' + + +const hx = hyperx(vdom.h) test('style', function (t) { - var key = 'type' - var value = 'text' - var tree = hx`` t.equal( @@ -18,9 +20,9 @@ test('style', function (t) { test('embedded style', function (t) { - var key = 'type' - var value = 'text' - var tree = hx`