Thinking about DOM
const liveData = {}
const dom = new Proxy(liveData, {
get(o, key) {
if (o[key]) {
return o[key]
} else {
const fn = node.bind(null, key)
return fn}}});
const tags = {}
const isTag = tag => {
if (tags[tag] != null) {
// already calculatedreturn tags[tag]
}const result = !/Unknown/.test(document.createElement(tag) + '')
tags[tag] = result
return result}const click = new WeakMap()
function pointerUp(e) {
const curr = e.target;
if (!curr) return
const action = click.get(curr)
if (action) action(e)
// bubble to parentif (curr?.parentNode?.tagName != 'BODY') {
pointerUp({ target: e.target.parentNode })
}}document.addEventListener('pointerup', e => {
pointerUp(e)
})
function attrs(el, props) {
const keys = Reflect.ownKeys(props)
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
const val = props[key]
if (typeof val != 'function') {
el.setAttribute(key, val)
} else if (key === 'click') {
click.set(el, val)
}}}const textarea = document.createElement('textarea')
function node(type, ...args) {
let el;
const namedEl = isTag(type);
if (namedEl) {
el = document.createElement(type)
} else {
el = document.createElement('div')
el.className = type
}const leng = args.length
for (let i = 0; i < leng; i++) {
const arg = args[i]
if ((i === 1 || leng === 1)
&& typeof arg === 'string') {
if (arg.includes('&')) {
textarea.innerHTML = arg
el.innerText = textarea.innerHTML
} else {
el.innerText = arg
}} else if (i === 0 && typeof arg === 'string') {
el.classList.add(arg)
} else {
if (typeof arg === 'object') {
if (arg.el) {
el.appendChild(arg.el)
} else {
attrs(el, arg)
}}}}document.body.appendChild(el)
return { el }
}const { header, h1, h2, style, div, button } = dom
style(`body, html {
font-family: sans-serif;
}.edit-me {
margin: 1em;
outline: 1px solid red;
padding: .5em;
}`)header(h1('Dom Thoughts'),
h2('sub-header', 'Can\'t help playing with this',
{ style: 'font-style: italic;' }
))div('main',
button('hello', 'Hello', { click: () => alert('hello') }),
div('edit-me', 'Edit Me', { contentEditable: true })
)
Just playing around with DOM creation syntax, kind of reacty… This is the main part:
const { header, h1, h2, style, div, button } = dom
style(`body, html {
font-family: sans-serif;
}.edit-me {
margin: 1em;
outline: 1px solid red;
padding: .5em;
}`)header(h1('Dom Thoughts'),
h2('sub-header', 'Can\'t help playing with this',
{ style: 'font-style: italic;' }
))div('main',
button('hello', 'Hello', { click: () => alert('hello') }),
div('edit-me', 'Edit Me', { contentEditable: true })
)