diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..943f5e9f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,8 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # not working due missing www. +open_collective: hyperHTML +ko_fi: # Replace with a single Ko-fi username +tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel +custom: https://www.patreon.com/webreflection diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 00000000..73cf8d65 --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,31 @@ +# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: build + +on: [push, pull_request] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [16] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm ci + - run: npm run build --if-present + - run: npm test + - run: npm run coverage --if-present + - name: Coveralls + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 58b805fe..3cb01d4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .DS_Store -node_modules/ \ No newline at end of file +node_modules/ +coverage/ + diff --git a/.npmignore b/.npmignore index 238f8674..2b02e166 100644 --- a/.npmignore +++ b/.npmignore @@ -7,6 +7,7 @@ _config.yml .DS_Store .gitignore .travis.yml +.github/ISSUE_TEMPLATE.md babel-plugins.json CHANGELOG.md package-lock.json diff --git a/.travis.yml b/.travis.yml index acac48cd..cc127136 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: node_js node_js: - - 8 + - stable git: depth: 1 branches: @@ -8,4 +8,4 @@ branches: - master - /^greenkeeper/.*$/ after_success: - - "npm run coveralls" \ No newline at end of file + - "npm run coveralls" diff --git a/CHANGELOG.md b/CHANGELOG.md index 58f00be2..60ac2164 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,84 @@ # hyper(html) Changelog +### v.2.23 + * monkey patched rollup generated code to export once the same module shared within sub-modules + +### v2.22 + * using latest domtagger + +### v2.21 + * refactored out all dependencies + +### v2.20 + * re-tested every single supported browser nd fixed few outstanding issues with the 2.19 release + +### v2.19 + * refactored out most of the code + * finally managed to have coveralls show coverage stats + * attributes can have spaces around as per DOM standard - [#244](https://github.com/WebReflection/hyperHTML/issues/224) + * fixed SVG (non-critical) errors when interpolations are used for numerically expected values + * fixed minor issues with Edge attributes + * changed the unique id so if any of your logic was trusting `_hyper: ....;` comments you need to update your logic - [#300](https://github.com/WebReflection/hyperHTML/issues/300) + +### v2.16.8 + * improved MutationObserver and fallback so that double `dis/connected` events won't happen again + * exposed `observe` utility for 3rd parts so that it is possible to observe any node, not only those defined via template literals. Once observed, a node can have `connected` and `disconnected` listeners that will be triggered automatically. + +### v2.16 + * modified `Wire` class to better handle "_same target_" case, making the `haunted.html` demo work same way as if it was bound to the node, through `valueOf()` invoke which would result in just exactly the same node if the wired content produced a node instead of a fragment. While regular users won't be affected, this is an implementation detail that changes a lot for libraries integrating `hyperHTML.wire` in their logic, making wires as fast as `bind` in most component related use cases. + +### v2.15 + * added [invokable slots](https://github.com/WebReflection/hyperHTML/pull/282#issuecomment-433614081) to let developers explore patterns through callbacks that will receive a unique live node for weak references while rendered. + +### v2.14 + * updated [domdiff](https://github.com/WebReflection/domdiff#domdiff) to match [petit-dom](https://github.com/yelouafi/petit-dom) performance + * up to 3X performance on huge lists + * improved reliability over random changes + * unfortunately there's a +0.6K overall size increase due amount of extra logic involved + +### v2.13.2 + * added support for custom CSS properties as object keys. + +### v2.13.1 + * worked around [TypeScript transpilation bug with Template Literals](https://twitter.com/WebReflection/status/1038115439539363840). + +### v2.13 + * added the ability to define custom attributes via `hyperHTML.define("hyper-attribute", callback)`, so that `

` would invoke `callback(target, anyValue)` where `p` would be the target. + +### v2.12 + * added `hyper.Component#dispatch(type, detail)` method to simplify events dispatching between lightweight components, bubbling a cancelable Custom Event with a `.component` property that points at the dispatcher, while the `event.currentTarget` will be the first node found within the component render. + +### v2.11 + * updated [domdiff](https://github.com/WebReflection/domdiff#domdiff) to v1.0 + +### v2.10.12 + * patched missing `.children` in SVG node in IE / Edge https://github.com/WebReflection/hyperHTML/issues/244 + +### v2.10.10 + * updated [domdiff](https://github.com/WebReflection/domdiff#domdiff) to solve issue #243 (breaking with some sorted list) + +### v2.10.5 + * various fixes and changes after [changes applied to ECMAScript 2015](https://github.com/tc39/ecma262/pull/890) + +### v2.8.0 + * updated [domdiff](https://github.com/WebReflection/domdiff#domdiff) engine to boost performance with segments and lists + +### v2.7.2 + * fixed #218 which was a variant of #200 + +### v2.7.0 + * the `Component.for(obj)` is now created first time via `new Component(obj)` - #216 + +### v2.6.0 + * declarative hyper.Component via `Component.for(context, uid?)` - #202 + * hyperHTML TypeScript information - #201 + +### v2.5.12 + * fixed #200: textarea/style with initial undefined value + +### v2.5.11 + * fixed #198: connected/disconnected events for nested components + ### v2.5.10 * more rigid / explicit RegExp to avoid glitches with self-closing tags diff --git a/HELPERS.md b/HELPERS.md new file mode 100644 index 00000000..d0f8aefb --- /dev/null +++ b/HELPERS.md @@ -0,0 +1,57 @@ +## [babel-plugin-remove-ungap] + +Remove the [@ungap ponyfill modules] from your bundle. This will decrease the size of +your bundle if you are targeting modern browsers only or if your build already includes +other polyfills. This has been tested with [hyperHTML] and [lighterhtml] bundles. + + +## [babel-plugin-template-html-minifier] + +Run [html-minifier] on hyperHTML templates. + + +## [babel-plugin-bare-import-rewrite] + +This can be used as an alternative to [rollup-plugin-node-resolve], or can be used with certain node.js +web servers to allow browsing live from source. + +Known web server integrations: +* [fastify-babel] plugin for [fastify] enables running any babel plugins, generally expects `payload.filename` as set by [fastify-static] +* [express-transform-bare-module-specifiers] for [express] servers + + +## [vinyl-rollup] + +This module copies the output of rollup builds to a stream of vinyl-fs objects for [gulp]. +In addition it optionally adds files from modules that were bundled into the stream. This +makes it easy to ensure that LICENSE and package.json files associated with bundled modules +are published on the web server without publishing node.js server-side dependencies to the web. +This can also be used to copy complete modules if required for licensing or if bundled code +requires additional assets that are not part of the bundled JS (images for example). + + +## [babel-plugin-bundled-import-meta] + +If `node_modules/some-web-component/index.js` uses `import.meta.url` to calculate the actual +path to `node_modules/some-web-components/image.png`, rollup does not compensate. This babel +plugin rewrites references to `import.meta.url` so it points to the original location where +it is expected that the additional assets (images and such) can be found. This plugin works +well with `vinyl-rollup` with `copyModules: true`. + + +[babel-plugin-remove-ungap]: https://github.com/cfware/babel-plugin-remove-ungap#readme +[@ungap ponyfill modules]: https://github.com/ungap/ungap.github.io#readme +[hyperHTML]: https://github.com/WebReflection/hyperHTML#readme +[lighterhtml]: https://github.com/WebReflection/lighterhtml#readme +[babel-plugin-template-html-minifier]: https://github.com/cfware/babel-plugin-template-html-minifier#readme +[html-minifier]: https://github.com/kangax/html-minifier#readme +[babel-plugin-bare-import-rewrite]: https://github.com/cfware/babel-plugin-bare-import-rewrite#readme +[rollup-plugin-node-resolve]: https://github.com/rollup/rollup-plugin-node-resolve#readme +[fastify]: https://github.com/fastify/fastify#readme +[fastify-babel]: https://github.com/cfware/fastify-babel#readme +[fastify-static]: https://github.com/fastify/fastify-static#readme +[express-transform-bare-module-specifiers]: https://github.com/nodecg/express-transform-bare-module-specifiers#readme +[express]: https://github.com/expressjs/express#readme +[vinyl-rollup]: https://github.com/cfware/vinyl-rollup#readme +[gulp]: https://github.com/gulpjs/gulp#readme +[babel-plugin-bundled-import-meta]: https://github.com/cfware/babel-plugin-bundled-import-meta#readme diff --git a/README.md b/README.md index e6e3a720..72f7e51a 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,74 @@ # hyper(HTML) +### Maintainance Only + +This module is great, works great, and served me greatly, but there's a pletora of modern, faster, more capable alternatives me, among many other OSS developers, offer so that if obvious bugs are proven to exist, these will be fixed, but there won't be a major release and I won't remove legacy support for stuff that, as previously mentioned, works just fine and it's battle-tested from IE to the latest Chrome. + +Removing that legacy support brings pretty much nothing in terms of size too: this module is already smaller than 90% of alternatives out there, dropping 0.xK so that there's less code that, behind feature detection, is not even used in modern browsers, won't benefit anyone. + +Thansk for your understanding and for not opening PRs which goal is to drop a check for legacy browsers ... these won't likely be merged ever as that'd be a major release update and I don't think anyone is interested in that. + +### ๐Ÿ“ฃ Community Announcement + +Please ask questions in the [dedicated discussions repository](https://github.com/WebReflection/discussions), to help the community around this project grow โ™ฅ + +- - - + hyperHTML logo -A **Fast & Light Virtual DOM Alternative** available for [NodeJS](https://viperhtml.js.org/viper.html) and [NativeScript](https://viperhtml.js.org/native.html) too. +A **Fast & Light Virtual DOM Alternative**. - - - -[![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000&style=flat)](https://github.com/WebReflection/donate) [![Backers on Open Collective](https://opencollective.com/hyperhtml/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/hyperhtml/sponsors/badge.svg)](#sponsors) +[![donate](https://img.shields.io/badge/$-donate-ff69b4.svg?maxAge=2592000&style=flat)](https://github.com/WebReflection/donate) [![Backers on Open Collective](https://opencollective.com/hyperhtml/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/hyperhtml/sponsors/badge.svg)](#sponsors) ![WebReflection status](https://offline.report/status/webreflection.svg) [![Coverage Status](https://coveralls.io/repos/github/WebReflection/hyperHTML/badge.svg?branch=master)](https://coveralls.io/github/WebReflection/hyperHTML?branch=master) [![Build Status](https://travis-ci.org/WebReflection/hyperHTML.svg?branch=master)](https://travis-ci.org/WebReflection/hyperHTML) [![License: ISC](https://img.shields.io/badge/License-ISC-yellow.svg)](https://opensource.org/licenses/ISC) -[![Greenkeeper badge](https://badges.greenkeeper.io/WebReflection/hyperHTML.svg)](https://greenkeeper.io/) +[![Greenkeeper badge](https://badges.greenkeeper.io/WebReflection/hyperHTML.svg)](https://greenkeeper.io/) ![Blazing Fast](https://img.shields.io/badge/speed-blazing%20๐Ÿ”ฅ-brightgreen.svg) + +- - - + +Following an overview of projects related, or inspired by, _hyperHTML_. For a deep comparison of current libraries, feel free to [check this gist out](https://gist.github.com/WebReflection/761052d6dae7c8207d2fcba7cdede295). + + +## ยตhtml + +The latest, smallest, iteration of all best concept from this library since 2017, have been packaged in _~2.5K_. If it's extreme minimalism and great _DX_ that you are after, check [uhtml](https://github.com/WebReflection/uhtml#readme) out. + + +## hypersimple + +If you've just started with template literals based projects and you like components, or you'd like to understand what's _hyperHTML_ capable of, give [hypersimple](https://github.com/WebReflection/hypersimple#readme) a try ๐ŸŽ‰ + + +## lighterhtml ๐Ÿ’ก + +This little brother is "_showing off_" these days, claiming better performance and unprecedented ease of use. + +[GitHub Repository](https://github.com/WebReflection/lighterhtml) + + +## Neverland ๐ŸŒˆ๐Ÿฆ„ + +If you like React hooks concept, don't miss this little wrap that adds 0._something_ overhead to the already lightweight hyperHTML, bringing in very similar concepts. + +[Blog Post](https://medium.com/@WebReflection/neverland-the-hyperhtmls-hook-a0c3e11324bb) + +[GitHub Repository](https://github.com/WebReflection/neverland) + +## Haunted ๐Ÿฆ‡ ๐ŸŽƒ + +If you also like React hooks mechanism and you'd like to combine these via hyperHTML or [HyperHTMLElement](https://github.com/WebReflection/hyperHTML-Element), try [haunted](https://github.com/matthewp/haunted#haunted--) out! + + +## Bundlers + +You can require or import _hyperHTML_ with any bundler and in different ways. + +If requiring or importing from `"hyperhtml"` doesn't work, try requiring from `"hyperhtml/cjs"` for CommonJS friendly bundlers (WebPack), or `"hyperhtml/esm"` for ESM compatible bundlers (Rollup). + +See [HELPERS.md](./HELPERS.md) for a list of additional tools which can be helpful for building hyperHTML based web applications. - - - @@ -30,11 +87,16 @@ Thank you to all our backers! ๐Ÿ™ [[Become a backer](https://opencollective.com ## Contributors This project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)]. - + - - - +### 2.34 Highlights + + * the new `?boolean=${value}` syntax from [ยตhtml](https://github.com/WebReflection/uhtml#readme) has landed in *hyperHTML* too. Feel free to [read this long discussion](https://github.com/WebReflection/discussions/discussions/13) to better understand *why* this syntax is necessary. + ### V2.5 Highlights + * `` tags for both custom elements and any other as well ๐ŸŽ‰ ### V2 Highlights @@ -54,6 +116,7 @@ Following most important changes in version 2: A proper documentation full of examples can be found in [viperhtml.js.org](https://viperhtml.js.org/). + ## Basic Example The easiest way to describe `hyperHTML` is through [an example](https://webreflection.github.io/hyperHTML/test/tick.html). ```js @@ -86,6 +149,12 @@ You can verify directly through the following links: * [100% code coverage](https://webreflection.github.io/hyperHTML/test/) for browsers natively compatible with string literals * [100% code coverage](https://webreflection.github.io/hyperHTML/test/ie/) for IE9+ and browsers that need transpiled code + +#### Weakmap error on ie < 11 + +'@ungap/weakmap': object is not extensible + +Babel freezes the template literals by spec but that causes problems with the weakmap polyfill. To fix this error add the fix explained on [ungap/weakmap](https://github.com/ungap/weakmap#transpiled-code-and-frozen-objects-in-legacy-browsers) ## HTML Syntax Highlight @@ -93,13 +162,17 @@ If you are using Visual Studio Code you can install `literally-html` to highligh ![literally-html example](https://viperhtml.js.org/hyperhtml/documentation/img/literally-html.png) +## Prettier Templates + +If you'd like to make your templates prettier than usual, don't miss this plugin: https://github.com/sgtpep/prettier-plugin-html-template-literals + ## Questions ? Please ask anything you'd like to know in [StackOverflow](https://stackoverflow.com) using the tag [`hyperhtml`](https://stackoverflow.com/questions/tagged/hyperhtml) so that others can benefit from answers and examples. #### hyper or lit ? -You can read more on this [hyperHTML vs lit-html](https://gist.github.com/WebReflection/fadcc419f5ccaae92bc167d8ff5c611b) comparison. +You can read more on this [hyperHTML vs lit-html](https://medium.com/@WebReflection/lit-html-vs-hyperhtml-vs-lighterhtml-c084abfe1285) comparison. #### installation? diff --git a/cjs/classes/Component.js b/cjs/classes/Component.js index 60849b9c..632986bf 100644 --- a/cjs/classes/Component.js +++ b/cjs/classes/Component.js @@ -1,19 +1,80 @@ 'use strict'; +const CustomEvent = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/custom-event')); +const Map = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/essential-map')); +const WeakMap = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/weakmap')); + // hyperHTML.Component is a very basic class // able to create Custom Elements like components // including the ability to listen to connect/disconnect // events via onconnect/ondisconnect attributes -function Component() {} +// Components can be created imperatively or declaratively. +// The main difference is that declared components +// will not automatically render on setState(...) +// to simplify state handling on render. +function Component() { + return this; // this is needed in Edge !!! +} Object.defineProperty(exports, '__esModule', {value: true}).default = Component -// components will lazily define html or svg properties -// as soon as these are invoked within the .render() method -// Such render() method is not provided by the base class -// but it must be available through the Component extend. +// Component is lazily setup because it needs +// wire mechanism as lazy content function setup(content) { + // there are various weakly referenced variables in here + // and mostly are to use Component.for(...) static method. + const children = new WeakMap; + const create = Object.create; + const createEntry = (wm, id, component) => { + wm.set(id, component); + return component; + }; + const get = (Class, info, context, id) => { + const relation = info.get(Class) || relate(Class, info); + switch (typeof id) { + case 'object': + case 'function': + const wm = relation.w || (relation.w = new WeakMap); + return wm.get(id) || createEntry(wm, id, new Class(context)); + default: + const sm = relation.p || (relation.p = create(null)); + return sm[id] || (sm[id] = new Class(context)); + } + }; + const relate = (Class, info) => { + const relation = {w: null, p: null}; + info.set(Class, relation); + return relation; + }; + const set = context => { + const info = new Map; + children.set(context, info); + return info; + }; + // The Component Class + Object.defineProperties( + Component, + { + // Component.for(context[, id]) is a convenient way + // to automatically relate data/context to children components + // If not created yet, the new Component(context) is weakly stored + // and after that same instance would always be returned. + for: { + configurable: true, + value(context, id) { + return get( + this, + children.get(context) || set(context), + context, + id == null ? + 'default' : id + ); + } + } + } + ); Object.defineProperties( Component.prototype, { + // all events are handled with the component as context handleEvent: {value(e) { const ct = e.currentTarget; this[ @@ -21,15 +82,46 @@ function setup(content) { ('on' + e.type) ](e); }}, + // components will lazily define html or svg properties + // as soon as these are invoked within the .render() method + // Such render() method is not provided by the base class + // but it must be available through the Component extend. + // Declared components could implement a + // render(props) method too and use props as needed. html: lazyGetter('html', content), svg: lazyGetter('svg', content), + // the state is a very basic/simple mechanism inspired by Preact state: lazyGetter('state', function () { return this.defaultState; }), + // it is possible to define a default state that'd be always an object otherwise defaultState: {get() { return {}; }}, - setState: {value(state) { + // dispatch a bubbling, cancelable, custom event + // through the first known/available node + dispatch: {value(type, detail) { + const {_wire$} = this; + if (_wire$) { + const event = new CustomEvent(type, { + bubbles: true, + cancelable: true, + detail + }); + event.component = this; + return (_wire$.dispatchEvent ? + _wire$ : + _wire$.firstChild + ).dispatchEvent(event); + } + return false; + }}, + // setting some property state through a new object + // or a callback, triggers also automatically a render + // unless explicitly specified to not do so (render === false) + setState: {value(state, render) { const target = this.state; const source = typeof state === 'function' ? state.call(this, target) : state; for (const key in source) target[key] = source[key]; - this.render(); + if (render !== false) + this.render(); + return this; }} } ); @@ -44,10 +136,31 @@ const lazyGetter = (type, fn) => { const secret = '_' + type + '$'; return { get() { - return this[secret] || (this[type] = fn.call(this, type)); + return this[secret] || setValue(this, secret, fn.call(this, type)); }, set(value) { - Object.defineProperty(this, secret, {configurable: true, value}); + setValue(this, secret, value); } }; }; + +// shortcut to set value on get or set(value) +const setValue = (self, secret, value) => + Object.defineProperty(self, secret, { + configurable: true, + value: typeof value === 'function' ? + function () { + return (self._wire$ = value.apply(this, arguments)); + } : + value + })[secret] +; + +Object.defineProperties( + Component.prototype, + { + // used to distinguish better than instanceof + ELEMENT_NODE: {value: 1}, + nodeType: {value: -1} + } +); diff --git a/cjs/classes/Wire.js b/cjs/classes/Wire.js deleted file mode 100644 index a57b6d2b..00000000 --- a/cjs/classes/Wire.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; -const { append } = require('../shared/utils.js'); -const { doc, fragment } = require('../shared/easy-dom.js'); - -function Wire(childNodes) { - this.childNodes = childNodes; - this.length = childNodes.length; - this.first = childNodes[0]; - this.last = childNodes[this.length - 1]; -} -Object.defineProperty(exports, '__esModule', {value: true}).default = Wire - -// when a wire is inserted, all its nodes will follow -Wire.prototype.insert = function insert() { - const df = fragment(this.first); - append(df, this.childNodes); - return df; -}; - -// when a wire is removed, all its nodes must be removed as well -Wire.prototype.remove = function remove() { - const first = this.first; - const last = this.last; - if (this.length === 2) { - last.parentNode.removeChild(last); - } else { - const range = doc(first).createRange(); - range.setStartBefore(this.childNodes[1]); - range.setEndAfter(last); - range.deleteContents(); - } - return first; -}; diff --git a/cjs/hyper/render.js b/cjs/hyper/render.js index 376ae28f..a401a66b 100644 --- a/cjs/hyper/render.js +++ b/cjs/hyper/render.js @@ -1,34 +1,25 @@ 'use strict'; -const {Map, WeakMap} = require('../shared/poorlyfills.js'); -const {UIDC, VOID_ELEMENTS} = require('../shared/constants.js'); -const Updates = (m => m.__esModule ? m.default : m)(require('../objects/Updates.js')); -const { - createFragment, - importNode, - unique -} = require('../shared/utils.js'); +const WeakMap = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/weakmap')); +const tta = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/template-tag-arguments')); -const {selfClosing} = require('../shared/re.js'); +const {OWNER_SVG_ELEMENT} = require('../shared/constants.js'); +const {Tagger} = require('../objects/Updates.js'); // a weak collection of contexts that // are already known to hyperHTML const bewitched = new WeakMap; -// the collection of all template literals -// since these are unique and immutable -// for the whole application life-cycle -const templates = new Map; - // better known as hyper.bind(node), the render is // the main tag function in charge of fully upgrading // or simply updating, contexts used as hyperHTML targets. // The `this` context is either a regular DOM node or a fragment. -function render(template) { +function render() { const wicked = bewitched.get(this); - if (wicked && wicked.template === unique(template)) { - update.apply(wicked.updates, arguments); + const args = tta.apply(null, arguments); + if (wicked && wicked.template === args[0]) { + wicked.tagger.apply(null, args); } else { - upgrade.apply(this, arguments); + upgrade.apply(this, args); } return this; } @@ -38,44 +29,11 @@ function render(template) { // as single DOM callbacks, relate such template // to the current context, and render it after cleaning the context up function upgrade(template) { - template = unique(template); - const info = templates.get(template) || - createTemplate.call(this, template); - const fragment = importNode(this.ownerDocument, info.fragment); - const updates = Updates.create(fragment, info.paths); - bewitched.set(this, {template, updates}); - update.apply(updates, arguments); + const type = OWNER_SVG_ELEMENT in this ? 'svg' : 'html'; + const tagger = new Tagger(type); + bewitched.set(this, {tagger, template: template}); this.textContent = ''; - this.appendChild(fragment); -} - -// an update simply loops over all mapped DOM operations -function update() { - const length = arguments.length; - for (let i = 1; i < length; i++) { - this[i - 1](arguments[i]); - } + this.appendChild(tagger.apply(null, arguments)); } -// a template can be used to create a document fragment -// aware of all interpolations and with a list -// of paths used to find once those nodes that need updates, -// no matter if these are attributes, text nodes, or regular one -function createTemplate(template) { - const paths = []; - const html = template.join(UIDC).replace(SC_RE, SC_PLACE); - const fragment = createFragment(this, html); - Updates.find(fragment, paths, template.slice()); - const info = {fragment, paths}; - templates.set(template, info); - return info; -} - -// some node could be special though, like a custom element -// with a self closing tag, which should work through these changes. -const SC_RE = selfClosing; -const SC_PLACE = ($0, $1, $2) => { - return VOID_ELEMENTS.test($1) ? $0 : ('<' + $1 + $2 + '>'); -}; - Object.defineProperty(exports, '__esModule', {value: true}).default = render; diff --git a/cjs/hyper/wire.js b/cjs/hyper/wire.js index be8eefa5..139eaaba 100644 --- a/cjs/hyper/wire.js +++ b/cjs/hyper/wire.js @@ -1,10 +1,10 @@ 'use strict'; -const {ELEMENT_NODE, SVG_NAMESPACE} = require('../shared/constants.js'); -const {WeakMap, trim} = require('../shared/poorlyfills.js'); -const {fragment} = require('../shared/easy-dom.js'); -const {append, slice, unique} = require('../shared/utils.js'); -const Wire = (m => m.__esModule ? m.default : m)(require('../classes/Wire.js')); -const render = (m => m.__esModule ? m.default : m)(require('./render.js')); +const WeakMap = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/weakmap')); +const tta = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/template-tag-arguments')); + +const Wire = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('hyperhtml-wire')); + +const {Tagger} = require('../objects/Updates.js'); // all wires used per each context const wires = new WeakMap; @@ -29,24 +29,15 @@ const wire = (obj, type) => obj == null ? // In few words, a wire content is like an invisible parent node // in charge of updating its content like a bound element would do. const content = type => { - let wire, container, content, template, updates; - return function (statics) { - statics = unique(statics); - let setup = template !== statics; - if (setup) { - template = statics; - content = fragment(document); - container = type === 'svg' ? - document.createElementNS(SVG_NAMESPACE, 'svg') : - content; - updates = render.bind(container); - } - updates.apply(null, arguments); - if (setup) { - if (type === 'svg') { - append(content, slice.call(container.childNodes)); - } - wire = wireContent(content); + let wire, tagger, template; + return function () { + const args = tta.apply(null, arguments); + if (template !== args[0]) { + template = args[0]; + tagger = new Tagger(type); + wire = wireContent(tagger.apply(tagger, args)); + } else { + tagger.apply(tagger, args); } return wire; }; @@ -63,34 +54,29 @@ const weakly = (obj, type) => { id = type.slice(i + 1); type = type.slice(0, i) || 'html'; } - if (!wire) wires.set(obj, wire = {}); + if (!wire) + wires.set(obj, wire = {}); return wire[id] || (wire[id] = content(type)); }; -// a document fragment loses its nodes as soon -// as it's appended into another node. -// This would easily lose wired content -// so that on a second render call, the parent -// node wouldn't know which node was there -// associated to the interpolation. -// To prevent hyperHTML to forget about wired nodes, -// these are either returned as Array or, if there's ony one entry, -// as single referenced node that won't disappear from the fragment. -// The initial fragment, at this point, would be used as unique reference. +// A document fragment loses its nodes +// as soon as it is appended into another node. +// This has the undesired effect of losing wired content +// on a second render call, because (by then) the fragment would be empty: +// no longer providing access to those sub-nodes that ultimately need to +// stay associated with the original interpolation. +// To prevent hyperHTML from forgetting about a fragment's sub-nodes, +// fragments are instead returned as an Array of nodes or, if there's only one entry, +// as a single referenced node which, unlike fragments, will indeed persist +// wire content throughout multiple renderings. +// The initial fragment, at this point, would be used as unique reference to this +// array of nodes or to this single referenced node. const wireContent = node => { const childNodes = node.childNodes; - const length = childNodes.length; - const wireNodes = []; - for (let i = 0; i < length; i++) { - let child = childNodes[i]; - if ( - child.nodeType === ELEMENT_NODE || - trim.call(child.textContent).length !== 0 - ) { - wireNodes.push(child); - } - } - return wireNodes.length === 1 ? wireNodes[0] : new Wire(wireNodes); + const {length} = childNodes; + return length === 1 ? + childNodes[0] : + (length ? new Wire(childNodes) : node); }; exports.content = content; diff --git a/cjs/index.js b/cjs/index.js index 0a05cd07..04ed734a 100644 --- a/cjs/index.js +++ b/cjs/index.js @@ -1,13 +1,16 @@ 'use strict'; /*! (c) Andrea Giammarchi (ISC) */ +const WeakMap = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/weakmap')); +const WeakSet = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/essential-weakset')); -const Component = (m => m.__esModule ? m.default : m)(require('./classes/Component.js')); +const diff = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('domdiff')); +const Component = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('./classes/Component.js')); const {setup} = require('./classes/Component.js'); -const Intent = (m => m.__esModule ? m.default : m)(require('./objects/Intent.js')); -const wire = (m => m.__esModule ? m.default : m)(require('./hyper/wire.js')); +const Intent = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('./objects/Intent.js')); +const {observe, Tagger} = require('./objects/Updates.js'); +const wire = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('./hyper/wire.js')); const {content, weakly} = require('./hyper/wire.js'); -const render = (m => m.__esModule ? m.default : m)(require('./hyper/render.js')); -const diff = (m => m.__esModule ? m.default : m)(require('./shared/domdiff.js')); +const render = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('./hyper/render.js')); // all functions are self bound to the right context // you can do the following @@ -15,14 +18,26 @@ const diff = (m => m.__esModule ? m.default : m)(require('./shared/domdiff.js')) // and use them right away: bind(node)`hello!`; const bind = context => render.bind(context); const define = Intent.define; +const tagger = Tagger.prototype; hyper.Component = Component; hyper.bind = bind; hyper.define = define; hyper.diff = diff; hyper.hyper = hyper; +hyper.observe = observe; +hyper.tagger = tagger; hyper.wire = wire; +// exported as shared utils +// for projects based on hyperHTML +// that don't necessarily need upfront polyfills +// i.e. those still targeting IE +hyper._ = { + WeakMap, + WeakSet +}; + // the wire content is the lazy defined // html or svg property of each hyper.Component setup(content); @@ -34,6 +49,8 @@ exports.bind = bind; exports.define = define; exports.diff = diff; exports.hyper = hyper; +exports.observe = observe; +exports.tagger = tagger; exports.wire = wire; // by default, hyperHTML is a smart function diff --git a/cjs/objects/Engine.js b/cjs/objects/Engine.js deleted file mode 100644 index b5195357..00000000 --- a/cjs/objects/Engine.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', {value: true}).default = { - update: ( - utils, - liveNodes, liveStart, liveEnd, liveLength, - virtualNodes, virtualStart, virtualEnd /*, virtualLength */ - ) => { - const { splicer } = utils; - while (liveStart < liveEnd && virtualStart < virtualEnd) { - const liveValue = liveNodes[liveStart]; - const virtualValue = virtualNodes[virtualStart]; - const status = liveValue === virtualValue ? - 0 : (liveNodes.indexOf(virtualValue) < 0 ? 1 : -1); - // nodes can be either removed ... - if (status < 0) { - splicer.splice(liveStart, 1); - liveEnd--; - liveLength--; - } - // ... appended ... - else if (0 < status) { - splicer.splice(liveStart, 0, virtualValue); - liveStart++; - liveEnd++; - liveLength++; - virtualStart++; - } - // ... or ignored, since it's the same ... - else { - liveStart++; - virtualStart++; - } - } - if (liveStart < liveEnd) { - splicer.splice(liveStart, liveEnd - liveStart); - } - if (virtualStart < virtualEnd) { - splicer.splice.apply( - splicer, - [liveEnd, 0].concat( - virtualNodes.slice(virtualStart, virtualEnd) - ) - ); - } - } -}; \ No newline at end of file diff --git a/cjs/objects/Intent.js b/cjs/objects/Intent.js index 9b01fbef..ef791d77 100644 --- a/cjs/objects/Intent.js +++ b/cjs/objects/Intent.js @@ -1,4 +1,5 @@ 'use strict'; +const attributes = {}; const intents = {}; const keys = []; const hasOwnProperty = intents.hasOwnProperty; @@ -7,16 +8,23 @@ let length = 0; Object.defineProperty(exports, '__esModule', {value: true}).default = { + // used to invoke right away hyper:attributes + attributes, + // hyperHTML.define('intent', (object, update) => {...}) // can be used to define a third parts update mechanism // when every other known mechanism failed. // hyper.define('user', info => info.name); // hyper(node)`

${{user}}

`; define: (intent, callback) => { - if (!(intent in intents)) { - length = keys.push(intent); + if (intent.indexOf('-') < 0) { + if (!(intent in intents)) { + length = keys.push(intent); + } + intents[intent] = callback; + } else { + attributes[intent] = callback; } - intents[intent] = callback; }, // this method is used internally as last resort diff --git a/cjs/objects/Path.js b/cjs/objects/Path.js deleted file mode 100644 index aef883cf..00000000 --- a/cjs/objects/Path.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict'; -const { - COMMENT_NODE, - DOCUMENT_FRAGMENT_NODE, - ELEMENT_NODE -} = require('../shared/constants.js'); - -// every template literal interpolation indicates -// a precise target in the DOM the template is representing. -// `

some ${'content'}

` -// hyperHTML finds only once per template literal, -// hence once per entire application life-cycle, -// all nodes that are related to interpolations. -// These nodes are stored as indexes used to retrieve, -// once per upgrade, nodes that will change on each future update. -// A path example is [2, 0, 1] representing the operation: -// node.childNodes[2].childNodes[0].childNodes[1] -// Attributes are addressed via their owner node and their name. -const createPath = node => { - const path = []; - let parentNode; - switch (node.nodeType) { - case ELEMENT_NODE: - case DOCUMENT_FRAGMENT_NODE: - parentNode = node; - break; - case COMMENT_NODE: - parentNode = node.parentNode; - prepend(path, parentNode, node); - break; - default: - parentNode = node.ownerElement; - break; - } - for ( - node = parentNode; - (parentNode = parentNode.parentNode); - node = parentNode - ) { - prepend(path, parentNode, node); - } - return path; -}; - -const prepend = (path, parent, node) => { - path.unshift(path.indexOf.call(parent.childNodes, node)); -}; - -Object.defineProperty(exports, '__esModule', {value: true}).default = { - create: (type, node, name) => ({type, name, node, path: createPath(node)}), - find: (node, path) => { - const length = path.length; - for (let i = 0; i < length; i++) { - node = node.childNodes[path[i]]; - } - return node; - } -} diff --git a/cjs/objects/Style.js b/cjs/objects/Style.js deleted file mode 100644 index 62656d4c..00000000 --- a/cjs/objects/Style.js +++ /dev/null @@ -1,72 +0,0 @@ -'use strict'; -// from https://github.com/developit/preact/blob/33fc697ac11762a1cb6e71e9847670d047af7ce5/src/constants.js -const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i; - -// style is handled as both string and object -// even if the target is an SVG element (consistency) -Object.defineProperty(exports, '__esModule', {value: true}).default = (node, original, isSVG) => { - if (isSVG) { - const style = original.cloneNode(true); - style.value = ''; - node.setAttributeNode(style); - return update(style, isSVG); - } - return update(node.style, isSVG); -}; - -// the update takes care or changing/replacing -// only properties that are different or -// in case of string, the whole node -const update = (style, isSVG) => { - let oldType, oldValue; - return newValue => { - switch (typeof newValue) { - case 'object': - if (newValue) { - if (oldType === 'object') { - if (!isSVG) { - if (oldValue !== newValue) { - for (const key in oldValue) { - if (!(key in newValue)) { - style[key] = ''; - } - } - } - } - } else { - if (isSVG) style.value = ''; - else style.cssText = ''; - } - const info = isSVG ? {} : style; - for (const key in newValue) { - const value = newValue[key]; - info[key] = typeof value === 'number' && - !IS_NON_DIMENSIONAL.test(key) ? - (value + 'px') : value; - } - oldType = 'object'; - if (isSVG) style.value = toStyle((oldValue = info)); - else oldValue = newValue; - break; - } - default: - if (oldValue != newValue) { - oldType = 'string'; - oldValue = newValue; - if (isSVG) style.value = newValue || ''; - else style.cssText = newValue || ''; - } - break; - } - }; -}; - -const hyphen = /([^A-Z])([A-Z]+)/g; -const ized = ($0, $1, $2) => $1 + '-' + $2.toLowerCase(); -const toStyle = object => { - const css = []; - for (const key in object) { - css.push(key.replace(hyphen, ized), ':', object[key], ';'); - } - return css.join(''); -}; \ No newline at end of file diff --git a/cjs/objects/Updates.js b/cjs/objects/Updates.js index 01834e5e..0df2e324 100644 --- a/cjs/objects/Updates.js +++ b/cjs/objects/Updates.js @@ -1,184 +1,77 @@ 'use strict'; +const CustomEvent = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/custom-event')); +const WeakSet = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/essential-weakset')); +const isArray = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/is-array')); +const createContent = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/create-content')); + +const disconnected = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('disconnected')); +const domdiff = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('domdiff')); +const domtagger = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('domtagger')); +const hyperStyle = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('hyperhtml-style')); +const Wire = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('hyperhtml-wire')); + const { - CONNECTED, DISCONNECTED, COMMENT_NODE, DOCUMENT_FRAGMENT_NODE, ELEMENT_NODE, TEXT_NODE, OWNER_SVG_ELEMENT, SHOULD_USE_TEXT_CONTENT, UID, UIDC + CONNECTED, DISCONNECTED, DOCUMENT_FRAGMENT_NODE, OWNER_SVG_ELEMENT } = require('../shared/constants.js'); -const Component = (m => m.__esModule ? m.default : m)(require('../classes/Component.js')); -const Wire = (m => m.__esModule ? m.default : m)(require('../classes/Wire.js')); -const Path = (m => m.__esModule ? m.default : m)(require('./Path.js')); -const Style = (m => m.__esModule ? m.default : m)(require('./Style.js')); -const Intent = (m => m.__esModule ? m.default : m)(require('./Intent.js')); -const domdiff = (m => m.__esModule ? m.default : m)(require('../shared/domdiff.js')); -const { create: createElement, text } = require('../shared/easy-dom.js'); -const { Event, WeakSet, isArray, trim } = require('../shared/poorlyfills.js'); -const { createFragment, slice } = require('../shared/utils.js'); +const Component = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('../classes/Component.js')); +const Intent = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('./Intent.js')); -// hyper.Component have a connected/disconnected -// mechanism provided by MutationObserver -// This weak set is used to recognize components -// as DOM node that needs to trigger connected/disconnected events -const components = new WeakSet; +const componentType = Component.prototype.nodeType; +const wireType = Wire.prototype.nodeType; -// a basic dictionary used to filter already cached attributes -// while looking for special hyperHTML values. -function Cache() {} -Cache.prototype = Object.create(null); +const observe = disconnected({Event: CustomEvent, WeakSet}); + +exports.Tagger = Tagger; +exports.observe = observe; // returns an intent to explicitly inject content as html const asHTML = html => ({html}); // returns nodes from wires and components const asNode = (item, i) => { - return 'ELEMENT_NODE' in item ? - item : - (item.constructor === Wire ? + switch (item.nodeType) { + case wireType: // in the Wire case, the content can be // removed, post-pended, inserted, or pre-pended and // all these cases are handled by domdiff already /* istanbul ignore next */ - ((1 / i) < 0 ? - (i ? item.remove() : item.last) : - (i ? item.insert() : item.first)) : - asNode(item.render(), i)); + return (1 / i) < 0 ? + (i ? item.remove(true) : item.lastChild) : + (i ? item.valueOf(true) : item.firstChild); + case componentType: + return asNode(item.render(), i); + default: + return item; + } } // returns true if domdiff can handle the value -const canDiff = value => 'ELEMENT_NODE' in value || -value instanceof Wire || -value instanceof Component; +const canDiff = value => 'ELEMENT_NODE' in value; -// updates are created once per context upgrade -// within the main render function (../hyper/render.js) -// These are an Array of callbacks to invoke passing -// each interpolation value. -// Updates can be related to any kind of content, -// attributes, or special text-only cases such - - -
-
-

- all files / hyperHTML/ index.c.js -

-
-
- 100% - Statements - 603/603 -
-
- 100% - Branches - 325/325 -
-
- 100% - Functions - 95/95 -
-
- 100% - Lines - 593/593 -
-
- 3 statements, 1 function, 8 branches - Ignored      -
-
-
-
-

-
-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -736 -737 -738 -739 -740 -741 -742 -743 -744 -745 -746 -747 -748 -749 -750 -751 -752 -753 -754 -755 -756 -757 -758 -759 -760 -761 -762 -763 -764 -765 -766 -767 -768 -769 -770 -771 -772 -773 -774 -775 -776 -777 -778 -779 -780 -781 -782 -783 -784 -785 -786 -787 -788 -789 -790 -791 -792 -793 -794 -795 -796 -797 -798 -799 -800 -801 -802 -803 -804 -805 -806 -807 -808 -809 -810 -811 -812 -813 -814 -815 -816 -817 -818 -819 -820 -821 -822 -823 -824 -825 -826 -827 -828 -829 -830 -831 -832 -833 -834 -835 -836 -837 -838 -839 -840 -841 -842 -843 -844 -845 -846 -847 -848 -849 -850 -851 -852 -853 -854 -855 -856 -857 -858 -859 -860 -861 -862 -863 -864 -865 -866 -867 -868 -869 -870 -871 -872 -873 -874 -875 -876 -877 -878 -879 -880 -881 -882 -883 -884 -885 -886 -887 -888 -889 -890 -891 -892 -893 -894 -895 -896 -897 -898 -899 -900 -901 -902 -903 -904 -905 -906 -907 -908 -909 -910 -911 -912 -913 -914 -915 -916 -917 -918 -919 -920 -921 -922 -923 -924 -925 -926 -927 -928 -929 -930 -931 -932 -933 -934 -935 -936 -937 -938 -939 -940 -941 -942 -943 -944 -945 -946 -947 -948 -949 -950 -951 -952 -953 -954 -955 -956 -957 -958 -959 -960 -961 -962 -963 -964 -965 -966 -967 -968 -969 -970 -971 -972 -973 -974 -975 -976 -977 -978 -979 -980 -981 -982 -983 -984 -985 -986 -987 -988 -989 -990 -991 -992 -993 -994 -995 -996 -997 -998 -999 -1000 -1001 -1002 -1003 -1004 -1005 -1006 -1007 -1008 -1009 -1010 -1011 -1012 -1013 -1014 -1015 -1016 -1017 -1018 -1019 -1020 -1021 -1022 -1023 -1024 -1025 -1026 -1027 -1028 -1029 -1030 -1031 -1032 -1033 -1034 -1035 -1036 -1037 -1038 -1039 -1040 -1041 -1042 -1043 -1044 -1045 -1046 -1047 -1048 -1049 -1050 -1051 -1052 -1053 -1054 -1055 -1056 -1057 -1058 -1059 -1060 -1061 -1062 -1063 -1064 -1065 -1066 -1067 -1068 -1069 -1070 -1071 -1072 -1073 -1074 -1075 -1076 -1077 -1078 -1079 -1080 -1081 -1082 -1083 -1084 -1085 -1086 -1087 -1088 -1089 -1090 -1091 -1092 -1093 -1094 -1095 -1096 -1097 -1098 -1099 -1100 -1101 -1102 -1103 -1104 -1105 -1106 -1107 -1108 -1109 -1110 -1111 -1112 -1113 -1114 -1115 -1116 -1117 -1118 -1119 -1120 -1121 -1122 -1123 -1124 -1125 -1126 -1127 -1128 -1129 -1130 -1131 -1132 -1133 -1134 -1135 -1136 -1137 -1138 -1139 -1140 -1141 -1142 -1143 -1144 -1145 -1146 -1147 -1148 -1149 -1150 -1151 -1152 -1153 -1154 -1155 -1156 -1157 -1158 -1159 -1160 -1161 -1162 -1163 -1164 -1165 -1166 -1167 -1168 -1169 -1170 -1171 -1172 -1173 -1174 -1175 -1176 -1177 -1178 -1179 -1180 -1181 -1182 -1183 -1184 -1185 -1186 -1187 -1188 -1189 -1190 -1191 -1192 -1193 -1194 -1195 -1196 -1197 -1198 -1199 -1200 -1201 -1202 -1203 -1204 -1205 -1206 -1207 -1208 -1209 -1210 -1211 -1212 -1213 -1214 -1215 -1216 -1217 -1218 -1219 -1220 -1221 -1222 -1223 -1224 -1225 -1226 -1227 -1228 -1229 -1230 -1231 -1232 -1233 -1234 -1235 -1236 -1237 -1238 -1239 -1240 -1241 -1242 -1243 -1244 -1245 -1246 -1247 -1248 -1249 -1250 -1251 -1252 -1253 -1254 -1255 -1256 -1257 -12582ร— -  -  -  -  -  -  -1ร— -  -  -  -  -  -1ร— -2ร— -  -  -24ร— -24ร— -  -  -  -  -  -6ร— -  -  -  -4ร— -  -  -  -  -6ร— -6ร— -6ร— -8ร— -6ร— -  -  -  -  -  -  -  -  -  -2ร— -6ร— -6ร— -  -60ร— -  -  -26ร— -  -  -  -  -2ร— -2ร— -2ร— -  -2ร— -  -2ร— -  -  -  -  -  -  -  -4ร— -2ร— -  -4ร— -  -  -  -  -  -16ร— -10ร— -10ร— -8ร— -  -  -  -  -  -2ร— -  -  -  -  -2ร— -2ร— -2ร— -2ร— -  -  -2ร— -  -  -2ร— -2ร— -  -  -2ร— -2ร— -  -  -2ร— -2ร— -2ร— -2ร— -  -  -  -  -  -  -  -2ร— -2ร— -2ร— -  -1ร— -12ร— -12ร— -12ร— -  -  -  -  -2ร— -1ร— -  -1ร— -  -98ร— -  -  -75ร— -  -  -  -  -  -2ร— -3ร— -  -265ร— -  -  -119ร— -  -  -  -  -  -  -  -  -2ร— -1ร— -1ร— -  -8ร— -  -  -37ร— -  -  -  -  -  -2ร— -1ร— -111ร— -  -  -  -2ร— -44ร— -  -  -  -2ร— -172ร— -  -2ร— -444ร— -  -2ร— -202ร— -  -2ร— -66ร— -  -  -  -  -  -2ร— -2ร— -2ร— -2ร— -2ร— -  -2ร— -  -2ร— -  -2ร— -  -  -2ร— -  -  -2ร— -  -  -2ร— -2ร— -2ร— -  -  -  -  -  -2ร— -  -  -  -  -  -2ร— -10ร— -  -94ร— -94ร— -160ร— -  -  -  -2ร— -2ร— -93ร— -  -2ร— -87ร— -  -  -  -  -  -2ร— -170ร— -  -  -  -  -  -  -2ร— -392ร— -392ร— -  -  -  -  -  -  -  -  -392ร— -392ร— -294ร— -  -392ร— -  -  -  -  -  -  -  -  -  -1ร— -  -  -  -2ร— -95ร— -  -98ร— -  -  -  -  -2ร— -  -  -  -  -  -  -  -  -  -  -2ร— -598ร— -  -  -  -  -  -2ร— -2ร— -  -  -  -  -  -1ร— -  -1ร— -305ร— -305ร— -  -  -  -1ร— -293ร— -  -  -2ร— -  -  -  -  -  -2ร— -82ร— -82ร— -82ร— -  -84ร— -84ร— -84ร— -1ร— -1ร— -1ร— -  -83ร— -83ร— -  -84ร— -  -  -  -  -2ร— -2ร— -2ร— -2ร— -2ร— -2ร— -  -2ร— -2ร— -2ร— -2ร— -2ร— -  -  -1ร— -12ร— -12ร— -12ร— -12ร— -  -  -  -2ร— -8ร— -8ร— -8ร— -  -  -  -2ร— -4ร— -4ร— -4ร— -2ร— -  -2ร— -2ร— -2ร— -2ร— -  -4ร— -  -  -  -  -  -  -  -  -  -  -  -  -  -2ร— -149ร— -149ร— -149ร— -  -  -8ร— -8ร— -  -54ร— -54ร— -54ร— -  -87ร— -87ร— -  -149ร— -132ร— -  -149ร— -  -  -2ร— -186ร— -  -  -2ร— -  -149ร— -  -  -197ร— -197ร— -259ร— -  -197ร— -  -  -  -  -2ร— -  -  -  -2ร— -8ร— -2ร— -2ร— -2ร— -2ร— -  -6ร— -  -  -  -  -  -2ร— -8ร— -  -8ร— -36ร— -  -22ร— -18ร— -10ร— -8ร— -6ร— -6ร— -4ร— -  -  -  -  -  -8ร— -  -18ร— -18ร— -18ร— -18ร— -  -18ร— -18ร— -18ร— -  -  -18ร— -14ร— -14ร— -14ร— -  -18ร— -  -  -  -  -2ร— -2ร— -2ร— -  -2ร— -4ร— -4ร— -4ร— -  -4ร— -  -  -  -  -  -  -  -  -  -  -  -2ร— -559ร— -  -  -2ร— -  -  -  -  -  -275ร— -275ร— -275ร— -  -275ร— -275ร— -275ร— -275ร— -275ร— -275ร— -275ร— -626ร— -46ร— -580ร— -12ร— -568ร— -22ร— -546ร— -5ร— -541ร— -222ร— -222ร— -319ร— -88ร— -88ร— -231ร— -65ร— -65ร— -65ร— -166ร— -28ร— -28ร— -28ร— -  -138ร— -138ร— -89ร— -89ร— -  -49ร— -49ร— -49ร— -49ร— -  -  -  -275ร— -232ร— -134ร— -134ร— -134ร— -100ร— -  -34ร— -34ร— -94ร— -  -34ร— -  -  -98ร— -98ร— -67ร— -  -31ร— -31ร— -31ร— -31ร— -  -  -  -275ร— -  -  -  -  -  -  -2ร— -  -  -  -1ร— -2ร— -  -  -2ร— -2ร— -  -  -  -2ร— -464ร— -  -  -  -  -  -  -  -  -2ร— -78ร— -  -  -  -  -  -  -  -  -  -2ร— -193ร— -193ร— -193ร— -197ร— -197ร— -197ร— -  -91ร— -91ร— -  -98ร— -98ร— -  -8ร— -8ร— -  -  -193ร— -  -  -  -  -  -  -  -  -  -  -2ร— -341ร— -341ร— -341ร— -478ร— -478ร— -  -193ร— -193ร— -193ร— -  -66ร— -62ร— -62ร— -  -  -  -  -  -66ร— -  -  -  -  -  -  -219ร— -1ร— -1ร— -  -219ร— -  -  -  -  -  -  -  -  -  -  -  -  -  -2ร— -193ร— -193ร— -193ร— -193ร— -193ร— -193ร— -137ร— -137ร— -87ร— -  -  -  -87ร— -87ร— -87ร— -  -  -  -  -87ร— -  -87ร— -  -  -193ร— -193ร— -87ร— -  -  -  -  -  -  -  -  -193ร— -193ร— -2ร— -2ร— -2ร— -  -2ร— -2ร— -  -  -  -  -  -  -  -2ร— -12ร— -12ร— -2ร— -10ร— -2ร— -8ร— -2ร— -  -6ร— -  -  -  -  -2ร— -123ร— -  -  -  -  -  -  -  -  -  -  -  -2ร— -91ร— -91ร— -91ร— -260ร— -  -  -  -92ร— -30ร— -10ร— -10ร— -  -  -62ร— -62ร— -62ร— -  -92ร— -  -  -168ร— -8ร— -8ร— -8ร— -  -  -160ร— -160ร— -160ร— -82ร— -9ร— -4ร— -  -  -73ร— -  -  -  -18ร— -18ร— -  -55ร— -8ร— -  -55ร— -4ร— -4ร— -  -  -51ร— -51ร— -  -  -78ร— -24ร— -54ร— -4ร— -50ร— -10ร— -40ร— -4ร— -36ร— -4ร— -32ร— -22ร— -10ร— -2ร— -  -8ร— -  -160ร— -  -  -91ร— -  -  -  -  -  -  -  -  -  -2ร— -98ร— -98ร— -  -  -98ร— -8ร— -  -  -  -90ร— -38ร— -38ร— -16ร— -2ร— -2ร— -  -16ร— -22ร— -20ร— -  -38ร— -52ร— -42ร— -42ร— -42ร— -  -  -  -  -  -  -52ร— -14ร— -28ร— -26ร— -26ร— -24ร— -24ร— -4ร— -  -  -  -  -  -  -  -  -38ร— -38ร— -38ร— -78ร— -54ร— -54ร— -50ร— -4ร— -2ร— -2ร— -  -4ร— -  -46ร— -46ร— -40ร— -40ร— -  -  -  -  -  -  -  -  -  -  -  -  -2ร— -8ร— -8ร— -54ร— -38ร— -38ร— -14ร— -2ร— -12ร— -2ร— -10ร— -2ร— -8ร— -2ร— -6ร— -2ร— -4ร— -2ร— -  -2ร— -  -  -24ร— -  -  -  -8ร— -  -  -2ร— -  -  -  -  -  -2ร— -1ร— -  -  -  -  -  -  -  -2ร— -24ร— -24ร— -24ร— -18ร— -18ร— -15ร— -  -  -  -  -  -  -2ร— -103ร— -18ร— -  -  -103ร— -103ร— -103ร— -88ร— -  -  -  -  -  -  -2ร— -2ร— -6ร— -6ร— -6ร— -6ร— -6ร— -  -  -  -1ร— -6ร— -  -1ร— -6ร— -  -  -  -  -  -  -2ร— -  -  -  -  -2ร— -  -  -  -  -  -1ร— -394ร— -394ร— -201ร— -  -193ร— -  -394ร— -  -  -  -  -  -  -1ร— -193ร— -193ร— -193ร— -193ร— -193ร— -193ร— -193ร— -193ร— -  -  -  -1ร— -394ร— -394ร— -428ร— -  -  -  -  -  -  -  -1ร— -148ร— -148ร— -148ร— -148ร— -148ร— -148ร— -148ร— -  -  -  -  -2ร— -2ร— -48ร— -  -  -  -2ร— -  -  -  -  -  -  -  -  -  -  -2ร— -94ร— -  -  -  -  -  -  -  -  -2ร— -96ร— -  -  -  -  -96ร— -170ร— -170ร— -170ร— -104ร— -104ร— -104ร— -104ร— -  -170ร— -170ร— -104ร— -8ร— -  -104ร— -  -170ร— -  -  -  -  -  -  -2ร— -50ร— -50ร— -50ร— -50ร— -12ร— -12ร— -  -50ร— -50ร— -  -  -  -  -  -  -  -  -  -  -  -  -2ร— -104ร— -104ร— -104ร— -104ร— -180ร— -180ร— -114ร— -  -  -104ร— -  -  -  -  -  -  -  -  -2ร— -189ร— -  -2ร— -  -2ร— -2ร— -2ร— -2ร— -2ร— -2ร— -  -  -  -2ร— -  -  -  -  -1ร— -20ร— -  -  -  -  -  -  -  -  -  -  -2ร— -  -  -2ร— - 
var hyperHTML = (function (global) {
-'use strict';
- 
-// hyperHTML.Component is a very basic class
-// able to create Custom Elements like components
-// including the ability to listen to connect/disconnect
-// events via onconnect/ondisconnect attributes
-function Component() {}
- 
-// components will lazily define html or svg properties
-// as soon as these are invoked within the .render() method
-// Such render() method is not provided by the base class
-// but it must be available through the Component extend.
-function setup(content) {
-  Object.defineProperties(Component.prototype, {
-    handleEvent: {
-      value: function value(e) {
-        var ct = e.currentTarget;
-        this['getAttribute' in ct && ct.getAttribute('data-call') || 'on' + e.type](e);
-      }
-    },
-    html: lazyGetter('html', content),
-    svg: lazyGetter('svg', content),
-    state: lazyGetter('state', function () {
-      return this.defaultState;
-    }),
-    defaultState: {
-      get: function get() {
-        return {};
-      }
-    },
-    setState: {
-      value: function value(state) {
-        var target = this.state;
-        var source = typeof state === 'function' ? state.call(this, target) : state;
-        for (var key in source) {
-          target[key] = source[key];
-        }this.render();
-      }
-    }
-  });
-}
- 
-// instead of a secret key I could've used a WeakMap
-// However, attaching a property directly will result
-// into better performance with thousands of components
-// hanging around, and less memory pressure caused by the WeakMap
-var lazyGetter = function lazyGetter(type, fn) {
-  var secret = '_' + type + '$';
-  return {
-    get: function get() {
-      return this[secret] || (this[type] = fn.call(this, type));
-    },
-    set: function set(value) {
-      Object.defineProperty(this, secret, { configurable: true, value: value });
-    }
-  };
-};
- 
-var intents = {};
-var keys = [];
-var hasOwnProperty = intents.hasOwnProperty;
- 
-var length = 0;
- 
-var Intent = {
- 
-  // hyperHTML.define('intent', (object, update) => {...})
-  // can be used to define a third parts update mechanism
-  // when every other known mechanism failed.
-  // hyper.define('user', info => info.name);
-  // hyper(node)`<p>${{user}}</p>`;
-  define: function define(intent, callback) {
-    if (!(intent in intents)) {
-      length = keys.push(intent);
-    }
-    intents[intent] = callback;
-  },
- 
-  // this method is used internally as last resort
-  // to retrieve a value out of an object
-  invoke: function invoke(object, callback) {
-    for (var i = 0; i < length; i++) {
-      var key = keys[i];
-      if (hasOwnProperty.call(object, key)) {
-        return intents[key](object[key], callback);
-      }
-    }
-  }
-};
- 
-var G = document.defaultView;
- 
-// Node.CONSTANTS
-// 'cause some engine has no global Node defined
-// (i.e. Node, NativeScript, basicHTML ... )
-var ELEMENT_NODE = 1;
-var TEXT_NODE = 3;
-var COMMENT_NODE = 8;
-var DOCUMENT_FRAGMENT_NODE = 11;
- 
-// HTML related constants
-var VOID_ELEMENTS = /^area|base|br|col|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr$/i;
- 
-// SVG related constants
-var OWNER_SVG_ELEMENT = 'ownerSVGElement';
-var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
- 
-// Custom Elements / MutationObserver constants
-var CONNECTED = 'connected';
-var DISCONNECTED = 'dis' + CONNECTED;
- 
-// hyperHTML related constants
-var EXPANDO = '_hyper: ';
-var SHOULD_USE_TEXT_CONTENT = /^style|textarea$/i;
-var UID = EXPANDO + (Math.random() * new Date() | 0) + ';';
-var UIDC = '<!--' + UID + '-->';
- 
-// you know that kind of basics you need to cover
-// your use case only but you don't want to bloat the library?
-// There's even a package in here:
-// https://www.npmjs.com/package/poorlyfills
- 
-// used to dispatch simple events
-var Event = G.Event;
-try {
-  new Event('Event');
-} catch (o_O) {
-  Event = function Event(type) {
-    var e = document.createEvent('Event');
-    e.initEvent(type, false, false);
-    return e;
-  };
-}
- 
-// used to store template literals
-var Map = G.Map || function Map() {
-  var keys = [],
-      values = [];
-  return {
-    get: function get(obj) {
-      return values[keys.indexOf(obj)];
-    },
-    set: function set(obj, value) {
-      values[keys.push(obj) - 1] = value;
-    }
-  };
-};
- 
-// used to store wired content
-var WeakMap = G.WeakMap || function WeakMap() {
-  return {
-    get: function get(obj) {
-      return obj[UID];
-    },
-    set: function set(obj, value) {
-      Object.defineProperty(obj, UID, {
-        configurable: true,
-        value: value
-      });
-    }
-  };
-};
- 
-// used to store hyper.Components
-var WeakSet = G.WeakSet || function WeakSet() {
-  var wm = new WeakMap();
-  return {
-    add: function add(obj) {
-      wm.set(obj, true);
-    },
-    has: function has(obj) {
-      return wm.get(obj) === true;
-    }
-  };
-};
- 
-// used to be sure IE9 or older Androids work as expected
-var isArray = Array.isArray || function (toString) {
-  return function (arr) {
-    return toString.call(arr) === '[object Array]';
-  };
-}({}.toString);
- 
-var trim = UID.trim || function () {
-  return this.replace(/^\s+|\s+$/g, '');
-};
- 
-// these are tiny helpers to simplify most common operations needed here
-var create = function create(node, type) {
-  return doc(node).createElement(type);
-};
-var doc = function doc(node) {
-  return node.ownerDocument || node;
-};
-var fragment = function fragment(node) {
-  return doc(node).createDocumentFragment();
-};
-var text = function text(node, _text) {
-  return doc(node).createTextNode(_text);
-};
- 
-// TODO:  I'd love to code-cover RegExp too here
-//        these are fundamental for this library
- 
-var spaces = ' \\f\\n\\r\\t';
-var almostEverything = '[^ ' + spaces + '\\/>"\'=]+';
-var attrName = '[ ' + spaces + ']+' + almostEverything;
-var tagName = '<([A-Za-z]+[A-Za-z0-9:_-]*)((?:';
-var attrPartials = '(?:=(?:\'[^\']*?\'|"[^"]*?"|<[^>]*?>|' + almostEverything + '))?)';
- 
-var attrSeeker = new RegExp(tagName + attrName + attrPartials + '+)([ ' + spaces + ']*/?>)', 'g');
- 
-var selfClosing = new RegExp(tagName + attrName + attrPartials + '*)([ ' + spaces + ']*/>)', 'g');
- 
-var testFragment = fragment(document);
- 
-// DOM4 node.append(...many)
-var hasAppend = 'append' in testFragment;
- 
-// detect old browsers without HTMLTemplateElement content support
-var hasContent = 'content' in create(document, 'template');
- 
-// IE 11 has problems with cloning templates: it "forgets" empty childNodes
-testFragment.appendChild(text(testFragment, 'g'));
-testFragment.appendChild(text(testFragment, ''));
-var hasDoomedCloneNode = testFragment.cloneNode(true).childNodes.length === 1;
- 
-// old browsers need to fallback to cloneNode
-// Custom Elements V0 and V1 will work polyfilled
-// but native implementations need importNode instead
-// (specially Chromium and its old V0 implementation)
-var hasImportNode = 'importNode' in document;
- 
-// appends an array of nodes
-// to a generic node/fragment
-// When available, uses append passing all arguments at once
-// hoping that's somehow faster, even if append has more checks on type
-var append = hasAppend ? function (node, childNodes) {
-  node.append.apply(node, childNodes);
-} : function (node, childNodes) {
-  var length = childNodes.length;
-  for (var i = 0; i < length; i++) {
-    node.appendChild(childNodes[i]);
-  }
-};
- 
-var findAttributes = new RegExp('(' + attrName + '=)([\'"]?)' + UIDC + '\\2', 'gi');
-var comments = function comments($0, $1, $2, $3) {
-  return '<' + $1 + $2.replace(findAttributes, replaceAttributes) + $3;
-};
-var replaceAttributes = function replaceAttributes($0, $1, $2) {
-  return $1 + ($2 || '"') + UID + ($2 || '"');
-};
- 
-// given a node and a generic HTML content,
-// create either an SVG or an HTML fragment
-// where such content will be injected
-var createFragment = function createFragment(node, html) {
-  return (OWNER_SVG_ELEMENT in node ? SVGFragment : HTMLFragment)(node, html.replace(attrSeeker, comments));
-};
- 
-// IE/Edge shenanigans proof cloneNode
-// it goes through all nodes manually
-// instead of relying the engine to suddenly
-// merge nodes together
-var cloneNode = hasDoomedCloneNode ? function (node) {
-  var clone = node.cloneNode();
-  var childNodes = node.childNodes ||
-  // this is an excess of caution
-  // but some node, in IE, might not
-  // have childNodes property.
-  // The following fallback ensure working code
-  // in older IE without compromising performance
-  // or any other browser/engine involved.
-  /* istanbul ignore next */
-  [];
-  var length = childNodes.length;
-  for (var i = 0; i < length; i++) {
-    clone.appendChild(cloneNode(childNodes[i]));
-  }
-  return clone;
-} :
-// the following ignore is due code-coverage
-// combination of not having document.importNode
-// but having a working node.cloneNode.
-// This shenario is common on older Android/WebKit browsers
-// but basicHTML here tests just two major cases:
-// with document.importNode or with broken cloneNode.
-/* istanbul ignore next */
-function (node) {
-  return node.cloneNode(true);
-};
- 
-// used to import html into fragments
-var importNode = hasImportNode ? function (doc$$1, node) {
-  return doc$$1.importNode(node, true);
-} : function (doc$$1, node) {
-  return cloneNode(node);
-};
- 
-// just recycling a one-off array to use slice
-// in every needed place
-var slice = [].slice;
- 
-// lazy evaluated, returns the unique identity
-// of a template literal, as tempalte literal itself.
-// By default, ES2015 template literals are unique
-// tag`a${1}z` === tag`a${2}z`
-// even if interpolated values are different
-// the template chunks are in a frozen Array
-// that is identical each time you use the same
-// literal to represent same static content
-// around its own interpolations.
-var unique = function unique(template) {
-  return _TL(template);
-};
- 
-// TL returns a unique version of the template
-// it needs lazy feature detection
-// (cannot trust literals with transpiled code)
-var _TL = function TL(template) {
-  if (
-  // TypeScript template literals are not standard
-  template.propertyIsEnumerable('raw') ||
-  // Firefox < 55 has not standard implementation neither
-  /Firefox\/(\d+)/.test((G.navigator || {}).userAgent) && parseFloat(RegExp.$1) < 55) {
-    // in these cases, address templates once
-    var templateObjects = {};
-    // but always return the same template
-    _TL = function TL(template) {
-      var key = '_' + template.join(UID);
-      return templateObjects[key] || (templateObjects[key] = template);
-    };
-  } else {
-    // make TL an identity like function
-    _TL = function TL(template) {
-      return template;
-    };
-  }
-  return _TL(template);
-};
- 
-// create document fragments via native template
-// with a fallback for browsers that won't be able
-// to deal with some injected element such <td> or others
-var HTMLFragment = hasContent ? function (node, html) {
-  var container = create(node, 'template');
-  container.innerHTML = html;
-  return container.content;
-} : function (node, html) {
-  var container = create(node, 'template');
-  var content = fragment(node);
-  if (/^[^\S]*?<(col(?:group)?|t(?:head|body|foot|r|d|h))/i.test(html)) {
-    var selector = RegExp.$1;
-    container.innerHTML = '<table>' + html + '</table>';
-    append(content, slice.call(container.querySelectorAll(selector)));
-  } else {
-    container.innerHTML = html;
-    append(content, slice.call(container.childNodes));
-  }
-  return content;
-};
- 
-// creates SVG fragment with a fallback for IE that needs SVG
-// within the HTML content
-var SVGFragment = hasContent ? function (node, html) {
-  var content = fragment(node);
-  var container = doc(node).createElementNS(SVG_NAMESPACE, 'svg');
-  container.innerHTML = html;
-  append(content, slice.call(container.childNodes));
-  return content;
-} : function (node, html) {
-  var content = fragment(node);
-  var container = create(node, 'div');
-  container.innerHTML = '<svg xmlns="' + SVG_NAMESPACE + '">' + html + '</svg>';
-  append(content, slice.call(container.firstChild.childNodes));
-  return content;
-};
- 
-function Wire(childNodes) {
-  this.childNodes = childNodes;
-  this.length = childNodes.length;
-  this.first = childNodes[0];
-  this.last = childNodes[this.length - 1];
-}
- 
-// when a wire is inserted, all its nodes will follow
-Wire.prototype.insert = function insert() {
-  var df = fragment(this.first);
-  append(df, this.childNodes);
-  return df;
-};
- 
-// when a wire is removed, all its nodes must be removed as well
-Wire.prototype.remove = function remove() {
-  var first = this.first;
-  var last = this.last;
-  if (this.length === 2) {
-    last.parentNode.removeChild(last);
-  } else {
-    var range = doc(first).createRange();
-    range.setStartBefore(this.childNodes[1]);
-    range.setEndAfter(last);
-    range.deleteContents();
-  }
-  return first;
-};
- 
-// every template literal interpolation indicates
-// a precise target in the DOM the template is representing.
-// `<p id=${'attribute'}>some ${'content'}</p>`
-// hyperHTML finds only once per template literal,
-// hence once per entire application life-cycle,
-// all nodes that are related to interpolations.
-// These nodes are stored as indexes used to retrieve,
-// once per upgrade, nodes that will change on each future update.
-// A path example is [2, 0, 1] representing the operation:
-// node.childNodes[2].childNodes[0].childNodes[1]
-// Attributes are addressed via their owner node and their name.
-var createPath = function createPath(node) {
-  var path = [];
-  var parentNode = void 0;
-  switch (node.nodeType) {
-    case ELEMENT_NODE:
-    case DOCUMENT_FRAGMENT_NODE:
-      parentNode = node;
-      break;
-    case COMMENT_NODE:
-      parentNode = node.parentNode;
-      prepend(path, parentNode, node);
-      break;
-    default:
-      parentNode = node.ownerElement;
-      break;
-  }
-  for (node = parentNode; parentNode = parentNode.parentNode; node = parentNode) {
-    prepend(path, parentNode, node);
-  }
-  return path;
-};
- 
-var prepend = function prepend(path, parent, node) {
-  path.unshift(path.indexOf.call(parent.childNodes, node));
-};
- 
-var Path = {
-  create: function create(type, node, name) {
-    return { type: type, name: name, node: node, path: createPath(node) };
-  },
-  find: function find(node, path) {
-    var length = path.length;
-    for (var i = 0; i < length; i++) {
-      node = node.childNodes[path[i]];
-    }
-    return node;
-  }
-};
- 
-// from https://github.com/developit/preact/blob/33fc697ac11762a1cb6e71e9847670d047af7ce5/src/constants.js
-var IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i;
- 
-// style is handled as both string and object
-// even if the target is an SVG element (consistency)
-var Style = (function (node, original, isSVG) {
-  if (isSVG) {
-    var style = original.cloneNode(true);
-    style.value = '';
-    node.setAttributeNode(style);
-    return update(style, isSVG);
-  }
-  return update(node.style, isSVG);
-});
- 
-// the update takes care or changing/replacing
-// only properties that are different or
-// in case of string, the whole node
-var update = function update(style, isSVG) {
-  var oldType = void 0,
-      oldValue = void 0;
-  return function (newValue) {
-    switch (typeof newValue) {
-      case 'object':
-        if (newValue) {
-          if (oldType === 'object') {
-            if (!isSVG) {
-              if (oldValue !== newValue) {
-                for (var key in oldValue) {
-                  if (!(key in newValue)) {
-                    style[key] = '';
-                  }
-                }
-              }
-            }
-          } else {
-            if (isSVG) style.value = '';else style.cssText = '';
-          }
-          var info = isSVG ? {} : style;
-          for (var _key in newValue) {
-            var value = newValue[_key];
-            info[_key] = typeof value === 'number' && !IS_NON_DIMENSIONAL.test(_key) ? value + 'px' : value;
-          }
-          oldType = 'object';
-          if (isSVG) style.value = toStyle(oldValue = info);else oldValue = newValue;
-          break;
-        }
-      default:
-        if (oldValue != newValue) {
-          oldType = 'string';
-          oldValue = newValue;
-          if (isSVG) style.value = newValue || '';else style.cssText = newValue || '';
-        }
-        break;
-    }
-  };
-};
- 
-var hyphen = /([^A-Z])([A-Z]+)/g;
-var ized = function ized($0, $1, $2) {
-  return $1 + '-' + $2.toLowerCase();
-};
-var toStyle = function toStyle(object) {
-  var css = [];
-  for (var key in object) {
-    css.push(key.replace(hyphen, ized), ':', object[key], ';');
-  }
-  return css.join('');
-};
- 
-/* AUTOMATICALLY IMPORTED, DO NOT MODIFY */
-/*! (c) 2017 Andrea Giammarchi (ISC) */
- 
-/**
- * This code is a revisited port of the snabbdom vDOM diffing logic,
- * the same that fuels as fork Vue.js or other libraries.
- * @credits https://github.com/snabbdom/snabbdom
- */
- 
-var identity = function identity(O) {
-  return O;
-};
- 
-var domdiff = function domdiff(parentNode, // where changes happen
-currentNodes, // Array of current items/nodes
-futureNodes, // Array of future items/nodes
-getNode, // optional way to retrieve a node from an item
-beforeNode // optional item/node to use as insertBefore delimiter
-) {
-  var get = getNode || identity;
-  var before = beforeNode == null ? null : get(beforeNode, 0);
-  var currentStart = 0,
-      futureStart = 0;
-  var currentEnd = currentNodes.length - 1;
-  var currentStartNode = currentNodes[0];
-  var currentEndNode = currentNodes[currentEnd];
-  var futureEnd = futureNodes.length - 1;
-  var futureStartNode = futureNodes[0];
-  var futureEndNode = futureNodes[futureEnd];
-  while (currentStart <= currentEnd && futureStart <= futureEnd) {
-    if (currentStartNode == null) {
-      currentStartNode = currentNodes[++currentStart];
-    } else if (currentEndNode == null) {
-      currentEndNode = currentNodes[--currentEnd];
-    } else if (futureStartNode == null) {
-      futureStartNode = futureNodes[++futureStart];
-    } else if (futureEndNode == null) {
-      futureEndNode = futureNodes[--futureEnd];
-    } else if (currentStartNode == futureStartNode) {
-      currentStartNode = currentNodes[++currentStart];
-      futureStartNode = futureNodes[++futureStart];
-    } else if (currentEndNode == futureEndNode) {
-      currentEndNode = currentNodes[--currentEnd];
-      futureEndNode = futureNodes[--futureEnd];
-    } else if (currentStartNode == futureEndNode) {
-      parentNode.insertBefore(get(currentStartNode, 1), get(currentEndNode, -0).nextSibling);
-      currentStartNode = currentNodes[++currentStart];
-      futureEndNode = futureNodes[--futureEnd];
-    } else if (currentEndNode == futureStartNode) {
-      parentNode.insertBefore(get(currentEndNode, 1), get(currentStartNode, 0));
-      currentEndNode = currentNodes[--currentEnd];
-      futureStartNode = futureNodes[++futureStart];
-    } else {
-      var index = currentNodes.indexOf(futureStartNode);
-      if (index < 0) {
-        parentNode.insertBefore(get(futureStartNode, 1), get(currentStartNode, 0));
-        futureStartNode = futureNodes[++futureStart];
-      } else {
-        var el = currentNodes[index];
-        currentNodes[index] = null;
-        parentNode.insertBefore(get(el, 1), get(currentStartNode, 0));
-        futureStartNode = futureNodes[++futureStart];
-      }
-    }
-  }
-  if (currentStart <= currentEnd || futureStart <= futureEnd) {
-    if (currentStart > currentEnd) {
-      var pin = futureNodes[futureEnd + 1];
-      var place = pin == null ? before : get(pin, 0);
-      if (futureStart === futureEnd) {
-        parentNode.insertBefore(get(futureNodes[futureStart], 1), place);
-      } else {
-        var fragment = parentNode.ownerDocument.createDocumentFragment();
-        while (futureStart <= futureEnd) {
-          fragment.appendChild(get(futureNodes[futureStart++], 1));
-        }
-        parentNode.insertBefore(fragment, place);
-      }
-    } else {
-      if (currentNodes[currentStart] == null) currentStart++;
-      if (currentStart === currentEnd) {
-        parentNode.removeChild(get(currentNodes[currentStart], -1));
-      } else {
-        var range = parentNode.ownerDocument.createRange();
-        range.setStartBefore(get(currentNodes[currentStart], -1));
-        range.setEndAfter(get(currentNodes[currentEnd], -1));
-        range.deleteContents();
-      }
-    }
-  }
-  return futureNodes;
-};
- 
-// hyper.Component have a connected/disconnected
-// mechanism provided by MutationObserver
-// This weak set is used to recognize components
-// as DOM node that needs to trigger connected/disconnected events
-var components = new WeakSet();
- 
-// a basic dictionary used to filter already cached attributes
-// while looking for special hyperHTML values.
-function Cache() {}
-Cache.prototype = Object.create(null);
- 
-// returns an intent to explicitly inject content as html
-var asHTML = function asHTML(html) {
-  return { html: html };
-};
- 
-// returns nodes from wires and components
-var asNode = function asNode(item, i) {
-  return 'ELEMENT_NODE' in item ? item : item.constructor === Wire ?
-  // in the Wire case, the content can be
-  // removed, post-pended, inserted, or pre-pended and
-  // all these cases are handled by domdiff already
-  /* istanbul ignore next */
-  1 / i < 0 ? i ? item.remove() : item.last : i ? item.insert() : item.first : asNode(item.render(), i);
-};
- 
-// returns true if domdiff can handle the value
-var canDiff = function canDiff(value) {
-  return 'ELEMENT_NODE' in value || value instanceof Wire || value instanceof Component;
-};
- 
-// updates are created once per context upgrade
-// within the main render function (../hyper/render.js)
-// These are an Array of callbacks to invoke passing
-// each interpolation value.
-// Updates can be related to any kind of content,
-// attributes, or special text-only cases such <style>
-// elements or <textarea>
-var create$1 = function create$$1(root, paths) {
-  var updates = [];
-  var length = paths.length;
-  for (var i = 0; i < length; i++) {
-    var info = paths[i];
-    var node = Path.find(root, info.path);
-    switch (info.type) {
-      case 'any':
-        updates.push(setAnyContent(node, []));
-        break;
-      case 'attr':
-        updates.push(setAttribute(node, info.name, info.node));
-        break;
-      case 'text':
-        updates.push(setTextContent(node));
-        break;
-    }
-  }
-  return updates;
-};
- 
-// finding all paths is a one-off operation performed
-// when a new template literal is used.
-// The goal is to map all target nodes that will be
-// used to update content/attributes every time
-// the same template literal is used to create content.
-// The result is a list of paths related to the template
-// with all the necessary info to create updates as
-// list of callbacks that target directly affected nodes.
-var find = function find(node, paths, parts) {
-  var childNodes = node.childNodes;
-  var length = childNodes.length;
-  for (var i = 0; i < length; i++) {
-    var child = childNodes[i];
-    switch (child.nodeType) {
-      case ELEMENT_NODE:
-        findAttributes$1(child, paths, parts);
-        find(child, paths, parts);
-        break;
-      case COMMENT_NODE:
-        if (child.textContent === UID) {
-          parts.shift();
-          paths.push(
-          // basicHTML or other non standard engines
-          // might end up having comments in nodes
-          // where they shouldn't, hence this check.
-          SHOULD_USE_TEXT_CONTENT.test(node.nodeName) ? Path.create('text', node) : Path.create('any', child));
-        }
-        break;
-      case TEXT_NODE:
-        // the following ignore is actually covered by browsers
-        // only basicHTML ends up on previous COMMENT_NODE case
-        // instead of TEXT_NODE because it knows nothing about
-        // special style or textarea behavior
-        /* istanbul ignore if */
-        Iif (SHOULD_USE_TEXT_CONTENT.test(node.nodeName) && trim.call(child.textContent) === UIDC) {
-          parts.shift();
-          paths.push(Path.create('text', node));
-        }
-        break;
-    }
-  }
-};
- 
-// attributes are searched via unique hyperHTML id value.
-// Despite HTML being case insensitive, hyperHTML is able
-// to recognize attributes by name in a caseSensitive way.
-// This plays well with Custom Elements definitions
-// and also with XML-like environments, without trusting
-// the resulting DOM but the template literal as the source of truth.
-// IE/Edge has a funny bug with attributes and these might be duplicated.
-// This is why there is a cache in charge of being sure no duplicated
-// attributes are ever considered in future updates.
-var findAttributes$1 = function findAttributes(node, paths, parts) {
-  var cache = new Cache();
-  var attributes = node.attributes;
-  var array = slice.call(attributes);
-  var remove = [];
-  var length = array.length;
-  for (var i = 0; i < length; i++) {
-    var attribute = array[i];
-    if (attribute.value === UID) {
-      var name = attribute.name;
-      // the following ignore is covered by IE
-      // and the IE9 double viewBox test
-      /* istanbul ignore else */
-      Eif (!(name in cache)) {
-        var realName = parts.shift().replace(/^(?:|[\S\s]*?\s)(\S+?)=['"]?$/, '$1');
-        cache[name] = attributes[realName] ||
-        // the following ignore is covered by browsers
-        // while basicHTML is already case-sensitive
-        /* istanbul ignore next */
-        attributes[realName.toLowerCase()];
-        paths.push(Path.create('attr', cache[name], realName));
-      }
-      remove.push(attribute);
-    }
-  }
-  var len = remove.length;
-  for (var _i = 0; _i < len; _i++) {
-    node.removeAttributeNode(remove[_i]);
-  }
- 
-  // This is a very specific Firefox/Safari issue
-  // but since it should be a not so common pattern,
-  // it's probably worth patching regardless.
-  // Basically, scripts created through strings are death.
-  // You need to create fresh new scripts instead.
-  // TODO: is there any other node that needs such nonsense ?
-  var nodeName = node.nodeName;
-  if (/^script$/i.test(nodeName)) {
-    var script = create(node, nodeName);
-    for (var _i2 = 0; _i2 < attributes.length; _i2++) {
-      script.setAttributeNode(attributes[_i2].cloneNode(true));
-    }
-    script.textContent = node.textContent;
-    node.parentNode.replaceChild(script, node);
-  }
-};
- 
-// when a Promise is used as interpolation value
-// its result must be parsed once resolved.
-// This callback is in charge of understanding what to do
-// with a returned value once the promise is resolved.
-var invokeAtDistance = function invokeAtDistance(value, callback) {
-  callback(value.placeholder);
-  if ('text' in value) {
-    Promise.resolve(value.text).then(String).then(callback);
-  } else if ('any' in value) {
-    Promise.resolve(value.any).then(callback);
-  } else if ('html' in value) {
-    Promise.resolve(value.html).then(asHTML).then(callback);
-  } else {
-    Promise.resolve(Intent.invoke(value, callback)).then(callback);
-  }
-};
- 
-// quick and dirty way to check for Promise/ish values
-var isPromise_ish = function isPromise_ish(value) {
-  return value != null && 'then' in value;
-};
- 
-// in a hyper(node)`<div>${content}</div>` case
-// everything could happen:
-//  * it's a JS primitive, stored as text
-//  * it's null or undefined, the node should be cleaned
-//  * it's a component, update the content by rendering it
-//  * it's a promise, update the content once resolved
-//  * it's an explicit intent, perform the desired operation
-//  * it's an Array, resolve all values if Promises and/or
-//    update the node with the resulting list of content
-var setAnyContent = function setAnyContent(node, childNodes) {
-  var fastPath = false;
-  var oldValue = void 0;
-  var anyContent = function anyContent(value) {
-    switch (typeof value) {
-      case 'string':
-      case 'number':
-      case 'boolean':
-        if (fastPath) {
-          if (oldValue !== value) {
-            oldValue = value;
-            childNodes[0].textContent = value;
-          }
-        } else {
-          fastPath = true;
-          oldValue = value;
-          childNodes = domdiff(node.parentNode, childNodes, [text(node, value)], asNode, node);
-        }
-        break;
-      case 'object':
-      case 'undefined':
-        if (value == null) {
-          fastPath = false;
-          childNodes = domdiff(node.parentNode, childNodes, [], asNode, node);
-          break;
-        }
-      default:
-        fastPath = false;
-        oldValue = value;
-        if (isArray(value)) {
-          if (value.length === 0) {
-            if (childNodes.length) {
-              childNodes = domdiff(node.parentNode, childNodes, [], asNode, node);
-            }
-          } else {
-            switch (typeof value[0]) {
-              case 'string':
-              case 'number':
-              case 'boolean':
-                anyContent({ html: value });
-                break;
-              case 'object':
-                if (isArray(value[0])) {
-                  value = value.concat.apply([], value);
-                }
-                if (isPromise_ish(value[0])) {
-                  Promise.all(value).then(anyContent);
-                  break;
-                }
-              default:
-                childNodes = domdiff(node.parentNode, childNodes, value, asNode, node);
-                break;
-            }
-          }
-        } else if (canDiff(value)) {
-          childNodes = domdiff(node.parentNode, childNodes, value.nodeType === DOCUMENT_FRAGMENT_NODE ? slice.call(value.childNodes) : [value], asNode, node);
-        } else if (isPromise_ish(value)) {
-          value.then(anyContent);
-        } else if ('placeholder' in value) {
-          invokeAtDistance(value, anyContent);
-        } else if ('text' in value) {
-          anyContent(String(value.text));
-        } else if ('any' in value) {
-          anyContent(value.any);
-        } else if ('html' in value) {
-          childNodes = domdiff(node.parentNode, childNodes, slice.call(createFragment(node, [].concat(value.html).join('')).childNodes), asNode, node);
-        } else if ('length' in value) {
-          anyContent(slice.call(value));
-        } else {
-          anyContent(Intent.invoke(value, anyContent));
-        }
-        break;
-    }
-  };
-  return anyContent;
-};
- 
-// there are four kind of attributes, and related behavior:
-//  * events, with a name starting with `on`, to add/remove event listeners
-//  * special, with a name present in their inherited prototype, accessed directly
-//  * regular, accessed through get/setAttribute standard DOM methods
-//  * style, the only regular attribute that also accepts an object as value
-//    so that you can style=${{width: 120}}. In this case, the behavior has been
-//    fully inspired by Preact library and its simplicity.
-var setAttribute = function setAttribute(node, name, original) {
-  var isSVG = OWNER_SVG_ELEMENT in node;
-  var oldValue = void 0;
-  // if the attribute is the style one
-  // handle it differently from others
-  if (name === 'style') {
-    return Style(node, original, isSVG);
-  }
-  // the name is an event one,
-  // add/remove event listeners accordingly
-  else if (/^on/.test(name)) {
-      var type = name.slice(2);
-      if (type === CONNECTED || type === DISCONNECTED) {
-        if (notObserving) {
-          notObserving = false;
-          observe();
-        }
-        components.add(node);
-      } else if (name.toLowerCase() in node) {
-        type = type.toLowerCase();
-      }
-      return function (newValue) {
-        if (oldValue !== newValue) {
-          if (oldValue) node.removeEventListener(type, oldValue, false);
-          oldValue = newValue;
-          if (newValue) node.addEventListener(type, newValue, false);
-        }
-      };
-    }
-    // the attribute is special ('value' in input)
-    // and it's not SVG *or* the name is exactly data,
-    // in this case assign the value directly
-    else if (name === 'data' || !isSVG && name in node) {
-        return function (newValue) {
-          if (oldValue !== newValue) {
-            oldValue = newValue;
-            if (node[name] !== newValue) {
-              node[name] = newValue;
-              if (newValue == null) {
-                node.removeAttribute(name);
-              }
-            }
-          }
-        };
-      }
-      // in every other case, use the attribute node as it is
-      // update only the value, set it as node only when/if needed
-      else {
-          var owner = false;
-          var attribute = original.cloneNode(true);
-          return function (newValue) {
-            if (oldValue !== newValue) {
-              oldValue = newValue;
-              if (attribute.value !== newValue) {
-                if (newValue == null) {
-                  if (owner) {
-                    owner = false;
-                    node.removeAttributeNode(attribute);
-                  }
-                  attribute.value = newValue;
-                } else {
-                  attribute.value = newValue;
-                  if (!owner) {
-                    owner = true;
-                    node.setAttributeNode(attribute);
-                  }
-                }
-              }
-            }
-          };
-        }
-};
- 
-// style or textareas don't accept HTML as content
-// it's pointless to transform or analyze anything
-// different from text there but it's worth checking
-// for possible defined intents.
-var setTextContent = function setTextContent(node) {
-  var oldValue = void 0;
-  var textContent = function textContent(value) {
-    if (oldValue !== value) {
-      oldValue = value;
-      if (typeof value === 'object' && value) {
-        if (isPromise_ish(value)) {
-          value.then(textContent);
-        } else if ('placeholder' in value) {
-          invokeAtDistance(value, textContent);
-        } else if ('text' in value) {
-          textContent(String(value.text));
-        } else if ('any' in value) {
-          textContent(value.any);
-        } else if ('html' in value) {
-          textContent([].concat(value.html).join(''));
-        } else if ('length' in value) {
-          textContent(slice.call(value).join(''));
-        } else {
-          textContent(Intent.invoke(value, textContent));
-        }
-      } else {
-        node.textContent = value == null ? '' : value;
-      }
-    }
-  };
-  return textContent;
-};
- 
-var Updates = { create: create$1, find: find };
- 
-// hyper.Components might need connected/disconnected notifications
-// used by components and their onconnect/ondisconnect callbacks.
-// When one of these callbacks is encountered,
-// the document starts being observed.
-var notObserving = true;
-function observe() {
- 
-  // when hyper.Component related DOM nodes
-  // are appended or removed from the live tree
-  // these might listen to connected/disconnected events
-  // This utility is in charge of finding all components
-  // involved in the DOM update/change and dispatch
-  // related information to them
-  var dispatchAll = function dispatchAll(nodes, type) {
-    var event = new Event(type);
-    var length = nodes.length;
-    for (var i = 0; i < length; i++) {
-      var node = nodes[i];
-      if (node.nodeType === ELEMENT_NODE) {
-        dispatchTarget(node, event);
-      }
-    }
-  };
- 
-  // the way it's done is via the components weak set
-  // and recursively looking for nested components too
-  var dispatchTarget = function dispatchTarget(node, event) {
-    if (components.has(node)) {
-      node.dispatchEvent(event);
-    }
- 
-    var children = node.children;
-    var length = children.length;
-    for (var i = 0; i < length; i++) {
-      dispatchTarget(children[i], event);
-    }
-  };
- 
-  // The MutationObserver is the best way to implement that
-  // but there is a fallback to deprecated DOMNodeInserted/Removed
-  // so that even older browsers/engines can help components life-cycle
-  try {
-    new MutationObserver(function (records) {
-      var length = records.length;
-      for (var i = 0; i < length; i++) {
-        var record = records[i];
-        dispatchAll(record.removedNodes, DISCONNECTED);
-        dispatchAll(record.addedNodes, CONNECTED);
-      }
-    }).observe(document, { subtree: true, childList: true });
-  } catch (o_O) {
-    document.addEventListener('DOMNodeRemoved', function (event) {
-      dispatchAll([event.target], DISCONNECTED);
-    }, false);
-    document.addEventListener('DOMNodeInserted', function (event) {
-      dispatchAll([event.target], CONNECTED);
-    }, false);
-  }
-}
- 
-// a weak collection of contexts that
-// are already known to hyperHTML
-var bewitched = new WeakMap();
- 
-// the collection of all template literals
-// since these are unique and immutable
-// for the whole application life-cycle
-var templates = new Map();
- 
-// better known as hyper.bind(node), the render is
-// the main tag function in charge of fully upgrading
-// or simply updating, contexts used as hyperHTML targets.
-// The `this` context is either a regular DOM node or a fragment.
-function render(template) {
-  var wicked = bewitched.get(this);
-  if (wicked && wicked.template === unique(template)) {
-    update$1.apply(wicked.updates, arguments);
-  } else {
-    upgrade.apply(this, arguments);
-  }
-  return this;
-}
- 
-// an upgrade is in charge of collecting template info,
-// parse it once, if unknown, to map all interpolations
-// as single DOM callbacks, relate such template
-// to the current context, and render it after cleaning the context up
-function upgrade(template) {
-  template = unique(template);
-  var info = templates.get(template) || createTemplate.call(this, template);
-  var fragment = importNode(this.ownerDocument, info.fragment);
-  var updates = Updates.create(fragment, info.paths);
-  bewitched.set(this, { template: template, updates: updates });
-  update$1.apply(updates, arguments);
-  this.textContent = '';
-  this.appendChild(fragment);
-}
- 
-// an update simply loops over all mapped DOM operations
-function update$1() {
-  var length = arguments.length;
-  for (var i = 1; i < length; i++) {
-    this[i - 1](arguments[i]);
-  }
-}
- 
-// a template can be used to create a document fragment
-// aware of all interpolations and with a list
-// of paths used to find once those nodes that need updates,
-// no matter if these are attributes, text nodes, or regular one
-function createTemplate(template) {
-  var paths = [];
-  var html = template.join(UIDC).replace(SC_RE, SC_PLACE);
-  var fragment = createFragment(this, html);
-  Updates.find(fragment, paths, template.slice());
-  var info = { fragment: fragment, paths: paths };
-  templates.set(template, info);
-  return info;
-}
- 
-// some node could be special though, like a custom element
-// with a self closing tag, which should work through these changes.
-var SC_RE = selfClosing;
-var SC_PLACE = function SC_PLACE($0, $1, $2) {
-  return VOID_ELEMENTS.test($1) ? $0 : '<' + $1 + $2 + '></' + $1 + '>';
-};
- 
-// all wires used per each context
-var wires = new WeakMap();
- 
-// A wire is a callback used as tag function
-// to lazily relate a generic object to a template literal.
-// hyper.wire(user)`<div id=user>${user.name}</div>`; => the div#user
-// This provides the ability to have a unique DOM structure
-// related to a unique JS object through a reusable template literal.
-// A wire can specify a type, as svg or html, and also an id
-// via html:id or :id convention. Such :id allows same JS objects
-// to be associated to different DOM structures accordingly with
-// the used template literal without losing previously rendered parts.
-var wire = function wire(obj, type) {
-  return obj == null ? content(type || 'html') : weakly(obj, type || 'html');
-};
- 
-// A wire content is a virtual reference to one or more nodes.
-// It's represented by either a DOM node, or an Array.
-// In both cases, the wire content role is to simply update
-// all nodes through the list of related callbacks.
-// In few words, a wire content is like an invisible parent node
-// in charge of updating its content like a bound element would do.
-var content = function content(type) {
-  var wire = void 0,
-      container = void 0,
-      content = void 0,
-      template = void 0,
-      updates = void 0;
-  return function (statics) {
-    statics = unique(statics);
-    var setup = template !== statics;
-    if (setup) {
-      template = statics;
-      content = fragment(document);
-      container = type === 'svg' ? document.createElementNS(SVG_NAMESPACE, 'svg') : content;
-      updates = render.bind(container);
-    }
-    updates.apply(null, arguments);
-    if (setup) {
-      if (type === 'svg') {
-        append(content, slice.call(container.childNodes));
-      }
-      wire = wireContent(content);
-    }
-    return wire;
-  };
-};
- 
-// wires are weakly created through objects.
-// Each object can have multiple wires associated
-// and this is thanks to the type + :id feature.
-var weakly = function weakly(obj, type) {
-  var i = type.indexOf(':');
-  var wire = wires.get(obj);
-  var id = type;
-  if (-1 < i) {
-    id = type.slice(i + 1);
-    type = type.slice(0, i) || 'html';
-  }
-  if (!wire) wires.set(obj, wire = {});
-  return wire[id] || (wire[id] = content(type));
-};
- 
-// a document fragment loses its nodes as soon
-// as it's appended into another node.
-// This would easily lose wired content
-// so that on a second render call, the parent
-// node wouldn't know which node was there
-// associated to the interpolation.
-// To prevent hyperHTML to forget about wired nodes,
-// these are either returned as Array or, if there's ony one entry,
-// as single referenced node that won't disappear from the fragment.
-// The initial fragment, at this point, would be used as unique reference.
-var wireContent = function wireContent(node) {
-  var childNodes = node.childNodes;
-  var length = childNodes.length;
-  var wireNodes = [];
-  for (var i = 0; i < length; i++) {
-    var child = childNodes[i];
-    if (child.nodeType === ELEMENT_NODE || trim.call(child.textContent).length !== 0) {
-      wireNodes.push(child);
-    }
-  }
-  return wireNodes.length === 1 ? wireNodes[0] : new Wire(wireNodes);
-};
- 
-/*! (c) Andrea Giammarchi (ISC) */
- 
-// all functions are self bound to the right context
-// you can do the following
-// const {bind, wire} = hyperHTML;
-// and use them right away: bind(node)`hello!`;
-var bind = function bind(context) {
-  return render.bind(context);
-};
-var define = Intent.define;
- 
-hyper.Component = Component;
-hyper.bind = bind;
-hyper.define = define;
-hyper.diff = domdiff;
-hyper.hyper = hyper;
-hyper.wire = wire;
- 
-// the wire content is the lazy defined
-// html or svg property of each hyper.Component
-setup(content);
- 
-// by default, hyperHTML is a smart function
-// that "magically" understands what's the best
-// thing to do with passed arguments
-function hyper(HTML) {
-  return arguments.length < 2 ? HTML == null ? content('html') : typeof HTML === 'string' ? hyper.wire(null, HTML) : 'raw' in HTML ? content('html')(HTML) : 'nodeType' in HTML ? hyper.bind(HTML) : weakly(HTML, 'html') : ('raw' in HTML ? content('html') : hyper.wire).apply(null, arguments);
-}
- 
- 
- 
- 
- 
- 
- 
- 
- 
-return hyper;
- 
-}(window));
-module.exports = hyperHTML;
- 
-
-
- - - - - - - diff --git a/coverage/lcov-report/hyperHTML/index.html b/coverage/lcov-report/hyperHTML/index.html deleted file mode 100644 index 4ce785c0..00000000 --- a/coverage/lcov-report/hyperHTML/index.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - Code coverage report for hyperHTML/ - - - - - - - -
-
-

- all files hyperHTML/ -

-
-
- 100% - Statements - 603/603 -
-
- 100% - Branches - 325/325 -
-
- 100% - Functions - 95/95 -
-
- 100% - Lines - 593/593 -
-
- 3 statements, 1 function, 8 branches - Ignored      -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.c.js
100%603/603100%325/325100%95/95100%593/593
-
-
- - - - - - - diff --git a/coverage/lcov-report/index.html b/coverage/lcov-report/index.html deleted file mode 100644 index 87137723..00000000 --- a/coverage/lcov-report/index.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - Code coverage report for All files - - - - - - - -
-
-

- / -

-
-
- 100% - Statements - 603/603 -
-
- 100% - Branches - 325/325 -
-
- 100% - Functions - 95/95 -
-
- 100% - Lines - 593/593 -
-
- 3 statements, 1 function, 8 branches - Ignored      -
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
hyperHTML/
100%603/603100%325/325100%95/95100%593/593
-
-
- - - - - - - diff --git a/coverage/lcov-report/prettify.css b/coverage/lcov-report/prettify.css deleted file mode 100644 index b317a7cd..00000000 --- a/coverage/lcov-report/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/lcov-report/prettify.js b/coverage/lcov-report/prettify.js deleted file mode 100644 index ef51e038..00000000 --- a/coverage/lcov-report/prettify.js +++ /dev/null @@ -1 +0,0 @@ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/lcov-report/sort-arrow-sprite.png b/coverage/lcov-report/sort-arrow-sprite.png deleted file mode 100644 index 03f704a6..00000000 Binary files a/coverage/lcov-report/sort-arrow-sprite.png and /dev/null differ diff --git a/coverage/lcov-report/sorter.js b/coverage/lcov-report/sorter.js deleted file mode 100644 index 6c5034e4..00000000 --- a/coverage/lcov-report/sorter.js +++ /dev/null @@ -1,158 +0,0 @@ -var addSorting = (function () { - "use strict"; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { return document.querySelector('.coverage-summary'); } - // returns the thead element of the summary table - function getTableHeader() { return getTable().querySelector('thead tr'); } - // returns the tbody element of the summary table - function getTableBody() { return getTable().querySelector('tbody'); } - // returns the th element for nth column - function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function (a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function (a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function () { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i =0 ; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function () { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(cols); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/coverage/lcov.info b/coverage/lcov.info deleted file mode 100644 index 86c18264..00000000 --- a/coverage/lcov.info +++ /dev/null @@ -1,1117 +0,0 @@ -TN: -SF:/Users/ming/src/hyperHTML/index.c.js -FN:1,(anonymous_1) -FN:8,Component -FN:14,setup -FN:17,value -FN:24,(anonymous_5) -FN:28,get -FN:33,value -FN:48,lazyGetter -FN:51,get -FN:54,set -FN:73,define -FN:82,invoke -FN:129,Event -FN:137,Map -FN:141,get -FN:144,set -FN:151,WeakMap -FN:153,get -FN:156,set -FN:166,WeakSet -FN:169,add -FN:172,has -FN:179,(anonymous_23) -FN:180,(anonymous_24) -FN:185,(anonymous_25) -FN:190,create -FN:193,doc -FN:196,fragment -FN:199,text -FN:239,(anonymous_30) -FN:241,(anonymous_31) -FN:249,comments -FN:252,replaceAttributes -FN:259,createFragment -FN:267,(anonymous_35) -FN:291,(anonymous_36) -FN:296,(anonymous_37) -FN:298,(anonymous_38) -FN:315,unique -FN:322,TL -FN:331,TL -FN:337,TL -FN:347,(anonymous_43) -FN:351,(anonymous_44) -FN:367,(anonymous_45) -FN:373,(anonymous_46) -FN:381,Wire -FN:389,insert -FN:396,remove -FN:421,createPath -FN:443,prepend -FN:448,create -FN:451,find -FN:465,(anonymous_54) -FN:478,update -FN:481,(anonymous_56) -FN:519,ized -FN:522,toStyle -FN:539,identity -FN:543,domdiff -FN:631,Cache -FN:635,asHTML -FN:640,asNode -FN:650,canDiff -FN:661,create$$1 -FN:690,find -FN:734,findAttributes -FN:785,invokeAtDistance -FN:799,isPromise_ish -FN:812,setAnyContent -FN:815,anyContent -FN:896,setAttribute -FN:917,(anonymous_73) -FN:929,(anonymous_74) -FN:946,(anonymous_75) -FN:973,setTextContent -FN:975,textContent -FN:1009,observe -FN:1017,dispatchAll -FN:1030,dispatchTarget -FN:1046,(anonymous_81) -FN:1055,(anonymous_82) -FN:1058,(anonymous_83) -FN:1077,render -FN:1091,upgrade -FN:1103,update$1 -FN:1114,createTemplate -FN:1127,SC_PLACE -FN:1143,wire -FN:1153,content -FN:1159,(anonymous_91) -FN:1182,weakly -FN:1204,wireContent -FN:1223,bind -FN:1242,hyper -FNF:95 -FNH:95 -FNDA:2,(anonymous_1) -FNDA:22,Component -FNDA:2,setup -FNDA:24,value -FNDA:6,(anonymous_5) -FNDA:4,get -FNDA:6,value -FNDA:6,lazyGetter -FNDA:60,get -FNDA:26,set -FNDA:4,define -FNDA:16,invoke -FNDA:12,Event -FNDA:1,Map -FNDA:98,get -FNDA:75,set -FNDA:3,WeakMap -FNDA:265,get -FNDA:119,set -FNDA:1,WeakSet -FNDA:8,add -FNDA:37,has -FNDA:1,(anonymous_23) -FNDA:111,(anonymous_24) -FNDA:44,(anonymous_25) -FNDA:172,create -FNDA:444,doc -FNDA:202,fragment -FNDA:66,text -FNDA:10,(anonymous_30) -FNDA:94,(anonymous_31) -FNDA:93,comments -FNDA:87,replaceAttributes -FNDA:170,createFragment -FNDA:392,(anonymous_35) -FNDA:0,(anonymous_36) -FNDA:95,(anonymous_37) -FNDA:98,(anonymous_38) -FNDA:598,unique -FNDA:2,TL -FNDA:305,TL -FNDA:293,TL -FNDA:82,(anonymous_43) -FNDA:84,(anonymous_44) -FNDA:2,(anonymous_45) -FNDA:2,(anonymous_46) -FNDA:12,Wire -FNDA:8,insert -FNDA:4,remove -FNDA:149,createPath -FNDA:186,prepend -FNDA:149,create -FNDA:197,find -FNDA:8,(anonymous_54) -FNDA:8,update -FNDA:36,(anonymous_56) -FNDA:2,ized -FNDA:4,toStyle -FNDA:559,identity -FNDA:275,domdiff -FNDA:193,Cache -FNDA:2,asHTML -FNDA:464,asNode -FNDA:78,canDiff -FNDA:193,create$$1 -FNDA:341,find -FNDA:193,findAttributes -FNDA:12,invokeAtDistance -FNDA:123,isPromise_ish -FNDA:91,setAnyContent -FNDA:260,anyContent -FNDA:98,setAttribute -FNDA:52,(anonymous_73) -FNDA:28,(anonymous_74) -FNDA:78,(anonymous_75) -FNDA:8,setTextContent -FNDA:54,textContent -FNDA:2,observe -FNDA:24,dispatchAll -FNDA:103,dispatchTarget -FNDA:6,(anonymous_81) -FNDA:6,(anonymous_82) -FNDA:6,(anonymous_83) -FNDA:394,render -FNDA:193,upgrade -FNDA:394,update$1 -FNDA:148,createTemplate -FNDA:48,SC_PLACE -FNDA:94,wire -FNDA:96,content -FNDA:170,(anonymous_91) -FNDA:50,weakly -FNDA:104,wireContent -FNDA:189,bind -FNDA:20,hyper -DA:1,2 -DA:8,1 -DA:14,1 -DA:15,2 -DA:18,24 -DA:19,24 -DA:25,6 -DA:29,4 -DA:34,6 -DA:35,6 -DA:36,6 -DA:37,8 -DA:38,6 -DA:48,2 -DA:49,6 -DA:50,6 -DA:52,60 -DA:55,26 -DA:60,2 -DA:61,2 -DA:62,2 -DA:64,2 -DA:66,2 -DA:74,4 -DA:75,2 -DA:77,4 -DA:83,16 -DA:84,10 -DA:85,10 -DA:86,8 -DA:92,2 -DA:97,2 -DA:98,2 -DA:99,2 -DA:100,2 -DA:103,2 -DA:106,2 -DA:107,2 -DA:110,2 -DA:111,2 -DA:114,2 -DA:115,2 -DA:116,2 -DA:117,2 -DA:125,2 -DA:126,2 -DA:127,2 -DA:129,1 -DA:130,12 -DA:131,12 -DA:132,12 -DA:137,2 -DA:138,1 -DA:140,1 -DA:142,98 -DA:145,75 -DA:151,2 -DA:152,3 -DA:154,265 -DA:157,119 -DA:166,2 -DA:167,1 -DA:168,1 -DA:170,8 -DA:173,37 -DA:179,2 -DA:180,1 -DA:181,111 -DA:185,2 -DA:186,44 -DA:190,2 -DA:191,172 -DA:193,2 -DA:194,444 -DA:196,2 -DA:197,202 -DA:199,2 -DA:200,66 -DA:206,2 -DA:207,2 -DA:208,2 -DA:209,2 -DA:210,2 -DA:212,2 -DA:214,2 -DA:216,2 -DA:219,2 -DA:222,2 -DA:225,2 -DA:226,2 -DA:227,2 -DA:233,2 -DA:239,2 -DA:240,10 -DA:242,94 -DA:243,94 -DA:244,160 -DA:248,2 -DA:249,2 -DA:250,93 -DA:252,2 -DA:253,87 -DA:259,2 -DA:260,170 -DA:267,2 -DA:268,392 -DA:269,392 -DA:278,392 -DA:279,392 -DA:280,294 -DA:282,392 -DA:292,1 -DA:296,2 -DA:297,95 -DA:299,98 -DA:304,2 -DA:315,2 -DA:316,598 -DA:322,2 -DA:323,2 -DA:329,1 -DA:331,1 -DA:332,305 -DA:333,305 -DA:337,1 -DA:338,293 -DA:341,2 -DA:347,2 -DA:348,82 -DA:349,82 -DA:350,82 -DA:352,84 -DA:353,84 -DA:354,84 -DA:355,1 -DA:356,1 -DA:357,1 -DA:359,83 -DA:360,83 -DA:362,84 -DA:367,2 -DA:368,2 -DA:369,2 -DA:370,2 -DA:371,2 -DA:372,2 -DA:374,2 -DA:375,2 -DA:376,2 -DA:377,2 -DA:378,2 -DA:381,1 -DA:382,12 -DA:383,12 -DA:384,12 -DA:385,12 -DA:389,2 -DA:390,8 -DA:391,8 -DA:392,8 -DA:396,2 -DA:397,4 -DA:398,4 -DA:399,4 -DA:400,2 -DA:402,2 -DA:403,2 -DA:404,2 -DA:405,2 -DA:407,4 -DA:421,2 -DA:422,149 -DA:423,149 -DA:424,149 -DA:427,8 -DA:428,8 -DA:430,54 -DA:431,54 -DA:432,54 -DA:434,87 -DA:435,87 -DA:437,149 -DA:438,132 -DA:440,149 -DA:443,2 -DA:444,186 -DA:447,2 -DA:449,149 -DA:452,197 -DA:453,197 -DA:454,259 -DA:456,197 -DA:461,2 -DA:465,2 -DA:466,8 -DA:467,2 -DA:468,2 -DA:469,2 -DA:470,2 -DA:472,6 -DA:478,2 -DA:479,8 -DA:481,8 -DA:482,36 -DA:484,22 -DA:485,18 -DA:486,10 -DA:487,8 -DA:488,6 -DA:489,6 -DA:490,4 -DA:496,8 -DA:498,18 -DA:499,18 -DA:500,18 -DA:501,18 -DA:503,18 -DA:504,18 -DA:505,18 -DA:508,18 -DA:509,14 -DA:510,14 -DA:511,14 -DA:513,18 -DA:518,2 -DA:519,2 -DA:520,2 -DA:522,2 -DA:523,4 -DA:524,4 -DA:525,4 -DA:527,4 -DA:539,2 -DA:540,559 -DA:543,2 -DA:549,275 -DA:550,275 -DA:551,275 -DA:553,275 -DA:554,275 -DA:555,275 -DA:556,275 -DA:557,275 -DA:558,275 -DA:559,275 -DA:560,626 -DA:561,46 -DA:562,580 -DA:563,12 -DA:564,568 -DA:565,22 -DA:566,546 -DA:567,5 -DA:568,541 -DA:569,222 -DA:570,222 -DA:571,319 -DA:572,88 -DA:573,88 -DA:574,231 -DA:575,65 -DA:576,65 -DA:577,65 -DA:578,166 -DA:579,28 -DA:580,28 -DA:581,28 -DA:583,138 -DA:584,138 -DA:585,89 -DA:586,89 -DA:588,49 -DA:589,49 -DA:590,49 -DA:591,49 -DA:595,275 -DA:596,232 -DA:597,134 -DA:598,134 -DA:599,134 -DA:600,100 -DA:602,34 -DA:603,34 -DA:604,94 -DA:606,34 -DA:609,98 -DA:610,98 -DA:611,67 -DA:613,31 -DA:614,31 -DA:615,31 -DA:616,31 -DA:620,275 -DA:627,2 -DA:631,1 -DA:632,2 -DA:635,2 -DA:636,2 -DA:640,2 -DA:641,464 -DA:650,2 -DA:651,78 -DA:661,2 -DA:662,193 -DA:663,193 -DA:664,193 -DA:665,197 -DA:666,197 -DA:667,197 -DA:669,91 -DA:670,91 -DA:672,98 -DA:673,98 -DA:675,8 -DA:676,8 -DA:679,193 -DA:690,2 -DA:691,341 -DA:692,341 -DA:693,341 -DA:694,478 -DA:695,478 -DA:697,193 -DA:698,193 -DA:699,193 -DA:701,66 -DA:702,62 -DA:703,62 -DA:709,66 -DA:716,219 -DA:717,1 -DA:718,1 -DA:720,219 -DA:734,2 -DA:735,193 -DA:736,193 -DA:737,193 -DA:738,193 -DA:739,193 -DA:740,193 -DA:741,137 -DA:742,137 -DA:743,87 -DA:747,87 -DA:748,87 -DA:749,87 -DA:754,87 -DA:756,87 -DA:759,193 -DA:760,193 -DA:761,87 -DA:770,193 -DA:771,193 -DA:772,2 -DA:773,2 -DA:774,2 -DA:776,2 -DA:777,2 -DA:785,2 -DA:786,12 -DA:787,12 -DA:788,2 -DA:789,10 -DA:790,2 -DA:791,8 -DA:792,2 -DA:794,6 -DA:799,2 -DA:800,123 -DA:812,2 -DA:813,91 -DA:814,91 -DA:815,91 -DA:816,260 -DA:820,92 -DA:821,30 -DA:822,10 -DA:823,10 -DA:826,62 -DA:827,62 -DA:828,62 -DA:830,92 -DA:833,168 -DA:834,8 -DA:835,8 -DA:836,8 -DA:839,160 -DA:840,160 -DA:841,160 -DA:842,82 -DA:843,9 -DA:844,4 -DA:847,73 -DA:851,18 -DA:852,18 -DA:854,55 -DA:855,8 -DA:857,55 -DA:858,4 -DA:859,4 -DA:862,51 -DA:863,51 -DA:866,78 -DA:867,24 -DA:868,54 -DA:869,4 -DA:870,50 -DA:871,10 -DA:872,40 -DA:873,4 -DA:874,36 -DA:875,4 -DA:876,32 -DA:877,22 -DA:878,10 -DA:879,2 -DA:881,8 -DA:883,160 -DA:886,91 -DA:896,2 -DA:897,98 -DA:898,98 -DA:901,98 -DA:902,8 -DA:906,90 -DA:907,38 -DA:908,38 -DA:909,16 -DA:910,2 -DA:911,2 -DA:913,16 -DA:914,22 -DA:915,20 -DA:917,38 -DA:918,52 -DA:919,42 -DA:920,42 -DA:921,42 -DA:928,52 -DA:929,14 -DA:930,28 -DA:931,26 -DA:932,26 -DA:933,24 -DA:934,24 -DA:935,4 -DA:944,38 -DA:945,38 -DA:946,38 -DA:947,78 -DA:948,54 -DA:949,54 -DA:950,50 -DA:951,4 -DA:952,2 -DA:953,2 -DA:955,4 -DA:957,46 -DA:958,46 -DA:959,40 -DA:960,40 -DA:973,2 -DA:974,8 -DA:975,8 -DA:976,54 -DA:977,38 -DA:978,38 -DA:979,14 -DA:980,2 -DA:981,12 -DA:982,2 -DA:983,10 -DA:984,2 -DA:985,8 -DA:986,2 -DA:987,6 -DA:988,2 -DA:989,4 -DA:990,2 -DA:992,2 -DA:995,24 -DA:999,8 -DA:1002,2 -DA:1008,2 -DA:1009,1 -DA:1017,2 -DA:1018,24 -DA:1019,24 -DA:1020,24 -DA:1021,18 -DA:1022,18 -DA:1023,15 -DA:1030,2 -DA:1031,103 -DA:1032,18 -DA:1035,103 -DA:1036,103 -DA:1037,103 -DA:1038,88 -DA:1045,2 -DA:1046,2 -DA:1047,6 -DA:1048,6 -DA:1049,6 -DA:1050,6 -DA:1051,6 -DA:1055,1 -DA:1056,6 -DA:1058,1 -DA:1059,6 -DA:1066,2 -DA:1071,2 -DA:1077,1 -DA:1078,394 -DA:1079,394 -DA:1080,201 -DA:1082,193 -DA:1084,394 -DA:1091,1 -DA:1092,193 -DA:1093,193 -DA:1094,193 -DA:1095,193 -DA:1096,193 -DA:1097,193 -DA:1098,193 -DA:1099,193 -DA:1103,1 -DA:1104,394 -DA:1105,394 -DA:1106,428 -DA:1114,1 -DA:1115,148 -DA:1116,148 -DA:1117,148 -DA:1118,148 -DA:1119,148 -DA:1120,148 -DA:1121,148 -DA:1126,2 -DA:1127,2 -DA:1128,48 -DA:1132,2 -DA:1143,2 -DA:1144,94 -DA:1153,2 -DA:1154,96 -DA:1159,96 -DA:1160,170 -DA:1161,170 -DA:1162,170 -DA:1163,104 -DA:1164,104 -DA:1165,104 -DA:1166,104 -DA:1168,170 -DA:1169,170 -DA:1170,104 -DA:1171,8 -DA:1173,104 -DA:1175,170 -DA:1182,2 -DA:1183,50 -DA:1184,50 -DA:1185,50 -DA:1186,50 -DA:1187,12 -DA:1188,12 -DA:1190,50 -DA:1191,50 -DA:1204,2 -DA:1205,104 -DA:1206,104 -DA:1207,104 -DA:1208,104 -DA:1209,180 -DA:1210,180 -DA:1211,114 -DA:1214,104 -DA:1223,2 -DA:1224,189 -DA:1226,2 -DA:1228,2 -DA:1229,2 -DA:1230,2 -DA:1231,2 -DA:1232,2 -DA:1233,2 -DA:1237,2 -DA:1242,1 -DA:1243,20 -DA:1254,2 -DA:1257,2 -LF:593 -LH:593 -BRDA:19,1,0,24 -BRDA:19,1,1,22 -BRDA:19,1,2,22 -BRDA:35,2,0,2 -BRDA:35,2,1,4 -BRDA:52,3,0,60 -BRDA:52,3,1,22 -BRDA:74,4,0,2 -BRDA:74,4,1,2 -BRDA:85,5,0,8 -BRDA:85,5,1,2 -BRDA:137,6,0,2 -BRDA:137,6,1,1 -BRDA:151,7,0,2 -BRDA:151,7,1,1 -BRDA:166,8,0,2 -BRDA:166,8,1,1 -BRDA:179,9,0,2 -BRDA:179,9,1,1 -BRDA:185,10,0,2 -BRDA:185,10,1,1 -BRDA:194,11,0,444 -BRDA:194,11,1,108 -BRDA:239,12,0,1 -BRDA:239,12,1,1 -BRDA:253,13,0,87 -BRDA:253,13,1,64 -BRDA:253,14,0,87 -BRDA:253,14,1,64 -BRDA:260,15,0,4 -BRDA:260,15,1,166 -BRDA:267,16,0,1 -BRDA:267,16,1,1 -BRDA:269,17,0,392 -BRDA:269,17,1,0 -BRDA:296,18,0,1 -BRDA:296,18,1,1 -BRDA:323,19,0,1 -BRDA:323,19,1,1 -BRDA:325,20,0,2 -BRDA:325,20,1,2 -BRDA:325,20,2,1 -BRDA:327,21,0,2 -BRDA:327,21,1,1 -BRDA:333,22,0,305 -BRDA:333,22,1,75 -BRDA:347,23,0,1 -BRDA:347,23,1,1 -BRDA:354,24,0,1 -BRDA:354,24,1,83 -BRDA:367,25,0,1 -BRDA:367,25,1,1 -BRDA:399,26,0,2 -BRDA:399,26,1,2 -BRDA:424,27,0,8 -BRDA:424,27,1,8 -BRDA:424,27,2,54 -BRDA:424,27,3,87 -BRDA:466,28,0,2 -BRDA:466,28,1,6 -BRDA:482,29,0,22 -BRDA:482,29,1,18 -BRDA:484,30,0,18 -BRDA:484,30,1,4 -BRDA:485,31,0,10 -BRDA:485,31,1,8 -BRDA:486,32,0,8 -BRDA:486,32,1,2 -BRDA:487,33,0,6 -BRDA:487,33,1,2 -BRDA:489,34,0,4 -BRDA:489,34,1,2 -BRDA:496,35,0,2 -BRDA:496,35,1,6 -BRDA:498,36,0,4 -BRDA:498,36,1,14 -BRDA:501,37,0,12 -BRDA:501,37,1,6 -BRDA:501,38,0,18 -BRDA:501,38,1,16 -BRDA:504,39,0,4 -BRDA:504,39,1,14 -BRDA:508,40,0,14 -BRDA:508,40,1,4 -BRDA:511,41,0,4 -BRDA:511,41,1,10 -BRDA:511,42,0,4 -BRDA:511,42,1,2 -BRDA:511,43,0,10 -BRDA:511,43,1,4 -BRDA:549,44,0,275 -BRDA:549,44,1,102 -BRDA:550,45,0,53 -BRDA:550,45,1,222 -BRDA:559,46,0,901 -BRDA:559,46,1,724 -BRDA:560,47,0,46 -BRDA:560,47,1,580 -BRDA:562,48,0,12 -BRDA:562,48,1,568 -BRDA:564,49,0,22 -BRDA:564,49,1,546 -BRDA:566,50,0,5 -BRDA:566,50,1,541 -BRDA:568,51,0,222 -BRDA:568,51,1,319 -BRDA:571,52,0,88 -BRDA:571,52,1,231 -BRDA:574,53,0,65 -BRDA:574,53,1,166 -BRDA:578,54,0,28 -BRDA:578,54,1,138 -BRDA:584,55,0,89 -BRDA:584,55,1,49 -BRDA:595,56,0,232 -BRDA:595,56,1,43 -BRDA:595,57,0,275 -BRDA:595,57,1,177 -BRDA:596,58,0,134 -BRDA:596,58,1,98 -BRDA:598,59,0,123 -BRDA:598,59,1,11 -BRDA:599,60,0,100 -BRDA:599,60,1,34 -BRDA:609,61,0,2 -BRDA:609,61,1,96 -BRDA:610,62,0,67 -BRDA:610,62,1,31 -BRDA:641,63,0,440 -BRDA:641,63,1,24 -BRDA:641,64,0,8 -BRDA:641,64,1,16 -BRDA:646,65,0,0 -BRDA:646,65,1,8 -BRDA:646,66,0,0 -BRDA:646,66,1,0 -BRDA:646,67,0,8 -BRDA:646,67,1,0 -BRDA:651,68,0,78 -BRDA:651,68,1,60 -BRDA:651,68,2,60 -BRDA:667,69,0,91 -BRDA:667,69,1,98 -BRDA:667,69,2,8 -BRDA:695,70,0,193 -BRDA:695,70,1,66 -BRDA:695,70,2,219 -BRDA:701,71,0,62 -BRDA:701,71,1,4 -BRDA:707,72,0,8 -BRDA:707,72,1,54 -BRDA:716,73,0,0 -BRDA:716,73,1,219 -BRDA:716,74,0,219 -BRDA:716,74,1,4 -BRDA:742,75,0,87 -BRDA:742,75,1,50 -BRDA:747,76,0,87 -BRDA:747,76,1,0 -BRDA:749,77,0,87 -BRDA:749,77,1,0 -BRDA:771,78,0,2 -BRDA:771,78,1,191 -BRDA:787,79,0,2 -BRDA:787,79,1,10 -BRDA:789,80,0,2 -BRDA:789,80,1,8 -BRDA:791,81,0,2 -BRDA:791,81,1,6 -BRDA:800,82,0,123 -BRDA:800,82,1,123 -BRDA:816,83,0,80 -BRDA:816,83,1,90 -BRDA:816,83,2,92 -BRDA:816,83,3,162 -BRDA:816,83,4,168 -BRDA:816,83,5,160 -BRDA:820,84,0,30 -BRDA:820,84,1,62 -BRDA:821,85,0,10 -BRDA:821,85,1,20 -BRDA:833,86,0,8 -BRDA:833,86,1,160 -BRDA:841,87,0,82 -BRDA:841,87,1,78 -BRDA:842,88,0,9 -BRDA:842,88,1,73 -BRDA:843,89,0,4 -BRDA:843,89,1,5 -BRDA:847,90,0,10 -BRDA:847,90,1,18 -BRDA:847,90,2,18 -BRDA:847,90,3,55 -BRDA:847,90,4,51 -BRDA:854,91,0,8 -BRDA:854,91,1,47 -BRDA:857,92,0,4 -BRDA:857,92,1,51 -BRDA:866,93,0,24 -BRDA:866,93,1,54 -BRDA:867,94,0,8 -BRDA:867,94,1,16 -BRDA:868,95,0,4 -BRDA:868,95,1,50 -BRDA:870,96,0,10 -BRDA:870,96,1,40 -BRDA:872,97,0,4 -BRDA:872,97,1,36 -BRDA:874,98,0,4 -BRDA:874,98,1,32 -BRDA:876,99,0,22 -BRDA:876,99,1,10 -BRDA:878,100,0,2 -BRDA:878,100,1,8 -BRDA:901,101,0,8 -BRDA:901,101,1,90 -BRDA:906,102,0,38 -BRDA:906,102,1,52 -BRDA:908,103,0,16 -BRDA:908,103,1,22 -BRDA:908,104,0,38 -BRDA:908,104,1,30 -BRDA:909,105,0,2 -BRDA:909,105,1,14 -BRDA:914,106,0,20 -BRDA:914,106,1,2 -BRDA:918,107,0,42 -BRDA:918,107,1,10 -BRDA:919,108,0,4 -BRDA:919,108,1,38 -BRDA:921,109,0,40 -BRDA:921,109,1,2 -BRDA:928,110,0,14 -BRDA:928,110,1,38 -BRDA:928,111,0,52 -BRDA:928,111,1,46 -BRDA:928,111,2,46 -BRDA:930,112,0,26 -BRDA:930,112,1,2 -BRDA:932,113,0,24 -BRDA:932,113,1,2 -BRDA:934,114,0,4 -BRDA:934,114,1,20 -BRDA:947,115,0,54 -BRDA:947,115,1,24 -BRDA:949,116,0,50 -BRDA:949,116,1,4 -BRDA:950,117,0,4 -BRDA:950,117,1,46 -BRDA:951,118,0,2 -BRDA:951,118,1,2 -BRDA:958,119,0,40 -BRDA:958,119,1,6 -BRDA:976,120,0,38 -BRDA:976,120,1,16 -BRDA:978,121,0,14 -BRDA:978,121,1,24 -BRDA:978,122,0,38 -BRDA:978,122,1,16 -BRDA:979,123,0,2 -BRDA:979,123,1,12 -BRDA:981,124,0,2 -BRDA:981,124,1,10 -BRDA:983,125,0,2 -BRDA:983,125,1,8 -BRDA:985,126,0,2 -BRDA:985,126,1,6 -BRDA:987,127,0,2 -BRDA:987,127,1,4 -BRDA:989,128,0,2 -BRDA:989,128,1,2 -BRDA:995,129,0,4 -BRDA:995,129,1,20 -BRDA:1022,130,0,15 -BRDA:1022,130,1,3 -BRDA:1031,131,0,18 -BRDA:1031,131,1,85 -BRDA:1079,132,0,201 -BRDA:1079,132,1,193 -BRDA:1079,133,0,394 -BRDA:1079,133,1,235 -BRDA:1093,134,0,193 -BRDA:1093,134,1,148 -BRDA:1128,135,0,20 -BRDA:1128,135,1,28 -BRDA:1144,136,0,48 -BRDA:1144,136,1,46 -BRDA:1144,137,0,48 -BRDA:1144,137,1,42 -BRDA:1144,138,0,46 -BRDA:1144,138,1,34 -BRDA:1162,139,0,104 -BRDA:1162,139,1,66 -BRDA:1165,140,0,8 -BRDA:1165,140,1,96 -BRDA:1169,141,0,104 -BRDA:1169,141,1,66 -BRDA:1170,142,0,8 -BRDA:1170,142,1,96 -BRDA:1186,143,0,12 -BRDA:1186,143,1,38 -BRDA:1188,144,0,12 -BRDA:1188,144,1,12 -BRDA:1190,145,0,24 -BRDA:1190,145,1,26 -BRDA:1191,146,0,50 -BRDA:1191,146,1,26 -BRDA:1210,147,0,114 -BRDA:1210,147,1,66 -BRDA:1210,148,0,180 -BRDA:1210,148,1,80 -BRDA:1214,149,0,92 -BRDA:1214,149,1,12 -BRDA:1243,150,0,14 -BRDA:1243,150,1,6 -BRDA:1243,151,0,2 -BRDA:1243,151,1,12 -BRDA:1243,152,0,2 -BRDA:1243,152,1,10 -BRDA:1243,153,0,2 -BRDA:1243,153,1,8 -BRDA:1243,154,0,4 -BRDA:1243,154,1,4 -BRDA:1243,155,0,2 -BRDA:1243,155,1,4 -BRF:325 -BRH:325 -end_of_record diff --git a/esm.js b/esm.js new file mode 100644 index 00000000..1ded632c --- /dev/null +++ b/esm.js @@ -0,0 +1,3 @@ +/*! (c) Andrea Giammarchi (ISC) */var hyperHTML=function(N){"use strict";var t={};try{t.WeakMap=WeakMap}catch(e){t.WeakMap=function(t,e){var n=e.defineProperty,r=e.hasOwnProperty,i=a.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},a;function a(e){n(this,"_",{value:"_@ungap/weakmap"+t++}),e&&e.forEach(o,this)}function o(e){this.set(e[0],e[1])}}(Math.random(),Object)}var s=t.WeakMap,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 m(e,t,n,r,i,a){for(var o=("selectedIndex"in t),u=o;ro;)--c;l=u+r-c;var m=Array(l),y=s[c];for(--n;y;){for(var b=y.newi,w=y.oldi;b>>0;n"+e+"",r.querySelectorAll(t)):(r.innerHTML=e,r.childNodes)),n},function(e,t){return("svg"===t?function(e){var t=H(O),n=H("div");return n.innerHTML=''+e+"",F(t,n.firstChild.childNodes),t}:M)(e)});function F(e,t){for(var n=t.length;n--;)e.appendChild(t[0])}function H(e){return e===O?S.createDocumentFragment():S.createElementNS("http://www.w3.org/1999/xhtml",e)}var I,z,V,Z,G,q,B,J,K,Q,U=(z="appendChild",V="cloneNode",Z="createTextNode",q=(G="importNode")in(I=N),(B=I.createDocumentFragment())[z](I[Z]("g")),B[z](I[Z]("")),(q?I[G](B,!0):B[V](!0)).childNodes.length<2?function e(t,n){for(var r=t[V](),i=t.childNodes||[],a=i.length,o=0;n&&o

',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,ae=/^(?:style|textarea)$/i,oe=/^(?: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("\\/","")+"))?)",he=new RegExp(se+le+fe+"+)(["+ue+"]*/?>)","g"),de=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,ge)+r}function ge(e,t,n){return t+(n||'"')+Y+(n||'"')}function me(e,t,n){return oe.test(t)?e:"<"+t+n+">"}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,n,r){for(var i=e.childNodes,a=i.length,o=0;o { + wm.set(id, component); + return component; + }; + const get = (Class, info, context, id) => { + const relation = info.get(Class) || relate(Class, info); + switch (typeof id) { + case 'object': + case 'function': + const wm = relation.w || (relation.w = new WeakMap); + return wm.get(id) || createEntry(wm, id, new Class(context)); + default: + const sm = relation.p || (relation.p = create(null)); + return sm[id] || (sm[id] = new Class(context)); + } + }; + const relate = (Class, info) => { + const relation = {w: null, p: null}; + info.set(Class, relation); + return relation; + }; + const set = context => { + const info = new Map; + children.set(context, info); + return info; + }; + // The Component Class + Object.defineProperties( + Component, + { + // Component.for(context[, id]) is a convenient way + // to automatically relate data/context to children components + // If not created yet, the new Component(context) is weakly stored + // and after that same instance would always be returned. + for: { + configurable: true, + value(context, id) { + return get( + this, + children.get(context) || set(context), + context, + id == null ? + 'default' : id + ); + } + } + } + ); Object.defineProperties( Component.prototype, { + // all events are handled with the component as context handleEvent: {value(e) { const ct = e.currentTarget; this[ @@ -19,15 +80,46 @@ export function setup(content) { ('on' + e.type) ](e); }}, + // components will lazily define html or svg properties + // as soon as these are invoked within the .render() method + // Such render() method is not provided by the base class + // but it must be available through the Component extend. + // Declared components could implement a + // render(props) method too and use props as needed. html: lazyGetter('html', content), svg: lazyGetter('svg', content), + // the state is a very basic/simple mechanism inspired by Preact state: lazyGetter('state', function () { return this.defaultState; }), + // it is possible to define a default state that'd be always an object otherwise defaultState: {get() { return {}; }}, - setState: {value(state) { + // dispatch a bubbling, cancelable, custom event + // through the first known/available node + dispatch: {value(type, detail) { + const {_wire$} = this; + if (_wire$) { + const event = new CustomEvent(type, { + bubbles: true, + cancelable: true, + detail + }); + event.component = this; + return (_wire$.dispatchEvent ? + _wire$ : + _wire$.firstChild + ).dispatchEvent(event); + } + return false; + }}, + // setting some property state through a new object + // or a callback, triggers also automatically a render + // unless explicitly specified to not do so (render === false) + setState: {value(state, render) { const target = this.state; const source = typeof state === 'function' ? state.call(this, target) : state; for (const key in source) target[key] = source[key]; - this.render(); + if (render !== false) + this.render(); + return this; }} } ); @@ -41,10 +133,31 @@ const lazyGetter = (type, fn) => { const secret = '_' + type + '$'; return { get() { - return this[secret] || (this[type] = fn.call(this, type)); + return this[secret] || setValue(this, secret, fn.call(this, type)); }, set(value) { - Object.defineProperty(this, secret, {configurable: true, value}); + setValue(this, secret, value); } }; }; + +// shortcut to set value on get or set(value) +const setValue = (self, secret, value) => + Object.defineProperty(self, secret, { + configurable: true, + value: typeof value === 'function' ? + function () { + return (self._wire$ = value.apply(this, arguments)); + } : + value + })[secret] +; + +Object.defineProperties( + Component.prototype, + { + // used to distinguish better than instanceof + ELEMENT_NODE: {value: 1}, + nodeType: {value: -1} + } +); diff --git a/esm/classes/Wire.js b/esm/classes/Wire.js deleted file mode 100644 index 7347335f..00000000 --- a/esm/classes/Wire.js +++ /dev/null @@ -1,31 +0,0 @@ -import { append } from '../shared/utils.js'; -import { doc, fragment } from '../shared/easy-dom.js'; - -export default function Wire(childNodes) { - this.childNodes = childNodes; - this.length = childNodes.length; - this.first = childNodes[0]; - this.last = childNodes[this.length - 1]; -} - -// when a wire is inserted, all its nodes will follow -Wire.prototype.insert = function insert() { - const df = fragment(this.first); - append(df, this.childNodes); - return df; -}; - -// when a wire is removed, all its nodes must be removed as well -Wire.prototype.remove = function remove() { - const first = this.first; - const last = this.last; - if (this.length === 2) { - last.parentNode.removeChild(last); - } else { - const range = doc(first).createRange(); - range.setStartBefore(this.childNodes[1]); - range.setEndAfter(last); - range.deleteContents(); - } - return first; -}; diff --git a/esm/hyper/render.js b/esm/hyper/render.js index 10598eef..b3c4c863 100644 --- a/esm/hyper/render.js +++ b/esm/hyper/render.js @@ -1,33 +1,24 @@ -import {Map, WeakMap} from '../shared/poorlyfills.js'; -import {UIDC, VOID_ELEMENTS} from '../shared/constants.js'; -import Updates from '../objects/Updates.js'; -import { - createFragment, - importNode, - unique -} from '../shared/utils.js'; +import WeakMap from '@ungap/weakmap'; +import tta from '@ungap/template-tag-arguments'; -import {selfClosing} from '../shared/re.js'; +import {OWNER_SVG_ELEMENT} from '../shared/constants.js'; +import {Tagger} from '../objects/Updates.js'; // a weak collection of contexts that // are already known to hyperHTML const bewitched = new WeakMap; -// the collection of all template literals -// since these are unique and immutable -// for the whole application life-cycle -const templates = new Map; - // better known as hyper.bind(node), the render is // the main tag function in charge of fully upgrading // or simply updating, contexts used as hyperHTML targets. // The `this` context is either a regular DOM node or a fragment. -function render(template) { +function render() { const wicked = bewitched.get(this); - if (wicked && wicked.template === unique(template)) { - update.apply(wicked.updates, arguments); + const args = tta.apply(null, arguments); + if (wicked && wicked.template === args[0]) { + wicked.tagger.apply(null, args); } else { - upgrade.apply(this, arguments); + upgrade.apply(this, args); } return this; } @@ -37,44 +28,11 @@ function render(template) { // as single DOM callbacks, relate such template // to the current context, and render it after cleaning the context up function upgrade(template) { - template = unique(template); - const info = templates.get(template) || - createTemplate.call(this, template); - const fragment = importNode(this.ownerDocument, info.fragment); - const updates = Updates.create(fragment, info.paths); - bewitched.set(this, {template, updates}); - update.apply(updates, arguments); + const type = OWNER_SVG_ELEMENT in this ? 'svg' : 'html'; + const tagger = new Tagger(type); + bewitched.set(this, {tagger, template: template}); this.textContent = ''; - this.appendChild(fragment); -} - -// an update simply loops over all mapped DOM operations -function update() { - const length = arguments.length; - for (let i = 1; i < length; i++) { - this[i - 1](arguments[i]); - } + this.appendChild(tagger.apply(null, arguments)); } -// a template can be used to create a document fragment -// aware of all interpolations and with a list -// of paths used to find once those nodes that need updates, -// no matter if these are attributes, text nodes, or regular one -function createTemplate(template) { - const paths = []; - const html = template.join(UIDC).replace(SC_RE, SC_PLACE); - const fragment = createFragment(this, html); - Updates.find(fragment, paths, template.slice()); - const info = {fragment, paths}; - templates.set(template, info); - return info; -} - -// some node could be special though, like a custom element -// with a self closing tag, which should work through these changes. -const SC_RE = selfClosing; -const SC_PLACE = ($0, $1, $2) => { - return VOID_ELEMENTS.test($1) ? $0 : ('<' + $1 + $2 + '>'); -}; - export default render; diff --git a/esm/hyper/wire.js b/esm/hyper/wire.js index 47b02a7c..3911fbc7 100644 --- a/esm/hyper/wire.js +++ b/esm/hyper/wire.js @@ -1,9 +1,9 @@ -import {ELEMENT_NODE, SVG_NAMESPACE} from '../shared/constants.js'; -import {WeakMap, trim} from '../shared/poorlyfills.js'; -import {fragment} from '../shared/easy-dom.js'; -import {append, slice, unique} from '../shared/utils.js'; -import Wire from '../classes/Wire.js'; -import render from './render.js'; +import WeakMap from '@ungap/weakmap'; +import tta from '@ungap/template-tag-arguments'; + +import Wire from 'hyperhtml-wire'; + +import {Tagger} from '../objects/Updates.js'; // all wires used per each context const wires = new WeakMap; @@ -28,24 +28,15 @@ const wire = (obj, type) => obj == null ? // In few words, a wire content is like an invisible parent node // in charge of updating its content like a bound element would do. const content = type => { - let wire, container, content, template, updates; - return function (statics) { - statics = unique(statics); - let setup = template !== statics; - if (setup) { - template = statics; - content = fragment(document); - container = type === 'svg' ? - document.createElementNS(SVG_NAMESPACE, 'svg') : - content; - updates = render.bind(container); - } - updates.apply(null, arguments); - if (setup) { - if (type === 'svg') { - append(content, slice.call(container.childNodes)); - } - wire = wireContent(content); + let wire, tagger, template; + return function () { + const args = tta.apply(null, arguments); + if (template !== args[0]) { + template = args[0]; + tagger = new Tagger(type); + wire = wireContent(tagger.apply(tagger, args)); + } else { + tagger.apply(tagger, args); } return wire; }; @@ -62,34 +53,29 @@ const weakly = (obj, type) => { id = type.slice(i + 1); type = type.slice(0, i) || 'html'; } - if (!wire) wires.set(obj, wire = {}); + if (!wire) + wires.set(obj, wire = {}); return wire[id] || (wire[id] = content(type)); }; -// a document fragment loses its nodes as soon -// as it's appended into another node. -// This would easily lose wired content -// so that on a second render call, the parent -// node wouldn't know which node was there -// associated to the interpolation. -// To prevent hyperHTML to forget about wired nodes, -// these are either returned as Array or, if there's ony one entry, -// as single referenced node that won't disappear from the fragment. -// The initial fragment, at this point, would be used as unique reference. +// A document fragment loses its nodes +// as soon as it is appended into another node. +// This has the undesired effect of losing wired content +// on a second render call, because (by then) the fragment would be empty: +// no longer providing access to those sub-nodes that ultimately need to +// stay associated with the original interpolation. +// To prevent hyperHTML from forgetting about a fragment's sub-nodes, +// fragments are instead returned as an Array of nodes or, if there's only one entry, +// as a single referenced node which, unlike fragments, will indeed persist +// wire content throughout multiple renderings. +// The initial fragment, at this point, would be used as unique reference to this +// array of nodes or to this single referenced node. const wireContent = node => { const childNodes = node.childNodes; - const length = childNodes.length; - const wireNodes = []; - for (let i = 0; i < length; i++) { - let child = childNodes[i]; - if ( - child.nodeType === ELEMENT_NODE || - trim.call(child.textContent).length !== 0 - ) { - wireNodes.push(child); - } - } - return wireNodes.length === 1 ? wireNodes[0] : new Wire(wireNodes); + const {length} = childNodes; + return length === 1 ? + childNodes[0] : + (length ? new Wire(childNodes) : node); }; export { content, weakly }; diff --git a/esm/index.d.ts b/esm/index.d.ts new file mode 100644 index 00000000..02ce463a --- /dev/null +++ b/esm/index.d.ts @@ -0,0 +1,3 @@ +import hyper from ".."; +export * from '..'; +export default hyper; diff --git a/esm/index.js b/esm/index.js index b2aa770c..254708a6 100644 --- a/esm/index.js +++ b/esm/index.js @@ -1,10 +1,13 @@ /*! (c) Andrea Giammarchi (ISC) */ +import WeakMap from '@ungap/weakmap'; +import WeakSet from '@ungap/essential-weakset'; +import diff from 'domdiff'; import Component, {setup} from './classes/Component.js'; import Intent from './objects/Intent.js'; +import {observe, Tagger} from './objects/Updates.js'; import wire, {content, weakly} from './hyper/wire.js'; import render from './hyper/render.js'; -import diff from './shared/domdiff.js'; // all functions are self bound to the right context // you can do the following @@ -12,21 +15,33 @@ import diff from './shared/domdiff.js'; // and use them right away: bind(node)`hello!`; const bind = context => render.bind(context); const define = Intent.define; +const tagger = Tagger.prototype; hyper.Component = Component; hyper.bind = bind; hyper.define = define; hyper.diff = diff; hyper.hyper = hyper; +hyper.observe = observe; +hyper.tagger = tagger; hyper.wire = wire; +// exported as shared utils +// for projects based on hyperHTML +// that don't necessarily need upfront polyfills +// i.e. those still targeting IE +hyper._ = { + WeakMap, + WeakSet +}; + // the wire content is the lazy defined // html or svg property of each hyper.Component setup(content); // everything is exported directly or through the // hyperHTML callback, when used as top level script -export {Component, bind, define, diff, hyper, wire}; +export {Component, bind, define, diff, hyper, observe, tagger, wire}; // by default, hyperHTML is a smart function // that "magically" understands what's the best diff --git a/esm/objects/Engine.js b/esm/objects/Engine.js deleted file mode 100644 index 958273c3..00000000 --- a/esm/objects/Engine.js +++ /dev/null @@ -1,45 +0,0 @@ -export default { - update: ( - utils, - liveNodes, liveStart, liveEnd, liveLength, - virtualNodes, virtualStart, virtualEnd /*, virtualLength */ - ) => { - const { splicer } = utils; - while (liveStart < liveEnd && virtualStart < virtualEnd) { - const liveValue = liveNodes[liveStart]; - const virtualValue = virtualNodes[virtualStart]; - const status = liveValue === virtualValue ? - 0 : (liveNodes.indexOf(virtualValue) < 0 ? 1 : -1); - // nodes can be either removed ... - if (status < 0) { - splicer.splice(liveStart, 1); - liveEnd--; - liveLength--; - } - // ... appended ... - else if (0 < status) { - splicer.splice(liveStart, 0, virtualValue); - liveStart++; - liveEnd++; - liveLength++; - virtualStart++; - } - // ... or ignored, since it's the same ... - else { - liveStart++; - virtualStart++; - } - } - if (liveStart < liveEnd) { - splicer.splice(liveStart, liveEnd - liveStart); - } - if (virtualStart < virtualEnd) { - splicer.splice.apply( - splicer, - [liveEnd, 0].concat( - virtualNodes.slice(virtualStart, virtualEnd) - ) - ); - } - } -}; \ No newline at end of file diff --git a/esm/objects/Intent.js b/esm/objects/Intent.js index 57f0017f..a18dab89 100644 --- a/esm/objects/Intent.js +++ b/esm/objects/Intent.js @@ -1,3 +1,4 @@ +const attributes = {}; const intents = {}; const keys = []; const hasOwnProperty = intents.hasOwnProperty; @@ -6,16 +7,23 @@ let length = 0; export default { + // used to invoke right away hyper:attributes + attributes, + // hyperHTML.define('intent', (object, update) => {...}) // can be used to define a third parts update mechanism // when every other known mechanism failed. // hyper.define('user', info => info.name); // hyper(node)`

${{user}}

`; define: (intent, callback) => { - if (!(intent in intents)) { - length = keys.push(intent); + if (intent.indexOf('-') < 0) { + if (!(intent in intents)) { + length = keys.push(intent); + } + intents[intent] = callback; + } else { + attributes[intent] = callback; } - intents[intent] = callback; }, // this method is used internally as last resort diff --git a/esm/objects/Path.js b/esm/objects/Path.js deleted file mode 100644 index 0db75cda..00000000 --- a/esm/objects/Path.js +++ /dev/null @@ -1,57 +0,0 @@ -import { - COMMENT_NODE, - DOCUMENT_FRAGMENT_NODE, - ELEMENT_NODE -} from '../shared/constants.js'; - -// every template literal interpolation indicates -// a precise target in the DOM the template is representing. -// `

some ${'content'}

` -// hyperHTML finds only once per template literal, -// hence once per entire application life-cycle, -// all nodes that are related to interpolations. -// These nodes are stored as indexes used to retrieve, -// once per upgrade, nodes that will change on each future update. -// A path example is [2, 0, 1] representing the operation: -// node.childNodes[2].childNodes[0].childNodes[1] -// Attributes are addressed via their owner node and their name. -const createPath = node => { - const path = []; - let parentNode; - switch (node.nodeType) { - case ELEMENT_NODE: - case DOCUMENT_FRAGMENT_NODE: - parentNode = node; - break; - case COMMENT_NODE: - parentNode = node.parentNode; - prepend(path, parentNode, node); - break; - default: - parentNode = node.ownerElement; - break; - } - for ( - node = parentNode; - (parentNode = parentNode.parentNode); - node = parentNode - ) { - prepend(path, parentNode, node); - } - return path; -}; - -const prepend = (path, parent, node) => { - path.unshift(path.indexOf.call(parent.childNodes, node)); -}; - -export default { - create: (type, node, name) => ({type, name, node, path: createPath(node)}), - find: (node, path) => { - const length = path.length; - for (let i = 0; i < length; i++) { - node = node.childNodes[path[i]]; - } - return node; - } -} diff --git a/esm/objects/Style.js b/esm/objects/Style.js deleted file mode 100644 index a0f99565..00000000 --- a/esm/objects/Style.js +++ /dev/null @@ -1,71 +0,0 @@ -// from https://github.com/developit/preact/blob/33fc697ac11762a1cb6e71e9847670d047af7ce5/src/constants.js -const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i; - -// style is handled as both string and object -// even if the target is an SVG element (consistency) -export default (node, original, isSVG) => { - if (isSVG) { - const style = original.cloneNode(true); - style.value = ''; - node.setAttributeNode(style); - return update(style, isSVG); - } - return update(node.style, isSVG); -}; - -// the update takes care or changing/replacing -// only properties that are different or -// in case of string, the whole node -const update = (style, isSVG) => { - let oldType, oldValue; - return newValue => { - switch (typeof newValue) { - case 'object': - if (newValue) { - if (oldType === 'object') { - if (!isSVG) { - if (oldValue !== newValue) { - for (const key in oldValue) { - if (!(key in newValue)) { - style[key] = ''; - } - } - } - } - } else { - if (isSVG) style.value = ''; - else style.cssText = ''; - } - const info = isSVG ? {} : style; - for (const key in newValue) { - const value = newValue[key]; - info[key] = typeof value === 'number' && - !IS_NON_DIMENSIONAL.test(key) ? - (value + 'px') : value; - } - oldType = 'object'; - if (isSVG) style.value = toStyle((oldValue = info)); - else oldValue = newValue; - break; - } - default: - if (oldValue != newValue) { - oldType = 'string'; - oldValue = newValue; - if (isSVG) style.value = newValue || ''; - else style.cssText = newValue || ''; - } - break; - } - }; -}; - -const hyphen = /([^A-Z])([A-Z]+)/g; -const ized = ($0, $1, $2) => $1 + '-' + $2.toLowerCase(); -const toStyle = object => { - const css = []; - for (const key in object) { - css.push(key.replace(hyphen, ized), ':', object[key], ';'); - } - return css.join(''); -}; \ No newline at end of file diff --git a/esm/objects/Updates.js b/esm/objects/Updates.js index ab8d239f..103b45ff 100644 --- a/esm/objects/Updates.js +++ b/esm/objects/Updates.js @@ -1,187 +1,77 @@ +import CustomEvent from '@ungap/custom-event'; +import WeakSet from '@ungap/essential-weakset'; +import isArray from '@ungap/is-array'; +import createContent from '@ungap/create-content'; + +import disconnected from 'disconnected'; +import domdiff from 'domdiff'; +import domtagger from 'domtagger'; +import hyperStyle from 'hyperhtml-style'; +import Wire from 'hyperhtml-wire'; + import { CONNECTED, DISCONNECTED, - COMMENT_NODE, DOCUMENT_FRAGMENT_NODE, ELEMENT_NODE, TEXT_NODE, - OWNER_SVG_ELEMENT, - SHOULD_USE_TEXT_CONTENT, - UID, UIDC + DOCUMENT_FRAGMENT_NODE, + OWNER_SVG_ELEMENT } from '../shared/constants.js'; import Component from '../classes/Component.js'; -import Wire from '../classes/Wire.js'; -import Path from './Path.js'; -import Style from './Style.js'; import Intent from './Intent.js'; -import domdiff from '../shared/domdiff.js'; -import { create as createElement, text } from '../shared/easy-dom.js'; -import { Event, WeakSet, isArray, trim } from '../shared/poorlyfills.js'; -import { createFragment, slice } from '../shared/utils.js'; -// hyper.Component have a connected/disconnected -// mechanism provided by MutationObserver -// This weak set is used to recognize components -// as DOM node that needs to trigger connected/disconnected events -const components = new WeakSet; +const componentType = Component.prototype.nodeType; +const wireType = Wire.prototype.nodeType; -// a basic dictionary used to filter already cached attributes -// while looking for special hyperHTML values. -function Cache() {} -Cache.prototype = Object.create(null); +const observe = disconnected({Event: CustomEvent, WeakSet}); + +export {Tagger, observe}; // returns an intent to explicitly inject content as html const asHTML = html => ({html}); // returns nodes from wires and components const asNode = (item, i) => { - return 'ELEMENT_NODE' in item ? - item : - (item.constructor === Wire ? + switch (item.nodeType) { + case wireType: // in the Wire case, the content can be // removed, post-pended, inserted, or pre-pended and // all these cases are handled by domdiff already /* istanbul ignore next */ - ((1 / i) < 0 ? - (i ? item.remove() : item.last) : - (i ? item.insert() : item.first)) : - asNode(item.render(), i)); + return (1 / i) < 0 ? + (i ? item.remove(true) : item.lastChild) : + (i ? item.valueOf(true) : item.firstChild); + case componentType: + return asNode(item.render(), i); + default: + return item; + } } // returns true if domdiff can handle the value -const canDiff = value => 'ELEMENT_NODE' in value || -value instanceof Wire || -value instanceof Component; +const canDiff = value => 'ELEMENT_NODE' in value; -// updates are created once per context upgrade -// within the main render function (../hyper/render.js) -// These are an Array of callbacks to invoke passing -// each interpolation value. -// Updates can be related to any kind of content, -// attributes, or special text-only cases such + - +

results in console

diff --git a/test/ie/test/test.js b/test/ie/test/test.js index bfaf3c09..0b3662a0 100644 --- a/test/ie/test/test.js +++ b/test/ie/test/test.js @@ -1,1218 +1,3051 @@ -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - -var _templateObject = _taggedTemplateLiteral(['\n

\n Time: ', '\n

\n '], ['\n

\n Time: ', '\n

\n ']), - _templateObject2 = _taggedTemplateLiteral(['

', ' world

'], ['

', ' world

']), - _templateObject3 = _taggedTemplateLiteral(['

', '

'], ['

', '

']), - _templateObject4 = _taggedTemplateLiteral(['click'], ['click']), - _templateObject5 = _taggedTemplateLiteral(['how cool'], ['how cool']), - _templateObject6 = _taggedTemplateLiteral(['\n

1

\n

2

\n '], ['\n

1

\n

2

\n ']), - _templateObject7 = _taggedTemplateLiteral(['\n

1

\n

2

\n

3

\n '], ['\n

1

\n

2

\n

3

\n ']), - _templateObject8 = _taggedTemplateLiteral(['\n

1

\n '], ['\n

1

\n ']), - _templateObject9 = _taggedTemplateLiteral(['\n 0\n

1

\n '], ['\n 0\n

1

\n ']), - _templateObject10 = _taggedTemplateLiteral(['', ''], ['', '']), - _templateObject11 = _taggedTemplateLiteral(['a'], ['a']), - _templateObject12 = _taggedTemplateLiteral(['b'], ['b']), - _templateObject13 = _taggedTemplateLiteral(['\n O'], ['\n O']), - _templateObject14 = _taggedTemplateLiteral(['\n
\n
    ', '
\n
'], ['\n
\n
    ', '
\n
']), - _templateObject15 = _taggedTemplateLiteral(['\n
  • ', '
  • \n '], ['\n
  • ', '
  • \n ']), - _templateObject16 = _taggedTemplateLiteral(['
    ', '
    '], ['
    ', '
    ']), - _templateObject17 = _taggedTemplateLiteral([''], ['']), - _templateObject18 = _taggedTemplateLiteral(['

    '], ['

    ']), - _templateObject19 = _taggedTemplateLiteral(['

    ', '

    ', '
    ', '
    ', ''], ['

    ', '

    ', '
    ', '
    ', '']), - _templateObject20 = _taggedTemplateLiteral([''], ['']), - _templateObject21 = _taggedTemplateLiteral(['
    ', ''], ['
    ', '']), - _templateObject22 = _taggedTemplateLiteral(['', '
    '], ['', '
    ']), - _templateObject23 = _taggedTemplateLiteral([''], ['']), - _templateObject24 = _taggedTemplateLiteral(['a=', ''], ['a=', '']), - _templateObject25 = _taggedTemplateLiteral(['[', ']'], ['[', ']']), - _templateObject26 = _taggedTemplateLiteral(['

    '], ['

    ']), - _templateObject27 = _taggedTemplateLiteral(['
    ', '
    '], ['
    ', '
    ']), - _templateObject28 = _taggedTemplateLiteral([''], ['']), - _templateObject29 = _taggedTemplateLiteral([''], ['']), - _templateObject30 = _taggedTemplateLiteral([''], ['']), - _templateObject31 = _taggedTemplateLiteral(['ok'], ['ok']), - _templateObject32 = _taggedTemplateLiteral(['
    ', '
    '], ['
    ', '
    ']), - _templateObject33 = _taggedTemplateLiteral([''], ['']), - _templateObject34 = _taggedTemplateLiteral(['

    '], ['

    ']), - _templateObject35 = _taggedTemplateLiteral(['

    ', '

    '], ['

    ', '

    ']), - _templateObject36 = _taggedTemplateLiteral([''], ['']), - _templateObject37 = _taggedTemplateLiteral(['

    '], ['

    ']), - _templateObject38 = _taggedTemplateLiteral([''], ['']), - _templateObject39 = _taggedTemplateLiteral([''], ['']), - _templateObject40 = _taggedTemplateLiteral(['\n '], ['\n ']), - _templateObject41 = _taggedTemplateLiteral(['\n
    First name: ', '
    \n

    '], ['\n
    First name: ', '
    \n

    ']), - _templateObject42 = _taggedTemplateLiteral(['\n

    ', ''], ['\n

    ', '']), - _templateObject43 = _taggedTemplateLiteral(['\n

    ', ''], ['\n

    ', '']), - _templateObject44 = _taggedTemplateLiteral([''], ['']), - _templateObject45 = _taggedTemplateLiteral(['

    '], ['

    ']), - _templateObject46 = _taggedTemplateLiteral(['

    '], ['

    ']), - _templateObject47 = _taggedTemplateLiteral(['a ', ''], ['a ', '']), - _templateObject48 = _taggedTemplateLiteral(['

    any content

    '], ['

    any content

    ']), - _templateObject49 = _taggedTemplateLiteral([''], ['']), - _templateObject50 = _taggedTemplateLiteral(['abc'], ['abc']), - _templateObject51 = _taggedTemplateLiteral(['

    a', 'c

    '], ['

    a', 'c

    ']), - _templateObject52 = _taggedTemplateLiteral(['a', 'c'], ['a', 'c']), - _templateObject53 = _taggedTemplateLiteral([''], ['']), - _templateObject54 = _taggedTemplateLiteral(['
    abc
    '], ['
    abc
    ']), - _templateObject55 = _taggedTemplateLiteral(['\n '], ['\n ']), - _templateObject56 = _taggedTemplateLiteral(['\n '], ['\n ']), - _templateObject57 = _taggedTemplateLiteral(['\n

    hello

    '], ['\n

    hello

    ']), - _templateObject58 = _taggedTemplateLiteral(['\n

    hello

    '], ['\n

    hello

    ']), - _templateObject59 = _taggedTemplateLiteral(['
    \n \n
    '], ['
    \n \n
    ']), - _templateObject60 = _taggedTemplateLiteral(['
      \n ', '\n
    '], ['
      \n ', '\n
    ']), - _templateObject61 = _taggedTemplateLiteral(['
  • ', '
  • '], ['
  • ', '
  • ']), - _templateObject62 = _taggedTemplateLiteral(['\n

    hello

    '], ['\n

    hello

    ']), - _templateObject63 = _taggedTemplateLiteral(['

    '], ['

    ']), - _templateObject64 = _taggedTemplateLiteral(['
    '], ['
    ']), - _templateObject65 = _taggedTemplateLiteral(['
    \n \n
    '], ['
    \n \n
    ']), - _templateObject66 = _taggedTemplateLiteral(['\n
    \n \n \n \n \n
    \n '], ['\n
    \n \n \n \n \n
    \n ']), - _templateObject67 = _taggedTemplateLiteral(['\n
    \n