├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE.md
└── workflows
│ └── node.js.yml
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── CONTRIBUTING.md
├── HELPERS.md
├── LICENSE.txt
├── README.md
├── babel-plugins.json
├── cjs
├── classes
│ └── Component.js
├── hyper
│ ├── render.js
│ └── wire.js
├── index.js
├── objects
│ ├── Intent.js
│ └── Updates.js
├── package.json
└── shared
│ ├── constants.js
│ └── utils.js
├── esm.js
├── esm
├── .eslintrc
├── classes
│ └── Component.js
├── hyper
│ ├── render.js
│ └── wire.js
├── index.d.ts
├── index.js
├── objects
│ ├── Intent.js
│ └── Updates.js
└── shared
│ └── constants.js
├── index.d.ts
├── index.js
├── logo.txt
├── logo
├── basichtml.inkscape.svg
├── basichtml.png
├── basichtml.svg
├── creepy-html.jpg
├── hyperhtml.inkscape.svg
├── hyperhtml.png
├── hyperhtml.svg
├── nativehtml.inkscape.svg
├── nativehtml.png
├── nativehtml.svg
├── viper.png
├── viper.svg
├── viperhtml.inkscape.svg
├── viperhtml.png
└── viperhtml.svg
├── min.js
├── no.js
├── package-lock.json
├── package.json
├── rollup.config.js
├── rollup.ie.js
├── test
├── OpenExchangeRates.js
├── abstracts.md
├── adopt.html
├── adopt.js
├── article.html
├── attributes.html
├── basic-table.html
├── basic.html
├── boot-speed.html
├── bootstrap.min.css
├── bundle.html
├── cars-mithril.html
├── cars-wired.html
├── cars.html
├── ce.html
├── connected.html
├── dbmonster-bench.html
├── dbmonster.css
├── dbmonster.html
├── dbmonster.js
├── dbmonster100.js
├── diff.html
├── dist
│ ├── double-rainbow.js
│ ├── hyper.js
│ └── ie.js
├── dom-splicer.js
├── domdiff.js
├── double-rainbow.html
├── e-icon.html
├── edge.html
├── esm.html
├── exchange.html
├── form.html
├── fuzzysort.html
├── haunted.html
├── hello-world-ce.html
├── ie.html
├── ie
│ ├── index.html
│ └── test
│ │ └── test.js
├── incremental.html
├── index.html
├── infinite.html
├── js
│ ├── double-rainbow.js
│ ├── hyper.js
│ └── ie.js
├── lib.html
├── many-rows-adopted.html
├── many-rows.html
├── mjs.html
├── multi-wire.html
├── mutations.html
├── my-button-ns.js
├── my-button.css
├── my-button.html
├── my-button.js
├── repl.html
├── runner.js
├── select.html
├── shared
│ └── main.js
├── svgclass.html
├── tabindex.html
├── table.html
├── test-attribute-value.html
├── test.js
├── tick.html
├── tick
│ └── index.html
├── todo.html
├── value.html
├── virtual.html
└── webkit.html
├── umd.d.ts
└── umd.js
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # not working due missing www.
5 | open_collective: hyperHTML
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | custom: https://www.patreon.com/webreflection
9 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | # 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
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: build
5 |
6 | on: [push, pull_request]
7 |
8 | jobs:
9 | build:
10 |
11 | runs-on: ubuntu-latest
12 |
13 | strategy:
14 | matrix:
15 | node-version: [16]
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Use Node.js ${{ matrix.node-version }}
20 | uses: actions/setup-node@v2
21 | with:
22 | node-version: ${{ matrix.node-version }}
23 | cache: 'npm'
24 | - run: npm ci
25 | - run: npm run build --if-present
26 | - run: npm test
27 | - run: npm run coverage --if-present
28 | - name: Coveralls
29 | uses: coverallsapp/github-action@master
30 | with:
31 | github-token: ${{ secrets.GITHUB_TOKEN }}
32 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | coverage/
4 |
5 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | coverage/*
2 | esm/.eslintrc
3 | logo/*
4 | node_modules/*
5 | test/*
6 | _config.yml
7 | .DS_Store
8 | .gitignore
9 | .travis.yml
10 | .github/ISSUE_TEMPLATE.md
11 | babel-plugins.json
12 | CHANGELOG.md
13 | package-lock.json
14 | rollup.config.js
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - stable
4 | git:
5 | depth: 1
6 | branches:
7 | only:
8 | - master
9 | - /^greenkeeper/.*$/
10 | after_success:
11 | - "npm run coveralls"
12 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # hyper(html) Changelog
2 |
3 | ### v.2.23
4 | * monkey patched rollup generated code to export once the same module shared within sub-modules
5 |
6 | ### v2.22
7 | * using latest domtagger
8 |
9 | ### v2.21
10 | * refactored out all dependencies
11 |
12 | ### v2.20
13 | * re-tested every single supported browser nd fixed few outstanding issues with the 2.19 release
14 |
15 | ### v2.19
16 | * refactored out most of the code
17 | * finally managed to have coveralls show coverage stats
18 | * attributes can have spaces around as per DOM standard - [#244](https://github.com/WebReflection/hyperHTML/issues/224)
19 | * fixed SVG (non-critical) errors when interpolations are used for numerically expected values
20 | * fixed minor issues with Edge attributes
21 | * 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)
22 |
23 | ### v2.16.8
24 | * improved MutationObserver and fallback so that double `dis/connected` events won't happen again
25 | * 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.
26 |
27 | ### v2.16
28 | * 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.
29 |
30 | ### v2.15
31 | * 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.
32 |
33 | ### v2.14
34 | * updated [domdiff](https://github.com/WebReflection/domdiff#domdiff) to match [petit-dom](https://github.com/yelouafi/petit-dom) performance
35 | * up to 3X performance on huge lists
36 | * improved reliability over random changes
37 | * unfortunately there's a +0.6K overall size increase due amount of extra logic involved
38 |
39 | ### v2.13.2
40 | * added support for custom CSS properties as object keys.
41 |
42 | ### v2.13.1
43 | * worked around [TypeScript transpilation bug with Template Literals](https://twitter.com/WebReflection/status/1038115439539363840).
44 |
45 | ### v2.13
46 | * 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.
47 |
48 | ### v2.12
49 | * 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.
50 |
51 | ### v2.11
52 | * updated [domdiff](https://github.com/WebReflection/domdiff#domdiff) to v1.0
53 |
54 | ### v2.10.12
55 | * patched missing `.children` in SVG node in IE / Edge https://github.com/WebReflection/hyperHTML/issues/244
56 |
57 | ### v2.10.10
58 | * updated [domdiff](https://github.com/WebReflection/domdiff#domdiff) to solve issue #243 (breaking with some sorted list)
59 |
60 | ### v2.10.5
61 | * various fixes and changes after [changes applied to ECMAScript 2015](https://github.com/tc39/ecma262/pull/890)
62 |
63 | ### v2.8.0
64 | * updated [domdiff](https://github.com/WebReflection/domdiff#domdiff) engine to boost performance with segments and lists
65 |
66 | ### v2.7.2
67 | * fixed #218 which was a variant of #200
68 |
69 | ### v2.7.0
70 | * the `Component.for(obj)` is now created first time via `new Component(obj)` - #216
71 |
72 | ### v2.6.0
73 | * declarative hyper.Component via `Component.for(context, uid?)` - #202
74 | * hyperHTML TypeScript information - #201
75 |
76 | ### v2.5.12
77 | * fixed #200: textarea/style with initial undefined value
78 |
79 | ### v2.5.11
80 | * fixed #198: connected/disconnected events for nested components
81 |
82 | ### v2.5.10
83 | * more rigid / explicit RegExp to avoid glitches with self-closing tags
84 |
85 | ### v2.5.8
86 | * improved `VOID_ELEMENTS` regular expression (aligned with the _viperHTML_ one)
87 |
88 | ### v2.5.7
89 | * fixed `no.js` patch when wrong count of args is passed
90 |
91 | ### v2.5.6
92 | * added `no.js` file for environments without the ability to use modern JS or based on other languages such Dart.
93 |
94 | ### v2.5.5
95 | * build runs on macOS too
96 | * added umd.js file
97 |
98 | ### v2.5.2
99 | * fixed weird SVG case (see #172)
100 |
101 | ### v2.5.1
102 | * improved self-closing reliability recycling and sharing attributes RegExp
103 |
104 | ### v2.5.0
105 | * updated `domdiff` library to the latest version
106 | * implemented self-closing tags (and after various tests)
107 |
108 | ### v2.4.3
109 | * ensure attributes values are updated when different from previous one
110 | * avoid the usage of the word `global` in the whole code
111 |
112 | ### v2.4.2
113 | * fix scripts with actual content too.
114 |
115 | ### v2.4.1
116 | * fix a bug with scripts that don't trigger network requests in both Firefox and Safari (see bug #152)
117 |
118 | ### v2.4.0
119 | * created a `Wire` class to handle via `domdiff` multiple wired nodes.
120 | * brought back multi nodes per wire, a feature lost since **v2.0**
121 | * simplified `Component` handling too, making it compatible again with multi wired content.
122 | * fixed some check to make IE9+ tests green again
123 |
124 | ### v2.3.0
125 | * dropped the `engine` already. Too complex, no real benefits, refactored the whole internal logic to use [domdiff](https://github.com/WebReflection/domdiff) instead. Deprecated [hyperhtml-majinbuu](https://github.com/WebReflection/hyperhtml-majinbuu) and solved diffing "_forever_".
126 |
127 | ### v2.2.0
128 | * the whole `hyperHTML.engine` has been refactored to use [dom-splicer](https://github.com/WebReflection/dom-splicer) as an effort to make engine development easier
129 |
130 | ### v2.1.3
131 | * the MutationObserver is installed only once and only if there are components that have _on(dis)?connect_ handlers.
132 |
133 | ### v2.1.2
134 | * using a new folders convention with `esm/index.js` as main module and `cjs/index.js` as transformed artifact. This plays very well with bundlers when you `import {hyper} from 'hyperhtml/esm'` or `const {hyper} = require('hyperhtml/cjs');`
135 |
136 | ### v2.1.1
137 | * fast changes where prepending or appending same lists; now dropping upfront or removing at the end are part of the fast path too.
138 |
139 | ### v2.1.0
140 |
141 | * created a simple default merge engine focused on performance
142 | * remove majinbuu as core dependency, created [hyperhtml-majinbuu](https://github.com/WebReflection/hyperhtml-majinbuu) project to swap it back via `hyperHTML.engine = require('hyperhtml-majinbuu')` or as ESM
143 | * reduced final bundle size down to 4.1K via brotli
144 |
145 | ## v2.0.0
146 |
147 | Refactoring following ticket #140
148 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contribute
2 |
3 | ## Introduction
4 |
5 | First, thank you for considering contributing to hyperhtml! It's people like you that make the open source community such a great community! 😊
6 |
7 | We welcome any type of contribution, not only code. You can help with
8 | - **QA**: file bug reports, the more details you can give the better (e.g. screenshots with the console open)
9 | - **Marketing**: writing blog posts, howto's, printing stickers, ...
10 | - **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ...
11 | - **Code**: take a look at the [open issues](issues). Even if you can't write code, commenting on them, showing that you care about a given issue matters. It helps us triage them.
12 | - **Money**: we welcome financial contributions in full transparency on our [open collective](https://opencollective.com/hyperhtml).
13 |
14 | ## Your First Contribution
15 |
16 | Working on your first Pull Request? You can learn how from this *free* series, [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github).
17 |
18 | ## Submitting code
19 |
20 | Any code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it. The pull request should also contain tests.
21 |
22 | ## Code review process
23 |
24 | The bigger the pull request, the longer it will take to review and merge. Try to break down large pull requests in smaller chunks that are easier to review and merge.
25 | It is also always helpful to have some context for your pull request. What was the purpose? Why does it matter to you?
26 |
27 | ## Financial contributions
28 |
29 | We also welcome financial contributions in full transparency on our [open collective](https://opencollective.com/hyperhtml).
30 | Anyone can file an expense. If the expense makes sense for the development of the community, it will be "merged" in the ledger of our open collective by the core contributors and the person who filed the expense will be reimbursed.
31 |
32 | ## Questions
33 |
34 | If you have any questions, create an [issue](issue) (protip: do a quick search first to see if someone else didn't ask the same question before!).
35 | You can also reach us at hello@hyperhtml.opencollective.com.
36 |
37 | ## Credits
38 |
39 | ### Contributors
40 |
41 | Thank you to all the people who have already contributed to hyperhtml!
42 |
43 |
44 |
45 | ### Backers
46 |
47 | Thank you to all our backers! [[Become a backer](https://opencollective.com/hyperhtml#backer)]
48 |
49 |
50 |
51 |
52 | ### Sponsors
53 |
54 | Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/hyperhtml#sponsor))
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/HELPERS.md:
--------------------------------------------------------------------------------
1 | ## [babel-plugin-remove-ungap]
2 |
3 | Remove the [@ungap ponyfill modules] from your bundle. This will decrease the size of
4 | your bundle if you are targeting modern browsers only or if your build already includes
5 | other polyfills. This has been tested with [hyperHTML] and [lighterhtml] bundles.
6 |
7 |
8 | ## [babel-plugin-template-html-minifier]
9 |
10 | Run [html-minifier] on hyperHTML templates.
11 |
12 |
13 | ## [babel-plugin-bare-import-rewrite]
14 |
15 | This can be used as an alternative to [rollup-plugin-node-resolve], or can be used with certain node.js
16 | web servers to allow browsing live from source.
17 |
18 | Known web server integrations:
19 | * [fastify-babel] plugin for [fastify] enables running any babel plugins, generally expects `payload.filename` as set by [fastify-static]
20 | * [express-transform-bare-module-specifiers] for [express] servers
21 |
22 |
23 | ## [vinyl-rollup]
24 |
25 | This module copies the output of rollup builds to a stream of vinyl-fs objects for [gulp].
26 | In addition it optionally adds files from modules that were bundled into the stream. This
27 | makes it easy to ensure that LICENSE and package.json files associated with bundled modules
28 | are published on the web server without publishing node.js server-side dependencies to the web.
29 | This can also be used to copy complete modules if required for licensing or if bundled code
30 | requires additional assets that are not part of the bundled JS (images for example).
31 |
32 |
33 | ## [babel-plugin-bundled-import-meta]
34 |
35 | If `node_modules/some-web-component/index.js` uses `import.meta.url` to calculate the actual
36 | path to `node_modules/some-web-components/image.png`, rollup does not compensate. This babel
37 | plugin rewrites references to `import.meta.url` so it points to the original location where
38 | it is expected that the additional assets (images and such) can be found. This plugin works
39 | well with `vinyl-rollup` with `copyModules: true`.
40 |
41 |
42 | [babel-plugin-remove-ungap]: https://github.com/cfware/babel-plugin-remove-ungap#readme
43 | [@ungap ponyfill modules]: https://github.com/ungap/ungap.github.io#readme
44 | [hyperHTML]: https://github.com/WebReflection/hyperHTML#readme
45 | [lighterhtml]: https://github.com/WebReflection/lighterhtml#readme
46 | [babel-plugin-template-html-minifier]: https://github.com/cfware/babel-plugin-template-html-minifier#readme
47 | [html-minifier]: https://github.com/kangax/html-minifier#readme
48 | [babel-plugin-bare-import-rewrite]: https://github.com/cfware/babel-plugin-bare-import-rewrite#readme
49 | [rollup-plugin-node-resolve]: https://github.com/rollup/rollup-plugin-node-resolve#readme
50 | [fastify]: https://github.com/fastify/fastify#readme
51 | [fastify-babel]: https://github.com/cfware/fastify-babel#readme
52 | [fastify-static]: https://github.com/fastify/fastify-static#readme
53 | [express-transform-bare-module-specifiers]: https://github.com/nodecg/express-transform-bare-module-specifiers#readme
54 | [express]: https://github.com/expressjs/express#readme
55 | [vinyl-rollup]: https://github.com/cfware/vinyl-rollup#readme
56 | [gulp]: https://github.com/gulpjs/gulp#readme
57 | [babel-plugin-bundled-import-meta]: https://github.com/cfware/babel-plugin-bundled-import-meta#readme
58 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | ISC License
2 |
3 | Copyright (c) 2017, Andrea Giammarchi, @WebReflection
4 |
5 | Permission to use, copy, modify, and/or distribute this software for any
6 | purpose with or without fee is hereby granted, provided that the above
7 | copyright notice and this permission notice appear in all copies.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10 | REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 | AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12 | INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 | PERFORMANCE OF THIS SOFTWARE.
16 |
--------------------------------------------------------------------------------
/babel-plugins.json:
--------------------------------------------------------------------------------
1 | [
2 | "check-es2015-constants",
3 | "transform-es2015-arrow-functions",
4 | "transform-es2015-block-scoped-functions",
5 | "transform-es2015-block-scoping",
6 | "transform-es2015-computed-properties",
7 | "transform-es2015-destructuring",
8 | "transform-es2015-duplicate-keys",
9 | "transform-es2015-function-name",
10 | "transform-es2015-literals",
11 | "transform-es2015-shorthand-properties",
12 | "transform-es2015-spread"
13 | ]
--------------------------------------------------------------------------------
/cjs/classes/Component.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const CustomEvent = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/custom-event'));
3 | const Map = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/essential-map'));
4 | const WeakMap = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/weakmap'));
5 |
6 | // hyperHTML.Component is a very basic class
7 | // able to create Custom Elements like components
8 | // including the ability to listen to connect/disconnect
9 | // events via onconnect/ondisconnect attributes
10 | // Components can be created imperatively or declaratively.
11 | // The main difference is that declared components
12 | // will not automatically render on setState(...)
13 | // to simplify state handling on render.
14 | function Component() {
15 | return this; // this is needed in Edge !!!
16 | }
17 | Object.defineProperty(exports, '__esModule', {value: true}).default = Component
18 |
19 | // Component is lazily setup because it needs
20 | // wire mechanism as lazy content
21 | function setup(content) {
22 | // there are various weakly referenced variables in here
23 | // and mostly are to use Component.for(...) static method.
24 | const children = new WeakMap;
25 | const create = Object.create;
26 | const createEntry = (wm, id, component) => {
27 | wm.set(id, component);
28 | return component;
29 | };
30 | const get = (Class, info, context, id) => {
31 | const relation = info.get(Class) || relate(Class, info);
32 | switch (typeof id) {
33 | case 'object':
34 | case 'function':
35 | const wm = relation.w || (relation.w = new WeakMap);
36 | return wm.get(id) || createEntry(wm, id, new Class(context));
37 | default:
38 | const sm = relation.p || (relation.p = create(null));
39 | return sm[id] || (sm[id] = new Class(context));
40 | }
41 | };
42 | const relate = (Class, info) => {
43 | const relation = {w: null, p: null};
44 | info.set(Class, relation);
45 | return relation;
46 | };
47 | const set = context => {
48 | const info = new Map;
49 | children.set(context, info);
50 | return info;
51 | };
52 | // The Component Class
53 | Object.defineProperties(
54 | Component,
55 | {
56 | // Component.for(context[, id]) is a convenient way
57 | // to automatically relate data/context to children components
58 | // If not created yet, the new Component(context) is weakly stored
59 | // and after that same instance would always be returned.
60 | for: {
61 | configurable: true,
62 | value(context, id) {
63 | return get(
64 | this,
65 | children.get(context) || set(context),
66 | context,
67 | id == null ?
68 | 'default' : id
69 | );
70 | }
71 | }
72 | }
73 | );
74 | Object.defineProperties(
75 | Component.prototype,
76 | {
77 | // all events are handled with the component as context
78 | handleEvent: {value(e) {
79 | const ct = e.currentTarget;
80 | this[
81 | ('getAttribute' in ct && ct.getAttribute('data-call')) ||
82 | ('on' + e.type)
83 | ](e);
84 | }},
85 | // components will lazily define html or svg properties
86 | // as soon as these are invoked within the .render() method
87 | // Such render() method is not provided by the base class
88 | // but it must be available through the Component extend.
89 | // Declared components could implement a
90 | // render(props) method too and use props as needed.
91 | html: lazyGetter('html', content),
92 | svg: lazyGetter('svg', content),
93 | // the state is a very basic/simple mechanism inspired by Preact
94 | state: lazyGetter('state', function () { return this.defaultState; }),
95 | // it is possible to define a default state that'd be always an object otherwise
96 | defaultState: {get() { return {}; }},
97 | // dispatch a bubbling, cancelable, custom event
98 | // through the first known/available node
99 | dispatch: {value(type, detail) {
100 | const {_wire$} = this;
101 | if (_wire$) {
102 | const event = new CustomEvent(type, {
103 | bubbles: true,
104 | cancelable: true,
105 | detail
106 | });
107 | event.component = this;
108 | return (_wire$.dispatchEvent ?
109 | _wire$ :
110 | _wire$.firstChild
111 | ).dispatchEvent(event);
112 | }
113 | return false;
114 | }},
115 | // setting some property state through a new object
116 | // or a callback, triggers also automatically a render
117 | // unless explicitly specified to not do so (render === false)
118 | setState: {value(state, render) {
119 | const target = this.state;
120 | const source = typeof state === 'function' ? state.call(this, target) : state;
121 | for (const key in source) target[key] = source[key];
122 | if (render !== false)
123 | this.render();
124 | return this;
125 | }}
126 | }
127 | );
128 | }
129 | exports.setup = setup
130 |
131 | // instead of a secret key I could've used a WeakMap
132 | // However, attaching a property directly will result
133 | // into better performance with thousands of components
134 | // hanging around, and less memory pressure caused by the WeakMap
135 | const lazyGetter = (type, fn) => {
136 | const secret = '_' + type + '$';
137 | return {
138 | get() {
139 | return this[secret] || setValue(this, secret, fn.call(this, type));
140 | },
141 | set(value) {
142 | setValue(this, secret, value);
143 | }
144 | };
145 | };
146 |
147 | // shortcut to set value on get or set(value)
148 | const setValue = (self, secret, value) =>
149 | Object.defineProperty(self, secret, {
150 | configurable: true,
151 | value: typeof value === 'function' ?
152 | function () {
153 | return (self._wire$ = value.apply(this, arguments));
154 | } :
155 | value
156 | })[secret]
157 | ;
158 |
159 | Object.defineProperties(
160 | Component.prototype,
161 | {
162 | // used to distinguish better than instanceof
163 | ELEMENT_NODE: {value: 1},
164 | nodeType: {value: -1}
165 | }
166 | );
167 |
--------------------------------------------------------------------------------
/cjs/hyper/render.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const WeakMap = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/weakmap'));
3 | const tta = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/template-tag-arguments'));
4 |
5 | const {OWNER_SVG_ELEMENT} = require('../shared/constants.js');
6 | const {Tagger} = require('../objects/Updates.js');
7 |
8 | // a weak collection of contexts that
9 | // are already known to hyperHTML
10 | const bewitched = new WeakMap;
11 |
12 | // better known as hyper.bind(node), the render is
13 | // the main tag function in charge of fully upgrading
14 | // or simply updating, contexts used as hyperHTML targets.
15 | // The `this` context is either a regular DOM node or a fragment.
16 | function render() {
17 | const wicked = bewitched.get(this);
18 | const args = tta.apply(null, arguments);
19 | if (wicked && wicked.template === args[0]) {
20 | wicked.tagger.apply(null, args);
21 | } else {
22 | upgrade.apply(this, args);
23 | }
24 | return this;
25 | }
26 |
27 | // an upgrade is in charge of collecting template info,
28 | // parse it once, if unknown, to map all interpolations
29 | // as single DOM callbacks, relate such template
30 | // to the current context, and render it after cleaning the context up
31 | function upgrade(template) {
32 | const type = OWNER_SVG_ELEMENT in this ? 'svg' : 'html';
33 | const tagger = new Tagger(type);
34 | bewitched.set(this, {tagger, template: template});
35 | this.textContent = '';
36 | this.appendChild(tagger.apply(null, arguments));
37 | }
38 |
39 | Object.defineProperty(exports, '__esModule', {value: true}).default = render;
40 |
--------------------------------------------------------------------------------
/cjs/hyper/wire.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const WeakMap = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/weakmap'));
3 | const tta = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/template-tag-arguments'));
4 |
5 | const Wire = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('hyperhtml-wire'));
6 |
7 | const {Tagger} = require('../objects/Updates.js');
8 |
9 | // all wires used per each context
10 | const wires = new WeakMap;
11 |
12 | // A wire is a callback used as tag function
13 | // to lazily relate a generic object to a template literal.
14 | // hyper.wire(user)`
${user.name}
`; => the div#user
15 | // This provides the ability to have a unique DOM structure
16 | // related to a unique JS object through a reusable template literal.
17 | // A wire can specify a type, as svg or html, and also an id
18 | // via html:id or :id convention. Such :id allows same JS objects
19 | // to be associated to different DOM structures accordingly with
20 | // the used template literal without losing previously rendered parts.
21 | const wire = (obj, type) => obj == null ?
22 | content(type || 'html') :
23 | weakly(obj, type || 'html');
24 |
25 | // A wire content is a virtual reference to one or more nodes.
26 | // It's represented by either a DOM node, or an Array.
27 | // In both cases, the wire content role is to simply update
28 | // all nodes through the list of related callbacks.
29 | // In few words, a wire content is like an invisible parent node
30 | // in charge of updating its content like a bound element would do.
31 | const content = type => {
32 | let wire, tagger, template;
33 | return function () {
34 | const args = tta.apply(null, arguments);
35 | if (template !== args[0]) {
36 | template = args[0];
37 | tagger = new Tagger(type);
38 | wire = wireContent(tagger.apply(tagger, args));
39 | } else {
40 | tagger.apply(tagger, args);
41 | }
42 | return wire;
43 | };
44 | };
45 |
46 | // wires are weakly created through objects.
47 | // Each object can have multiple wires associated
48 | // and this is thanks to the type + :id feature.
49 | const weakly = (obj, type) => {
50 | const i = type.indexOf(':');
51 | let wire = wires.get(obj);
52 | let id = type;
53 | if (-1 < i) {
54 | id = type.slice(i + 1);
55 | type = type.slice(0, i) || 'html';
56 | }
57 | if (!wire)
58 | wires.set(obj, wire = {});
59 | return wire[id] || (wire[id] = content(type));
60 | };
61 |
62 | // A document fragment loses its nodes
63 | // as soon as it is appended into another node.
64 | // This has the undesired effect of losing wired content
65 | // on a second render call, because (by then) the fragment would be empty:
66 | // no longer providing access to those sub-nodes that ultimately need to
67 | // stay associated with the original interpolation.
68 | // To prevent hyperHTML from forgetting about a fragment's sub-nodes,
69 | // fragments are instead returned as an Array of nodes or, if there's only one entry,
70 | // as a single referenced node which, unlike fragments, will indeed persist
71 | // wire content throughout multiple renderings.
72 | // The initial fragment, at this point, would be used as unique reference to this
73 | // array of nodes or to this single referenced node.
74 | const wireContent = node => {
75 | const childNodes = node.childNodes;
76 | const {length} = childNodes;
77 | return length === 1 ?
78 | childNodes[0] :
79 | (length ? new Wire(childNodes) : node);
80 | };
81 |
82 | exports.content = content;
83 | exports.weakly = weakly;
84 | Object.defineProperty(exports, '__esModule', {value: true}).default = wire;
85 |
--------------------------------------------------------------------------------
/cjs/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /*! (c) Andrea Giammarchi (ISC) */
3 | const WeakMap = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/weakmap'));
4 | const WeakSet = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('@ungap/essential-weakset'));
5 |
6 | const diff = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('domdiff'));
7 | const Component = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('./classes/Component.js'));
8 | const {setup} = require('./classes/Component.js');
9 | const Intent = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('./objects/Intent.js'));
10 | const {observe, Tagger} = require('./objects/Updates.js');
11 | const wire = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('./hyper/wire.js'));
12 | const {content, weakly} = require('./hyper/wire.js');
13 | const render = (m => m.__esModule ? /* istanbul ignore next */ m.default : /* istanbul ignore next */ m)(require('./hyper/render.js'));
14 |
15 | // all functions are self bound to the right context
16 | // you can do the following
17 | // const {bind, wire} = hyperHTML;
18 | // and use them right away: bind(node)`hello!`;
19 | const bind = context => render.bind(context);
20 | const define = Intent.define;
21 | const tagger = Tagger.prototype;
22 |
23 | hyper.Component = Component;
24 | hyper.bind = bind;
25 | hyper.define = define;
26 | hyper.diff = diff;
27 | hyper.hyper = hyper;
28 | hyper.observe = observe;
29 | hyper.tagger = tagger;
30 | hyper.wire = wire;
31 |
32 | // exported as shared utils
33 | // for projects based on hyperHTML
34 | // that don't necessarily need upfront polyfills
35 | // i.e. those still targeting IE
36 | hyper._ = {
37 | WeakMap,
38 | WeakSet
39 | };
40 |
41 | // the wire content is the lazy defined
42 | // html or svg property of each hyper.Component
43 | setup(content);
44 |
45 | // everything is exported directly or through the
46 | // hyperHTML callback, when used as top level script
47 | exports.Component = Component;
48 | exports.bind = bind;
49 | exports.define = define;
50 | exports.diff = diff;
51 | exports.hyper = hyper;
52 | exports.observe = observe;
53 | exports.tagger = tagger;
54 | exports.wire = wire;
55 |
56 | // by default, hyperHTML is a smart function
57 | // that "magically" understands what's the best
58 | // thing to do with passed arguments
59 | function hyper(HTML) {
60 | return arguments.length < 2 ?
61 | (HTML == null ?
62 | content('html') :
63 | (typeof HTML === 'string' ?
64 | hyper.wire(null, HTML) :
65 | ('raw' in HTML ?
66 | content('html')(HTML) :
67 | ('nodeType' in HTML ?
68 | hyper.bind(HTML) :
69 | weakly(HTML, 'html')
70 | )
71 | )
72 | )) :
73 | ('raw' in HTML ?
74 | content('html') : hyper.wire
75 | ).apply(null, arguments);
76 | }
77 | Object.defineProperty(exports, '__esModule', {value: true}).default = hyper
78 |
--------------------------------------------------------------------------------
/cjs/objects/Intent.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const attributes = {};
3 | const intents = {};
4 | const keys = [];
5 | const hasOwnProperty = intents.hasOwnProperty;
6 |
7 | let length = 0;
8 |
9 | Object.defineProperty(exports, '__esModule', {value: true}).default = {
10 |
11 | // used to invoke right away hyper:attributes
12 | attributes,
13 |
14 | // hyperHTML.define('intent', (object, update) => {...})
15 | // can be used to define a third parts update mechanism
16 | // when every other known mechanism failed.
17 | // hyper.define('user', info => info.name);
18 | // hyper(node)`
${{user}}
`;
19 | define: (intent, callback) => {
20 | if (intent.indexOf('-') < 0) {
21 | if (!(intent in intents)) {
22 | length = keys.push(intent);
23 | }
24 | intents[intent] = callback;
25 | } else {
26 | attributes[intent] = callback;
27 | }
28 | },
29 |
30 | // this method is used internally as last resort
31 | // to retrieve a value out of an object
32 | invoke: (object, callback) => {
33 | for (let i = 0; i < length; i++) {
34 | let key = keys[i];
35 | if (hasOwnProperty.call(object, key)) {
36 | return intents[key](object[key], callback);
37 | }
38 | }
39 | }
40 | };
41 |
--------------------------------------------------------------------------------
/cjs/package.json:
--------------------------------------------------------------------------------
1 | {"type":"commonjs"}
--------------------------------------------------------------------------------
/cjs/shared/constants.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | // Node.CONSTANTS
3 | // 'cause some engine has no global Node defined
4 | // (i.e. Node, NativeScript, basicHTML ... )
5 | const ELEMENT_NODE = 1;
6 | exports.ELEMENT_NODE = ELEMENT_NODE;
7 | const DOCUMENT_FRAGMENT_NODE = 11;
8 | exports.DOCUMENT_FRAGMENT_NODE = DOCUMENT_FRAGMENT_NODE;
9 |
10 | // SVG related constants
11 | const OWNER_SVG_ELEMENT = 'ownerSVGElement';
12 | exports.OWNER_SVG_ELEMENT = OWNER_SVG_ELEMENT;
13 |
14 | // Custom Elements / MutationObserver constants
15 | const CONNECTED = 'connected';
16 | exports.CONNECTED = CONNECTED;
17 | const DISCONNECTED = 'dis' + CONNECTED;
18 | exports.DISCONNECTED = DISCONNECTED;
19 |
--------------------------------------------------------------------------------
/cjs/shared/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
--------------------------------------------------------------------------------
/esm/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "eslint:recommended",
3 | "globals": {
4 | "setTimeout": true,
5 | "clearTimeout": true,
6 | "MutationObserver": true,
7 | "Promise": true,
8 | "document": true
9 | },
10 | "parserOptions": {
11 | "sourceType": "module"
12 | },
13 | "rules": {
14 | "no-case-declarations": 0,
15 | "no-fallthrough": 0
16 | }
17 | }
--------------------------------------------------------------------------------
/esm/classes/Component.js:
--------------------------------------------------------------------------------
1 | import CustomEvent from '@ungap/custom-event';
2 | import Map from '@ungap/essential-map';
3 | import WeakMap from '@ungap/weakmap';
4 |
5 | // hyperHTML.Component is a very basic class
6 | // able to create Custom Elements like components
7 | // including the ability to listen to connect/disconnect
8 | // events via onconnect/ondisconnect attributes
9 | // Components can be created imperatively or declaratively.
10 | // The main difference is that declared components
11 | // will not automatically render on setState(...)
12 | // to simplify state handling on render.
13 | export default function Component() {
14 | return this; // this is needed in Edge !!!
15 | }
16 |
17 | // Component is lazily setup because it needs
18 | // wire mechanism as lazy content
19 | export function setup(content) {
20 | // there are various weakly referenced variables in here
21 | // and mostly are to use Component.for(...) static method.
22 | const children = new WeakMap;
23 | const create = Object.create;
24 | const createEntry = (wm, id, component) => {
25 | wm.set(id, component);
26 | return component;
27 | };
28 | const get = (Class, info, context, id) => {
29 | const relation = info.get(Class) || relate(Class, info);
30 | switch (typeof id) {
31 | case 'object':
32 | case 'function':
33 | const wm = relation.w || (relation.w = new WeakMap);
34 | return wm.get(id) || createEntry(wm, id, new Class(context));
35 | default:
36 | const sm = relation.p || (relation.p = create(null));
37 | return sm[id] || (sm[id] = new Class(context));
38 | }
39 | };
40 | const relate = (Class, info) => {
41 | const relation = {w: null, p: null};
42 | info.set(Class, relation);
43 | return relation;
44 | };
45 | const set = context => {
46 | const info = new Map;
47 | children.set(context, info);
48 | return info;
49 | };
50 | // The Component Class
51 | Object.defineProperties(
52 | Component,
53 | {
54 | // Component.for(context[, id]) is a convenient way
55 | // to automatically relate data/context to children components
56 | // If not created yet, the new Component(context) is weakly stored
57 | // and after that same instance would always be returned.
58 | for: {
59 | configurable: true,
60 | value(context, id) {
61 | return get(
62 | this,
63 | children.get(context) || set(context),
64 | context,
65 | id == null ?
66 | 'default' : id
67 | );
68 | }
69 | }
70 | }
71 | );
72 | Object.defineProperties(
73 | Component.prototype,
74 | {
75 | // all events are handled with the component as context
76 | handleEvent: {value(e) {
77 | const ct = e.currentTarget;
78 | this[
79 | ('getAttribute' in ct && ct.getAttribute('data-call')) ||
80 | ('on' + e.type)
81 | ](e);
82 | }},
83 | // components will lazily define html or svg properties
84 | // as soon as these are invoked within the .render() method
85 | // Such render() method is not provided by the base class
86 | // but it must be available through the Component extend.
87 | // Declared components could implement a
88 | // render(props) method too and use props as needed.
89 | html: lazyGetter('html', content),
90 | svg: lazyGetter('svg', content),
91 | // the state is a very basic/simple mechanism inspired by Preact
92 | state: lazyGetter('state', function () { return this.defaultState; }),
93 | // it is possible to define a default state that'd be always an object otherwise
94 | defaultState: {get() { return {}; }},
95 | // dispatch a bubbling, cancelable, custom event
96 | // through the first known/available node
97 | dispatch: {value(type, detail) {
98 | const {_wire$} = this;
99 | if (_wire$) {
100 | const event = new CustomEvent(type, {
101 | bubbles: true,
102 | cancelable: true,
103 | detail
104 | });
105 | event.component = this;
106 | return (_wire$.dispatchEvent ?
107 | _wire$ :
108 | _wire$.firstChild
109 | ).dispatchEvent(event);
110 | }
111 | return false;
112 | }},
113 | // setting some property state through a new object
114 | // or a callback, triggers also automatically a render
115 | // unless explicitly specified to not do so (render === false)
116 | setState: {value(state, render) {
117 | const target = this.state;
118 | const source = typeof state === 'function' ? state.call(this, target) : state;
119 | for (const key in source) target[key] = source[key];
120 | if (render !== false)
121 | this.render();
122 | return this;
123 | }}
124 | }
125 | );
126 | }
127 |
128 | // instead of a secret key I could've used a WeakMap
129 | // However, attaching a property directly will result
130 | // into better performance with thousands of components
131 | // hanging around, and less memory pressure caused by the WeakMap
132 | const lazyGetter = (type, fn) => {
133 | const secret = '_' + type + '$';
134 | return {
135 | get() {
136 | return this[secret] || setValue(this, secret, fn.call(this, type));
137 | },
138 | set(value) {
139 | setValue(this, secret, value);
140 | }
141 | };
142 | };
143 |
144 | // shortcut to set value on get or set(value)
145 | const setValue = (self, secret, value) =>
146 | Object.defineProperty(self, secret, {
147 | configurable: true,
148 | value: typeof value === 'function' ?
149 | function () {
150 | return (self._wire$ = value.apply(this, arguments));
151 | } :
152 | value
153 | })[secret]
154 | ;
155 |
156 | Object.defineProperties(
157 | Component.prototype,
158 | {
159 | // used to distinguish better than instanceof
160 | ELEMENT_NODE: {value: 1},
161 | nodeType: {value: -1}
162 | }
163 | );
164 |
--------------------------------------------------------------------------------
/esm/hyper/render.js:
--------------------------------------------------------------------------------
1 | import WeakMap from '@ungap/weakmap';
2 | import tta from '@ungap/template-tag-arguments';
3 |
4 | import {OWNER_SVG_ELEMENT} from '../shared/constants.js';
5 | import {Tagger} from '../objects/Updates.js';
6 |
7 | // a weak collection of contexts that
8 | // are already known to hyperHTML
9 | const bewitched = new WeakMap;
10 |
11 | // better known as hyper.bind(node), the render is
12 | // the main tag function in charge of fully upgrading
13 | // or simply updating, contexts used as hyperHTML targets.
14 | // The `this` context is either a regular DOM node or a fragment.
15 | function render() {
16 | const wicked = bewitched.get(this);
17 | const args = tta.apply(null, arguments);
18 | if (wicked && wicked.template === args[0]) {
19 | wicked.tagger.apply(null, args);
20 | } else {
21 | upgrade.apply(this, args);
22 | }
23 | return this;
24 | }
25 |
26 | // an upgrade is in charge of collecting template info,
27 | // parse it once, if unknown, to map all interpolations
28 | // as single DOM callbacks, relate such template
29 | // to the current context, and render it after cleaning the context up
30 | function upgrade(template) {
31 | const type = OWNER_SVG_ELEMENT in this ? 'svg' : 'html';
32 | const tagger = new Tagger(type);
33 | bewitched.set(this, {tagger, template: template});
34 | this.textContent = '';
35 | this.appendChild(tagger.apply(null, arguments));
36 | }
37 |
38 | export default render;
39 |
--------------------------------------------------------------------------------
/esm/hyper/wire.js:
--------------------------------------------------------------------------------
1 | import WeakMap from '@ungap/weakmap';
2 | import tta from '@ungap/template-tag-arguments';
3 |
4 | import Wire from 'hyperhtml-wire';
5 |
6 | import {Tagger} from '../objects/Updates.js';
7 |
8 | // all wires used per each context
9 | const wires = new WeakMap;
10 |
11 | // A wire is a callback used as tag function
12 | // to lazily relate a generic object to a template literal.
13 | // hyper.wire(user)`
${user.name}
`; => the div#user
14 | // This provides the ability to have a unique DOM structure
15 | // related to a unique JS object through a reusable template literal.
16 | // A wire can specify a type, as svg or html, and also an id
17 | // via html:id or :id convention. Such :id allows same JS objects
18 | // to be associated to different DOM structures accordingly with
19 | // the used template literal without losing previously rendered parts.
20 | const wire = (obj, type) => obj == null ?
21 | content(type || 'html') :
22 | weakly(obj, type || 'html');
23 |
24 | // A wire content is a virtual reference to one or more nodes.
25 | // It's represented by either a DOM node, or an Array.
26 | // In both cases, the wire content role is to simply update
27 | // all nodes through the list of related callbacks.
28 | // In few words, a wire content is like an invisible parent node
29 | // in charge of updating its content like a bound element would do.
30 | const content = type => {
31 | let wire, tagger, template;
32 | return function () {
33 | const args = tta.apply(null, arguments);
34 | if (template !== args[0]) {
35 | template = args[0];
36 | tagger = new Tagger(type);
37 | wire = wireContent(tagger.apply(tagger, args));
38 | } else {
39 | tagger.apply(tagger, args);
40 | }
41 | return wire;
42 | };
43 | };
44 |
45 | // wires are weakly created through objects.
46 | // Each object can have multiple wires associated
47 | // and this is thanks to the type + :id feature.
48 | const weakly = (obj, type) => {
49 | const i = type.indexOf(':');
50 | let wire = wires.get(obj);
51 | let id = type;
52 | if (-1 < i) {
53 | id = type.slice(i + 1);
54 | type = type.slice(0, i) || 'html';
55 | }
56 | if (!wire)
57 | wires.set(obj, wire = {});
58 | return wire[id] || (wire[id] = content(type));
59 | };
60 |
61 | // A document fragment loses its nodes
62 | // as soon as it is appended into another node.
63 | // This has the undesired effect of losing wired content
64 | // on a second render call, because (by then) the fragment would be empty:
65 | // no longer providing access to those sub-nodes that ultimately need to
66 | // stay associated with the original interpolation.
67 | // To prevent hyperHTML from forgetting about a fragment's sub-nodes,
68 | // fragments are instead returned as an Array of nodes or, if there's only one entry,
69 | // as a single referenced node which, unlike fragments, will indeed persist
70 | // wire content throughout multiple renderings.
71 | // The initial fragment, at this point, would be used as unique reference to this
72 | // array of nodes or to this single referenced node.
73 | const wireContent = node => {
74 | const childNodes = node.childNodes;
75 | const {length} = childNodes;
76 | return length === 1 ?
77 | childNodes[0] :
78 | (length ? new Wire(childNodes) : node);
79 | };
80 |
81 | export { content, weakly };
82 | export default wire;
83 |
--------------------------------------------------------------------------------
/esm/index.d.ts:
--------------------------------------------------------------------------------
1 | import hyper from "..";
2 | export * from '..';
3 | export default hyper;
4 |
--------------------------------------------------------------------------------
/esm/index.js:
--------------------------------------------------------------------------------
1 | /*! (c) Andrea Giammarchi (ISC) */
2 | import WeakMap from '@ungap/weakmap';
3 | import WeakSet from '@ungap/essential-weakset';
4 |
5 | import diff from 'domdiff';
6 | import Component, {setup} from './classes/Component.js';
7 | import Intent from './objects/Intent.js';
8 | import {observe, Tagger} from './objects/Updates.js';
9 | import wire, {content, weakly} from './hyper/wire.js';
10 | import render from './hyper/render.js';
11 |
12 | // all functions are self bound to the right context
13 | // you can do the following
14 | // const {bind, wire} = hyperHTML;
15 | // and use them right away: bind(node)`hello!`;
16 | const bind = context => render.bind(context);
17 | const define = Intent.define;
18 | const tagger = Tagger.prototype;
19 |
20 | hyper.Component = Component;
21 | hyper.bind = bind;
22 | hyper.define = define;
23 | hyper.diff = diff;
24 | hyper.hyper = hyper;
25 | hyper.observe = observe;
26 | hyper.tagger = tagger;
27 | hyper.wire = wire;
28 |
29 | // exported as shared utils
30 | // for projects based on hyperHTML
31 | // that don't necessarily need upfront polyfills
32 | // i.e. those still targeting IE
33 | hyper._ = {
34 | WeakMap,
35 | WeakSet
36 | };
37 |
38 | // the wire content is the lazy defined
39 | // html or svg property of each hyper.Component
40 | setup(content);
41 |
42 | // everything is exported directly or through the
43 | // hyperHTML callback, when used as top level script
44 | export {Component, bind, define, diff, hyper, observe, tagger, wire};
45 |
46 | // by default, hyperHTML is a smart function
47 | // that "magically" understands what's the best
48 | // thing to do with passed arguments
49 | export default function hyper(HTML) {
50 | return arguments.length < 2 ?
51 | (HTML == null ?
52 | content('html') :
53 | (typeof HTML === 'string' ?
54 | hyper.wire(null, HTML) :
55 | ('raw' in HTML ?
56 | content('html')(HTML) :
57 | ('nodeType' in HTML ?
58 | hyper.bind(HTML) :
59 | weakly(HTML, 'html')
60 | )
61 | )
62 | )) :
63 | ('raw' in HTML ?
64 | content('html') : hyper.wire
65 | ).apply(null, arguments);
66 | }
67 |
--------------------------------------------------------------------------------
/esm/objects/Intent.js:
--------------------------------------------------------------------------------
1 | const attributes = {};
2 | const intents = {};
3 | const keys = [];
4 | const hasOwnProperty = intents.hasOwnProperty;
5 |
6 | let length = 0;
7 |
8 | export default {
9 |
10 | // used to invoke right away hyper:attributes
11 | attributes,
12 |
13 | // hyperHTML.define('intent', (object, update) => {...})
14 | // can be used to define a third parts update mechanism
15 | // when every other known mechanism failed.
16 | // hyper.define('user', info => info.name);
17 | // hyper(node)`