UNPKG

ceri-compiler

Version:

compiles template strings for ceriJS

167 lines (156 loc) 4.44 kB
var camelize, htmlparser, marker, parseAttr, parseDirective, spliceStr, templateArgs; htmlparser = require("htmlparser2"); marker = "####"; camelize = (str) => { return str.replace(/-(\w)/g, (_, c) => { if (c) { return c.toUpperCase(); } else { return ''; } }); }; spliceStr = (str, index, count, add) => { if (index < 0) { index = str.length + index; if (index < 0) { index = 0; } } return str.slice(0, index) + (add || "") + str.slice(index + count); }; templateArgs = []; templateArgs.toArg = (depth, nr) => { return String.fromCharCode(96 + nr) + (depth ? String.fromCharCode(96 + depth) : ""); }; templateArgs.toArgs = (tmp) => { var arr, i; if ((i = tmp.args) != null) { arr = []; while (i) { arr.unshift(templateArgs.toArg(tmp.depth, i--)); } } return arr; }; parseAttr = require("./compile1_parseAttr")(camelize, spliceStr, marker, templateArgs); parseDirective = require("./compile1_parseDirective")(camelize, marker); module.exports = (template) => { var addOptions, currentLevel, lastLevel, options, parseTemplateArgs, parser, result, wasTemplate; result = "function(){return ["; parseTemplateArgs = (args) => { var arr; if ((arr = templateArgs.toArgs(args)) != null) { return result = spliceStr(result, args.position, 0, arr.join(',')); } }; templateArgs.push({ position: 9 }); lastLevel = 0; currentLevel = 0; wasTemplate = false; options = []; addOptions = (bracket) => { var opt; if (options.length > 0) { opt = options.pop(); if (opt) { result += `${JSON.stringify(opt)},`; } else { result += "null,"; } if (bracket) { return result += "["; } } }; parser = new htmlparser.Parser({ onopentag: (name, attr) => { var sep; if (parseDirective(name, attr, options)) { return; } currentLevel++; if (currentLevel === lastLevel) { sep = ","; } else { addOptions(name !== "template"); sep = ""; } if (name === "slot") { name = attr.name; if (name == null) { name = "default"; } return result += `${sep}\"${name}\"`; } else if (name === "template") { result += "function(){return ["; return templateArgs.push({ position: result.length - 10, depth: templateArgs.length }); } else { options.push(parseAttr(attr)); return result += `${sep}this.el(\"${name}\",`; } }, ontext: (txt) => { var base, base1, opt; if (options.length > 0 && txt.trim()) { opt = options[options.length - 1]; if (opt == null) { opt = {}; } if (opt.text == null) { opt.text = {}; } if (txt.indexOf("{{") > -1) { txt = txt.replace(/{{/g, "\"+(").replace(/}}/g, ")+\""); if ((base = opt.text)[":"] == null) { base[":"] = `${marker}function(){return \"${txt}\";}${marker}`.replace(/\+""/g, "").replace(/""\+/g, ""); } } else { if ((base1 = opt.text)["#"] == null) { base1["#"] = txt; } } return options[options.length - 1] = opt; } }, onclosetag: (name) => { if (parseDirective(name)) { return; } addOptions(true); lastLevel = currentLevel; currentLevel--; if (name === "template") { result += "]})"; wasTemplate = true; return parseTemplateArgs(templateArgs.pop()); } else { if (wasTemplate) { return wasTemplate = false; } else if (name !== "slot") { return result += "])"; } } } }); parser.write(template); parser.end(); result += "]}"; parseTemplateArgs(templateArgs.pop()); // unescape marked function result = result.replace(new RegExp(`\"${marker}(.*?)${marker}\"`, "g"), (a, b) => { var m; if (((m = b.match(/return/g)) != null) && m.length > 1) { // remove default return if one is used in expression b = b.replace(/function\(\)\{return /, "function(){"); } return b.replace(/\\"/g, "\"").replace(/[^\\]@/g, (a) => { // unescape qoutes return a.replace("@", "this."); // replace unescaped @ by this. }).replace(/\\\\@/g, "@"); // replace escaped @ }); return result; };