Skip to content

Declarative hyperHTML.Component #202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 46 additions & 2 deletions cjs/classes/Component.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,59 @@
'use strict';
const { UID } = require('../shared/constants.js');
const { WeakMap } = require('../shared/poorlyfills.js');

// 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
// 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() {}
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.
// Declared components could implement a
// render(props) method too and use props as needed.
function setup(content) {
const children = new WeakMap;
const create = Object.create;
const createEntry = (wm, id, component) => {
wm.set(id, component);
return component;
};
const get = (Class, info, id) => {
switch (typeof id) {
case 'object':
case 'function':
const wm = info.w || (info.w = new WeakMap);
return wm.get(id) || createEntry(wm, id, new Class);
default:
const sm = info.p || (info.p = create(null));
return sm[id] || (sm[id] = new Class);
}
};
const set = context => {
const info = {w: null, p: null};
children.set(context, info);
return info;
};
Object.defineProperties(
Component,
{
for: {
configurable: true,
value(context, id) {
const info = children.get(context) || set(context);
return get(this, info, id == null ? 'default' : id);
}
}
}
);
Object.defineProperties(
Component.prototype,
{
Expand All @@ -25,11 +68,12 @@ function setup(content) {
svg: lazyGetter('svg', content),
state: lazyGetter('state', function () { return this.defaultState; }),
defaultState: {get() { return {}; }},
setState: {value(state) {
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;
}}
}
);
Expand Down
1 change: 0 additions & 1 deletion coverage/coverage.json

Large diffs are not rendered by default.

Loading