Last active
July 27, 2023 10:34
-
-
Save whiteinge/f67caf1df03e46e5fa5c7a5099753fe0 to your computer and use it in GitHub Desktop.
Add Shadow DOM support to hyperscript experiment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Live demo on https://blocks.roadtolarissa.com