Created
June 26, 2018 23:38
-
-
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.
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
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