-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtemplit.js
41 lines (36 loc) · 1.42 KB
/
templit.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Templit {
constructor(templateString) {
this.tpl = templateString
}
render(data) {
// We actually want to use a copy of this.tpl, since we want a templit to be reusable
let out = this.tpl
// {{ introduces a variable, and }} closes the tag
const reVar = /{{([^%>]+)?}}/g,
reExp = /(^( )?(if|for|else|switch|case|break|{|}))(.*)?/g
let code = 'var r=[];\n',
cursor = 0,
vars;
var add = function (line, js) {
// Put escapes in the template string
js
// In the case it actually is JavaScript, we do not want to have quotes around a variable name
// But at the same time we don't want loops, ifs and stuff to be treated as a variable, so we need to make a distinction between a var and an expression
? code += line.match(reExp) ? line + '\n' : 'r.push(' + line + ');\n'
: code += 'r.push("' + line.replace(/"/g, '\\"') + '");\n';
}
while (vars = reVar.exec(out)) {
// Add the new line to the function body
add(out.slice(cursor, vars.index));
add(vars[1], true); // <-- this is actual javascript!
// Shift the cursor
cursor = vars.index + vars[0].length;
}
add(out.substr(cursor, out.length - cursor));
code += 'return r.join("");'; // <-- return the result
console.log(code);
// This sets a scope for the data, meaning we can acces data.prop with this.prop in the template
return new Function(code.replace(/[\r\t\n]/g, '')).apply(data);
}
}
module.exports = Templit