Created
April 1, 2020 00:46
-
-
Save tomhodgins/a535016fd5cd10520672175946a1566f to your computer and use it in GitHub Desktop.
This file contains hidden or 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
function html(strings, ...things) { | |
function stringify(object = '') { | |
if (Array.isArray(object)) { | |
return object.map(stringify).join('') | |
} | |
if (object instanceof DocumentFragment) { | |
return Array.from(object.childNodes) | |
.map(node => node.outerHTML || node.nodeValue) | |
.join('') | |
} | |
if (object instanceof Element) { | |
return object.outerHTML | |
} | |
return object | |
} | |
return document.implementation | |
.createHTMLDocument() | |
.createRange() | |
.createContextualFragment( | |
strings.reduce((markup, string, index) => | |
markup + stringify(things[index - 1]) + string | |
) | |
) | |
} | |
function DOMProcessor(object = new DocumentFragment, transforms = {}) { | |
if ( | |
object.nodeName === '#text' | |
&& transforms['#text'] | |
) { | |
return transforms['#text'](object) | |
} | |
if (object instanceof Element) { | |
Object.keys(transforms) | |
.filter(key => object.matches(key)) | |
.forEach(transform => { | |
object.replaceWith(transforms[transform](object)) | |
}) | |
} | |
if (object instanceof NodeList) { | |
[...object].forEach(child => | |
child.replaceWith(DOMProcessor(child, transforms)) | |
) | |
} | |
if (object.childNodes) { | |
object.childNodes.forEach(child => | |
child.replaceWith(DOMProcessor(child, transforms)) | |
) | |
} | |
return object | |
} | |
// NOW…for the demo!! | |
const headline = 'Hello' | |
const subheadline = 'Subheadline' | |
document.body.append( | |
DOMProcessor( | |
html` | |
<test-1> | |
<flex-container> | |
<hero-section></hero-section> | |
<side-bar></side-bar> | |
</flex-container> | |
</test-1> | |
`, | |
{ | |
'hero-section': node => { | |
node.append( | |
html` | |
<h1>${headline}</h1> | |
<h2>${subheadline}</h2> | |
` | |
) | |
return node | |
}, | |
'side-bar': node => { | |
node.append( | |
html` | |
Hello! | |
` | |
) | |
return node | |
}, | |
} | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment