Skip to content

Instantly share code, notes, and snippets.

@staltz
Forked from anonymous/dom$.js
Last active May 6, 2024 03:15
Show Gist options
  • Save staltz/2ebad92f1e7a2b637d16 to your computer and use it in GitHub Desktop.
Save staltz/2ebad92f1e7a2b637d16 to your computer and use it in GitHub Desktop.
import Cycle from 'cyclejs';
const { h, Rx } = Cycle;
// all html/svg element names <<
var elements = [
'a',
'abbr',
'address',
'area',
'article',
'aside',
'audio',
'b',
'base',
'bdi',
'bdo',
'big',
'blockquote',
'body',
'br',
'button',
'canvas',
'caption',
'cite',
'code',
'col',
'colgroup',
'data',
'datalist',
'dd',
'del',
'details',
'dfn',
'dialog',
'div',
'dl',
'dt',
'em',
'embed',
'fieldset',
'figcaption',
'figure',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'head',
'header',
'hr',
'html',
'i',
'iframe',
'img',
'input',
'ins',
'kbd',
'keygen',
'label',
'legend',
'li',
'link',
'main',
'map',
'mark',
'menu',
'menuitem',
'meta',
'meter',
'nav',
'noscript',
'object',
'ol',
'optgroup',
'option',
'output',
'p',
'param',
'picture',
'pre',
'progress',
'q',
'rp',
'rt',
'ruby',
's',
'samp',
'script',
'section',
'select',
'small',
'source',
'span',
'strong',
'style',
'sub',
'summary',
'sup',
'table',
'tbody',
'td',
'textarea',
'tfoot',
'th',
'thead',
'time',
'title',
'tr',
'track',
'u',
'ul',
'var',
'video',
'wbr',
// SVG
'circle',
'defs',
'ellipse',
'g',
'line',
'linearGradient',
'mask',
'path',
'pattern',
'polygon',
'polyline',
'radialGradient',
'rect',
'stop',
'svg',
'text',
'tspan'
];
// >>
var comb$ = Rx.Observable.combineLatest;
var just$ = Rx.Observable.just;
var isArray = require('x-is-array');
var VNode = require('../vnode/vnode.js');
var VText = require('../vnode/vtext.js');
var isVNode = require('../vnode/is-vnode');
var isVText = require('../vnode/is-vtext');
var isWidget = require('../vnode/is-widget');
var isHook = require('../vnode/is-vhook');
var isVThunk = require('../vnode/is-thunk');
function isChild(x) {
return isVNode(x) || isVText(x) || isWidget(x) || isVThunk(x);
}
function isChildren(x) {
return typeof x === 'string' || isArray(x) || isChild(x);
}
var h$ = function (name, properties, children) {
var childNodes = children || [];
var tag, props, key, namespace;
if (!children && isChildren(properties)) {
childNodes = properties;
props = {};
}
props = props || properties || {};
if ( typeof childNodes === "string" ) {
childNodes = [ childNodes ];
}
var children$ = lift(childNodes);
var props$ = lift(props);
var name$ = lift(name);
name$.map(el => console.log(el))
return comb$(name$, props$, children$, function(name, props, children) {
// console.log(name, props, children);
return Cycle.h(name, props, children);
});
};
var lift = function (structure) {
if ( structure instanceof Rx.Observable ) {
// already a stream
return structure;
} else if ( Array.isArray(structure) ) {
// [ Obs any ] -> Obs [any]
// return comb$(structure.map(lift), () => Array.from(arguments));
return comb$(structure.map(lift), function() {
return Array.from(arguments);
});
} else if ( structure !== null && typeof structure === 'object' ) {
// { k: Obs v } -> Obs { k: v }
// { k: v } -> Obs { k: v }
var mapping$s = Object.keys(structure)
.map(function(key) {
return [key, structure[key]];
})
.map(function([key, val]) {
if ( val instanceof Rx.Observable ) {
return [just$(key), val];
} else {
return [key, val];
}
});
return comb$(mapping$s.map(lift), function(...args) {
var o = {};
args.forEach(function([key, val]) {
o[key] = val;
});
return o;
});
} else {
// v -> Obs v
return just$(structure);
}
};
var wrap = function(name) {
return h$.bind(null, name);
};
var dom$ = {};
elements.forEach(function (name) {
dom$[name] = wrap(name);
});
dom$.h = h$;
export default dom$;
import Cycle from 'cyclejs';
import dom from './wrappers.js';
import dom$ from './dom$.js';
const { h, Rx } = Cycle;
var sec$ = Rx.Observable.timer(1000, 1000)
.startWith(0);
var UI = function (interactions) {
// internal state in closure
var i = 0;
var colors = [
'red'
, 'green'
, 'blue'
, 'purple'
];
var click$ = interactions.get('.text', 'click');
var i$ = click$.map(function(ev) {
return i = (i + 1) % colors.length;
})
.startWith(0);
var color$ = i$.map(function(i) {
return colors[i];
})
var j = 0;
var text$ = sec$.map(function() {
j += 1;
return `time: ${j}`;
})
return dom$.div({ className: 'ok' }, [
dom$.div({ className: 'text', style: { color: color$ }}, text$)
, 'hello!'
]);
};
Cycle.applyToDOM('.app', UI);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment