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 calculated
return 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 parent
if (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 }))