├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── cjs
├── index.js
├── package.json
└── utils.js
├── esm
├── index.js
└── utils.js
├── index.js
├── min.js
├── package.json
├── rollup.config.js
└── test
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | coverage/
3 | .DS_Store
4 | package-lock.json
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | test/
3 | _config.yml
4 | .DS_Store
5 | .gitignore
6 | .travis.yml
7 | package-lock.json
8 | rollup.config.js
9 | es.config.js
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2019, Andrea Giammarchi, @WebReflection
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 | PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # hypersimple
2 |
3 | The easiest way to use [hyperHTML](https://github.com/WebReflection/hyperHTML#readme) 🦄
4 |
5 | * `hooks` like simplicity implemented through the model
6 | * component implemented as callbacks
7 | * an entire model/props driven development
8 |
9 | - - -
10 | **Social Media Photo by [Juliana Malta](https://unsplash.com/@julianamalta) on [Unsplash](https://unsplash.com/)**
11 |
12 |  [](https://opensource.org/licenses/ISC)
13 |
14 |
15 | #### Example
16 |
17 | [Live on Code Pen](https://codepen.io/WebReflection/pen/RXaWyR?editors=0010).
18 |
19 | ```js
20 | import {comp, html, render} from 'hypersimple';
21 |
22 | // components
23 | const Button = comp(model => html`
24 |
27 | `);
28 |
29 | // main App: just like any component
30 | const App = comp(model => html`
31 | Lorem ipsum: ${model.count}
32 |
33 | ${Button(model.button)}
34 | `);
35 |
36 | // model: it will be mutated to trigger updates on changes
37 | const model = {
38 | count: 0,
39 | button: {
40 | text: 'increment',
41 | onclick() {
42 | // will update the view right away
43 | model.count += 1;
44 | }
45 | }
46 | };
47 |
48 | // render
49 | render(document.body, () => App(model));
50 | ```
51 |
52 | ## API in a nutshell
53 |
54 | * `comp(fn)` returns a component based on some `props` or `model` object. The `fn` _must_ return the result of `html` or `svg`
55 | * `html` and `svg` are a template literal tag that accept everything _hyperHTML_ can produce
56 | * `render(where, what)` will populate the content of a generic node with whatever a component returns
57 | * `update(model[, {...changes}])` to update all components based on the same model and, eventually, batch all updates at once through changes
58 | * `define(...)` to enrich _hyperHTML_ potentials [as described in the documentation](https://viperhtml.js.org/hyperhtml/documentation/#api-3)
59 |
60 | The `model` _will be modified_ to reflect any change of any of its properties in the UI, and every method will be automatically bound to the related context.
61 |
62 | A `model` _can be used with multiple components_ without needing to nest a sub model/object per each component related to the same model.
63 |
64 | If you use immutable structures, you'll trash the whole layout each time so ... to **keep it simple**, as the project suggests, but also to keep it memory safe, just pass mutable models and update those directly instead of duplicating references.
65 |
66 | The whole idea is indeed to abstract away everything that's more complicated than setting, or updating, a generic property.
67 |
--------------------------------------------------------------------------------
/cjs/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const WeakMap = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/weakmap'));
3 | const Map = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/essential-map'));
4 | const {
5 | define, html, svg, augment, merge, refresh, same, slice
6 | } = require('./utils.js');
7 |
8 | var comps = new WeakMap;
9 | var param = new WeakMap;
10 | var store = new WeakMap;
11 |
12 | var ids = 0;
13 | var sync = true;
14 |
15 | (m => {
16 | exports.escape = m.escape;
17 | exports.unescape = m.unescape;
18 | })(require('html-escaper'));
19 | exports.define = define;
20 | exports.html = html;
21 | exports.svg = svg;
22 |
23 | function comp(Component) {
24 | var id = ++ids;
25 | comps.set(component, id);
26 | return component;
27 | function component(model) {
28 | var mod = model || {};
29 | var map = store.get(mod) || setMap(mod);
30 | return updateComponent.call(
31 | mod,
32 | map.get(component) ||
33 | setInfo(map, component, Component, id, slice.call(arguments, 0))
34 | );
35 | };
36 | }
37 | exports.comp = comp;
38 |
39 | function render(where, comp) {
40 | var content = comps.has(comp) ?
41 | comp(param.get(where) || setParam(where)) :
42 | comp();
43 | var isElement = content.nodeType === 1;
44 | if (!(
45 | (isElement && where.firstChild === content) ||
46 | (!isElement && content.childNodes.every(same, where.childNodes))
47 | )) {
48 | where.textContent = '';
49 | where.appendChild(content.valueOf(true));
50 | }
51 | return where;
52 | }
53 | exports.render = render;
54 |
55 | function update(model, changes) {
56 | var map = store.get(model);
57 | if (!map)
58 | throw new Error('unknown model');
59 | sync = false;
60 | try {
61 | merge(model, changes || {});
62 | }
63 | finally {
64 | sync = true;
65 | map.forEach(updateComponent, model);
66 | }
67 | }
68 | exports.update = update;
69 |
70 | function setInfo(map, comp, Component, id, args) {
71 | var info = {Component: Component, id: id, args: args};
72 | map.set(comp, info);
73 | return info;
74 | }
75 |
76 | function setMap(model) {
77 | var map = new Map;
78 | store.set(model, map);
79 | augment(model, updateAll);
80 | return map;
81 | }
82 |
83 | function setParam(where) {
84 | var model = {};
85 | param.set(where, model);
86 | return model;
87 | }
88 |
89 | function updateAll(model) {
90 | if (sync)
91 | store.get(model).forEach(updateComponent, model);
92 | }
93 |
94 | function updateComponent(info) {
95 | return refresh(this, info.Component, info.id, info.args);
96 | }
97 |
--------------------------------------------------------------------------------
/cjs/package.json:
--------------------------------------------------------------------------------
1 | {"type":"commonjs"}
--------------------------------------------------------------------------------
/cjs/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const {define, wire} = require('hyperhtml');
3 |
4 | var defineProperty = Object.defineProperty;
5 | var gOPD = Object.getOwnPropertyDescriptor;
6 | var keys = Object.keys;
7 |
8 | var hOP = {}.hasOwnProperty;
9 | var slice = [].slice;
10 | var wired = {id: 0, model: null};
11 |
12 | // hyper utilities
13 | exports.define = define;
14 |
15 | function html() {
16 | return wire(wired.model, 'html:' + wired.id).apply(null, arguments);
17 | }
18 | exports.html = html;
19 |
20 | function svg() {
21 | return wire(wired.model, 'svg:' + wired.id).apply(null, arguments);
22 | }
23 | exports.svg = svg;
24 |
25 | // extra utilities
26 | function augment(model, update) {
27 | keys(model).forEach(function (key) {
28 | var value, desc = gOPD(model, key);
29 | if (desc.configurable) {
30 | if ('value' in desc) {
31 | value = bound(desc.value, model);
32 | defineProperty(model, key, {
33 | configurable: true,
34 | enumerable: true,
35 | get: function () {
36 | return value;
37 | },
38 | set: function ($) {
39 | value = bound($, model);
40 | update(model);
41 | }
42 | });
43 | } else if ('set' in desc) {
44 | value = desc.set;
45 | desc.set = function ($) {
46 | value.call(model, $);
47 | update(model);
48 | };
49 | defineProperty(model, key, desc);
50 | }
51 | }
52 | });
53 | }
54 | exports.augment = augment;
55 |
56 | function merge(model, changes) {
57 | for (var key in changes) {
58 | if (hOP.call(changes, key)) {
59 | var has = hOP.call(model, key);
60 | var curr = changes[key];
61 | var prev = has ? model[key] : null;
62 | if (has && curr !== null && typeof curr === "object")
63 | merge(prev, curr);
64 | else if (!has || curr !== prev)
65 | model[key] = curr;
66 | }
67 | }
68 | }
69 | exports.merge = merge;
70 |
71 | function refresh(model, Component, id, args) {
72 | var wid = wired.id;
73 | var wmodel = wired.model;
74 | wired.id = id;
75 | wired.model = model;
76 | try {
77 | return Component.apply(null, args);
78 | }
79 | finally {
80 | wired.id = wid;
81 | wired.model = wmodel;
82 | }
83 | }
84 | exports.refresh = refresh;
85 |
86 | function same(node, i) {
87 | return this[i] === node[i];
88 | }
89 | exports.same = same;
90 |
91 | exports.slice = slice;
92 |
93 | function bound(value, model) {
94 | return typeof value === 'function' ? value.bind(model) : value;
95 | }
96 |
--------------------------------------------------------------------------------
/esm/index.js:
--------------------------------------------------------------------------------
1 | import WeakMap from '@ungap/weakmap';
2 | import Map from '@ungap/essential-map';
3 | import {
4 | define, html, svg,
5 | augment, merge, refresh, same, slice
6 | } from './utils.js';
7 |
8 | var comps = new WeakMap;
9 | var param = new WeakMap;
10 | var store = new WeakMap;
11 |
12 | var ids = 0;
13 | var sync = true;
14 |
15 | export {escape, unescape} from 'html-escaper';
16 | export {define, html, svg};
17 |
18 | export function comp(Component) {
19 | var id = ++ids;
20 | comps.set(component, id);
21 | return component;
22 | function component(model) {
23 | var mod = model || {};
24 | var map = store.get(mod) || setMap(mod);
25 | return updateComponent.call(
26 | mod,
27 | map.get(component) ||
28 | setInfo(map, component, Component, id, slice.call(arguments, 0))
29 | );
30 | };
31 | };
32 |
33 | export function render(where, comp) {
34 | var content = comps.has(comp) ?
35 | comp(param.get(where) || setParam(where)) :
36 | comp();
37 | var isElement = content.nodeType === 1;
38 | if (!(
39 | (isElement && where.firstChild === content) ||
40 | (!isElement && content.childNodes.every(same, where.childNodes))
41 | )) {
42 | where.textContent = '';
43 | where.appendChild(content.valueOf(true));
44 | }
45 | return where;
46 | };
47 |
48 | export function update(model, changes) {
49 | var map = store.get(model);
50 | if (!map)
51 | throw new Error('unknown model');
52 | sync = false;
53 | try {
54 | merge(model, changes || {});
55 | }
56 | finally {
57 | sync = true;
58 | map.forEach(updateComponent, model);
59 | }
60 | };
61 |
62 | function setInfo(map, comp, Component, id, args) {
63 | var info = {Component: Component, id: id, args: args};
64 | map.set(comp, info);
65 | return info;
66 | }
67 |
68 | function setMap(model) {
69 | var map = new Map;
70 | store.set(model, map);
71 | augment(model, updateAll);
72 | return map;
73 | }
74 |
75 | function setParam(where) {
76 | var model = {};
77 | param.set(where, model);
78 | return model;
79 | }
80 |
81 | function updateAll(model) {
82 | if (sync)
83 | store.get(model).forEach(updateComponent, model);
84 | }
85 |
86 | function updateComponent(info) {
87 | return refresh(this, info.Component, info.id, info.args);
88 | }
89 |
--------------------------------------------------------------------------------
/esm/utils.js:
--------------------------------------------------------------------------------
1 | import {define, wire} from 'hyperhtml';
2 |
3 | var defineProperty = Object.defineProperty;
4 | var gOPD = Object.getOwnPropertyDescriptor;
5 | var keys = Object.keys;
6 |
7 | var hOP = {}.hasOwnProperty;
8 | var slice = [].slice;
9 | var wired = {id: 0, model: null};
10 |
11 | // hyper utilities
12 | export {define};
13 |
14 | export function html() {
15 | return wire(wired.model, 'html:' + wired.id).apply(null, arguments);
16 | };
17 |
18 | export function svg() {
19 | return wire(wired.model, 'svg:' + wired.id).apply(null, arguments);
20 | };
21 |
22 | // extra utilities
23 | export function augment(model, update) {
24 | keys(model).forEach(function (key) {
25 | var value, desc = gOPD(model, key);
26 | if (desc.configurable) {
27 | if ('value' in desc) {
28 | value = bound(desc.value, model);
29 | defineProperty(model, key, {
30 | configurable: true,
31 | enumerable: true,
32 | get: function () {
33 | return value;
34 | },
35 | set: function ($) {
36 | value = bound($, model);
37 | update(model);
38 | }
39 | });
40 | } else if ('set' in desc) {
41 | value = desc.set;
42 | desc.set = function ($) {
43 | value.call(model, $);
44 | update(model);
45 | };
46 | defineProperty(model, key, desc);
47 | }
48 | }
49 | });
50 | };
51 |
52 | export function merge(model, changes) {
53 | for (var key in changes) {
54 | if (hOP.call(changes, key)) {
55 | var has = hOP.call(model, key);
56 | var curr = changes[key];
57 | var prev = has ? model[key] : null;
58 | if (has && curr !== null && typeof curr === "object")
59 | merge(prev, curr);
60 | else if (!has || curr !== prev)
61 | model[key] = curr;
62 | }
63 | }
64 | };
65 |
66 | export function refresh(model, Component, id, args) {
67 | var wid = wired.id;
68 | var wmodel = wired.model;
69 | wired.id = id;
70 | wired.model = model;
71 | try {
72 | return Component.apply(null, args);
73 | }
74 | finally {
75 | wired.id = wid;
76 | wired.model = wmodel;
77 | }
78 | };
79 |
80 | export function same(node, i) {
81 | return this[i] === node[i];
82 | };
83 |
84 | export {slice};
85 |
86 | function bound(value, model) {
87 | return typeof value === 'function' ? value.bind(model) : value;
88 | }
89 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var hypersimple = (function (exports) {
2 | 'use strict';
3 |
4 | /*! (c) Andrea Giammarchi - ISC */
5 | var self = null ||
6 | /* istanbul ignore next */
7 | {};
8 |
9 | try {
10 | self.WeakMap = WeakMap;
11 | } catch (WeakMap) {
12 | // this could be better but 90% of the time
13 | // it's everything developers need as fallback
14 | self.WeakMap = function (id, Object) {
15 |
16 | var dP = Object.defineProperty;
17 | var hOP = Object.hasOwnProperty;
18 | var proto = WeakMap.prototype;
19 |
20 | proto["delete"] = function (key) {
21 | return this.has(key) && delete key[this._];
22 | };
23 |
24 | proto.get = function (key) {
25 | return this.has(key) ? key[this._] : void 0;
26 | };
27 |
28 | proto.has = function (key) {
29 | return hOP.call(key, this._);
30 | };
31 |
32 | proto.set = function (key, value) {
33 | dP(key, this._, {
34 | configurable: true,
35 | value: value
36 | });
37 | return this;
38 | };
39 |
40 | return WeakMap;
41 |
42 | function WeakMap(iterable) {
43 | dP(this, '_', {
44 | value: '_@ungap/weakmap' + id++
45 | });
46 | if (iterable) iterable.forEach(add, this);
47 | }
48 |
49 | function add(pair) {
50 | this.set(pair[0], pair[1]);
51 | }
52 | }(Math.random(), Object);
53 | }
54 |
55 | var WeakMap$1 = self.WeakMap;
56 |
57 | /*! (c) Andrea Giammarchi - ISC */
58 | var self$1 = null ||
59 | /* istanbul ignore next */
60 | {};
61 |
62 | try {
63 | self$1.Map = Map;
64 | } catch (Map) {
65 | self$1.Map = function Map() {
66 | var i = 0;
67 | var k = [];
68 | var v = [];
69 | return {
70 | "delete": function _delete(key) {
71 | var had = contains(key);
72 |
73 | if (had) {
74 | k.splice(i, 1);
75 | v.splice(i, 1);
76 | }
77 |
78 | return had;
79 | },
80 | forEach: function forEach(callback, context) {
81 | k.forEach(function (key, i) {
82 | callback.call(context, v[i], key, this);
83 | }, this);
84 | },
85 | get: function get(key) {
86 | return contains(key) ? v[i] : void 0;
87 | },
88 | has: function has(key) {
89 | return contains(key);
90 | },
91 | set: function set(key, value) {
92 | v[contains(key) ? i : k.push(key) - 1] = value;
93 | return this;
94 | }
95 | };
96 |
97 | function contains(v) {
98 | i = k.indexOf(v);
99 | return -1 < i;
100 | }
101 | };
102 | }
103 |
104 | var Map$1 = self$1.Map;
105 |
106 |
107 |
108 | /*! (c) Andrea Giammarchi - ISC */
109 | var self$2 = null ||
110 | /* istanbul ignore next */
111 | {};
112 |
113 | try {
114 | self$2.WeakSet = WeakSet;
115 | } catch (WeakSet) {
116 | (function (id, dP) {
117 | var proto = WeakSet.prototype;
118 |
119 | proto.add = function (object) {
120 | if (!this.has(object)) dP(object, this._, {
121 | value: true,
122 | configurable: true
123 | });
124 | return this;
125 | };
126 |
127 | proto.has = function (object) {
128 | return this.hasOwnProperty.call(object, this._);
129 | };
130 |
131 | proto["delete"] = function (object) {
132 | return this.has(object) && delete object[this._];
133 | };
134 |
135 | self$2.WeakSet = WeakSet;
136 |
137 | function WeakSet() {
138 |
139 | dP(this, '_', {
140 | value: '_@ungap/weakmap' + id++
141 | });
142 | }
143 | })(Math.random(), Object.defineProperty);
144 | }
145 |
146 | var WeakSet$1 = self$2.WeakSet;
147 |
148 | var _ref = [],
149 | indexOf = _ref.indexOf;
150 |
151 | var append = function append(get, parent, children, start, end, before) {
152 | var isSelect = ('selectedIndex' in parent);
153 | var noSelection = isSelect;
154 |
155 | while (start < end) {
156 | var child = get(children[start], 1);
157 | parent.insertBefore(child, before);
158 |
159 | if (isSelect && noSelection && child.selected) {
160 | noSelection = !noSelection;
161 | var selectedIndex = parent.selectedIndex;
162 | parent.selectedIndex = selectedIndex < 0 ? start : indexOf.call(parent.querySelectorAll('option'), child);
163 | }
164 |
165 | start++;
166 | }
167 | };
168 | var eqeq = function eqeq(a, b) {
169 | return a == b;
170 | };
171 | var identity = function identity(O) {
172 | return O;
173 | };
174 | var indexOf$1 = function indexOf(moreNodes, moreStart, moreEnd, lessNodes, lessStart, lessEnd, compare) {
175 | var length = lessEnd - lessStart;
176 | /* istanbul ignore if */
177 |
178 | if (length < 1) return -1;
179 |
180 | while (moreEnd - moreStart >= length) {
181 | var m = moreStart;
182 | var l = lessStart;
183 |
184 | while (m < moreEnd && l < lessEnd && compare(moreNodes[m], lessNodes[l])) {
185 | m++;
186 | l++;
187 | }
188 |
189 | if (l === lessEnd) return moreStart;
190 | moreStart = m + 1;
191 | }
192 |
193 | return -1;
194 | };
195 | var isReversed = function isReversed(futureNodes, futureEnd, currentNodes, currentStart, currentEnd, compare) {
196 | while (currentStart < currentEnd && compare(currentNodes[currentStart], futureNodes[futureEnd - 1])) {
197 | currentStart++;
198 | futureEnd--;
199 | }
200 | return futureEnd === 0;
201 | };
202 | var next = function next(get, list, i, length, before) {
203 | return i < length ? get(list[i], 0) : 0 < i ? get(list[i - 1], -0).nextSibling : before;
204 | };
205 | var remove = function remove(get, children, start, end) {
206 | while (start < end) {
207 | drop(get(children[start++], -1));
208 | }
209 | }; // - - - - - - - - - - - - - - - - - - -
210 | // diff related constants and utilities
211 | // - - - - - - - - - - - - - - - - - - -
212 |
213 | var DELETION = -1;
214 | var INSERTION = 1;
215 | var SKIP = 0;
216 | var SKIP_OND = 50;
217 |
218 | var HS = function HS(futureNodes, futureStart, futureEnd, futureChanges, currentNodes, currentStart, currentEnd, currentChanges) {
219 | var k = 0;
220 | /* istanbul ignore next */
221 |
222 | var minLen = futureChanges < currentChanges ? futureChanges : currentChanges;
223 | var link = Array(minLen++);
224 | var tresh = Array(minLen);
225 | tresh[0] = -1;
226 |
227 | for (var i = 1; i < minLen; i++) {
228 | tresh[i] = currentEnd;
229 | }
230 |
231 | var nodes = currentNodes.slice(currentStart, currentEnd);
232 |
233 | for (var _i = futureStart; _i < futureEnd; _i++) {
234 | var index = nodes.indexOf(futureNodes[_i]);
235 |
236 | if (-1 < index) {
237 | var idxInOld = index + currentStart;
238 | k = findK(tresh, minLen, idxInOld);
239 | /* istanbul ignore else */
240 |
241 | if (-1 < k) {
242 | tresh[k] = idxInOld;
243 | link[k] = {
244 | newi: _i,
245 | oldi: idxInOld,
246 | prev: link[k - 1]
247 | };
248 | }
249 | }
250 | }
251 |
252 | k = --minLen;
253 | --currentEnd;
254 |
255 | while (tresh[k] > currentEnd) {
256 | --k;
257 | }
258 |
259 | minLen = currentChanges + futureChanges - k;
260 | var diff = Array(minLen);
261 | var ptr = link[k];
262 | --futureEnd;
263 |
264 | while (ptr) {
265 | var _ptr = ptr,
266 | newi = _ptr.newi,
267 | oldi = _ptr.oldi;
268 |
269 | while (futureEnd > newi) {
270 | diff[--minLen] = INSERTION;
271 | --futureEnd;
272 | }
273 |
274 | while (currentEnd > oldi) {
275 | diff[--minLen] = DELETION;
276 | --currentEnd;
277 | }
278 |
279 | diff[--minLen] = SKIP;
280 | --futureEnd;
281 | --currentEnd;
282 | ptr = ptr.prev;
283 | }
284 |
285 | while (futureEnd >= futureStart) {
286 | diff[--minLen] = INSERTION;
287 | --futureEnd;
288 | }
289 |
290 | while (currentEnd >= currentStart) {
291 | diff[--minLen] = DELETION;
292 | --currentEnd;
293 | }
294 |
295 | return diff;
296 | }; // this is pretty much the same petit-dom code without the delete map part
297 | // https://github.com/yelouafi/petit-dom/blob/bd6f5c919b5ae5297be01612c524c40be45f14a7/src/vdom.js#L556-L561
298 |
299 |
300 | var OND = function OND(futureNodes, futureStart, rows, currentNodes, currentStart, cols, compare) {
301 | var length = rows + cols;
302 | var v = [];
303 | var d, k, r, c, pv, cv, pd;
304 |
305 | outer: for (d = 0; d <= length; d++) {
306 | /* istanbul ignore if */
307 | if (d > SKIP_OND) return null;
308 | pd = d - 1;
309 | /* istanbul ignore next */
310 |
311 | pv = d ? v[d - 1] : [0, 0];
312 | cv = v[d] = [];
313 |
314 | for (k = -d; k <= d; k += 2) {
315 | if (k === -d || k !== d && pv[pd + k - 1] < pv[pd + k + 1]) {
316 | c = pv[pd + k + 1];
317 | } else {
318 | c = pv[pd + k - 1] + 1;
319 | }
320 |
321 | r = c - k;
322 |
323 | while (c < cols && r < rows && compare(currentNodes[currentStart + c], futureNodes[futureStart + r])) {
324 | c++;
325 | r++;
326 | }
327 |
328 | if (c === cols && r === rows) {
329 | break outer;
330 | }
331 |
332 | cv[d + k] = c;
333 | }
334 | }
335 |
336 | var diff = Array(d / 2 + length / 2);
337 | var diffIdx = diff.length - 1;
338 |
339 | for (d = v.length - 1; d >= 0; d--) {
340 | while (c > 0 && r > 0 && compare(currentNodes[currentStart + c - 1], futureNodes[futureStart + r - 1])) {
341 | // diagonal edge = equality
342 | diff[diffIdx--] = SKIP;
343 | c--;
344 | r--;
345 | }
346 |
347 | if (!d) break;
348 | pd = d - 1;
349 | /* istanbul ignore next */
350 |
351 | pv = d ? v[d - 1] : [0, 0];
352 | k = c - r;
353 |
354 | if (k === -d || k !== d && pv[pd + k - 1] < pv[pd + k + 1]) {
355 | // vertical edge = insertion
356 | r--;
357 | diff[diffIdx--] = INSERTION;
358 | } else {
359 | // horizontal edge = deletion
360 | c--;
361 | diff[diffIdx--] = DELETION;
362 | }
363 | }
364 |
365 | return diff;
366 | };
367 |
368 | var applyDiff = function applyDiff(diff, get, parentNode, futureNodes, futureStart, currentNodes, currentStart, currentLength, before) {
369 | var live = [];
370 | var length = diff.length;
371 | var currentIndex = currentStart;
372 | var i = 0;
373 |
374 | while (i < length) {
375 | switch (diff[i++]) {
376 | case SKIP:
377 | futureStart++;
378 | currentIndex++;
379 | break;
380 |
381 | case INSERTION:
382 | // TODO: bulk appends for sequential nodes
383 | live.push(futureNodes[futureStart]);
384 | append(get, parentNode, futureNodes, futureStart++, futureStart, currentIndex < currentLength ? get(currentNodes[currentIndex], 0) : before);
385 | break;
386 |
387 | case DELETION:
388 | currentIndex++;
389 | break;
390 | }
391 | }
392 |
393 | i = 0;
394 |
395 | while (i < length) {
396 | switch (diff[i++]) {
397 | case SKIP:
398 | currentStart++;
399 | break;
400 |
401 | case DELETION:
402 | // TODO: bulk removes for sequential nodes
403 | if (-1 < live.indexOf(currentNodes[currentStart])) currentStart++;else remove(get, currentNodes, currentStart++, currentStart);
404 | break;
405 | }
406 | }
407 | };
408 |
409 | var findK = function findK(ktr, length, j) {
410 | var lo = 1;
411 | var hi = length;
412 |
413 | while (lo < hi) {
414 | var mid = (lo + hi) / 2 >>> 0;
415 | if (j < ktr[mid]) hi = mid;else lo = mid + 1;
416 | }
417 |
418 | return lo;
419 | };
420 |
421 | var smartDiff = function smartDiff(get, parentNode, futureNodes, futureStart, futureEnd, futureChanges, currentNodes, currentStart, currentEnd, currentChanges, currentLength, compare, before) {
422 | applyDiff(OND(futureNodes, futureStart, futureChanges, currentNodes, currentStart, currentChanges, compare) || HS(futureNodes, futureStart, futureEnd, futureChanges, currentNodes, currentStart, currentEnd, currentChanges), get, parentNode, futureNodes, futureStart, currentNodes, currentStart, currentLength, before);
423 | };
424 |
425 | var drop = function drop(node) {
426 | return (node.remove || dropChild).call(node);
427 | };
428 |
429 | function dropChild() {
430 | var parentNode = this.parentNode;
431 | /* istanbul ignore else */
432 |
433 | if (parentNode) parentNode.removeChild(this);
434 | }
435 |
436 | /*! (c) 2018 Andrea Giammarchi (ISC) */
437 |
438 | var domdiff = function domdiff(parentNode, // where changes happen
439 | currentNodes, // Array of current items/nodes
440 | futureNodes, // Array of future items/nodes
441 | options // optional object with one of the following properties
442 | // before: domNode
443 | // compare(generic, generic) => true if same generic
444 | // node(generic) => Node
445 | ) {
446 | if (!options) options = {};
447 | var compare = options.compare || eqeq;
448 | var get = options.node || identity;
449 | var before = options.before == null ? null : get(options.before, 0);
450 | var currentLength = currentNodes.length;
451 | var currentEnd = currentLength;
452 | var currentStart = 0;
453 | var futureEnd = futureNodes.length;
454 | var futureStart = 0; // common prefix
455 |
456 | while (currentStart < currentEnd && futureStart < futureEnd && compare(currentNodes[currentStart], futureNodes[futureStart])) {
457 | currentStart++;
458 | futureStart++;
459 | } // common suffix
460 |
461 |
462 | while (currentStart < currentEnd && futureStart < futureEnd && compare(currentNodes[currentEnd - 1], futureNodes[futureEnd - 1])) {
463 | currentEnd--;
464 | futureEnd--;
465 | }
466 |
467 | var currentSame = currentStart === currentEnd;
468 | var futureSame = futureStart === futureEnd; // same list
469 |
470 | if (currentSame && futureSame) return futureNodes; // only stuff to add
471 |
472 | if (currentSame && futureStart < futureEnd) {
473 | append(get, parentNode, futureNodes, futureStart, futureEnd, next(get, currentNodes, currentStart, currentLength, before));
474 | return futureNodes;
475 | } // only stuff to remove
476 |
477 |
478 | if (futureSame && currentStart < currentEnd) {
479 | remove(get, currentNodes, currentStart, currentEnd);
480 | return futureNodes;
481 | }
482 |
483 | var currentChanges = currentEnd - currentStart;
484 | var futureChanges = futureEnd - futureStart;
485 | var i = -1; // 2 simple indels: the shortest sequence is a subsequence of the longest
486 |
487 | if (currentChanges < futureChanges) {
488 | i = indexOf$1(futureNodes, futureStart, futureEnd, currentNodes, currentStart, currentEnd, compare); // inner diff
489 |
490 | if (-1 < i) {
491 | append(get, parentNode, futureNodes, futureStart, i, get(currentNodes[currentStart], 0));
492 | append(get, parentNode, futureNodes, i + currentChanges, futureEnd, next(get, currentNodes, currentEnd, currentLength, before));
493 | return futureNodes;
494 | }
495 | }
496 | /* istanbul ignore else */
497 | else if (futureChanges < currentChanges) {
498 | i = indexOf$1(currentNodes, currentStart, currentEnd, futureNodes, futureStart, futureEnd, compare); // outer diff
499 |
500 | if (-1 < i) {
501 | remove(get, currentNodes, currentStart, i);
502 | remove(get, currentNodes, i + futureChanges, currentEnd);
503 | return futureNodes;
504 | }
505 | } // common case with one replacement for many nodes
506 | // or many nodes replaced for a single one
507 |
508 | /* istanbul ignore else */
509 |
510 |
511 | if (currentChanges < 2 || futureChanges < 2) {
512 | append(get, parentNode, futureNodes, futureStart, futureEnd, get(currentNodes[currentStart], 0));
513 | remove(get, currentNodes, currentStart, currentEnd);
514 | return futureNodes;
515 | } // the half match diff part has been skipped in petit-dom
516 | // https://github.com/yelouafi/petit-dom/blob/bd6f5c919b5ae5297be01612c524c40be45f14a7/src/vdom.js#L391-L397
517 | // accordingly, I think it's safe to skip in here too
518 | // if one day it'll come out like the speediest thing ever to do
519 | // then I might add it in here too
520 | // Extra: before going too fancy, what about reversed lists ?
521 | // This should bail out pretty quickly if that's not the case.
522 |
523 |
524 | if (currentChanges === futureChanges && isReversed(futureNodes, futureEnd, currentNodes, currentStart, currentEnd, compare)) {
525 | append(get, parentNode, futureNodes, futureStart, futureEnd, next(get, currentNodes, currentEnd, currentLength, before));
526 | return futureNodes;
527 | } // last resort through a smart diff
528 |
529 |
530 | smartDiff(get, parentNode, futureNodes, futureStart, futureEnd, futureChanges, currentNodes, currentStart, currentEnd, currentChanges, currentLength, compare, before);
531 | return futureNodes;
532 | };
533 |
534 | /*! (c) Andrea Giammarchi - ISC */
535 | var self$3 = null ||
536 | /* istanbul ignore next */
537 | {};
538 | self$3.CustomEvent = typeof CustomEvent === 'function' ? CustomEvent : function (__p__) {
539 | CustomEvent[__p__] = new CustomEvent('').constructor[__p__];
540 | return CustomEvent;
541 |
542 | function CustomEvent(type, init) {
543 | if (!init) init = {};
544 | var e = document.createEvent('CustomEvent');
545 | e.initCustomEvent(type, !!init.bubbles, !!init.cancelable, init.detail);
546 | return e;
547 | }
548 | }('prototype');
549 | var CustomEvent$1 = self$3.CustomEvent;
550 |
551 | // able to create Custom Elements like components
552 | // including the ability to listen to connect/disconnect
553 | // events via onconnect/ondisconnect attributes
554 | // Components can be created imperatively or declaratively.
555 | // The main difference is that declared components
556 | // will not automatically render on setState(...)
557 | // to simplify state handling on render.
558 |
559 | function Component() {
560 | return this; // this is needed in Edge !!!
561 | } // Component is lazily setup because it needs
562 | // wire mechanism as lazy content
563 |
564 | function setup(content) {
565 | // there are various weakly referenced variables in here
566 | // and mostly are to use Component.for(...) static method.
567 | var children = new WeakMap$1();
568 | var create = Object.create;
569 |
570 | var createEntry = function createEntry(wm, id, component) {
571 | wm.set(id, component);
572 | return component;
573 | };
574 |
575 | var get = function get(Class, info, context, id) {
576 | var relation = info.get(Class) || relate(Class, info);
577 |
578 | switch (typeof(id)) {
579 | case 'object':
580 | case 'function':
581 | var wm = relation.w || (relation.w = new WeakMap$1());
582 | return wm.get(id) || createEntry(wm, id, new Class(context));
583 |
584 | default:
585 | var sm = relation.p || (relation.p = create(null));
586 | return sm[id] || (sm[id] = new Class(context));
587 | }
588 | };
589 |
590 | var relate = function relate(Class, info) {
591 | var relation = {
592 | w: null,
593 | p: null
594 | };
595 | info.set(Class, relation);
596 | return relation;
597 | };
598 |
599 | var set = function set(context) {
600 | var info = new Map$1();
601 | children.set(context, info);
602 | return info;
603 | }; // The Component Class
604 |
605 |
606 | Object.defineProperties(Component, {
607 | // Component.for(context[, id]) is a convenient way
608 | // to automatically relate data/context to children components
609 | // If not created yet, the new Component(context) is weakly stored
610 | // and after that same instance would always be returned.
611 | "for": {
612 | configurable: true,
613 | value: function value(context, id) {
614 | return get(this, children.get(context) || set(context), context, id == null ? 'default' : id);
615 | }
616 | }
617 | });
618 | Object.defineProperties(Component.prototype, {
619 | // all events are handled with the component as context
620 | handleEvent: {
621 | value: function value(e) {
622 | var ct = e.currentTarget;
623 | this['getAttribute' in ct && ct.getAttribute('data-call') || 'on' + e.type](e);
624 | }
625 | },
626 | // components will lazily define html or svg properties
627 | // as soon as these are invoked within the .render() method
628 | // Such render() method is not provided by the base class
629 | // but it must be available through the Component extend.
630 | // Declared components could implement a
631 | // render(props) method too and use props as needed.
632 | html: lazyGetter('html', content),
633 | svg: lazyGetter('svg', content),
634 | // the state is a very basic/simple mechanism inspired by Preact
635 | state: lazyGetter('state', function () {
636 | return this.defaultState;
637 | }),
638 | // it is possible to define a default state that'd be always an object otherwise
639 | defaultState: {
640 | get: function get() {
641 | return {};
642 | }
643 | },
644 | // dispatch a bubbling, cancelable, custom event
645 | // through the first known/available node
646 | dispatch: {
647 | value: function value(type, detail) {
648 | var _wire$ = this._wire$;
649 |
650 | if (_wire$) {
651 | var event = new CustomEvent$1(type, {
652 | bubbles: true,
653 | cancelable: true,
654 | detail: detail
655 | });
656 | event.component = this;
657 | return (_wire$.dispatchEvent ? _wire$ : _wire$.firstChild).dispatchEvent(event);
658 | }
659 |
660 | return false;
661 | }
662 | },
663 | // setting some property state through a new object
664 | // or a callback, triggers also automatically a render
665 | // unless explicitly specified to not do so (render === false)
666 | setState: {
667 | value: function value(state, render) {
668 | var target = this.state;
669 | var source = typeof state === 'function' ? state.call(this, target) : state;
670 |
671 | for (var key in source) {
672 | target[key] = source[key];
673 | }
674 |
675 | if (render !== false) this.render();
676 | return this;
677 | }
678 | }
679 | });
680 | } // instead of a secret key I could've used a WeakMap
681 | // However, attaching a property directly will result
682 | // into better performance with thousands of components
683 | // hanging around, and less memory pressure caused by the WeakMap
684 |
685 | var lazyGetter = function lazyGetter(type, fn) {
686 | var secret = '_' + type + '$';
687 | return {
688 | get: function get() {
689 | return this[secret] || setValue(this, secret, fn.call(this, type));
690 | },
691 | set: function set(value) {
692 | setValue(this, secret, value);
693 | }
694 | };
695 | }; // shortcut to set value on get or set(value)
696 |
697 |
698 | var setValue = function setValue(self, secret, value) {
699 | return Object.defineProperty(self, secret, {
700 | configurable: true,
701 | value: typeof value === 'function' ? function () {
702 | return self._wire$ = value.apply(this, arguments);
703 | } : value
704 | })[secret];
705 | };
706 |
707 | Object.defineProperties(Component.prototype, {
708 | // used to distinguish better than instanceof
709 | ELEMENT_NODE: {
710 | value: 1
711 | },
712 | nodeType: {
713 | value: -1
714 | }
715 | });
716 |
717 | var attributes = {};
718 | var intents = {};
719 | var keys = [];
720 | var hasOwnProperty = intents.hasOwnProperty;
721 | var length = 0;
722 | var Intent = {
723 | // used to invoke right away hyper:attributes
724 | attributes: attributes,
725 | // hyperHTML.define('intent', (object, update) => {...})
726 | // can be used to define a third parts update mechanism
727 | // when every other known mechanism failed.
728 | // hyper.define('user', info => info.name);
729 | // hyper(node)`
${{user}}
`;
730 | define: function define(intent, callback) {
731 | if (intent.indexOf('-') < 0) {
732 | if (!(intent in intents)) {
733 | length = keys.push(intent);
734 | }
735 |
736 | intents[intent] = callback;
737 | } else {
738 | attributes[intent] = callback;
739 | }
740 | },
741 | // this method is used internally as last resort
742 | // to retrieve a value out of an object
743 | invoke: function invoke(object, callback) {
744 | for (var i = 0; i < length; i++) {
745 | var key = keys[i];
746 |
747 | if (hasOwnProperty.call(object, key)) {
748 | return intents[key](object[key], callback);
749 | }
750 | }
751 | }
752 | };
753 |
754 | var isArray = Array.isArray || function (toString) {
755 | var $ = toString.call([]);
756 | return function isArray(object) {
757 | return toString.call(object) === $;
758 | };
759 | }({}.toString);
760 |
761 | /*! (c) Andrea Giammarchi - ISC */
762 | var createContent = function (document) {
763 |
764 | var FRAGMENT = 'fragment';
765 | var TEMPLATE = 'template';
766 | var HAS_CONTENT = ('content' in create(TEMPLATE));
767 | var createHTML = HAS_CONTENT ? function (html) {
768 | var template = create(TEMPLATE);
769 | template.innerHTML = html;
770 | return template.content;
771 | } : function (html) {
772 | var content = create(FRAGMENT);
773 | var template = create(TEMPLATE);
774 | var childNodes = null;
775 |
776 | if (/^[^\S]*?<(col(?:group)?|t(?:head|body|foot|r|d|h))/i.test(html)) {
777 | var selector = RegExp.$1;
778 | template.innerHTML = '';
779 | childNodes = template.querySelectorAll(selector);
780 | } else {
781 | template.innerHTML = html;
782 | childNodes = template.childNodes;
783 | }
784 |
785 | append(content, childNodes);
786 | return content;
787 | };
788 | return function createContent(markup, type) {
789 | return (type === 'svg' ? createSVG : createHTML)(markup);
790 | };
791 |
792 | function append(root, childNodes) {
793 | var length = childNodes.length;
794 |
795 | while (length--) {
796 | root.appendChild(childNodes[0]);
797 | }
798 | }
799 |
800 | function create(element) {
801 | return element === FRAGMENT ? document.createDocumentFragment() : document.createElementNS('http://www.w3.org/1999/xhtml', element);
802 | } // it could use createElementNS when hasNode is there
803 | // but this fallback is equally fast and easier to maintain
804 | // it is also battle tested already in all IE
805 |
806 |
807 | function createSVG(svg) {
808 | var content = create(FRAGMENT);
809 | var template = create('div');
810 | template.innerHTML = '';
811 | append(content, template.firstChild.childNodes);
812 | return content;
813 | }
814 | }(document);
815 |
816 | /*! (c) Andrea Giammarchi */
817 | function disconnected(poly) {
818 |
819 | var Event = poly.Event;
820 | var WeakSet = poly.WeakSet;
821 | var notObserving = true;
822 | var observer = null;
823 | return function observe(node) {
824 | if (notObserving) {
825 | notObserving = !notObserving;
826 | observer = new WeakSet();
827 | startObserving(node.ownerDocument);
828 | }
829 |
830 | observer.add(node);
831 | return node;
832 | };
833 |
834 | function startObserving(document) {
835 | var connected = new WeakSet();
836 | var disconnected = new WeakSet();
837 |
838 | try {
839 | new MutationObserver(changes).observe(document, {
840 | subtree: true,
841 | childList: true
842 | });
843 | } catch (o_O) {
844 | var timer = 0;
845 | var records = [];
846 |
847 | var reschedule = function reschedule(record) {
848 | records.push(record);
849 | clearTimeout(timer);
850 | timer = setTimeout(function () {
851 | changes(records.splice(timer = 0, records.length));
852 | }, 0);
853 | };
854 |
855 | document.addEventListener('DOMNodeRemoved', function (event) {
856 | reschedule({
857 | addedNodes: [],
858 | removedNodes: [event.target]
859 | });
860 | }, true);
861 | document.addEventListener('DOMNodeInserted', function (event) {
862 | reschedule({
863 | addedNodes: [event.target],
864 | removedNodes: []
865 | });
866 | }, true);
867 | }
868 |
869 | function changes(records) {
870 | for (var record, length = records.length, i = 0; i < length; i++) {
871 | record = records[i];
872 | dispatchAll(record.removedNodes, 'disconnected', disconnected, connected);
873 | dispatchAll(record.addedNodes, 'connected', connected, disconnected);
874 | }
875 | }
876 |
877 | function dispatchAll(nodes, type, wsin, wsout) {
878 | for (var node, event = new Event(type), length = nodes.length, i = 0; i < length; (node = nodes[i++]).nodeType === 1 && dispatchTarget(node, event, type, wsin, wsout)) {
879 | }
880 | }
881 |
882 | function dispatchTarget(node, event, type, wsin, wsout) {
883 | if (observer.has(node) && !wsin.has(node)) {
884 | wsout["delete"](node);
885 | wsin.add(node);
886 | node.dispatchEvent(event);
887 | /*
888 | // The event is not bubbling (perf reason: should it?),
889 | // hence there's no way to know if
890 | // stop/Immediate/Propagation() was called.
891 | // Should DOM Level 0 work at all?
892 | // I say it's a YAGNI case for the time being,
893 | // and easy to implement in user-land.
894 | if (!event.cancelBubble) {
895 | var fn = node['on' + type];
896 | if (fn)
897 | fn.call(node, event);
898 | }
899 | */
900 | }
901 |
902 | for (var // apparently is node.children || IE11 ... ^_^;;
903 | // https://github.com/WebReflection/disconnected/issues/1
904 | children = node.children || [], length = children.length, i = 0; i < length; dispatchTarget(children[i++], event, type, wsin, wsout)) {
905 | }
906 | }
907 | }
908 | }
909 |
910 | /*! (c) Andrea Giammarchi - ISC */
911 | var importNode = function (document, appendChild, cloneNode, createTextNode, importNode) {
912 | var _native = (importNode in document); // IE 11 has problems with cloning templates:
913 | // it "forgets" empty childNodes. This feature-detects that.
914 |
915 |
916 | var fragment = document.createDocumentFragment();
917 | fragment[appendChild](document[createTextNode]('g'));
918 | fragment[appendChild](document[createTextNode](''));
919 | var content = _native ? document[importNode](fragment, true) : fragment[cloneNode](true);
920 | return content.childNodes.length < 2 ? function importNode(node, deep) {
921 | var clone = node[cloneNode]();
922 |
923 | for (var childNodes = node.childNodes || [], length = childNodes.length, i = 0; deep && i < length; i++) {
924 | clone[appendChild](importNode(childNodes[i], deep));
925 | }
926 |
927 | return clone;
928 | } : _native ? document[importNode] : function (node, deep) {
929 | return node[cloneNode](!!deep);
930 | };
931 | }(document, 'appendChild', 'cloneNode', 'createTextNode', 'importNode');
932 |
933 | var trim = ''.trim || function () {
934 | return String(this).replace(/^\s+|\s+/g, '');
935 | };
936 |
937 | /*! (c) Andrea Giammarchi - ISC */
938 | // Custom
939 | var UID = '-' + Math.random().toFixed(6) + '%'; // Edge issue!
940 |
941 | var UID_IE = false;
942 |
943 | try {
944 | if (!function (template, content, tabindex) {
945 | return content in template && (template.innerHTML = '', template[content].childNodes[0].getAttribute(tabindex) == UID);
946 | }(document.createElement('template'), 'content', 'tabindex')) {
947 | UID = '_dt: ' + UID.slice(1, -1) + ';';
948 | UID_IE = true;
949 | }
950 | } catch (meh) {}
951 |
952 | var UIDC = ''; // DOM
953 |
954 | var COMMENT_NODE = 8;
955 | var ELEMENT_NODE = 1;
956 | var TEXT_NODE = 3;
957 | var SHOULD_USE_TEXT_CONTENT = /^(?:style|textarea)$/i;
958 | var VOID_ELEMENTS = /^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;
959 |
960 | /*! (c) Andrea Giammarchi - ISC */
961 | function sanitize (template) {
962 | return template.join(UIDC).replace(selfClosing, fullClosing).replace(attrSeeker, attrReplacer);
963 | }
964 | var spaces = ' \\f\\n\\r\\t';
965 | var almostEverything = '[^' + spaces + '\\/>"\'=]+';
966 | var attrName = '[' + spaces + ']+' + almostEverything;
967 | var tagName = '<([A-Za-z]+[A-Za-z0-9:._-]*)((?:';
968 | var attrPartials = '(?:\\s*=\\s*(?:\'[^\']*?\'|"[^"]*?"|<[^>]*?>|' + almostEverything.replace('\\/', '') + '))?)';
969 | var attrSeeker = new RegExp(tagName + attrName + attrPartials + '+)([' + spaces + ']*/?>)', 'g');
970 | var selfClosing = new RegExp(tagName + attrName + attrPartials + '*)([' + spaces + ']*/>)', 'g');
971 | var findAttributes = new RegExp('(' + attrName + '\\s*=\\s*)([\'"]?)' + UIDC + '\\2', 'gi');
972 |
973 | function attrReplacer($0, $1, $2, $3) {
974 | return '<' + $1 + $2.replace(findAttributes, replaceAttributes) + $3;
975 | }
976 |
977 | function replaceAttributes($0, $1, $2) {
978 | return $1 + ($2 || '"') + UID + ($2 || '"');
979 | }
980 |
981 | function fullClosing($0, $1, $2) {
982 | return VOID_ELEMENTS.test($1) ? $0 : '<' + $1 + $2 + '>' + $1 + '>';
983 | }
984 |
985 | var umap = (function (_) {
986 | return {
987 | // About: get: _.get.bind(_)
988 | // It looks like WebKit/Safari didn't optimize bind at all,
989 | // so that using bind slows it down by 60%.
990 | // Firefox and Chrome are just fine in both cases,
991 | // so let's use the approach that works fast everywhere 👍
992 | get: function get(key) {
993 | return _.get(key);
994 | },
995 | set: function set(key, value) {
996 | return _.set(key, value), value;
997 | }
998 | };
999 | });
1000 |
1001 | /* istanbul ignore next */
1002 |
1003 | var normalizeAttributes = UID_IE ? function (attributes, parts) {
1004 | var html = parts.join(' ');
1005 | return parts.slice.call(attributes, 0).sort(function (left, right) {
1006 | return html.indexOf(left.name) <= html.indexOf(right.name) ? -1 : 1;
1007 | });
1008 | } : function (attributes, parts) {
1009 | return parts.slice.call(attributes, 0);
1010 | };
1011 |
1012 | function find(node, path) {
1013 | var length = path.length;
1014 | var i = 0;
1015 |
1016 | while (i < length) {
1017 | node = node.childNodes[path[i++]];
1018 | }
1019 |
1020 | return node;
1021 | }
1022 |
1023 | function parse(node, holes, parts, path) {
1024 | var childNodes = node.childNodes;
1025 | var length = childNodes.length;
1026 | var i = 0;
1027 |
1028 | while (i < length) {
1029 | var child = childNodes[i];
1030 |
1031 | switch (child.nodeType) {
1032 | case ELEMENT_NODE:
1033 | var childPath = path.concat(i);
1034 | parseAttributes(child, holes, parts, childPath);
1035 | parse(child, holes, parts, childPath);
1036 | break;
1037 |
1038 | case COMMENT_NODE:
1039 | var textContent = child.textContent;
1040 |
1041 | if (textContent === UID) {
1042 | parts.shift();
1043 | holes.push( // basicHTML or other non standard engines
1044 | // might end up having comments in nodes
1045 | // where they shouldn't, hence this check.
1046 | SHOULD_USE_TEXT_CONTENT.test(node.nodeName) ? Text(node, path) : Any(child, path.concat(i)));
1047 | } else {
1048 | switch (textContent.slice(0, 2)) {
1049 | case '/*':
1050 | if (textContent.slice(-2) !== '*/') break;
1051 |
1052 | case "\uD83D\uDC7B":
1053 | // ghost
1054 | node.removeChild(child);
1055 | i--;
1056 | length--;
1057 | }
1058 | }
1059 |
1060 | break;
1061 |
1062 | case TEXT_NODE:
1063 | // the following ignore is actually covered by browsers
1064 | // only basicHTML ends up on previous COMMENT_NODE case
1065 | // instead of TEXT_NODE because it knows nothing about
1066 | // special style or textarea behavior
1067 |
1068 | /* istanbul ignore if */
1069 | if (SHOULD_USE_TEXT_CONTENT.test(node.nodeName) && trim.call(child.textContent) === UIDC) {
1070 | parts.shift();
1071 | holes.push(Text(node, path));
1072 | }
1073 |
1074 | break;
1075 | }
1076 |
1077 | i++;
1078 | }
1079 | }
1080 |
1081 | function parseAttributes(node, holes, parts, path) {
1082 | var attributes = node.attributes;
1083 | var cache = [];
1084 | var remove = [];
1085 | var array = normalizeAttributes(attributes, parts);
1086 | var length = array.length;
1087 | var i = 0;
1088 |
1089 | while (i < length) {
1090 | var attribute = array[i++];
1091 | var direct = attribute.value === UID;
1092 | var sparse;
1093 |
1094 | if (direct || 1 < (sparse = attribute.value.split(UIDC)).length) {
1095 | var name = attribute.name; // the following ignore is covered by IE
1096 | // and the IE9 double viewBox test
1097 |
1098 | /* istanbul ignore else */
1099 |
1100 | if (cache.indexOf(name) < 0) {
1101 | cache.push(name);
1102 | var realName = parts.shift().replace(direct ? /^(?:|[\S\s]*?\s)(\S+?)\s*=\s*('|")?$/ : new RegExp('^(?:|[\\S\\s]*?\\s)(' + name + ')\\s*=\\s*(\'|")[\\S\\s]*', 'i'), '$1');
1103 | var value = attributes[realName] || // the following ignore is covered by browsers
1104 | // while basicHTML is already case-sensitive
1105 |
1106 | /* istanbul ignore next */
1107 | attributes[realName.toLowerCase()];
1108 | if (direct) holes.push(Attr(value, path, realName, null));else {
1109 | var skip = sparse.length - 2;
1110 |
1111 | while (skip--) {
1112 | parts.shift();
1113 | }
1114 |
1115 | holes.push(Attr(value, path, realName, sparse));
1116 | }
1117 | }
1118 |
1119 | remove.push(attribute);
1120 | }
1121 | }
1122 |
1123 | length = remove.length;
1124 | i = 0;
1125 | /* istanbul ignore next */
1126 |
1127 | var cleanValue = 0 < length && UID_IE && !('ownerSVGElement' in node);
1128 |
1129 | while (i < length) {
1130 | // Edge HTML bug #16878726
1131 | var attr = remove[i++]; // IE/Edge bug lighterhtml#63 - clean the value or it'll persist
1132 |
1133 | /* istanbul ignore next */
1134 |
1135 | if (cleanValue) attr.value = ''; // IE/Edge bug lighterhtml#64 - don't use removeAttributeNode
1136 |
1137 | node.removeAttribute(attr.name);
1138 | } // This is a very specific Firefox/Safari issue
1139 | // but since it should be a not so common pattern,
1140 | // it's probably worth patching regardless.
1141 | // Basically, scripts created through strings are death.
1142 | // You need to create fresh new scripts instead.
1143 | // TODO: is there any other node that needs such nonsense?
1144 |
1145 |
1146 | var nodeName = node.nodeName;
1147 |
1148 | if (/^script$/i.test(nodeName)) {
1149 | // this used to be like that
1150 | // var script = createElement(node, nodeName);
1151 | // then Edge arrived and decided that scripts created
1152 | // through template documents aren't worth executing
1153 | // so it became this ... hopefully it won't hurt in the wild
1154 | var script = document.createElement(nodeName);
1155 | length = attributes.length;
1156 | i = 0;
1157 |
1158 | while (i < length) {
1159 | script.setAttributeNode(attributes[i++].cloneNode(true));
1160 | }
1161 |
1162 | script.textContent = node.textContent;
1163 | node.parentNode.replaceChild(script, node);
1164 | }
1165 | }
1166 |
1167 | function Any(node, path) {
1168 | return {
1169 | type: 'any',
1170 | node: node,
1171 | path: path
1172 | };
1173 | }
1174 |
1175 | function Attr(node, path, name, sparse) {
1176 | return {
1177 | type: 'attr',
1178 | node: node,
1179 | path: path,
1180 | name: name,
1181 | sparse: sparse
1182 | };
1183 | }
1184 |
1185 | function Text(node, path) {
1186 | return {
1187 | type: 'text',
1188 | node: node,
1189 | path: path
1190 | };
1191 | }
1192 |
1193 | // globals
1194 | var parsed = umap(new WeakMap$1());
1195 |
1196 | function createInfo(options, template) {
1197 | var markup = (options.convert || sanitize)(template);
1198 | var transform = options.transform;
1199 | if (transform) markup = transform(markup);
1200 | var content = createContent(markup, options.type);
1201 | cleanContent(content);
1202 | var holes = [];
1203 | parse(content, holes, template.slice(0), []);
1204 | return {
1205 | content: content,
1206 | updates: function updates(content) {
1207 | var updates = [];
1208 | var len = holes.length;
1209 | var i = 0;
1210 | var off = 0;
1211 |
1212 | while (i < len) {
1213 | var info = holes[i++];
1214 | var node = find(content, info.path);
1215 |
1216 | switch (info.type) {
1217 | case 'any':
1218 | updates.push({
1219 | fn: options.any(node, []),
1220 | sparse: false
1221 | });
1222 | break;
1223 |
1224 | case 'attr':
1225 | var sparse = info.sparse;
1226 | var fn = options.attribute(node, info.name, info.node);
1227 | if (sparse === null) updates.push({
1228 | fn: fn,
1229 | sparse: false
1230 | });else {
1231 | off += sparse.length - 2;
1232 | updates.push({
1233 | fn: fn,
1234 | sparse: true,
1235 | values: sparse
1236 | });
1237 | }
1238 | break;
1239 |
1240 | case 'text':
1241 | updates.push({
1242 | fn: options.text(node),
1243 | sparse: false
1244 | });
1245 | node.textContent = '';
1246 | break;
1247 | }
1248 | }
1249 |
1250 | len += off;
1251 | return function () {
1252 | var length = arguments.length;
1253 |
1254 | if (len !== length - 1) {
1255 | throw new Error(length - 1 + ' values instead of ' + len + '\n' + template.join('${value}'));
1256 | }
1257 |
1258 | var i = 1;
1259 | var off = 1;
1260 |
1261 | while (i < length) {
1262 | var update = updates[i - off];
1263 |
1264 | if (update.sparse) {
1265 | var values = update.values;
1266 | var value = values[0];
1267 | var j = 1;
1268 | var l = values.length;
1269 | off += l - 2;
1270 |
1271 | while (j < l) {
1272 | value += arguments[i++] + values[j++];
1273 | }
1274 |
1275 | update.fn(value);
1276 | } else update.fn(arguments[i++]);
1277 | }
1278 |
1279 | return content;
1280 | };
1281 | }
1282 | };
1283 | }
1284 |
1285 | function createDetails(options, template) {
1286 | var info = parsed.get(template) || parsed.set(template, createInfo(options, template));
1287 | return info.updates(importNode.call(document, info.content, true));
1288 | }
1289 |
1290 | var empty = [];
1291 |
1292 | function domtagger(options) {
1293 | var previous = empty;
1294 | var updates = cleanContent;
1295 | return function (template) {
1296 | if (previous !== template) updates = createDetails(options, previous = template);
1297 | return updates.apply(null, arguments);
1298 | };
1299 | }
1300 |
1301 | function cleanContent(fragment) {
1302 | var childNodes = fragment.childNodes;
1303 | var i = childNodes.length;
1304 |
1305 | while (i--) {
1306 | var child = childNodes[i];
1307 |
1308 | if (child.nodeType !== 1 && trim.call(child.textContent).length === 0) {
1309 | fragment.removeChild(child);
1310 | }
1311 | }
1312 | }
1313 |
1314 | /*! (c) Andrea Giammarchi - ISC */
1315 | var hyperStyle = function () {
1316 |
1317 | var IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i;
1318 | var hyphen = /([^A-Z])([A-Z]+)/g;
1319 | return function hyperStyle(node, original) {
1320 | return 'ownerSVGElement' in node ? svg(node, original) : update(node.style, false);
1321 | };
1322 |
1323 | function ized($0, $1, $2) {
1324 | return $1 + '-' + $2.toLowerCase();
1325 | }
1326 |
1327 | function svg(node, original) {
1328 | var style;
1329 | if (original) style = original.cloneNode(true);else {
1330 | node.setAttribute('style', '--hyper:style;');
1331 | style = node.getAttributeNode('style');
1332 | }
1333 | style.value = '';
1334 | node.setAttributeNode(style);
1335 | return update(style, true);
1336 | }
1337 |
1338 | function toStyle(object) {
1339 | var key,
1340 | css = [];
1341 |
1342 | for (key in object) {
1343 | css.push(key.replace(hyphen, ized), ':', object[key], ';');
1344 | }
1345 |
1346 | return css.join('');
1347 | }
1348 |
1349 | function update(style, isSVG) {
1350 | var oldType, oldValue;
1351 | return function (newValue) {
1352 | var info, key, styleValue, value;
1353 |
1354 | switch (typeof(newValue)) {
1355 | case 'object':
1356 | if (newValue) {
1357 | if (oldType === 'object') {
1358 | if (!isSVG) {
1359 | if (oldValue !== newValue) {
1360 | for (key in oldValue) {
1361 | if (!(key in newValue)) {
1362 | style[key] = '';
1363 | }
1364 | }
1365 | }
1366 | }
1367 | } else {
1368 | if (isSVG) style.value = '';else style.cssText = '';
1369 | }
1370 |
1371 | info = isSVG ? {} : style;
1372 |
1373 | for (key in newValue) {
1374 | value = newValue[key];
1375 | styleValue = typeof value === 'number' && !IS_NON_DIMENSIONAL.test(key) ? value + 'px' : value;
1376 | if (!isSVG && /^--/.test(key)) info.setProperty(key, styleValue);else info[key] = styleValue;
1377 | }
1378 |
1379 | oldType = 'object';
1380 | if (isSVG) style.value = toStyle(oldValue = info);else oldValue = newValue;
1381 | break;
1382 | }
1383 |
1384 | default:
1385 | if (oldValue != newValue) {
1386 | oldType = 'string';
1387 | oldValue = newValue;
1388 | if (isSVG) style.value = newValue || '';else style.cssText = newValue || '';
1389 | }
1390 |
1391 | break;
1392 | }
1393 | };
1394 | }
1395 | }();
1396 |
1397 | /*! (c) Andrea Giammarchi - ISC */
1398 | var Wire = function (slice, proto) {
1399 | proto = Wire.prototype;
1400 | proto.ELEMENT_NODE = 1;
1401 | proto.nodeType = 111;
1402 |
1403 | proto.remove = function (keepFirst) {
1404 | var childNodes = this.childNodes;
1405 | var first = this.firstChild;
1406 | var last = this.lastChild;
1407 | this._ = null;
1408 |
1409 | if (keepFirst && childNodes.length === 2) {
1410 | last.parentNode.removeChild(last);
1411 | } else {
1412 | var range = this.ownerDocument.createRange();
1413 | range.setStartBefore(keepFirst ? childNodes[1] : first);
1414 | range.setEndAfter(last);
1415 | range.deleteContents();
1416 | }
1417 |
1418 | return first;
1419 | };
1420 |
1421 | proto.valueOf = function (forceAppend) {
1422 | var fragment = this._;
1423 | var noFragment = fragment == null;
1424 | if (noFragment) fragment = this._ = this.ownerDocument.createDocumentFragment();
1425 |
1426 | if (noFragment || forceAppend) {
1427 | for (var n = this.childNodes, i = 0, l = n.length; i < l; i++) {
1428 | fragment.appendChild(n[i]);
1429 | }
1430 | }
1431 |
1432 | return fragment;
1433 | };
1434 |
1435 | return Wire;
1436 |
1437 | function Wire(childNodes) {
1438 | var nodes = this.childNodes = slice.call(childNodes, 0);
1439 | this.firstChild = nodes[0];
1440 | this.lastChild = nodes[nodes.length - 1];
1441 | this.ownerDocument = nodes[0].ownerDocument;
1442 | this._ = null;
1443 | }
1444 | }([].slice);
1445 |
1446 | // Node.CONSTANTS
1447 | var DOCUMENT_FRAGMENT_NODE = 11; // SVG related constants
1448 |
1449 | var OWNER_SVG_ELEMENT = 'ownerSVGElement'; // Custom Elements / MutationObserver constants
1450 |
1451 | var CONNECTED = 'connected';
1452 | var DISCONNECTED = 'dis' + CONNECTED;
1453 |
1454 | var componentType = Component.prototype.nodeType;
1455 | var wireType = Wire.prototype.nodeType;
1456 | var observe = disconnected({
1457 | Event: CustomEvent$1,
1458 | WeakSet: WeakSet$1
1459 | });
1460 |
1461 | var asHTML = function asHTML(html) {
1462 | return {
1463 | html: html
1464 | };
1465 | }; // returns nodes from wires and components
1466 |
1467 |
1468 | var asNode = function asNode(item, i) {
1469 | switch (item.nodeType) {
1470 | case wireType:
1471 | // in the Wire case, the content can be
1472 | // removed, post-pended, inserted, or pre-pended and
1473 | // all these cases are handled by domdiff already
1474 |
1475 | /* istanbul ignore next */
1476 | return 1 / i < 0 ? i ? item.remove(true) : item.lastChild : i ? item.valueOf(true) : item.firstChild;
1477 |
1478 | case componentType:
1479 | return asNode(item.render(), i);
1480 |
1481 | default:
1482 | return item;
1483 | }
1484 | }; // returns true if domdiff can handle the value
1485 |
1486 |
1487 | var canDiff = function canDiff(value) {
1488 | return 'ELEMENT_NODE' in value;
1489 | };
1490 |
1491 | var hyperSetter = function hyperSetter(node, name, svg) {
1492 | return svg ? function (value) {
1493 | try {
1494 | node[name] = value;
1495 | } catch (nope) {
1496 | node.setAttribute(name, value);
1497 | }
1498 | } : function (value) {
1499 | node[name] = value;
1500 | };
1501 | }; // when a Promise is used as interpolation value
1502 | // its result must be parsed once resolved.
1503 | // This callback is in charge of understanding what to do
1504 | // with a returned value once the promise is resolved.
1505 |
1506 |
1507 | var invokeAtDistance = function invokeAtDistance(value, callback) {
1508 | callback(value.placeholder);
1509 |
1510 | if ('text' in value) {
1511 | Promise.resolve(value.text).then(String).then(callback);
1512 | } else if ('any' in value) {
1513 | Promise.resolve(value.any).then(callback);
1514 | } else if ('html' in value) {
1515 | Promise.resolve(value.html).then(asHTML).then(callback);
1516 | } else {
1517 | Promise.resolve(Intent.invoke(value, callback)).then(callback);
1518 | }
1519 | }; // quick and dirty way to check for Promise/ish values
1520 |
1521 |
1522 | var isPromise_ish = function isPromise_ish(value) {
1523 | return value != null && 'then' in value;
1524 | }; // list of attributes that should not be directly assigned
1525 |
1526 |
1527 | var readOnly = /^(?:form|list)$/i; // reused every slice time
1528 |
1529 | var slice = [].slice; // simplifies text node creation
1530 |
1531 | var text = function text(node, _text) {
1532 | return node.ownerDocument.createTextNode(_text);
1533 | };
1534 |
1535 | function Tagger(type) {
1536 | this.type = type;
1537 | return domtagger(this);
1538 | }
1539 |
1540 | Tagger.prototype = {
1541 | // there are four kind of attributes, and related behavior:
1542 | // * events, with a name starting with `on`, to add/remove event listeners
1543 | // * special, with a name present in their inherited prototype, accessed directly
1544 | // * regular, accessed through get/setAttribute standard DOM methods
1545 | // * style, the only regular attribute that also accepts an object as value
1546 | // so that you can style=${{width: 120}}. In this case, the behavior has been
1547 | // fully inspired by Preact library and its simplicity.
1548 | attribute: function attribute(node, name, original) {
1549 | var isSVG = (OWNER_SVG_ELEMENT in node);
1550 | var oldValue; // if the attribute is the style one
1551 | // handle it differently from others
1552 |
1553 | if (name === 'style') return hyperStyle(node, original, isSVG); // direct accessors for and friends
1554 | else if (name.slice(0, 1) === '.') return hyperSetter(node, name.slice(1), isSVG); // the name is an event one,
1555 | // add/remove event listeners accordingly
1556 | else if (/^on/.test(name)) {
1557 | var type = name.slice(2);
1558 |
1559 | if (type === CONNECTED || type === DISCONNECTED) {
1560 | observe(node);
1561 | } else if (name.toLowerCase() in node) {
1562 | type = type.toLowerCase();
1563 | }
1564 |
1565 | return function (newValue) {
1566 | if (oldValue !== newValue) {
1567 | if (oldValue) node.removeEventListener(type, oldValue, false);
1568 | oldValue = newValue;
1569 | if (newValue) node.addEventListener(type, newValue, false);
1570 | }
1571 | };
1572 | } // the attribute is special ('value' in input)
1573 | // and it's not SVG *or* the name is exactly data,
1574 | // in this case assign the value directly
1575 | else if (name === 'data' || !isSVG && name in node && !readOnly.test(name)) {
1576 | return function (newValue) {
1577 | if (oldValue !== newValue) {
1578 | oldValue = newValue;
1579 |
1580 | if (node[name] !== newValue && newValue == null) {
1581 | // cleanup on null to avoid silly IE/Edge bug
1582 | node[name] = '';
1583 | node.removeAttribute(name);
1584 | } else node[name] = newValue;
1585 | }
1586 | };
1587 | } else if (name in Intent.attributes) {
1588 | return function (any) {
1589 | var newValue = Intent.attributes[name](node, any);
1590 |
1591 | if (oldValue !== newValue) {
1592 | oldValue = newValue;
1593 | if (newValue == null) node.removeAttribute(name);else node.setAttribute(name, newValue);
1594 | }
1595 | };
1596 | } // in every other case, use the attribute node as it is
1597 | // update only the value, set it as node only when/if needed
1598 | else {
1599 | var owner = false;
1600 | var attribute = original.cloneNode(true);
1601 | return function (newValue) {
1602 | if (oldValue !== newValue) {
1603 | oldValue = newValue;
1604 |
1605 | if (attribute.value !== newValue) {
1606 | if (newValue == null) {
1607 | if (owner) {
1608 | owner = false;
1609 | node.removeAttributeNode(attribute);
1610 | }
1611 |
1612 | attribute.value = newValue;
1613 | } else {
1614 | attribute.value = newValue;
1615 |
1616 | if (!owner) {
1617 | owner = true;
1618 | node.setAttributeNode(attribute);
1619 | }
1620 | }
1621 | }
1622 | }
1623 | };
1624 | }
1625 | },
1626 | // in a hyper(node)`${content}
` case
1627 | // everything could happen:
1628 | // * it's a JS primitive, stored as text
1629 | // * it's null or undefined, the node should be cleaned
1630 | // * it's a component, update the content by rendering it
1631 | // * it's a promise, update the content once resolved
1632 | // * it's an explicit intent, perform the desired operation
1633 | // * it's an Array, resolve all values if Promises and/or
1634 | // update the node with the resulting list of content
1635 | any: function any(node, childNodes) {
1636 | var diffOptions = {
1637 | node: asNode,
1638 | before: node
1639 | };
1640 | var nodeType = OWNER_SVG_ELEMENT in node ?
1641 | /* istanbul ignore next */
1642 | 'svg' : 'html';
1643 | var fastPath = false;
1644 | var oldValue;
1645 |
1646 | var anyContent = function anyContent(value) {
1647 | switch (typeof(value)) {
1648 | case 'string':
1649 | case 'number':
1650 | case 'boolean':
1651 | if (fastPath) {
1652 | if (oldValue !== value) {
1653 | oldValue = value;
1654 | childNodes[0].textContent = value;
1655 | }
1656 | } else {
1657 | fastPath = true;
1658 | oldValue = value;
1659 | childNodes = domdiff(node.parentNode, childNodes, [text(node, value)], diffOptions);
1660 | }
1661 |
1662 | break;
1663 |
1664 | case 'function':
1665 | anyContent(value(node));
1666 | break;
1667 |
1668 | case 'object':
1669 | case 'undefined':
1670 | if (value == null) {
1671 | fastPath = false;
1672 | childNodes = domdiff(node.parentNode, childNodes, [], diffOptions);
1673 | break;
1674 | }
1675 |
1676 | default:
1677 | fastPath = false;
1678 | oldValue = value;
1679 |
1680 | if (isArray(value)) {
1681 | if (value.length === 0) {
1682 | if (childNodes.length) {
1683 | childNodes = domdiff(node.parentNode, childNodes, [], diffOptions);
1684 | }
1685 | } else {
1686 | switch (typeof(value[0])) {
1687 | case 'string':
1688 | case 'number':
1689 | case 'boolean':
1690 | anyContent({
1691 | html: value
1692 | });
1693 | break;
1694 |
1695 | case 'object':
1696 | if (isArray(value[0])) {
1697 | value = value.concat.apply([], value);
1698 | }
1699 |
1700 | if (isPromise_ish(value[0])) {
1701 | Promise.all(value).then(anyContent);
1702 | break;
1703 | }
1704 |
1705 | default:
1706 | childNodes = domdiff(node.parentNode, childNodes, value, diffOptions);
1707 | break;
1708 | }
1709 | }
1710 | } else if (canDiff(value)) {
1711 | childNodes = domdiff(node.parentNode, childNodes, value.nodeType === DOCUMENT_FRAGMENT_NODE ? slice.call(value.childNodes) : [value], diffOptions);
1712 | } else if (isPromise_ish(value)) {
1713 | value.then(anyContent);
1714 | } else if ('placeholder' in value) {
1715 | invokeAtDistance(value, anyContent);
1716 | } else if ('text' in value) {
1717 | anyContent(String(value.text));
1718 | } else if ('any' in value) {
1719 | anyContent(value.any);
1720 | } else if ('html' in value) {
1721 | childNodes = domdiff(node.parentNode, childNodes, slice.call(createContent([].concat(value.html).join(''), nodeType).childNodes), diffOptions);
1722 | } else if ('length' in value) {
1723 | anyContent(slice.call(value));
1724 | } else {
1725 | anyContent(Intent.invoke(value, anyContent));
1726 | }
1727 |
1728 | break;
1729 | }
1730 | };
1731 |
1732 | return anyContent;
1733 | },
1734 | // style or textareas don't accept HTML as content
1735 | // it's pointless to transform or analyze anything
1736 | // different from text there but it's worth checking
1737 | // for possible defined intents.
1738 | text: function text(node) {
1739 | var oldValue;
1740 |
1741 | var textContent = function textContent(value) {
1742 | if (oldValue !== value) {
1743 | oldValue = value;
1744 |
1745 | var type = typeof(value);
1746 |
1747 | if (type === 'object' && value) {
1748 | if (isPromise_ish(value)) {
1749 | value.then(textContent);
1750 | } else if ('placeholder' in value) {
1751 | invokeAtDistance(value, textContent);
1752 | } else if ('text' in value) {
1753 | textContent(String(value.text));
1754 | } else if ('any' in value) {
1755 | textContent(value.any);
1756 | } else if ('html' in value) {
1757 | textContent([].concat(value.html).join(''));
1758 | } else if ('length' in value) {
1759 | textContent(slice.call(value).join(''));
1760 | } else {
1761 | textContent(Intent.invoke(value, textContent));
1762 | }
1763 | } else if (type === 'function') {
1764 | textContent(value(node));
1765 | } else {
1766 | node.textContent = value == null ? '' : value;
1767 | }
1768 | }
1769 | };
1770 |
1771 | return textContent;
1772 | }
1773 | };
1774 |
1775 | var isNoOp = (typeof document === "undefined" ? "undefined" : typeof(document)) !== 'object';
1776 |
1777 | var _templateLiteral = function templateLiteral(tl) {
1778 | var RAW = 'raw';
1779 |
1780 | var isBroken = function isBroken(UA) {
1781 | return /(Firefox|Safari)\/(\d+)/.test(UA) && !/(Chrom[eium]+|Android)\/(\d+)/.test(UA);
1782 | };
1783 |
1784 | var broken = isBroken((document.defaultView.navigator || {}).userAgent);
1785 | var FTS = !(RAW in tl) || tl.propertyIsEnumerable(RAW) || !Object.isFrozen(tl[RAW]);
1786 |
1787 | if (broken || FTS) {
1788 | var forever = {};
1789 |
1790 | var foreverCache = function foreverCache(tl) {
1791 | for (var key = '.', i = 0; i < tl.length; i++) {
1792 | key += tl[i].length + '.' + tl[i];
1793 | }
1794 |
1795 | return forever[key] || (forever[key] = tl);
1796 | }; // Fallback TypeScript shenanigans
1797 |
1798 |
1799 | if (FTS) _templateLiteral = foreverCache; // try fast path for other browsers:
1800 | // store the template as WeakMap key
1801 | // and forever cache it only when it's not there.
1802 | // this way performance is still optimal,
1803 | // penalized only when there are GC issues
1804 | else {
1805 | var wm = new WeakMap$1();
1806 |
1807 | var set = function set(tl, unique) {
1808 | wm.set(tl, unique);
1809 | return unique;
1810 | };
1811 |
1812 | _templateLiteral = function templateLiteral(tl) {
1813 | return wm.get(tl) || set(tl, foreverCache(tl));
1814 | };
1815 | }
1816 | } else {
1817 | isNoOp = true;
1818 | }
1819 |
1820 | return TL(tl);
1821 | };
1822 |
1823 | function TL(tl) {
1824 | return isNoOp ? tl : _templateLiteral(tl);
1825 | }
1826 |
1827 | function tta (template) {
1828 | var length = arguments.length;
1829 | var args = [TL(template)];
1830 | var i = 1;
1831 |
1832 | while (i < length) {
1833 | args.push(arguments[i++]);
1834 | }
1835 |
1836 | return args;
1837 | }
1838 |
1839 | var wires = new WeakMap$1(); // A wire is a callback used as tag function
1840 | // to lazily relate a generic object to a template literal.
1841 | // hyper.wire(user)`${user.name}
`; => the div#user
1842 | // This provides the ability to have a unique DOM structure
1843 | // related to a unique JS object through a reusable template literal.
1844 | // A wire can specify a type, as svg or html, and also an id
1845 | // via html:id or :id convention. Such :id allows same JS objects
1846 | // to be associated to different DOM structures accordingly with
1847 | // the used template literal without losing previously rendered parts.
1848 |
1849 | var wire = function wire(obj, type) {
1850 | return obj == null ? content(type || 'html') : weakly(obj, type || 'html');
1851 | }; // A wire content is a virtual reference to one or more nodes.
1852 | // It's represented by either a DOM node, or an Array.
1853 | // In both cases, the wire content role is to simply update
1854 | // all nodes through the list of related callbacks.
1855 | // In few words, a wire content is like an invisible parent node
1856 | // in charge of updating its content like a bound element would do.
1857 |
1858 |
1859 | var content = function content(type) {
1860 | var wire, tagger, template;
1861 | return function () {
1862 | var args = tta.apply(null, arguments);
1863 |
1864 | if (template !== args[0]) {
1865 | template = args[0];
1866 | tagger = new Tagger(type);
1867 | wire = wireContent(tagger.apply(tagger, args));
1868 | } else {
1869 | tagger.apply(tagger, args);
1870 | }
1871 |
1872 | return wire;
1873 | };
1874 | }; // wires are weakly created through objects.
1875 | // Each object can have multiple wires associated
1876 | // and this is thanks to the type + :id feature.
1877 |
1878 |
1879 | var weakly = function weakly(obj, type) {
1880 | var i = type.indexOf(':');
1881 | var wire = wires.get(obj);
1882 | var id = type;
1883 |
1884 | if (-1 < i) {
1885 | id = type.slice(i + 1);
1886 | type = type.slice(0, i) || 'html';
1887 | }
1888 |
1889 | if (!wire) wires.set(obj, wire = {});
1890 | return wire[id] || (wire[id] = content(type));
1891 | }; // A document fragment loses its nodes
1892 | // as soon as it is appended into another node.
1893 | // This has the undesired effect of losing wired content
1894 | // on a second render call, because (by then) the fragment would be empty:
1895 | // no longer providing access to those sub-nodes that ultimately need to
1896 | // stay associated with the original interpolation.
1897 | // To prevent hyperHTML from forgetting about a fragment's sub-nodes,
1898 | // fragments are instead returned as an Array of nodes or, if there's only one entry,
1899 | // as a single referenced node which, unlike fragments, will indeed persist
1900 | // wire content throughout multiple renderings.
1901 | // The initial fragment, at this point, would be used as unique reference to this
1902 | // array of nodes or to this single referenced node.
1903 |
1904 |
1905 | var wireContent = function wireContent(node) {
1906 | var childNodes = node.childNodes;
1907 | var length = childNodes.length;
1908 | return length === 1 ? childNodes[0] : length ? new Wire(childNodes) : node;
1909 | };
1910 |
1911 | // are already known to hyperHTML
1912 |
1913 | var bewitched = new WeakMap$1(); // better known as hyper.bind(node), the render is
1914 |
1915 | /*! (c) Andrea Giammarchi (ISC) */
1916 |
1917 | var define = Intent.define;
1918 | // html or svg property of each hyper.Component
1919 |
1920 | setup(content); // everything is exported directly or through the
1921 |
1922 | var defineProperty = Object.defineProperty;
1923 | var gOPD = Object.getOwnPropertyDescriptor;
1924 | var keys$1 = Object.keys;
1925 | var hOP = {}.hasOwnProperty;
1926 | var slice$1 = [].slice;
1927 | var wired = {
1928 | id: 0,
1929 | model: null
1930 | }; // hyper utilities
1931 | function html() {
1932 | return wire(wired.model, 'html:' + wired.id).apply(null, arguments);
1933 | }
1934 | function svg() {
1935 | return wire(wired.model, 'svg:' + wired.id).apply(null, arguments);
1936 | }
1937 |
1938 | function augment(model, update) {
1939 | keys$1(model).forEach(function (key) {
1940 | var value,
1941 | desc = gOPD(model, key);
1942 |
1943 | if (desc.configurable) {
1944 | if ('value' in desc) {
1945 | value = bound(desc.value, model);
1946 | defineProperty(model, key, {
1947 | configurable: true,
1948 | enumerable: true,
1949 | get: function get() {
1950 | return value;
1951 | },
1952 | set: function set($) {
1953 | value = bound($, model);
1954 | update(model);
1955 | }
1956 | });
1957 | } else if ('set' in desc) {
1958 | value = desc.set;
1959 |
1960 | desc.set = function ($) {
1961 | value.call(model, $);
1962 | update(model);
1963 | };
1964 |
1965 | defineProperty(model, key, desc);
1966 | }
1967 | }
1968 | });
1969 | }
1970 | function merge(model, changes) {
1971 | for (var key in changes) {
1972 | if (hOP.call(changes, key)) {
1973 | var has = hOP.call(model, key);
1974 | var curr = changes[key];
1975 | var prev = has ? model[key] : null;
1976 | if (has && curr !== null && typeof(curr) === "object") merge(prev, curr);else if (!has || curr !== prev) model[key] = curr;
1977 | }
1978 | }
1979 | }
1980 | function refresh(model, Component, id, args) {
1981 | var wid = wired.id;
1982 | var wmodel = wired.model;
1983 | wired.id = id;
1984 | wired.model = model;
1985 |
1986 | try {
1987 | return Component.apply(null, args);
1988 | } finally {
1989 | wired.id = wid;
1990 | wired.model = wmodel;
1991 | }
1992 | }
1993 | function same(node, i) {
1994 | return this[i] === node[i];
1995 | }
1996 |
1997 | function bound(value, model) {
1998 | return typeof value === 'function' ? value.bind(model) : value;
1999 | }
2000 |
2001 | /**
2002 | * Copyright (C) 2017-present by Andrea Giammarchi - @WebReflection
2003 | *
2004 | * Permission is hereby granted, free of charge, to any person obtaining a copy
2005 | * of this software and associated documentation files (the "Software"), to deal
2006 | * in the Software without restriction, including without limitation the rights
2007 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2008 | * copies of the Software, and to permit persons to whom the Software is
2009 | * furnished to do so, subject to the following conditions:
2010 | *
2011 | * The above copyright notice and this permission notice shall be included in
2012 | * all copies or substantial portions of the Software.
2013 | *
2014 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2015 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2016 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2017 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2018 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2019 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2020 | * THE SOFTWARE.
2021 | */
2022 | var replace = ''.replace;
2023 | var ca = /[&<>'"]/g;
2024 | var es = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
2025 | var esca = {
2026 | '&': '&',
2027 | '<': '<',
2028 | '>': '>',
2029 | "'": ''',
2030 | '"': '"'
2031 | };
2032 | var unes = {
2033 | '&': '&',
2034 | '&': '&',
2035 | '<': '<',
2036 | '<': '<',
2037 | '>': '>',
2038 | '>': '>',
2039 | ''': "'",
2040 | ''': "'",
2041 | '"': '"',
2042 | '"': '"'
2043 | };
2044 | function escape(es) {
2045 | return replace.call(es, ca, pe);
2046 | }
2047 | function unescape(un) {
2048 | return replace.call(un, es, cape);
2049 | }
2050 |
2051 | function pe(m) {
2052 | return esca[m];
2053 | }
2054 |
2055 | function cape(m) {
2056 | return unes[m];
2057 | }
2058 |
2059 | var comps = new WeakMap$1();
2060 | var param = new WeakMap$1();
2061 | var store = new WeakMap$1();
2062 | var ids = 0;
2063 | var sync = true;
2064 | function comp(Component) {
2065 | var id = ++ids;
2066 | comps.set(component, id);
2067 | return component;
2068 |
2069 | function component(model) {
2070 | var mod = model || {};
2071 | var map = store.get(mod) || setMap(mod);
2072 | return updateComponent.call(mod, map.get(component) || setInfo(map, component, Component, id, slice$1.call(arguments, 0)));
2073 | }
2074 | }
2075 | function render(where, comp) {
2076 | var content = comps.has(comp) ? comp(param.get(where) || setParam(where)) : comp();
2077 | var isElement = content.nodeType === 1;
2078 |
2079 | if (!(isElement && where.firstChild === content || !isElement && content.childNodes.every(same, where.childNodes))) {
2080 | where.textContent = '';
2081 | where.appendChild(content.valueOf(true));
2082 | }
2083 |
2084 | return where;
2085 | }
2086 | function update(model, changes) {
2087 | var map = store.get(model);
2088 | if (!map) throw new Error('unknown model');
2089 | sync = false;
2090 |
2091 | try {
2092 | merge(model, changes || {});
2093 | } finally {
2094 | sync = true;
2095 | map.forEach(updateComponent, model);
2096 | }
2097 | }
2098 |
2099 | function setInfo(map, comp, Component, id, args) {
2100 | var info = {
2101 | Component: Component,
2102 | id: id,
2103 | args: args
2104 | };
2105 | map.set(comp, info);
2106 | return info;
2107 | }
2108 |
2109 | function setMap(model) {
2110 | var map = new Map$1();
2111 | store.set(model, map);
2112 | augment(model, updateAll);
2113 | return map;
2114 | }
2115 |
2116 | function setParam(where) {
2117 | var model = {};
2118 | param.set(where, model);
2119 | return model;
2120 | }
2121 |
2122 | function updateAll(model) {
2123 | if (sync) store.get(model).forEach(updateComponent, model);
2124 | }
2125 |
2126 | function updateComponent(info) {
2127 | return refresh(this, info.Component, info.id, info.args);
2128 | }
2129 |
2130 | exports.comp = comp;
2131 | exports.define = define;
2132 | exports.escape = escape;
2133 | exports.html = html;
2134 | exports.render = render;
2135 | exports.svg = svg;
2136 | exports.unescape = unescape;
2137 | exports.update = update;
2138 |
2139 | return exports;
2140 |
2141 | }({}));
2142 |
--------------------------------------------------------------------------------
/min.js:
--------------------------------------------------------------------------------
1 | /*! (c) Andrea Giammarchi - ISC */
2 | var hypersimple=function(e){"use strict";var t={};try{t.WeakMap=WeakMap}catch(e){t.WeakMap=function(t,e){var n=e.defineProperty,r=e.hasOwnProperty,i=o.prototype;return i.delete=function(e){return this.has(e)&&delete e[this._]},i.get=function(e){return this.has(e)?e[this._]:void 0},i.has=function(e){return r.call(e,this._)},i.set=function(e,t){return n(e,this._,{configurable:!0,value:t}),this},o;function o(e){n(this,"_",{value:"_@ungap/weakmap"+t++}),e&&e.forEach(a,this)}function a(e){this.set(e[0],e[1])}}(Math.random(),Object)}var s=t.WeakMap,n={};try{n.Map=Map}catch(e){n.Map=function(){var n=0,i=[],o=[];return{delete:function(e){var t=r(e);return t&&(i.splice(n,1),o.splice(n,1)),t},forEach:function(n,r){i.forEach(function(e,t){n.call(r,o[t],e,this)},this)},get:function(e){return r(e)?o[n]:void 0},has:function(e){return r(e)},set:function(e,t){return o[r(e)?n:i.push(e)-1]=t,this}};function r(e){return-1<(n=i.indexOf(e))}}}var v=n.Map,i={};try{i.WeakSet=WeakSet}catch(e){!function(e,t){var n=r.prototype;function r(){t(this,"_",{value:"_@ungap/weakmap"+e++})}n.add=function(e){return this.has(e)||t(e,this._,{value:!0,configurable:!0}),this},n.has=function(e){return this.hasOwnProperty.call(e,this._)},n.delete=function(e){return this.has(e)&&delete e[this._]},i.WeakSet=r}(Math.random(),Object.defineProperty)}function g(e,t,n,r,i,o){for(var a=("selectedIndex"in t),u=a;ra;)--c;l=u+r-c;var g=Array(l),y=s[c];for(--n;y;){for(var b=y.newi,w=y.oldi;b>>0;n"+e+"",r=n.querySelectorAll(i)}else n.innerHTML=e,r=n.childNodes;return F(t,r),t},function(e,t){return("svg"===t?function(e){var t=q(S),n=q("div");return n.innerHTML='",F(t,n.firstChild.childNodes),t}:T)(e)});function F(e,t){for(var n=t.length;n--;)e.appendChild(t[0])}function q(e){return e===S?A.createDocumentFragment():A.createElementNS("http://www.w3.org/1999/xhtml",e)}var H,I,z,V,Z,G,B,J,K,Q,U=(H=document,I="appendChild",z="cloneNode",V="createTextNode",G=(Z="importNode")in H,(B=H.createDocumentFragment())[I](H[V]("g")),B[I](H[V]("")),(G?H[Z](B,!0):B[z](!0)).childNodes.length<2?function e(t,n){for(var r=t[z](),i=t.childNodes||[],o=i.length,a=0;n&&a',J[K].childNodes[0].getAttribute(Q)==Y)||(Y="_dt: "+Y.slice(1,-1)+";",ee=!0)}catch(e){}var te="\x3c!--"+Y+"--\x3e",ne=8,re=1,ie=3,oe=/^(?:style|textarea)$/i,ae=/^(?:area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)$/i;var ue=" \\f\\n\\r\\t",ce="[^"+ue+"\\/>\"'=]+",le="["+ue+"]+"+ce,se="<([A-Za-z]+[A-Za-z0-9:._-]*)((?:",fe="(?:\\s*=\\s*(?:'[^']*?'|\"[^\"]*?\"|<[^>]*?>|"+ce.replace("\\/","")+"))?)",de=new RegExp(se+le+fe+"+)(["+ue+"]*/?>)","g"),he=new RegExp(se+le+fe+"*)(["+ue+"]*/>)","g"),ve=new RegExp("("+le+"\\s*=\\s*)(['\"]?)"+te+"\\2","gi");function pe(e,t,n,r){return"<"+t+n.replace(ve,me)+r}function me(e,t,n){return t+(n||'"')+Y+(n||'"')}function ge(e,t,n){return ae.test(t)?e:"<"+t+n+">"+t+">"}var ye=ee?function(e,t){var n=t.join(" ");return t.slice.call(e,0).sort(function(e,t){return n.indexOf(e.name)<=n.indexOf(t.name)?-1:1})}:function(e,t){return t.slice.call(e,0)};function be(e,t){for(var n=t.length,r=0;r'"]/g,Ct=/&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g,kt={"&":"&","<":"<",">":">","'":"'",'"':"""},Ot={"&":"&","&":"&","<":"<","<":"<",">":">",">":">","'":"'","'":"'",""":'"',""":'"'};function At(e){return kt[e]}function St(e){return Ot[e]}var jt=new s,Tt=new s,_t=new s,Mt=0,Pt=!0;function Lt(e){Pt&&_t.get(e).forEach(Dt,e)}function Dt(e){return function(e,t,n,r){var i=bt.id,o=bt.model;bt.id=n,bt.model=e;try{return t.apply(null,r)}finally{bt.id=i,bt.model=o}}(this,e.Component,e.id,e.args)}return e.comp=function(f){var d=++Mt;return jt.set(h,d),h;function h(e){var t,n,r,i,o,a,u,c,l=e||{},s=_t.get(l)||(t=l,n=new v,_t.set(t,n),function(r,i){mt(r).forEach(function(e){var t,n=pt(r,e);n.configurable&&("value"in n?(t=Nt(n.value,r),vt(r,e,{configurable:!0,enumerable:!0,get:function(){return t},set:function(e){t=Nt(e,r),i(r)}})):"set"in n&&(t=n.set,n.set=function(e){t.call(r,e),i(r)},vt(r,e,n)))})}(t,Lt),n);return Dt.call(l,s.get(h)||(r=s,i=h,o=f,a=d,u=yt.call(arguments,0),c={Component:o,id:a,args:u},r.set(i,c),c))}},e.define=ht,e.escape=function(e){return xt.call(e,Et,At)},e.html=function(){return it(bt.model,"html:"+bt.id).apply(null,arguments)},e.render=function(e,t){var n,r,i=jt.has(t)?t(Tt.get(e)||(n=e,r={},Tt.set(n,r),r)):t(),o=1===i.nodeType;return o&&e.firstChild===i||!o&&i.childNodes.every(wt,e.childNodes)||(e.textContent="",e.appendChild(i.valueOf(!0))),e},e.svg=function(){return it(bt.model,"svg:"+bt.id).apply(null,arguments)},e.unescape=function(e){return xt.call(e,Ct,St)},e.update=function(e,t){var n=_t.get(e);if(!n)throw new Error("unknown model");Pt=!1;try{!function e(t,n){for(var r in n)if(gt.call(n,r)){var i=gt.call(t,r),o=n[r],a=i?t[r]:null;i&&null!==o&&"object"==typeof o?e(a,o):i&&o===a||(t[r]=o)}}(e,t||{})}finally{Pt=!0,n.forEach(Dt,e)}},e}({});
3 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "hypersimple",
3 | "version": "0.4.1",
4 | "description": "The easiest way to use hyperHTML",
5 | "main": "cjs/index.js",
6 | "module": "esm/index.js",
7 | "unpkg": "min.js",
8 | "scripts": {
9 | "build": "npm run cjs && npm run rollup && npm run min && npm run size",
10 | "cjs": "ascjs esm cjs",
11 | "min": "echo '/*! (c) Andrea Giammarchi - ISC */' > min.js && uglifyjs index.js -c -m >> min.js",
12 | "rollup": "rollup --config rollup.config.js && drop-babel-typeof index.js",
13 | "size": "cat index.js | wc -c;cat min.js | wc -c;gzip -c9 min.js | wc -c"
14 | },
15 | "keywords": [
16 | "hyperHTML",
17 | "component",
18 | "hooks",
19 | "store"
20 | ],
21 | "author": "Andrea Giammarchi",
22 | "license": "ISC",
23 | "dependencies": {
24 | "@ungap/essential-map": "^0.2.0",
25 | "@ungap/weakmap": "^0.1.4",
26 | "html-escaper": "^2.0.1",
27 | "hyperhtml": "^2.32.2"
28 | },
29 | "devDependencies": {
30 | "@babel/core": "^7.9.0",
31 | "@babel/preset-env": "^7.9.0",
32 | "ascjs": "^3.1.2",
33 | "drop-babel-typeof": "^1.0.3",
34 | "rollup": "^2.1.0",
35 | "rollup-plugin-babel": "^4.4.0",
36 | "rollup-plugin-node-resolve": "^5.2.0",
37 | "uglify-js": "^3.8.0"
38 | },
39 | "repository": {
40 | "type": "git",
41 | "url": "git+https://github.com/WebReflection/hypersimple.git"
42 | },
43 | "bugs": {
44 | "url": "https://github.com/WebReflection/hypersimple/issues"
45 | },
46 | "homepage": "https://github.com/WebReflection/hypersimple#readme"
47 | }
48 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel';
2 | import resolve from 'rollup-plugin-node-resolve';
3 | export default {
4 | input: 'esm/index.js',
5 | plugins: [
6 | resolve({module: true}),
7 | babel({
8 | runtimeHelpers: true,
9 | presets: ['@babel/preset-env']
10 | })
11 | ],
12 | context: 'null',
13 | moduleContext: 'null',
14 | output: {
15 | exports: 'named',
16 | file: 'index.js',
17 | format: 'iife',
18 | name: 'hypersimple'
19 | }
20 | };
21 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | hypersimple
7 |
8 |
59 |
60 |
61 |
--------------------------------------------------------------------------------