Skip to content

Instantly share code, notes, and snippets.

@o0101
Last active September 24, 2017 04:25
Show Gist options
  • Save o0101/3cf108f6e8637692eea705b6a450834e to your computer and use it in GitHub Desktop.
Save o0101/3cf108f6e8637692eea705b6a450834e to your computer and use it in GitHub Desktop.
It all sucks. Time to make it better.
/**
So dosyhil gives good components on the server.
What about the client?
**/
// example
const components = {};
Object.assign( self, { components } );
def`
<MyComponent style=${{display:'block',border:'1px solid grey'}}>
${
['Hello', 'world'].map( text => `<p>${text}</p>` )
}
<a href=${ d => d.href }>${ d => d.linkText }</a>
</MyComponent>
`;
const data = {
href:'https://blog.plan99.net/its-time-to-kill-the-web-974a9fe80c89',
linkText:'Time to simplify at least?'
};
document.body.appendChild( components.mycomponent(data) );
/**
This looks like dosyhil.
Only difference is there is no signature object.
So we need to parse the HTML to get component name.
**/
function def( templates, ...values ) {
templates = Array.from(templates);
values = Array.from(values);
const rough_markup = parse( templates.join(' ') );
const component_name = rough_markup.localName;
console.log("Making component", component_name);
components[component_name] = component;
return component;
function component( data ) {
const resolvedValues = values.map( val => {
if ( typeof val == "string" ) return val;
if ( Array.isArray(val) ) return val.join('\n');
if ( typeof val == "object" ) return cssify( val );
if ( val.constructor && val.constructor.name == "AsyncFunction" ) {
throw new TypeError("Not supporting async components or values at this time.");
}
if ( typeof val == "function" ) return val( data );
});
return parse( weave( templates, resolvedValues ) );
}
}
// helpers
function cssify( obj ) {
const css = [];
for( const slot in obj ) {
css.push(`${slot}: ${obj[slot]};`);
}
return `"${css.join('\n').replace(/"/g,'&quot;')}"`;
}
function weave( x, y ) {
const z = []
while( x.length || y.length ) {
if ( x.length ) z.push(x.shift());
if ( y.length ) z.push(y.shift());
}
return z.join('');
}
function parse( markup ) {
const parser = new DOMParser();
const html = parser.parseFromString(markup,'text/html').body.firstChild;
return html;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment