├── .gitignore
├── .travis.yml
├── LICENSE.md
├── README.md
├── dist
├── index.es6.js
└── index.js
├── package.json
├── perf
├── .gitignore
├── build-branches.js
├── modules-attribute-props.js
├── modules-object-props.js
├── no-props.js
├── real-world-form.js
├── run.js
└── simple-props.js
├── snabbdom-pragma.d.ts
├── src
├── fn.js
├── index.js
└── is.js
├── test
├── build-specs
│ └── dist-file
│ │ ├── actual.js
│ │ └── expected.js
├── build-test.js
├── jsx-custom-modules-specs
│ ├── component-without-props
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ ├── component
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ ├── element-with-attributes
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ ├── element-with-class-names
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ ├── element-with-event
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ └── simple-element
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
├── jsx-custom-modules-test.js
├── jsx-specs
│ ├── component-without-props
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ ├── component
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ ├── element-with-attributes
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ ├── element-with-class-names
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ ├── element-with-event
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
│ └── simple-element
│ │ ├── actual.js
│ │ ├── transform-babel.js
│ │ ├── transform-buble.js
│ │ ├── transform-traceur.js
│ │ └── transform-typescript.js
├── jsx-test.js
├── pragma-specs
│ ├── vnode-text-and-var
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-text
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-type
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-with-array-children
│ │ ├── actual.js
│ │ └── expected.js
│ └── vnode-with-children
│ │ ├── actual.js
│ │ └── expected.js
├── pragma-test.js
├── snabbdom-specs
│ ├── vnode-class-names
│ │ ├── actual.js
│ │ ├── expected.js
│ │ └── neutral.js
│ ├── vnode-component-with-slot
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-component-without-props
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-component
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-data-aria-object
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-data-aria
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-events
│ │ ├── actual.js
│ │ ├── expected.js
│ │ └── neutral.js
│ ├── vnode-forced-attrs
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-hard-component
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-hooks
│ │ ├── actual.js
│ │ ├── expected.js
│ │ └── neutral.js
│ ├── vnode-mixed-module-ways
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-properties
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-reserved-module
│ │ ├── actual.js
│ │ └── expected.js
│ ├── vnode-style
│ │ ├── actual.js
│ │ └── expected.js
│ └── vnode-svg
│ │ ├── actual.js
│ │ └── expected.js
├── snabbdom-test.js
└── utils-test.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
3 | // Local sandbox purpose
4 | demo.js
5 | demo.ts
6 | demo.tsx
7 | tsconfig.json
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '6'
4 |
5 | cache:
6 | yarn: true
7 |
8 | matrix:
9 | fast_finish: true
10 |
11 | script:
12 | - yarn run lint
13 | - yarn run test:prebuild
14 | - export HASH=$(cksum dist/index.js)
15 | - yarn run build
16 | - bash -c 'if [[ "$(cksum dist/index.js)" != $HASH ]]; then exit 1; fi'
17 | - yarn run test:postbuild
18 |
19 | deploy:
20 | provider: npm
21 | email:
22 | secure: pOrobfDewXKlKVzdXJeuhfvuj5QRjnLBUHQHqoZNxu4dpm66PpSG7NiGX0gtMkJh/uCbN132bjx0gpCBd02fNYoc7w4ZuwHerlGVRUniWUWeWBxdTABy6loov5IkdTdsieFw1VYwczPDW4Q6pVC6qjoN/s9+A7ZVt6GwfFajMTXHNcJ5CgYX2FcyuJUNXJ+LCRqG0y0SVX4qnxgtNajVrlUPdUngRTDE3vqoVM2y5AAB2MHTJ1WtxRCRMcXbQy2wVDPs90cLbm79aH95bTnuvLM3DbPeXonh/RWXBkmByNSuxwVQdLy0SXJH2ft+nzQ1HwIoVwRsqZxc/sz98GnTQRM1d3jNxbSzDn7wdTpkhnrNu2iJ3V0h0WrYhyDQk5S81DymESVeJ95Pyg5iU+BzAke+LzKjOVAeEcUo3kbFmDhrmRshETbBxNC5fOFQcx93A37y3wZZgkB8GRvT5yDQis0gEe3zWH2VZyzWHnbQmvlW+sQVFoLsr6mdlRbTjRsaaqS00+2qNiywFgOzrXeLRByC1aLAYQMlvdihGQoEdTN1nzi+woYGrBrqod+NsB9JS8QP2KGgjpQWWp3naa+APv9NP/Y9eRKHT0m3xI6diNggsSsP09N1rX27ivMvbJR6mIFflNu2XK6FesHBwqufyYVcsA1UJTuO7LXHHjh6AAY=
23 | api_key:
24 | secure: uyCJ4nUDE35SDEK5GkJ41i8LFQ+8mX4xv6bVq7YZ0k7OA10a/xUrvZ+pFsftC3WHArE6I/s9e1hsKk5x16yV6K0+wXlgqVOkX/H+trkByBAAgXxrWPtwOUJYhxFC4vY4YJjRNNX7u6uCvtdilsQ+tto3qxly6TdYx825J+8ORyG3rSxSgDSwEgzcPjEGRhqAPA4kPs3ZOvBAHtexgeJfpmvacbrI6ROyLUb0NKOpOcJ4sZVM71aDWGTXB44GbLgXAGJZke1/kSeEaxGuNqGB/HPwsFRsCUwxkGkvr2bTRWlWKZP578lhyXBcfobAnAveQAvOAgJPrZQFAcJuGW+Y5TkcT2srHJHazjBcBKYRt6/WqTTE1yWIDQohaiIq1IdmglVKzca56GcsJjpqVpNYvrNzADJxPmp3mFjB5KDJUhGWnNny7XGWCkPaBDhdcdR88jI2aaufyxr385E49zSCSk5T2MSJ8XURGnzjGdOtMwxh+9waaqBzjObSNOfKZIIpfvS9mCV05VUXNmpyRk/pZmd1u0LLXV0hwuGM57DmSEjrPHzjxgB32jZj1FU1gKzxm+miRFZjxNe8MDpnlIvzaZIcIgZn4A5JcHLU23i/OsjadmWtS2c7+V9onv27XXXyzbTrZxVErFyd8/qjcs1jZQMlIFmS9FwyL5b2A+H+ImI=
25 | on:
26 | repo: Swizz/snabbdom-pragma
27 | branch: master
28 | tags: true
29 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Quentin Gerodel
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
Snabbdom-pragma
2 |
3 |
4 | Well tested NotReact.createElement
pragma although for Snabbdom !
5 |
6 |
7 |
8 |
9 |
20 |
21 |
22 |
23 | Snabbdom-pragma is the favorite way to use the [Facebook JSX](https://facebook.github.io/jsx/) syntax with the virtual DOM library [Snabbdom](https://github.com/snabbdom/snabbdom). Based on many principles, Snabbdom-pragma, aim to handle the same API as [React.createElement](https://facebook.github.io/react/docs/react-api.html#createelement) to take all benefits from the most used transpilers proven by the wider React community.
24 |
25 | Snabbdom-pragma draws its strength thanks to the [Snabbdom](https://github.com/snabbdom/snabbdom), [Facebook JSX](https://facebook.github.io/jsx/), and [React.createElement](https://facebook.github.io/react/docs/react-api.html#createelement) specs with some grounded tests.
26 |
27 | ## Table of Contents
28 |
29 |
30 | Table of Contents
31 |
32 | - [Overview](#snabbdom-pragma)
33 | - [Getting started](#getting-started)
34 | - [Usage](#usage)
35 | * [Bublé](#bublé)
36 | * [Typescript](#typescript)
37 | * [Babel](#babel)
38 | * [Traceur](#traceur)
39 | - [JSX Features](#jsx-features)
40 | * [Elements](#elements)
41 | * [Attributes](#attributes)
42 | * [SVG](#svg)
43 | - [Snabbdom Features](#snabbdom-features)
44 | * [Modules object](#modules-object)
45 | * [Modules attribute](#modules-object)
46 | * [Both](#both)
47 | * [Custom Modules](#custom-modules)
48 | - ['NotReact' Features](#notreact-features)
49 | * [Components](#components)
50 | - [Misc](#misc)
51 |
52 |
53 | ## Getting started
54 |
55 | - **1.** To use Snabbdom-pragma you need to download it thanks to your favorite JavaScript Package Manager.
56 | ```sh
57 | yarn add snabbdom-pragma
58 | ```
59 |
60 | ```sh
61 | npm install --save snabbdom-pragma
62 | ```
63 |
64 | - **2.** The pragma option tells to your transpiler to use `Snabbdom.createElement` function instead of the default `React.createElement`.
65 | ```js
66 | buble.transform(input, {
67 | jsx: 'Snabbdom.createElement'
68 | })
69 | ```
70 |
71 | - **3.** You will need to import the `Snabbdom.createElement` function into your code.
72 | ```js
73 | import Snabbdom from 'snabbdom-pragma'
74 | ```
75 |
76 | - **4.** Your JSX source code will now be transpiled to use Snabbdom.
77 | ```jsx
78 | const vnode = Hello World
79 |
80 | patch(document.body, vnode)
81 | ```
82 |
83 | ## Usage
84 | Snabbdom-pragma is compiler/transpiler independent ! At least your transpiler allow custom JSX pragma.
85 | (If you know a well used transpiler not in this list, feel free to open an issue)
86 |
87 | ### Bublé
88 | Snabbdom-pragma works fine and is fully tested for [Bublé](https://buble.surge.sh/guide/).
89 | ```js
90 | buble.transform(input, {
91 | jsx: 'Snabbdom.createElement'
92 | })
93 | ```
94 |
95 | ### Typescript
96 | Snabbdom-pragma works fine and is fully tested and typed for [Typescript](https://www.typescriptlang.org).
97 | ```js
98 | typescript.transpileModule(input, {
99 | compilerOptions: {
100 | jsx: 'react',
101 | jsxFactory: 'Snabbdom.createElement'
102 | }
103 | })
104 | ```
105 |
106 | ### Babel
107 | Snabbdom-pragma works fine and is fully tested for [Babel](https://babeljs.io) with the
108 | [transform-react-jsx](https://babeljs.io/docs/plugins/transform-react-jsx/) plugin enabled.
109 | ```js
110 | babel.transform(input, {
111 | plugins: ['transform-react-jsx', {
112 | pragma: 'Snabbdom.createElement'
113 | }]
114 | })
115 | ```
116 |
117 | ### Traceur
118 | Snabbdom-pragma works fine and is fully tested for [Traceur](https://github.com/google/traceur-compiler).
119 | ```js
120 | traceur.compile(input, {
121 | jsx: 'Snabbdom.createElement'
122 | })
123 | ```
124 |
125 | ## JSX Features
126 | Thanks to your transpiler, JSX tags will be transpiled into `NotReact.createElement` function following the `React.creatElement` specifications.
127 |
128 | ### Elements
129 | As `Snabbdom.createElement` is like a straightforward mapping to `Snabbdom/h`, HTML elements will work out of the box.
130 | ```jsx
131 | /* written */
132 | const vnode = Hello World
133 |
134 | /* Once Transpiled */
135 | const vnode = Snabbdom.createElement('div', null, 'Hello World')
136 |
137 | /* Similar to */
138 | const vnode = h('div', {}, 'Hello World')
139 | ```
140 |
141 | ### Attributes
142 | By default, attributes will be entrust to the `props` module. (see [Modules Features](#modules-object))
143 | ```jsx
144 | /* written */
145 | const vnode =
146 |
147 | /* Once Transpiled */
148 | const vnode = Snabbdom.createElement('input', { type: 'text' })
149 |
150 | /* Similar to */
151 | const vnode = h('input', { props: { type: 'text' } }, [])
152 | ```
153 |
154 | ### SVG
155 | SVG tags work without any configuration, but attributes will only work with the `attrs` module.
156 | ```jsx
157 | /* written */
158 | const vnode =
159 |
160 | /* Once Transpiled */
161 | const vnode = Snabbdom.createElement('circle', { cx: 43.5, cy: 23, r: 5 })
162 |
163 | /* Similar to */
164 | const vnode = h('circle', { attrs: { cx: 43.5, cy: 23, r: 5 } }, [])
165 | ```
166 |
167 | ## Snabbdom Features
168 | In Snabbdom, functionalities is delegated to separate modules. Like `hook` (lifecycle), `on` (events), `style`, `props`, etc...
169 | Snabbdom-pragma give you two ways to use these modules.
170 |
171 | ### Modules object
172 | You can deal with modules properties with an object.
173 | ```jsx
174 | /* written */
175 | const vnode =
176 |
177 | /* Once Transpiled */
178 | const vnode = Snabbdom.createElement('div', { style: { color: 'red', fontWeight: 'bold' } })
179 |
180 | /* Similar to */
181 | const vnode = h('div', { style: { color: 'red', fontWeight: 'bold' } }, [])
182 | ```
183 |
184 | ### Modules attribute
185 | Or by using the `MODULE-PROPERTY` attribute.
186 | ```jsx
187 | /* written */
188 | const vnode =
189 |
190 | /* Once Transpiled */
191 | const vnode = Snabbdom.createElement('button', { 'on-click': callback })
192 |
193 | /* Similar to */
194 | const vnode = h('button', { on: { click: callback } }, [])
195 | ```
196 |
197 | ### Both
198 | ```jsx
199 | /* written */
200 | const vnode =
201 |
202 | /* Once Transpiled */
203 | const vnode = Snabbdom.createElement('div', { 'style-color': 'red', style: { background: 'blue' } })
204 |
205 | /* Similar to */
206 | const vnode = h('div', { style: { color: 'red', background: 'blue' } }, [])
207 | ```
208 |
209 | ### Custom Modules
210 | Custom modules are supported through the `createElementWithModules` method.
211 | You will need to register this method as pragma instead of the `createElement`.
212 | ```js
213 | pragma: 'Snabbdom.createElementWithModules("ALIAS_1": "MODULE_1", "ALIAS_2": "MODULE_2", ...)'
214 | ```
215 | Then use
216 | ```jsx
217 | /* written */
218 | const vnode =
219 |
220 | /* Once Transpiled */
221 | const vnode = Snabbdom.createElementWithModules({ 'style': '' })('div', { style: { 'color': 'red' } })
222 |
223 | /* Similar to */
224 | const vnode = h('div', { style: { color: 'red' } }, [])
225 | ```
226 |
227 |
228 |
229 | ## 'NotReact' Features
230 | In React you can create components and use them inside other components, using the `React.createClass` function.
231 |
232 | ### Components
233 | Snabbdom-pragma use simple functions as component of type `(attributes, children) => vnode`.
234 | ```jsx
235 | /* written */
236 | const Component = ({ name }, children) =>
237 |
238 | Hello { name }
239 |
240 |
241 | { children }
242 |
243 |
244 |
245 | const vnode =
246 | It works !
247 |
248 |
249 | /* Once Transpiled */
250 | const Component = ({ name }, children) =>
251 | Snabbdom.createElement('div', null, 'Hello ', name,
252 | Snabbdom.createElement('div', null, children)
253 | )
254 |
255 | const vnode = Snabbdom.createElement(Component, { name: 'world' },
256 | Snabbdom.createElement('p', null, 'It works !')
257 | )
258 |
259 | /* Similar to */
260 | const Component = ({ name }, children) =>
261 | h('div', {}, ['Hello ', name,
262 | h('div', {}, children)
263 | ])
264 |
265 | const vnode = Component({ name: 'world' }, [
266 | h('p', {}, 'It works !')
267 | ])
268 | ```
269 | As in React, components function need to start with a capital letter, while regular HTML tags start with lower case letters. This is the common way to tell to your transpiler to give the function to the `Snabbdom.createElement` instead of a string.
270 |
271 | ## Misc
272 |
273 | - Snabbdom-pragma follows the [Compatible Versioning: major.minor only](https://github.com/staltz/comver) convention.
274 | - [Release notes](https://github.com/Swizz/snabbdom-pragma/releases) are [Keep a Changelog](http://keepachangelog.com/en/0.3.0/) compliants.
275 | - SVG capable thanks to @jvanbruegge PR#4
276 | - Documentation styling have been stolen to the [FlyJS](https://github.com/flyjs/fly) project
277 | - Some part are shameless copy of the [Snabbdom-jsx](https://github.com/yelouafi/snabbdom-jsx) documentation
278 |
--------------------------------------------------------------------------------
/dist/index.es6.js:
--------------------------------------------------------------------------------
1 | import _extend from 'extend';
2 |
3 | var undefinedv = function (v) { return v === undefined; };
4 |
5 | var number = function (v) { return typeof v === 'number'; };
6 |
7 | var string = function (v) { return typeof v === 'string'; };
8 |
9 | var text = function (v) { return string(v) || number(v); };
10 |
11 | var array = function (v) { return Array.isArray(v); };
12 |
13 | var object = function (v) { return typeof v === 'object' && v !== null; };
14 |
15 | var fun = function (v) { return typeof v === 'function'; };
16 |
17 | var vnode = function (v) { return object(v) && 'sel' in v && 'data' in v && 'children' in v && 'text' in v; };
18 |
19 | var svgPropsMap = { svg: 1, circle: 1, ellipse: 1, line: 1, polygon: 1,
20 | polyline: 1, rect: 1, g: 1, path: 1, text: 1 };
21 |
22 | var svg = function (v) { return v.sel in svgPropsMap; };
23 |
24 | // TODO: stop using extend here
25 | var extend = function () {
26 | var objs = [], len = arguments.length;
27 | while ( len-- ) objs[ len ] = arguments[ len ];
28 |
29 | return _extend.apply(void 0, [ true ].concat( objs ));
30 | };
31 |
32 | var assign = function () {
33 | var objs = [], len = arguments.length;
34 | while ( len-- ) objs[ len ] = arguments[ len ];
35 |
36 | return _extend.apply(void 0, [ false ].concat( objs ));
37 | };
38 |
39 | var reduceDeep = function (arr, fn, initial) {
40 | var result = initial;
41 | for (var i = 0; i < arr.length; i++) {
42 | var value = arr[i];
43 | if (array(value)) {
44 | result = reduceDeep(value, fn, result);
45 | } else {
46 | result = fn(result, value);
47 | }
48 | }
49 | return result
50 | };
51 |
52 | var mapObject = function (obj, fn) { return Object.keys(obj).map(
53 | function (key) { return fn(key, obj[key]); }
54 | ).reduce(
55 | function (acc, curr) { return extend(acc, curr); },
56 | {}
57 | ); };
58 |
59 | var deepifyKeys = function (obj, modules) { return mapObject(obj,
60 | function (key, val) {
61 | var dashIndex = key.indexOf('-');
62 | if (dashIndex > -1 && modules[key.slice(0, dashIndex)] !== undefined) {
63 | var moduleData = {};
64 | moduleData[key.slice(dashIndex + 1)] = val;
65 | return ( obj = {}, obj[key.slice(0, dashIndex)] = moduleData, obj )
66 | var obj;
67 | }
68 | return ( obj$1 = {}, obj$1[key] = val, obj$1 )
69 | var obj$1;
70 | }
71 | ); };
72 |
73 |
74 |
75 | var omit = function (key, obj) { return mapObject(obj,
76 | function (mod, data) { return mod !== key ? (( obj = {}, obj[mod] = data, obj )) : {}
77 | var obj; }
78 | ); };
79 |
80 | // Const fnName = (...params) => guard ? default : ...
81 |
82 | var createTextElement = function (text$$1) { return !text(text$$1) ? undefined : {
83 | text: text$$1,
84 | sel: undefined,
85 | data: undefined,
86 | children: undefined,
87 | elm: undefined,
88 | key: undefined
89 | }; };
90 |
91 | var considerSvg = function (vnode$$1) { return !svg(vnode$$1) ? vnode$$1 :
92 | assign(vnode$$1,
93 | { data: omit('props', extend(vnode$$1.data,
94 | { ns: 'http://www.w3.org/2000/svg', attrs: omit('className', extend(vnode$$1.data.props,
95 | { class: vnode$$1.data.props ? vnode$$1.data.props.className : undefined }
96 | )) }
97 | )) },
98 | { children: undefinedv(vnode$$1.children) ? undefined :
99 | vnode$$1.children.map(function (child) { return considerSvg(child); })
100 | }
101 | ); };
102 |
103 | var rewrites = {
104 | for: 'attrs',
105 | role: 'attrs',
106 | tabindex: 'attrs',
107 | 'aria-*': 'attrs',
108 | key: null
109 | };
110 |
111 | var rewriteModules = function (data, modules) { return mapObject(data, function (key, val) {
112 | var inner = {};
113 | inner[key] = val;
114 | if (rewrites[key] && modules[rewrites[key]] !== undefined) {
115 | return ( obj = {}, obj[rewrites[key]] = inner, obj )
116 | var obj;
117 | }
118 | if (rewrites[key] === null) {
119 | return {}
120 | }
121 | var keys = Object.keys(rewrites);
122 | for (var i = 0; i < keys.length; i++) {
123 | var k = keys[i];
124 | if (k.charAt(k.length - 1) === '*' && key.indexOf(k.slice(0, -1)) === 0 && modules[rewrites[k]] !== undefined) {
125 | return ( obj$1 = {}, obj$1[rewrites[k]] = inner, obj$1 )
126 | var obj$1;
127 | }
128 | }
129 | if (modules[key] !== undefined) {
130 | return ( obj$2 = {}, obj$2[modules[key] ? modules[key] : key] = val, obj$2 )
131 | var obj$2;
132 | }
133 | if (modules.props !== undefined) {
134 | return { props: inner }
135 | }
136 | return inner
137 | }); };
138 |
139 | var sanitizeData = function (data, modules) { return considerSvg(rewriteModules(deepifyKeys(data, modules), modules)); };
140 |
141 | var sanitizeText = function (children) { return children.length > 1 || !text(children[0]) ? undefined : children[0]; };
142 |
143 | var sanitizeChildren = function (children) { return reduceDeep(children, function (acc, child) {
144 | var vnode$$1 = vnode(child) ? child : createTextElement(child);
145 | acc.push(vnode$$1);
146 | return acc
147 | }
148 | , []); };
149 |
150 | var defaultModules = {
151 | attrs: '',
152 | props: '',
153 | class: '',
154 | data: 'dataset',
155 | style: '',
156 | hook: '',
157 | on: ''
158 | };
159 |
160 | var createElementWithModules = function (modules) {
161 | return function (sel, data) {
162 | var children = [], len = arguments.length - 2;
163 | while ( len-- > 0 ) children[ len ] = arguments[ len + 2 ];
164 |
165 | if (fun(sel)) {
166 | return sel(data || {}, children)
167 | }
168 | var text$$1 = sanitizeText(children, modules);
169 | return considerSvg({
170 | sel: sel,
171 | data: data ? sanitizeData(data, modules) : {},
172 | children: text$$1 ? undefined : sanitizeChildren(children),
173 | text: text$$1,
174 | elm: undefined,
175 | key: data ? data.key : undefined
176 | })
177 | }
178 | };
179 |
180 | var createElement = createElementWithModules(defaultModules);
181 |
182 | var index = {
183 | createElement: createElement,
184 | createElementWithModules: createElementWithModules
185 | };
186 |
187 | export { createElementWithModules, createElement };export default index;
188 |
--------------------------------------------------------------------------------
/dist/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, '__esModule', { value: true });
4 |
5 | function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6 |
7 | var _extend = _interopDefault(require('extend'));
8 |
9 | var undefinedv = function (v) { return v === undefined; };
10 |
11 | var number = function (v) { return typeof v === 'number'; };
12 |
13 | var string = function (v) { return typeof v === 'string'; };
14 |
15 | var text = function (v) { return string(v) || number(v); };
16 |
17 | var array = function (v) { return Array.isArray(v); };
18 |
19 | var object = function (v) { return typeof v === 'object' && v !== null; };
20 |
21 | var fun = function (v) { return typeof v === 'function'; };
22 |
23 | var vnode = function (v) { return object(v) && 'sel' in v && 'data' in v && 'children' in v && 'text' in v; };
24 |
25 | var svgPropsMap = { svg: 1, circle: 1, ellipse: 1, line: 1, polygon: 1,
26 | polyline: 1, rect: 1, g: 1, path: 1, text: 1 };
27 |
28 | var svg = function (v) { return v.sel in svgPropsMap; };
29 |
30 | // TODO: stop using extend here
31 | var extend = function () {
32 | var objs = [], len = arguments.length;
33 | while ( len-- ) objs[ len ] = arguments[ len ];
34 |
35 | return _extend.apply(void 0, [ true ].concat( objs ));
36 | };
37 |
38 | var assign = function () {
39 | var objs = [], len = arguments.length;
40 | while ( len-- ) objs[ len ] = arguments[ len ];
41 |
42 | return _extend.apply(void 0, [ false ].concat( objs ));
43 | };
44 |
45 | var reduceDeep = function (arr, fn, initial) {
46 | var result = initial;
47 | for (var i = 0; i < arr.length; i++) {
48 | var value = arr[i];
49 | if (array(value)) {
50 | result = reduceDeep(value, fn, result);
51 | } else {
52 | result = fn(result, value);
53 | }
54 | }
55 | return result
56 | };
57 |
58 | var mapObject = function (obj, fn) { return Object.keys(obj).map(
59 | function (key) { return fn(key, obj[key]); }
60 | ).reduce(
61 | function (acc, curr) { return extend(acc, curr); },
62 | {}
63 | ); };
64 |
65 | var deepifyKeys = function (obj, modules) { return mapObject(obj,
66 | function (key, val) {
67 | var dashIndex = key.indexOf('-');
68 | if (dashIndex > -1 && modules[key.slice(0, dashIndex)] !== undefined) {
69 | var moduleData = {};
70 | moduleData[key.slice(dashIndex + 1)] = val;
71 | return ( obj = {}, obj[key.slice(0, dashIndex)] = moduleData, obj )
72 | var obj;
73 | }
74 | return ( obj$1 = {}, obj$1[key] = val, obj$1 )
75 | var obj$1;
76 | }
77 | ); };
78 |
79 |
80 |
81 | var omit = function (key, obj) { return mapObject(obj,
82 | function (mod, data) { return mod !== key ? (( obj = {}, obj[mod] = data, obj )) : {}
83 | var obj; }
84 | ); };
85 |
86 | // Const fnName = (...params) => guard ? default : ...
87 |
88 | var createTextElement = function (text$$1) { return !text(text$$1) ? undefined : {
89 | text: text$$1,
90 | sel: undefined,
91 | data: undefined,
92 | children: undefined,
93 | elm: undefined,
94 | key: undefined
95 | }; };
96 |
97 | var considerSvg = function (vnode$$1) { return !svg(vnode$$1) ? vnode$$1 :
98 | assign(vnode$$1,
99 | { data: omit('props', extend(vnode$$1.data,
100 | { ns: 'http://www.w3.org/2000/svg', attrs: omit('className', extend(vnode$$1.data.props,
101 | { class: vnode$$1.data.props ? vnode$$1.data.props.className : undefined }
102 | )) }
103 | )) },
104 | { children: undefinedv(vnode$$1.children) ? undefined :
105 | vnode$$1.children.map(function (child) { return considerSvg(child); })
106 | }
107 | ); };
108 |
109 | var rewrites = {
110 | for: 'attrs',
111 | role: 'attrs',
112 | tabindex: 'attrs',
113 | 'aria-*': 'attrs',
114 | key: null
115 | };
116 |
117 | var rewriteModules = function (data, modules) { return mapObject(data, function (key, val) {
118 | var inner = {};
119 | inner[key] = val;
120 | if (rewrites[key] && modules[rewrites[key]] !== undefined) {
121 | return ( obj = {}, obj[rewrites[key]] = inner, obj )
122 | var obj;
123 | }
124 | if (rewrites[key] === null) {
125 | return {}
126 | }
127 | var keys = Object.keys(rewrites);
128 | for (var i = 0; i < keys.length; i++) {
129 | var k = keys[i];
130 | if (k.charAt(k.length - 1) === '*' && key.indexOf(k.slice(0, -1)) === 0 && modules[rewrites[k]] !== undefined) {
131 | return ( obj$1 = {}, obj$1[rewrites[k]] = inner, obj$1 )
132 | var obj$1;
133 | }
134 | }
135 | if (modules[key] !== undefined) {
136 | return ( obj$2 = {}, obj$2[modules[key] ? modules[key] : key] = val, obj$2 )
137 | var obj$2;
138 | }
139 | if (modules.props !== undefined) {
140 | return { props: inner }
141 | }
142 | return inner
143 | }); };
144 |
145 | var sanitizeData = function (data, modules) { return considerSvg(rewriteModules(deepifyKeys(data, modules), modules)); };
146 |
147 | var sanitizeText = function (children) { return children.length > 1 || !text(children[0]) ? undefined : children[0]; };
148 |
149 | var sanitizeChildren = function (children) { return reduceDeep(children, function (acc, child) {
150 | var vnode$$1 = vnode(child) ? child : createTextElement(child);
151 | acc.push(vnode$$1);
152 | return acc
153 | }
154 | , []); };
155 |
156 | var defaultModules = {
157 | attrs: '',
158 | props: '',
159 | class: '',
160 | data: 'dataset',
161 | style: '',
162 | hook: '',
163 | on: ''
164 | };
165 |
166 | var createElementWithModules = function (modules) {
167 | return function (sel, data) {
168 | var children = [], len = arguments.length - 2;
169 | while ( len-- > 0 ) children[ len ] = arguments[ len + 2 ];
170 |
171 | if (fun(sel)) {
172 | return sel(data || {}, children)
173 | }
174 | var text$$1 = sanitizeText(children, modules);
175 | return considerSvg({
176 | sel: sel,
177 | data: data ? sanitizeData(data, modules) : {},
178 | children: text$$1 ? undefined : sanitizeChildren(children),
179 | text: text$$1,
180 | elm: undefined,
181 | key: data ? data.key : undefined
182 | })
183 | }
184 | };
185 |
186 | var createElement = createElementWithModules(defaultModules);
187 |
188 | var index = {
189 | createElement: createElement,
190 | createElementWithModules: createElementWithModules
191 | };
192 |
193 | exports.createElementWithModules = createElementWithModules;
194 | exports.createElement = createElement;
195 | exports['default'] = index;
196 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "snabbdom-pragma",
3 | "version": "2.8.0",
4 | "description": "'NotReact.createElement' pragma although for snabbdom",
5 | "keywords": [
6 | "snabbdom",
7 | "pragma",
8 | "jsx",
9 | "createElement",
10 | "Bublé",
11 | "Buble",
12 | "Babel",
13 | "Traceur"
14 | ],
15 | "author": "Swizz ",
16 | "license": "MIT",
17 | "repository": "git@github.com:Swizz/snabbdom-pragma.git",
18 | "main": "dist/index.js",
19 | "module": "dist/index.es6.js",
20 | "types": "snabbdom-pragma.d.ts",
21 | "devDependencies": {
22 | "ava": "^0.25.0",
23 | "babel-core": "^6.24.0",
24 | "babel-plugin-transform-react-jsx": "^6.8.0",
25 | "babel-preset-es2015": "^6.24.1",
26 | "babel-preset-stage-2": "^6.24.1",
27 | "benchmark": "^2.1.4",
28 | "buble": "^0.17.3",
29 | "eslint-config-xo-swizz": "^0.11.0",
30 | "rimraf": "^2.6.1",
31 | "rollup": "^0.41.3",
32 | "simple-git": "^1.92.0",
33 | "snabbdom": "^0.6.7",
34 | "traceur": "^0.0.111",
35 | "typescript": "^2.3.2",
36 | "xo": "^0.18.2"
37 | },
38 | "dependencies": {
39 | "extend": "^3.0.0"
40 | },
41 | "scripts": {
42 | "lint": "./node_modules/.bin/xo",
43 | "test:prebuild": "ava --match \"trans -*\" --match \"src -*\" --match \"utils -*\"",
44 | "test:postbuild": "ava --match \"dist -*\"",
45 | "transpile": "./node_modules/.bin/buble -i src/ -o lib/ --no modules --objectAssign fn.assign",
46 | "modules": "rollup -i lib/index.js -o dist/index.js -f cjs && rollup -i lib/index.js -o dist/index.es6.js -f es",
47 | "clean": "./node_modules/.bin/rimraf 'lib/'",
48 | "build": "npm run transpile && npm run modules && npm run clean",
49 | "make": "npm run lint && npm run test:prebuild && npm run build && npm run test:postbuild",
50 | "perf:all": "node perf/build-branches && node perf/run",
51 | "perf": "node perf/run"
52 | },
53 | "ava": {
54 | "files": [
55 | "test/*-test.js"
56 | ],
57 | "require": [
58 | "babel-register"
59 | ]
60 | },
61 | "xo": {
62 | "semicolon": false,
63 | "space": true,
64 | "extends": "xo-swizz",
65 | "rules": {
66 | "import/no-dynamic-require": "off",
67 | "capitalized-comments": "off"
68 | },
69 | "ignores": [
70 | "test/**/transform-*.js"
71 | ]
72 | },
73 | "babel": {
74 | "presets": [
75 | "es2015",
76 | "stage-2"
77 | ]
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/perf/.gitignore:
--------------------------------------------------------------------------------
1 | /snnabdom-new.js
2 | /snnabdom-base.js
3 |
--------------------------------------------------------------------------------
/perf/build-branches.js:
--------------------------------------------------------------------------------
1 | /* eslint unicorn/no-process-exit: 0 */
2 |
3 | const execSync = require('child_process').execSync
4 | const fs = require('fs')
5 | const simpleGit = require('simple-git')()
6 |
7 | const baseBranch = process.argv[2] || 'develop'
8 |
9 | function buildSnabbdom(suffix) {
10 | execSync('npm run build', { stdio: [0, 1, 2] })
11 | fs.writeFileSync(`perf/snnabdom-${suffix}.js`, fs.readFileSync('dist/index.js', 'utf-8'), 'utf-8')
12 | }
13 |
14 | simpleGit.status((err, status) => {
15 | if (err) {
16 | console.error('Error getting status')
17 | process.exit(1)
18 | } else {
19 | const currentBranch = status.current
20 | if (currentBranch === baseBranch) {
21 | console.error('Current branch is already ' + baseBranch)
22 | process.exit(1)
23 | } else {
24 | console.log('Building ' + currentBranch + ' branch')
25 | buildSnabbdom('new')
26 | simpleGit.checkout(baseBranch, (err) => {
27 | if (err) {
28 | console.error('Error checkout ' + baseBranch)
29 | } else {
30 | console.log('Building ' + baseBranch + ' branch')
31 | buildSnabbdom('base')
32 | }
33 | simpleGit.checkout(currentBranch)
34 | if (err) {
35 | process.exit(1)
36 | }
37 | })
38 | }
39 | }
40 | })
41 |
--------------------------------------------------------------------------------
/perf/modules-attribute-props.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved: 0 */
2 |
3 | const Benchmark = require('benchmark')
4 | const h = require('snabbdom/h').default
5 | const baseCreateElement = require('./snnabdom-base').createElement
6 | const newCreateElement = require('./snnabdom-new').createElement
7 |
8 | const isVisible = true
9 | const isEnabled = false
10 |
11 | function attributePropsHyper() {
12 | return h('div', { dataset: { color: 'red' }, attrs: { 'aria-hidden': true } }, [
13 | h('span', { style: { color: 'red', 'background-color': 'blue' } }, 'Hello'),
14 | h('span', { class: { visible: isVisible, enabled: isEnabled, 'alert-danger': true } }, 'World')
15 | ])
16 | }
17 |
18 | function attributeProps(createElement) {
19 | return createElement('div', { 'data-color': 'red', 'aria-hidden': true }, [
20 | createElement('span', { 'style-color': 'red', 'style-background-color': 'blue' }, 'Hello'),
21 | createElement('span', { 'class-visible': isVisible, 'class-enabled': isEnabled, 'class-alert-danger': true }, 'World')
22 | ])
23 | }
24 |
25 | const suite = new Benchmark.Suite('modules attribute props')
26 |
27 | // add tests
28 | suite.add('hyperscript', () => {
29 | attributePropsHyper()
30 | }).
31 | add('jsx-base', () => {
32 | attributeProps(baseCreateElement)
33 | }).
34 | add('jsx-new', () => {
35 | attributeProps(newCreateElement)
36 | })
37 |
38 | module.exports = suite
39 |
--------------------------------------------------------------------------------
/perf/modules-object-props.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved: 0 */
2 |
3 | const Benchmark = require('benchmark')
4 | const h = require('snabbdom/h').default
5 | const baseCreateElement = require('./snnabdom-base').createElement
6 | const newCreateElement = require('./snnabdom-new').createElement
7 |
8 | function objectPropsHyper() {
9 | return h('div', { style: { color: 'red', fontWeight: 'bold' }, dataset: { color: 'red', hidden: true } }, [
10 | h('span', { attrs: { href: '/foo' } }, 'Hello'),
11 | h('span', { dataset: { action: 'reset' } }, 'World')
12 | ])
13 | }
14 |
15 | function objectProps(createElement) {
16 | return createElement('div', { style: { color: 'red', fontWeight: 'bold' }, data: { color: 'red', hidden: true } }, [
17 | createElement('span', { attrs: { href: '/foo' } }, 'Hello'),
18 | createElement('span', { data: { action: 'reset' } }, 'World')
19 | ])
20 | }
21 |
22 | const suite = new Benchmark.Suite('module object props')
23 |
24 | // add tests
25 | suite.add('hyperscript', () => {
26 | objectPropsHyper()
27 | }).
28 | add('jsx-base', () => {
29 | objectProps(baseCreateElement)
30 | }).
31 | add('jsx-new', () => {
32 | objectProps(newCreateElement)
33 | })
34 |
35 | module.exports = suite
36 |
--------------------------------------------------------------------------------
/perf/no-props.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved: 0 */
2 |
3 | const Benchmark = require('benchmark')
4 | const h = require('snabbdom/h').default
5 | const baseCreateElement = require('./snnabdom-base').createElement
6 | const newCreateElement = require('./snnabdom-new').createElement
7 |
8 | function noPropsHyper() {
9 | return h('div', {}, [
10 | h('span', {}, 'Hello'),
11 | h('span', {}, 'World')
12 | ])
13 | }
14 |
15 | function noProps(createElement) {
16 | return createElement('div', null, [
17 | createElement('span', null, 'Hello'),
18 | createElement('span', null, 'World')
19 | ])
20 | }
21 |
22 | const suite = new Benchmark.Suite('no props')
23 |
24 | // add tests
25 | suite.add('hyperscript', () => {
26 | noPropsHyper()
27 | }).
28 | add('jsx-base', () => {
29 | noProps(baseCreateElement)
30 | }).
31 | add('jsx-new', () => {
32 | noProps(newCreateElement)
33 | })
34 |
35 | module.exports = suite
36 |
--------------------------------------------------------------------------------
/perf/real-world-form.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved: 0 */
2 |
3 | const Benchmark = require('benchmark')
4 | const baseCreateElement = require('./snnabdom-base').createElement
5 | const newCreateElement = require('./snnabdom-new').createElement
6 |
7 | function realWorldForm(createElement) {
8 | const state = {}
9 | const patient = { get() {} }
10 | const clinicalCalcs = {
11 | get() {},
12 | isEmpty() {return false},
13 | keys() {return ['a', 'b', 'c', 'd', 'e']}
14 | }
15 | return createElement(
16 | 'div',
17 | { className: 'page compact-content' },
18 | createElement(
19 | 'div',
20 | { className: 'navbar' },
21 | createElement(
22 | 'div',
23 | { className: 'navbar-inner' },
24 | createElement(
25 | 'div',
26 | { className: 'left' },
27 | createElement(
28 | 'a',
29 | { href: '#', className: 'link icon-only back' },
30 | createElement('i', { className: 'icon icon-back' })
31 | )
32 | ),
33 | createElement(
34 | 'div',
35 | { className: 'center sliding' },
36 | 'Exames do Paciente'
37 | ),
38 | createElement('div', { className: 'right' })
39 | )
40 | ),
41 | createElement(
42 | 'div',
43 | { className: 'page-content' },
44 | createElement(
45 | 'div',
46 | { className: 'content-block' },
47 | createElement(
48 | 'h3',
49 | null,
50 | patient.get('name'),
51 | ' anos',
52 | createElement('br', null),
53 | createElement(
54 | 'span',
55 | { className: 'header-subtitle' },
56 | patient.get('sectorname') || '',
57 | ' Leito ',
58 | (patient.get('bednumber') || '').padStart(2, '0')
59 | )
60 | )
61 | ),
62 | createElement(
63 | 'div',
64 | { className: 'content-block' },
65 | createElement(
66 | 'div',
67 | { className: 'row' },
68 | createElement(
69 | 'div',
70 | { className: 'col' },
71 | createElement(
72 | 'b',
73 | null,
74 | 'Registro'
75 | ),
76 | createElement('br', null),
77 | patient.get('registry'),
78 | ' ',
79 | createElement('br', null)
80 | ),
81 | createElement(
82 | 'div',
83 | { className: 'col' },
84 | createElement(
85 | 'b',
86 | null,
87 | 'Admiss\xE3o Hospitalar'
88 | ),
89 | createElement('br', null),
90 | ' ',
91 | createElement('br', null)
92 | )
93 | )
94 | ),
95 | createElement(
96 | 'div',
97 | { className: 'list-block' },
98 | createElement(
99 | 'ul',
100 | null,
101 | createElement(
102 | 'li',
103 | { id: 'clinical-calcs', className: 'accordion-item' },
104 | createElement(
105 | 'a',
106 | { href: '#', className: 'item-content item-link' },
107 | createElement(
108 | 'div',
109 | { className: 'item-inner' },
110 | createElement(
111 | 'div',
112 | { className: 'item-title' },
113 | 'C\xE1lculos'
114 | )
115 | )
116 | ),
117 | createElement(
118 | 'div',
119 | { className: 'content-block' },
120 | createElement(
121 | 'div',
122 | { className: 'accordion-item-content' },
123 | clinicalCalcs ? createElement(
124 | 'div',
125 | null,
126 | ' ',
127 | createElement(
128 | 'div',
129 | { className: 'card-content' },
130 | !clinicalCalcs.isEmpty() ? createElement(
131 | 'div',
132 | { className: 'list-block media-list' },
133 | clinicalCalcs.keys().map((calcKey) => {
134 | return createElement(
135 | 'ul',
136 | null,
137 | createElement(
138 | 'li',
139 | null,
140 | createElement(
141 | 'a',
142 | { href: '#', className: 'item-link item-content calc-item', data: { calcKey } },
143 | createElement(
144 | 'div',
145 | { className: 'item-inner' },
146 | createElement(
147 | 'div',
148 | { className: 'item-title-row' },
149 | createElement(
150 | 'div',
151 | { className: 'item-title' },
152 | clinicalCalcs.get(calcKey)
153 | )
154 | ),
155 | createElement(
156 | 'div',
157 | { className: 'item-text' },
158 | clinicalCalcs.get(calcKey) || ''
159 | )
160 | )
161 | )
162 | )
163 | )
164 | })
165 | ) : 'Nenhum cálculo salvo'
166 | ),
167 | createElement(
168 | 'div',
169 | { className: 'card-footer' },
170 | createElement('div', null),
171 | ' ',
172 | createElement(
173 | 'a',
174 | { href: '#', id: 'add-calc-item', className: 'link' },
175 | 'Adicionar'
176 | )
177 | )
178 | ) : createElement(
179 | 'div',
180 | { className: 'text-center' },
181 | createElement('span', { className: 'preloader' })
182 | )
183 | )
184 | )
185 | )
186 | )
187 | ),
188 | createElement('div', { data: state.testsTableData })
189 | )
190 | )
191 | }
192 |
193 | const suite = new Benchmark.Suite('real world form')
194 |
195 | // add tests
196 | suite.add('jsx-base', () => {
197 | realWorldForm(baseCreateElement)
198 | }).
199 | add('jsx-new', () => {
200 | realWorldForm(newCreateElement)
201 | })
202 |
203 | module.exports = suite
204 |
--------------------------------------------------------------------------------
/perf/run.js:
--------------------------------------------------------------------------------
1 | const noProps = require('./no-props')
2 | const simpleProps = require('./simple-props')
3 | const objectProps = require('./modules-object-props')
4 | const attributeProps = require('./modules-attribute-props')
5 | const realForm = require('./real-world-form')
6 |
7 | const suites = []
8 |
9 | function runNextSuite() {
10 | if (suites.length !== 0) {
11 | suites.shift().run({ async: true })
12 | } else {
13 | console.log('\nAll benchmarks complete')
14 | }
15 | }
16 |
17 | function addSuite(suite) {
18 | suites.push(suite)
19 | suite.on('start', (event) => {
20 | console.log('\nBenchmarking', event.currentTarget.name)
21 | }).
22 | on('cycle', (event) => {
23 | console.log(String(event.target))
24 | }).
25 | on('complete', function (event) {
26 | const fastest = this.filter('fastest').map('name')
27 | const fastestJSX = this.filter((bench) => bench.name.indexOf('jsx') !== -1).filter('fastest').map('name')
28 | console.log(event.currentTarget.name, '- fastest is ' + fastest, ' fastest JSX is ', fastestJSX)
29 | runNextSuite()
30 | })
31 | }
32 |
33 | addSuite(noProps)
34 | addSuite(simpleProps)
35 | addSuite(objectProps)
36 | addSuite(attributeProps)
37 | addSuite(realForm)
38 |
39 | runNextSuite()
40 |
--------------------------------------------------------------------------------
/perf/simple-props.js:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved: 0 */
2 |
3 | const Benchmark = require('benchmark')
4 | const h = require('snabbdom/h').default
5 | const baseCreateElement = require('./snnabdom-base').createElement
6 | const newCreateElement = require('./snnabdom-new').createElement
7 |
8 | function simplePropsHyper() {
9 | return h('div', { props: { href: 'xxxxx', target: 'route' } }, [
10 | h('span', { props: { name: 'x', value: 1 } }, 'Hello'),
11 | h('span', { props: { name: 'y', value: 2 } }, 'World')
12 | ])
13 | }
14 |
15 | function simpleProps(createElement) {
16 | return createElement('div', { href: 'xxxxx', target: 'route' }, [
17 | createElement('span', { name: 'x', value: 1 }, 'Hello'),
18 | createElement('span', { name: 'y', value: 2 }, 'World')
19 | ])
20 | }
21 |
22 | const suite = new Benchmark.Suite('simple props')
23 |
24 | // add tests
25 | suite.add('hyperscript', () => {
26 | simplePropsHyper()
27 | }).
28 | add('jsx-base', () => {
29 | simpleProps(baseCreateElement)
30 | }).
31 | add('jsx-new', () => {
32 | simpleProps(newCreateElement)
33 | })
34 |
35 | module.exports = suite
36 |
--------------------------------------------------------------------------------
/snabbdom-pragma.d.ts:
--------------------------------------------------------------------------------
1 | import { VNode, VNodeData } from 'snabbdom/vnode'
2 |
3 | export = SnabbdomPragma
4 |
5 | declare namespace SnabbdomPragma {
6 | type Children = VNode[] | VNode | string | number
7 | type CircularChildren = Children | Children[]
8 |
9 | type Component = (props: VNodeData, children: CircularChildren[]) => VNode
10 |
11 | export function createElement(sel: string | Component, data: null | VNodeData, ...children: CircularChildren[]): VNode
12 | }
13 |
14 | declare global {
15 | namespace JSX {
16 | interface Element extends VNode { }
17 | interface IntrinsicElements {
18 | [elemName: string]: VNodeData
19 | }
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/fn.js:
--------------------------------------------------------------------------------
1 | // TODO: stop using extend here
2 | import _extend from 'extend'
3 |
4 | import * as is from './is'
5 |
6 | export const extend = (...objs) => _extend(true, ...objs)
7 |
8 | export const assign = (...objs) => _extend(false, ...objs)
9 |
10 | export const reduceDeep = (arr, fn, initial) => {
11 | let result = initial
12 | for (let i = 0; i < arr.length; i++) {
13 | const value = arr[i]
14 | if (is.array(value)) {
15 | result = reduceDeep(value, fn, result)
16 | } else {
17 | result = fn(result, value)
18 | }
19 | }
20 | return result
21 | }
22 |
23 | export const mapObject = (obj, fn) => Object.keys(obj).map(
24 | (key) => fn(key, obj[key])
25 | ).reduce(
26 | (acc, curr) => extend(acc, curr),
27 | {}
28 | )
29 |
30 | export const deepifyKeys = (obj, modules) => mapObject(obj,
31 | (key, val) => {
32 | const dashIndex = key.indexOf('-')
33 | if (dashIndex > -1 && modules[key.slice(0, dashIndex)] !== undefined) {
34 | const moduleData = {
35 | [key.slice(dashIndex + 1)]: val
36 | }
37 | return {
38 | [key.slice(0, dashIndex)]: moduleData
39 | }
40 | }
41 | return { [key]: val }
42 | }
43 | )
44 |
45 | export const flatifyKeys = (obj) => mapObject(obj,
46 | (mod, data) => !is.object(data) ? ({ [mod]: data }) : mapObject(
47 | flatifyKeys(data),
48 | (key, val) => ({ [`${mod}-${key}`]: val })
49 | )
50 | )
51 |
52 | export const omit = (key, obj) => mapObject(obj,
53 | (mod, data) => mod !== key ? ({ [mod]: data }) : {}
54 | )
55 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 |
2 | import * as is from './is'
3 | import * as fn from './fn'
4 |
5 | // Const fnName = (...params) => guard ? default : ...
6 |
7 | const createTextElement = (text) => !is.text(text) ? undefined : {
8 | text,
9 | sel: undefined,
10 | data: undefined,
11 | children: undefined,
12 | elm: undefined,
13 | key: undefined
14 | }
15 |
16 | const considerSvg = (vnode) => !is.svg(vnode) ? vnode :
17 | fn.assign(vnode,
18 | { data: fn.omit('props', fn.extend(vnode.data,
19 | { ns: 'http://www.w3.org/2000/svg', attrs: fn.omit('className', fn.extend(vnode.data.props,
20 | { class: vnode.data.props ? vnode.data.props.className : undefined }
21 | )) }
22 | )) },
23 | { children: is.undefinedv(vnode.children) ? undefined :
24 | vnode.children.map((child) => considerSvg(child))
25 | }
26 | )
27 |
28 | const rewrites = {
29 | for: 'attrs',
30 | role: 'attrs',
31 | tabindex: 'attrs',
32 | 'aria-*': 'attrs',
33 | key: null
34 | }
35 |
36 | const rewriteModules = (data, modules) => fn.mapObject(data, (key, val) => {
37 | const inner = { [key]: val }
38 | if (rewrites[key] && modules[rewrites[key]] !== undefined) {
39 | return { [rewrites[key]]: inner }
40 | }
41 | if (rewrites[key] === null) {
42 | return {}
43 | }
44 | const keys = Object.keys(rewrites)
45 | for (let i = 0; i < keys.length; i++) {
46 | const k = keys[i]
47 | if (k.charAt(k.length - 1) === '*' && key.indexOf(k.slice(0, -1)) === 0 && modules[rewrites[k]] !== undefined) {
48 | return { [rewrites[k]]: inner }
49 | }
50 | }
51 | if (modules[key] !== undefined) {
52 | return { [modules[key] ? modules[key] : key]: val }
53 | }
54 | if (modules.props !== undefined) {
55 | return { props: inner }
56 | }
57 | return inner
58 | })
59 |
60 | const sanitizeData = (data, modules) => considerSvg(rewriteModules(fn.deepifyKeys(data, modules), modules))
61 |
62 | const sanitizeText = (children) => children.length > 1 || !is.text(children[0]) ? undefined : children[0]
63 |
64 | const sanitizeChildren = (children) => fn.reduceDeep(children, (acc, child) => {
65 | const vnode = is.vnode(child) ? child : createTextElement(child)
66 | acc.push(vnode)
67 | return acc
68 | }
69 | , [])
70 |
71 | const defaultModules = {
72 | attrs: '',
73 | props: '',
74 | class: '',
75 | data: 'dataset',
76 | style: '',
77 | hook: '',
78 | on: ''
79 | }
80 |
81 | export const createElementWithModules = (modules) => {
82 | return (sel, data, ...children) => {
83 | if (is.fun(sel)) {
84 | return sel(data || {}, children)
85 | }
86 | const text = sanitizeText(children, modules)
87 | return considerSvg({
88 | sel,
89 | data: data ? sanitizeData(data, modules) : {},
90 | children: text ? undefined : sanitizeChildren(children),
91 | text,
92 | elm: undefined,
93 | key: data ? data.key : undefined
94 | })
95 | }
96 | }
97 |
98 | export const createElement = createElementWithModules(defaultModules)
99 |
100 | export default {
101 | createElement,
102 | createElementWithModules
103 | }
104 |
--------------------------------------------------------------------------------
/src/is.js:
--------------------------------------------------------------------------------
1 |
2 | export const nullv = (v) => v === null
3 |
4 | export const undefinedv = (v) => v === undefined
5 |
6 | export const number = (v) => typeof v === 'number'
7 |
8 | export const string = (v) => typeof v === 'string'
9 |
10 | export const text = (v) => string(v) || number(v)
11 |
12 | export const array = (v) => Array.isArray(v)
13 |
14 | export const object = (v) => typeof v === 'object' && v !== null
15 |
16 | export const fun = (v) => typeof v === 'function'
17 |
18 | export const vnode = (v) => object(v) && 'sel' in v && 'data' in v && 'children' in v && 'text' in v
19 |
20 | const svgPropsMap = { svg: 1, circle: 1, ellipse: 1, line: 1, polygon: 1,
21 | polyline: 1, rect: 1, g: 1, path: 1, text: 1 }
22 |
23 | export const svg = (v) => v.sel in svgPropsMap
24 |
--------------------------------------------------------------------------------
/test/build-specs/dist-file/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../dist/index'
3 |
4 | export default () => {
5 | return Snabbdom.createElement('div', null)
6 | }
7 |
--------------------------------------------------------------------------------
/test/build-specs/dist-file/expected.js:
--------------------------------------------------------------------------------
1 |
2 | import h from 'snabbdom/h'
3 |
4 | export default () => {
5 | return h('div', {}, [])
6 | }
7 |
--------------------------------------------------------------------------------
/test/build-test.js:
--------------------------------------------------------------------------------
1 |
2 | import path from 'path'
3 | import fs from 'fs'
4 |
5 | import test from 'ava'
6 |
7 | const fixturesDir = path.join(__dirname, 'build-specs')
8 |
9 | fs.readdirSync(fixturesDir).forEach((caseName) => {
10 | test(`Should works for ${caseName.split('-').join(' ')}`, (t) => {
11 | const fixtureDir = path.join(fixturesDir, caseName)
12 |
13 | const actual = require(
14 | path.join(fixtureDir, 'actual.js')
15 | ).default()
16 |
17 | const expected = require(
18 | path.join(fixtureDir, 'expected.js')
19 | ).default()
20 |
21 | t.deepEqual(actual, expected)
22 | })
23 | })
24 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component-without-props/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | const Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Hello { name }
7 |
8 | return
9 | }
10 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component-without-props/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | export default (() => {
5 | const Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Snabbdom.createElementWithModules({"attrs": "", "props": ""})(
7 | 'div',
8 | null,
9 | 'Hello ',
10 | name
11 | );
12 |
13 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})(Component, null);
14 | });
15 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component-without-props/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | var Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Snabbdom.createElementWithModules({"attrs": "", "props": ""})( 'div', null, "Hello ", name )
7 |
8 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})( Component, null )
9 | }
10 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component-without-props/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | const Component = ({name}) => Snabbdom.createElementWithModules({
5 | "attrs": "",
6 | "props": ""
7 | })("div", null, "Hello ", name);
8 | return Snabbdom.createElementWithModules({
9 | "attrs": "",
10 | "props": ""
11 | })(Component, null);
12 | };
13 | //# sourceURL=
14 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component-without-props/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | const Component = ({ name }) => Snabbdom.createElementWithModules({"attrs": "", "props": ""})("div", null,
5 | "Hello ",
6 | name);
7 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})(Component, null);
8 | };
9 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | const Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Hello { name }
7 |
8 | return
9 | }
10 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | export default (() => {
5 | const Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Snabbdom.createElementWithModules({"attrs": "", "props": ""})(
7 | "div",
8 | null,
9 | "Hello ",
10 | name
11 | );
12 |
13 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})(Component, { name: "world" });
14 | });
15 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | var Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Snabbdom.createElementWithModules({"attrs": "", "props": ""})( 'div', null, "Hello ", name )
7 |
8 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})( Component, { name: "world" })
9 | }
10 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | const Component = ({name}) => Snabbdom.createElementWithModules({
5 | "attrs": "",
6 | "props": ""
7 | })("div", null, "Hello ", name);
8 | return Snabbdom.createElementWithModules({
9 | "attrs": "",
10 | "props": ""
11 | })(Component, {name: "world"});
12 | };
13 | //# sourceURL=
14 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/component/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | const Component = ({ name }) => Snabbdom.createElementWithModules({"attrs": "", "props": ""})("div", null,
5 | "Hello ",
6 | name);
7 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})(Component, { name: "world" });
8 | };
9 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-attributes/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | return
6 | }
7 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-attributes/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | export default (() => {
5 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})("input", { "aria-role": "foo" });
6 | });
7 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-attributes/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})( 'input', { 'aria-role': "foo" })
6 | }
7 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-attributes/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | return Snabbdom.createElementWithModules({
5 | "attrs": "",
6 | "props": ""
7 | })("input", {"aria-role": "foo"});
8 | };
9 | //# sourceURL=
10 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-attributes/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})('input', { attrs: { "aria-role": "foo" }})
5 | };
6 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-class-names/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | const isVisible = () => {}
5 |
6 | export default () => {
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-class-names/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | const isVisible = () => {};
5 |
6 | export default (() => {
7 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})('div', { 'class-visible': isVisible });
8 | });
9 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-class-names/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | var isVisible = () => {}
5 |
6 | export default () => {
7 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})( 'div', { 'class-visible': isVisible })
8 | }
9 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-class-names/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | const isVisible = () => {};
4 | export default () => {
5 | return Snabbdom.createElementWithModules({
6 | "attrs": "",
7 | "props": ""
8 | })("div", {"class-visible": isVisible});
9 | };
10 | //# sourceURL=
11 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-class-names/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | const isVisible = () => { };
4 | export default () => {
5 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})('div', { props: { 'class-visible': isVisible }});
6 | };
7 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-event/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | const callback = () => {}
5 |
6 | export default () => {
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-event/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | const callback = () => {};
5 |
6 | export default (() => {
7 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})('button', { 'on-click': callback });
8 | });
9 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-event/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | var callback = () => {}
5 |
6 | export default () => {
7 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})( 'button', { 'on-click': callback })
8 | }
9 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-event/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | const callback = () => {};
4 | export default () => {
5 | return Snabbdom.createElementWithModules({
6 | "attrs": "",
7 | "props": ""
8 | })("button", {"on-click": callback});
9 | };
10 | //# sourceURL=
11 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/element-with-event/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | const callback = () => { };
4 | export default () => {
5 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})('button', { props: { 'on-click': callback }});
6 | };
7 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/simple-element/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | return Hello World
6 | }
7 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/simple-element/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | export default (() => {
5 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})(
6 | 'div',
7 | null,
8 | 'Hello World'
9 | );
10 | });
11 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/simple-element/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})( 'div', null, "Hello World" )
6 | }
7 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/simple-element/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | return Snabbdom.createElementWithModules({
5 | "attrs": "",
6 | "props": ""
7 | })("div", null, "Hello World");
8 | };
9 | //# sourceURL=
10 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-specs/simple-element/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | return Snabbdom.createElementWithModules({"attrs": "", "props": ""})("div", null, "Hello World");
5 | };
6 |
--------------------------------------------------------------------------------
/test/jsx-custom-modules-test.js:
--------------------------------------------------------------------------------
1 |
2 | import path from 'path'
3 | import fs from 'fs'
4 |
5 | import test from 'ava'
6 |
7 | const fixturesDir = path.join(__dirname, 'jsx-custom-modules-specs')
8 |
9 | fs.readdirSync(fixturesDir).forEach((caseName) => {
10 | test(`trans - Should Bublé transform ${caseName.split('-').join(' ')}`, (t) => {
11 | const fixtureDir = path.join(fixturesDir, caseName)
12 |
13 | const actual = require('buble').transform(
14 | fs.readFileSync(
15 | path.join(fixtureDir, 'actual.js')
16 | ).toString(), {
17 | transforms: {
18 | modules: false,
19 | arrow: false,
20 | parameterDestructuring: false
21 | },
22 | jsx: 'Snabbdom.createElementWithModules({"attrs": "", "props": ""})'
23 | }
24 | ).code
25 |
26 | const transform = fs.readFileSync(
27 | path.join(fixtureDir, 'transform-buble.js')
28 | ).toString()
29 |
30 | t.is(actual.trim(), transform.trim())
31 | })
32 |
33 | test(`trans - Should Babel transform ${caseName.split('-').join(' ')}`, (t) => {
34 | const fixtureDir = path.join(fixturesDir, caseName)
35 |
36 | const actual = require('babel-core').transform(
37 | fs.readFileSync(
38 | path.join(fixtureDir, 'actual.js')
39 | ).toString(), {
40 | plugins: [
41 | ['transform-react-jsx', { pragma: 'Snabbdom.createElementWithModules({"attrs": "", "props": ""})' }]
42 | ]
43 | }
44 | ).code
45 |
46 | let transform = fs.readFileSync(
47 | path.join(fixtureDir, 'transform-babel.js')
48 | ).toString()
49 |
50 | transform = transform.replace(/\r/gm, '')
51 |
52 | t.is(actual.trim(), transform.trim())
53 | })
54 |
55 | test(`trans - Should Traceur transform ${caseName.split('-').join(' ')}`, (t) => {
56 | const fixtureDir = path.join(fixturesDir, caseName)
57 |
58 | const actual = require('traceur').compile(
59 | fs.readFileSync(
60 | path.join(fixtureDir, 'actual.js')
61 | ).toString(), {
62 | jsx: 'Snabbdom.createElementWithModules({"attrs": "", "props": ""})',
63 | modules: false,
64 | outputLanguage: 'es6'
65 | }
66 | )
67 |
68 | let transform = fs.readFileSync(
69 | path.join(fixtureDir, 'transform-traceur.js')
70 | ).toString()
71 |
72 | transform = transform.replace(/\r/gm, '')
73 |
74 | t.is(actual.trim(), transform.trim())
75 | })
76 |
77 | // Typescript compiler does not support arbitrary pragma
78 | /* test(`trans - Should Typescript transform ${caseName.split('-').join(' ')}`, (t) => {
79 | const fixtureDir = path.join(fixturesDir, caseName)
80 |
81 | const actual = require('typescript').transpileModule(
82 | fs.readFileSync(
83 | path.join(fixtureDir, 'actual.js')
84 | ).toString(), {
85 | compilerOptions: {
86 | jsx: 'react',
87 | jsxFactory: 'Snabbdom.createElementWithModules({"attrs": "", "props": ""})',
88 | target: 'es6'
89 | }
90 | }
91 | ).outputText
92 |
93 | const transform = fs.readFileSync(
94 | path.join(fixtureDir, 'transform-typescript.js')
95 | ).toString()
96 |
97 | t.is(actual.trim(), transform.trim())
98 | }) */
99 | })
100 |
--------------------------------------------------------------------------------
/test/jsx-specs/component-without-props/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | const Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Hello { name }
7 |
8 | return
9 | }
10 |
--------------------------------------------------------------------------------
/test/jsx-specs/component-without-props/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | export default (() => {
5 | const Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Snabbdom.createElement(
7 | 'div',
8 | null,
9 | 'Hello ',
10 | name
11 | );
12 |
13 | return Snabbdom.createElement(Component, null);
14 | });
15 |
--------------------------------------------------------------------------------
/test/jsx-specs/component-without-props/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | var Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Snabbdom.createElement( 'div', null, "Hello ", name )
7 |
8 | return Snabbdom.createElement( Component, null )
9 | }
10 |
--------------------------------------------------------------------------------
/test/jsx-specs/component-without-props/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | const Component = ({name}) => Snabbdom.createElement("div", null, "Hello ", name);
5 | return Snabbdom.createElement(Component, null);
6 | };
7 | //# sourceURL=
8 |
--------------------------------------------------------------------------------
/test/jsx-specs/component-without-props/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | const Component = ({ name }) => Snabbdom.createElement("div", null,
5 | "Hello ",
6 | name);
7 | return Snabbdom.createElement(Component, null);
8 | };
9 |
--------------------------------------------------------------------------------
/test/jsx-specs/component/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | const Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Hello { name }
7 |
8 | return
9 | }
10 |
--------------------------------------------------------------------------------
/test/jsx-specs/component/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | export default (() => {
5 | const Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Snabbdom.createElement(
7 | "div",
8 | null,
9 | "Hello ",
10 | name
11 | );
12 |
13 | return Snabbdom.createElement(Component, { name: "world" });
14 | });
15 |
--------------------------------------------------------------------------------
/test/jsx-specs/component/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | var Component = ({ name }) => // eslint-disable-line no-unused-vars
6 | Snabbdom.createElement( 'div', null, "Hello ", name )
7 |
8 | return Snabbdom.createElement( Component, { name: "world" })
9 | }
10 |
--------------------------------------------------------------------------------
/test/jsx-specs/component/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | const Component = ({name}) => Snabbdom.createElement("div", null, "Hello ", name);
5 | return Snabbdom.createElement(Component, {name: "world"});
6 | };
7 | //# sourceURL=
8 |
--------------------------------------------------------------------------------
/test/jsx-specs/component/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | const Component = ({ name }) => Snabbdom.createElement("div", null,
5 | "Hello ",
6 | name);
7 | return Snabbdom.createElement(Component, { name: "world" });
8 | };
9 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-attributes/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | return
6 | }
7 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-attributes/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | export default (() => {
5 | return Snabbdom.createElement("input", { type: "text" });
6 | });
7 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-attributes/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | return Snabbdom.createElement( 'input', { type: "text" })
6 | }
7 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-attributes/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | return Snabbdom.createElement("input", {type: "text"});
5 | };
6 | //# sourceURL=
7 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-attributes/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | return Snabbdom.createElement("input", { type: "text" });
5 | };
6 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-class-names/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | const isVisible = () => {}
5 |
6 | export default () => {
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-class-names/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | const isVisible = () => {};
5 |
6 | export default (() => {
7 | return Snabbdom.createElement('div', { 'class-visible': isVisible });
8 | });
9 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-class-names/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | var isVisible = () => {}
5 |
6 | export default () => {
7 | return Snabbdom.createElement( 'div', { 'class-visible': isVisible })
8 | }
9 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-class-names/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | const isVisible = () => {};
4 | export default () => {
5 | return Snabbdom.createElement("div", {"class-visible": isVisible});
6 | };
7 | //# sourceURL=
8 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-class-names/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | const isVisible = () => { };
4 | export default () => {
5 | return Snabbdom.createElement("div", { "class-visible": isVisible });
6 | };
7 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-event/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | const callback = () => {}
5 |
6 | export default () => {
7 | return
8 | }
9 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-event/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | const callback = () => {};
5 |
6 | export default (() => {
7 | return Snabbdom.createElement('button', { 'on-click': callback });
8 | });
9 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-event/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | var callback = () => {}
5 |
6 | export default () => {
7 | return Snabbdom.createElement( 'button', { 'on-click': callback })
8 | }
9 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-event/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | const callback = () => {};
4 | export default () => {
5 | return Snabbdom.createElement("button", {"on-click": callback});
6 | };
7 | //# sourceURL=
8 |
--------------------------------------------------------------------------------
/test/jsx-specs/element-with-event/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | const callback = () => { };
4 | export default () => {
5 | return Snabbdom.createElement("button", { "on-click": callback });
6 | };
7 |
--------------------------------------------------------------------------------
/test/jsx-specs/simple-element/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | return Hello World
6 | }
7 |
--------------------------------------------------------------------------------
/test/jsx-specs/simple-element/transform-babel.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 |
4 | export default (() => {
5 | return Snabbdom.createElement(
6 | 'div',
7 | null,
8 | 'Hello World'
9 | );
10 | });
11 |
--------------------------------------------------------------------------------
/test/jsx-specs/simple-element/transform-buble.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index'
3 |
4 | export default () => {
5 | return Snabbdom.createElement( 'div', null, "Hello World" )
6 | }
7 |
--------------------------------------------------------------------------------
/test/jsx-specs/simple-element/transform-traceur.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | return Snabbdom.createElement("div", null, "Hello World");
5 | };
6 | //# sourceURL=
7 |
--------------------------------------------------------------------------------
/test/jsx-specs/simple-element/transform-typescript.js:
--------------------------------------------------------------------------------
1 |
2 | import Snabbdom from '../../../src/index';
3 | export default () => {
4 | return Snabbdom.createElement("div", null, "Hello World");
5 | };
6 |
--------------------------------------------------------------------------------
/test/jsx-test.js:
--------------------------------------------------------------------------------
1 |
2 | import path from 'path'
3 | import fs from 'fs'
4 |
5 | import test from 'ava'
6 |
7 | const fixturesDir = path.join(__dirname, 'jsx-specs')
8 |
9 | fs.readdirSync(fixturesDir).forEach((caseName) => {
10 | test(`trans - Should Bublé transform ${caseName.split('-').join(' ')}`, (t) => {
11 | const fixtureDir = path.join(fixturesDir, caseName)
12 |
13 | const actual = require('buble').transform(
14 | fs.readFileSync(
15 | path.join(fixtureDir, 'actual.js')
16 | ).toString(), {
17 | transforms: {
18 | modules: false,
19 | arrow: false,
20 | parameterDestructuring: false
21 | },
22 | jsx: 'Snabbdom.createElement'
23 | }
24 | ).code
25 |
26 | const transform = fs.readFileSync(
27 | path.join(fixtureDir, 'transform-buble.js')
28 | ).toString()
29 |
30 | t.is(actual.trim(), transform.trim())
31 | })
32 |
33 | test(`trans - Should Babel transform ${caseName.split('-').join(' ')}`, (t) => {
34 | const fixtureDir = path.join(fixturesDir, caseName)
35 |
36 | const actual = require('babel-core').transform(
37 | fs.readFileSync(
38 | path.join(fixtureDir, 'actual.js')
39 | ).toString(), {
40 | plugins: [
41 | ['transform-react-jsx', { pragma: 'Snabbdom.createElement' }]
42 | ]
43 | }
44 | ).code
45 |
46 | let transform = fs.readFileSync(
47 | path.join(fixtureDir, 'transform-babel.js')
48 | ).toString()
49 |
50 | transform = transform.replace(/\r/gm, '')
51 |
52 | t.is(actual.trim(), transform.trim())
53 | })
54 |
55 | test(`trans - Should Traceur transform ${caseName.split('-').join(' ')}`, (t) => {
56 | const fixtureDir = path.join(fixturesDir, caseName)
57 |
58 | const actual = require('traceur').compile(
59 | fs.readFileSync(
60 | path.join(fixtureDir, 'actual.js')
61 | ).toString(), {
62 | jsx: 'Snabbdom.createElement',
63 | modules: false,
64 | outputLanguage: 'es6'
65 | }
66 | )
67 |
68 | let transform = fs.readFileSync(
69 | path.join(fixtureDir, 'transform-traceur.js')
70 | ).toString()
71 |
72 | transform = transform.replace(/\r/gm, '')
73 |
74 | t.is(actual.trim(), transform.trim())
75 | })
76 |
77 | test(`trans - Should Typescript transform ${caseName.split('-').join(' ')}`, (t) => {
78 | const fixtureDir = path.join(fixturesDir, caseName)
79 |
80 | const actual = require('typescript').transpileModule(
81 | fs.readFileSync(
82 | path.join(fixtureDir, 'actual.js')
83 | ).toString(), {
84 | compilerOptions: {
85 | jsx: 'react',
86 | jsxFactory: 'Snabbdom.createElement',
87 | target: 'es6'
88 | }
89 | }
90 | ).outputText
91 |
92 | const transform = fs.readFileSync(
93 | path.join(fixtureDir, 'transform-typescript.js')
94 | ).toString()
95 |
96 | t.is(actual.trim(), transform.trim())
97 | })
98 | })
99 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-text-and-var/actual.js:
--------------------------------------------------------------------------------
1 |
2 | const name = 'world'
3 |
4 | export default (createElement) => {
5 | return createElement('span', null, 'Hello ', name)
6 | }
7 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-text-and-var/expected.js:
--------------------------------------------------------------------------------
1 |
2 | const name = 'world'
3 |
4 | export default (h) => {
5 | return h('span', {}, ['Hello ', name])
6 | }
7 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-text/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('span', null, 'Hello World')
4 | }
5 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-text/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('span', {}, 'Hello World')
4 | }
5 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-type/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('div', null)
4 | }
5 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-type/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('div', {}, [])
4 | }
5 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-with-array-children/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('div', null, [
4 | createElement('span', null, 'Hello'),
5 | createElement('span', null, 'World')
6 | ])
7 | }
8 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-with-array-children/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('div', {}, [
4 | h('span', {}, 'Hello'),
5 | h('span', {}, 'World')
6 | ])
7 | }
8 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-with-children/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('div', null,
4 | createElement('span', null, 'Hello'),
5 | createElement('span', null, 'World')
6 | )
7 | }
8 |
--------------------------------------------------------------------------------
/test/pragma-specs/vnode-with-children/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('div', {}, [
4 | h('span', {}, 'Hello'),
5 | h('span', {}, 'World')
6 | ])
7 | }
8 |
--------------------------------------------------------------------------------
/test/pragma-test.js:
--------------------------------------------------------------------------------
1 |
2 | import path from 'path'
3 | import fs from 'fs'
4 |
5 | import test from 'ava'
6 |
7 | import h from 'snabbdom/h'
8 | import { createElement as src } from '../src/index'
9 | import { createElement as dist } from '../dist/index'
10 |
11 | const fixturesDir = path.join(__dirname, 'pragma-specs')
12 |
13 | fs.readdirSync(fixturesDir).forEach((caseName) => {
14 | test(`src - Should works for ${caseName.split('-').join(' ')}`, (t) => {
15 | const fixtureDir = path.join(fixturesDir, caseName)
16 |
17 | const actual = require(
18 | path.join(fixtureDir, 'actual.js')
19 | ).default(src)
20 |
21 | const expected = require(
22 | path.join(fixtureDir, 'expected.js')
23 | ).default(h)
24 |
25 | t.deepEqual(actual, expected)
26 | })
27 |
28 | test(`dist - Should works for ${caseName.split('-').join(' ')}`, (t) => {
29 | const fixtureDir = path.join(fixturesDir, caseName)
30 |
31 | const actual = require(
32 | path.join(fixtureDir, 'actual.js')
33 | ).default(dist)
34 |
35 | const expected = require(
36 | path.join(fixtureDir, 'expected.js')
37 | ).default(h)
38 |
39 | t.deepEqual(actual, expected)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-class-names/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import { isVisible, isEnabled } from './neutral'
3 |
4 | export default (createElement) => {
5 | return createElement('div', { 'class-visible': isVisible, 'class-enabled': isEnabled, 'class-alert-danger': true })
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-class-names/expected.js:
--------------------------------------------------------------------------------
1 |
2 | import { isVisible, isEnabled } from './neutral'
3 |
4 | export default (h) => {
5 | return h('div', {
6 | class: { visible: isVisible, enabled: isEnabled, 'alert-danger': true }
7 | }, [])
8 | }
9 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-class-names/neutral.js:
--------------------------------------------------------------------------------
1 |
2 | export const isVisible = true
3 |
4 | export const isEnabled = false
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-component-with-slot/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | const Component = ({ name }, children) =>
4 | createElement('div', null, 'Hello ', name,
5 | createElement('div', null, children)
6 | )
7 |
8 | return createElement(Component, { name: 'world' },
9 | createElement('p', null, 'It works !')
10 | )
11 | }
12 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-component-with-slot/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | const Component = ({ name }, children) =>
4 | h('div', {}, ['Hello ', name,
5 | h('div', {}, children)
6 | ])
7 |
8 | return Component({ name: 'world' }, [
9 | h('p', {}, 'It works !')
10 | ])
11 | }
12 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-component-without-props/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | const Component = ({ name }) =>
4 | createElement('div', null, 'Hello ', name)
5 |
6 | return createElement(Component, null,
7 | createElement('span', null, 'Done')
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-component-without-props/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | const Component = ({ name }) =>
4 | h('div', {}, ['Hello ', name])
5 |
6 | return Component({}, [
7 | h('span', {}, 'Done')
8 | ])
9 | }
10 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-component/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | const Component = ({ name }) =>
4 | createElement('div', null, 'Hello ', name)
5 |
6 | return createElement(Component, { name: 'toto' },
7 | createElement('span', null, 'Done')
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-component/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | const Component = ({ name }) =>
4 | h('div', {}, ['Hello ', name])
5 |
6 | return Component({ name: 'toto' }, [
7 | h('span', {}, 'Done')
8 | ])
9 | }
10 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-data-aria-object/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('div', { data: { color: 'red', hidden: true } })
4 | }
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-data-aria-object/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('div', {
4 | dataset: { color: 'red', hidden: true }
5 | }, [])
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-data-aria/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('div', { 'data-color': 'red', 'aria-hidden': true })
4 | }
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-data-aria/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('div', {
4 | dataset: { color: 'red' },
5 | attrs: { 'aria-hidden': true }
6 | }, [])
7 | }
8 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-events/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import { clickHandler } from './neutral'
3 |
4 | export default (createElement) => {
5 | return createElement('div', { 'on-click': clickHandler })
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-events/expected.js:
--------------------------------------------------------------------------------
1 |
2 | import { clickHandler } from './neutral'
3 |
4 | export default (h) => {
5 | return h('div', { on: { click: clickHandler } }, [])
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-events/neutral.js:
--------------------------------------------------------------------------------
1 |
2 | export const clickHandler = () =>
3 | console.log('got clicked')
4 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-forced-attrs/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('label', { for: 'input' }, 'Label')
4 | }
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-forced-attrs/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('label', {
4 | attrs: { for: 'input' }
5 | }, 'Label')
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-hard-component/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | const Component = ({ name }) =>
4 | createElement('div', null, 'Hello ', name)
5 |
6 | return createElement(Component, { name: 'world' })
7 | }
8 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-hard-component/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('div', {}, ['Hello ', 'world'])
4 | }
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-hooks/actual.js:
--------------------------------------------------------------------------------
1 |
2 | import { onInit } from './neutral'
3 |
4 | export default (createElement) => {
5 | return createElement('div', { 'hook-init': onInit })
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-hooks/expected.js:
--------------------------------------------------------------------------------
1 |
2 | import { onInit } from './neutral'
3 |
4 | export default (h) => {
5 | return h('div', { hook: { init: onInit } }, [])
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-hooks/neutral.js:
--------------------------------------------------------------------------------
1 |
2 | export const onInit = () =>
3 | console.log('Inited')
4 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-mixed-module-ways/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('div', { 'style-color': 'red', style: { background: 'blue' } })
4 | }
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-mixed-module-ways/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('div', {
4 | style: { color: 'red', background: 'blue' }
5 | }, [])
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-properties/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('input', { type: 'text' })
4 | }
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-properties/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('input', { props: { type: 'text' } }, [])
4 | }
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-reserved-module/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('div', { style: ({ color: 'red', fontWeight: 'bold' }) })
4 | }
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-reserved-module/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('div', {
4 | style: { color: 'red', fontWeight: 'bold' }
5 | }, [])
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-style/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('div', { 'style-color': 'red', 'style-background-color': 'blue' })
4 | }
5 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-style/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('div', {
4 | style: { color: 'red', 'background-color': 'blue' }
5 | }, [])
6 | }
7 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-svg/actual.js:
--------------------------------------------------------------------------------
1 |
2 | export default (createElement) => {
3 | return createElement('svg', null, [
4 | createElement('g', null, [
5 | createElement('circle', { cx: 43.5, cy: 23, r: 5 }),
6 | createElement('path', { 'stroke-dasharray': 'foo' })
7 | ])
8 | ])
9 | }
10 |
--------------------------------------------------------------------------------
/test/snabbdom-specs/vnode-svg/expected.js:
--------------------------------------------------------------------------------
1 |
2 | export default (h) => {
3 | return h('svg', { attrs: {} }, [
4 | h('g', { attrs: {} }, [
5 | h('circle', {
6 | attrs: { cx: 43.5, cy: 23, r: 5 }
7 | }, []),
8 | h('path', {
9 | attrs: { 'stroke-dasharray': 'foo' }
10 | }, [])
11 | ])
12 | ])
13 | }
14 |
--------------------------------------------------------------------------------
/test/snabbdom-test.js:
--------------------------------------------------------------------------------
1 |
2 | import path from 'path'
3 | import fs from 'fs'
4 |
5 | import test from 'ava'
6 |
7 | import h from 'snabbdom/h'
8 | import { createElement as src } from '../src/index'
9 | import { createElement as dist } from '../dist/index'
10 |
11 | const fixturesDir = path.join(__dirname, 'snabbdom-specs')
12 |
13 | fs.readdirSync(fixturesDir).forEach((caseName) => {
14 | test(`src - Should works for ${caseName.split('-').join(' ')}`, (t) => {
15 | const fixtureDir = path.join(fixturesDir, caseName)
16 |
17 | const actual = require(
18 | path.join(fixtureDir, 'actual.js')
19 | ).default(src)
20 |
21 | const expected = require(
22 | path.join(fixtureDir, 'expected.js')
23 | ).default(h)
24 |
25 | t.deepEqual(actual, expected)
26 | })
27 |
28 | test(`dist - Should works for ${caseName.split('-').join(' ')}`, (t) => {
29 | const fixtureDir = path.join(fixturesDir, caseName)
30 |
31 | const actual = require(
32 | path.join(fixtureDir, 'actual.js')
33 | ).default(dist)
34 |
35 | const expected = require(
36 | path.join(fixtureDir, 'expected.js')
37 | ).default(h)
38 |
39 | t.deepEqual(actual, expected)
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/test/utils-test.js:
--------------------------------------------------------------------------------
1 | import test from 'ava'
2 | import { reduceDeep } from '../src/fn'
3 |
4 | test('utils - reduceDeep with flat array', (t) => {
5 | const arr = ['a', 'b', 'c', 'd', 'e']
6 | const actual = reduceDeep(arr, (acc, item) => {
7 | acc.push(item)
8 | return acc
9 | }, [])
10 | const expected = ['a', 'b', 'c', 'd', 'e']
11 | t.deepEqual(actual, expected)
12 | })
13 |
14 | test('utils - reduceDeep with nested array', (t) => {
15 | const arr = ['a', ['b', 'c'], [['d']], 'e']
16 | const actual = reduceDeep(arr, (acc, item) => {
17 | acc.push(item)
18 | return acc
19 | }, [])
20 | const expected = ['a', 'b', 'c', 'd', 'e']
21 | t.deepEqual(actual, expected)
22 | })
23 |
--------------------------------------------------------------------------------