Skip to content

Instantly share code, notes, and snippets.

@helloIAmPau
Created June 26, 2018 23:38
Show Gist options
  • Save helloIAmPau/5352316b2a4f2b61c999a5aa9d5965a9 to your computer and use it in GitHub Desktop.
Save helloIAmPau/5352316b2a4f2b61c999a5aa9d5965a9 to your computer and use it in GitHub Desktop.
Experimenting with incremental-dom framework. This is a parser that converts an HTML template into an incremental-dom template. This supports loops and conditions too.
var htmlparser = require("htmlparser2");
let spaces = 0;
const nodes = {
'dom-loop': function(name, attribs) {
return `for(const current of ${ attribs.items.trim().slice(2, -1).trim() }) {`;
},
'dom-if': function(name, attribs) {
return `if(${ attribs.test.trim().slice(2, -1).trim() }) {`;
},
default: function(name, attribs) {
const args = [`'${ name }'`, `'${ Math.random().toString(26).slice(-5) }'`, []];
Object.keys(attribs).forEach(function(key) {
const value = attribs[key].trim();
const matches = value.match(rx) || [];
if (matches.length === 1 && value.startsWith('${') && value.endsWith('}')) {
args.push(`'${ key }'`);
args.push(value.slice(2, -1).trim());
} else if (matches.length > 0) {
args.push(`'${ key }'`);
args.push(`\`${ value }\``);
} else {
args[2].push(`'${ key }'`);
args[2].push(`'${ value }'`);
}
});
args[2] = `[${ args[2].join(', ') }]`;
return `elementOpen(${ args.join(', ') });`;
}
};
const rx = /\${[a-z0-9\s\.]+}/ig;
var parser = new htmlparser.Parser({
onopentag: function(name, attribs) {
let f = 'default';
if (nodes[name] != null) {
f = name;
}
console.log(`${ Array(spaces++).fill(' ').join('') }${ nodes[f](name, attribs) }`);
},
ontext: function(text) {
text = text.trim();
if (!text) {
return;
}
console.log(`${ Array(spaces).fill(' ').join('') }text(\`${ text.trim() }\`);`)
},
onclosetag: function(name) {
let text = `elementClose('${ name }')`;
if (name === 'dom-if' || name === 'dom-loop') {
text = '}';
}
console.log(`${ Array(--spaces).fill(' ').join('') }${ text }`);
}
}, {
decodeEntities: true
});
const h = '<h1>Pippo ${ new Date() }</h1><dom-if test="${ enabled }"><input type="text" onclick="${ pippolone }"></dom-if><div><dom-loop items="${ items }"><span style="${ bgcolor }: ${ newColor }">cacca ${ color }</span></dom-loop></div>';
setTimeout(function() {
parser.write(h);
parser.end();
}, 1000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment