Skip to content

Instantly share code, notes, and snippets.

@whiteinge
Last active July 27, 2023 10:34
Show Gist options
  • Save whiteinge/f67caf1df03e46e5fa5c7a5099753fe0 to your computer and use it in GitHub Desktop.
Save whiteinge/f67caf1df03e46e5fa5c7a5099753fe0 to your computer and use it in GitHub Desktop.
Add Shadow DOM support to hyperscript experiment
<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
const el = h('div', {className: 'shadow-demos'}, [
h('style', `
.shadow-demos {
width: 300px;
border: 1px solid lightgrey;
margin: 1em;
}
hr { margin: 3em 0; }
p { text-align: center; }
`),
h('p', [
'Global styles: ',
h('br'),
'black, uppercase, and centered.',
]),
h('hr'),
h('#div', [
h('p', 'Sandboxed. No styles.'),
]),
h('hr'),
h('#div', [
h('p', 'Different sandbox.'),
h('style', `
p { text-transform: uppercase; color: blue; }
`),
]),
h('hr'),
h('#div', [
h('p', ['Nested sandboxes.', h('br'), 'Outer']),
h('style', `
p { text-transform: uppercase; color: green; }
`),
h('#div', [
h('p', 'Inner.'),
h('style', `
p { color: red; }
`),
]),
]),
])
ready(() => {
render(document.querySelector('#container'))(el)
})
// ----------------------------------------------------------------------------
function render(el) {
return (content) => {
el.innerHTML = '';
el.appendChild(content);
}
}
function ready(fn) {
if (document.readyState != 'loading') {
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
function h(tag, a, b) {
let el, _el
if (tag.startsWith('#')) {
_el = document.createElement(tag.slice(1))
el = _el.attachShadow({mode: 'open'})
} else {
el = document.createElement(tag);
}
// const el = document.createElement(tag);
let attrs, children;
if (Array.isArray(a) || typeof a === 'string' || a instanceof Element) {
attrs = {};
children = a;
} else {
attrs = a === undefined ? {} : a;
children = b === undefined ? [] : b;
}
Object.entries(attrs).forEach(([key, val]) => {
if (key === 'style' && val.constructor === Object) {
Object.entries(val).forEach(([k, v]) => el.style.setProperty(k, v))
} else {
el[key] = val;
}
});
[].concat(children).forEach(child =>
el.appendChild(typeof child === 'string'
? document.createTextNode(child)
: child));
return _el || el;
}
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
@whiteinge
Copy link
Author

whiteinge commented Sep 6, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment