UNPKG

vtpl

Version:
245 lines (240 loc) 6.62 kB
// src/filter.js var _filters = {}; var registerFilter = (name, fn) => { if (typeof fn === "function") { _filters[name] = fn; } }; var applyFilter = (name, str, ...args) => { const f = _filters[name]; if (!f) { return str; } return f(str, ...args); }; var filter_default = applyFilter; // src/escape.js var escapeMap = { "<": "&#60;", ">": "&#62;", '"': "&#34;", "'": "&#39;", "&": "&#38;" }; var escapeHtml = (content) => { content += ""; return content.replace(/&(?![\w#]+;)|[<>"']/g, (v) => escapeMap[v]); }; var escape_default = escapeHtml; // src/each.js var hasOwn = Object.prototype.hasOwnProperty; var each_default = (items, fn) => { if (Array.isArray(items)) { for (let i = 0, len = items.length; i < len; i++) { fn(items[i], i, items); } } else if (typeof items === "object") { for (const i in items) { if (hasOwn.call(items, i)) { fn(items[i], i, items); } } } }; // src/config.js var defaultConfig = { openTag: "{{", closeTag: "}}", escape: true }; var keys = Object.keys(defaultConfig); var config = Object.assign({}, defaultConfig); var config_default = (k, v) => { if (typeof v === "undefined") { return config[k]; } else { if (!~keys.indexOf(k)) { return; } config = Object.assign(config, { [k]: v }); return config; } }; // src/compile.js var util = { escape: escape_default, filter: filter_default, each: each_default }; var compile_default = (template, userConfig) => { const OPEN_TAG = (userConfig == null ? void 0 : userConfig.openTag) ?? config_default("openTag"); const CLOSE_TAG = (userConfig == null ? void 0 : userConfig.closeTag) ?? config_default("closeTag"); const ESCAPE = (userConfig == null ? void 0 : userConfig.escape) ?? config_default("escape"); const pieces = template.split(new RegExp(`(${OPEN_TAG}|${CLOSE_TAG})`, "g")); const code = []; const all = []; let counter = 1; let logic = false; pieces.forEach((v, i) => { let tmp; switch (v) { case OPEN_TAG: logic = true; break; case CLOSE_TAG: logic = false; break; default: tmp = { content: v.trim(), position: i }; all.push({ content: v, position: i, type: logic ? "code" : "html", refer: tmp }); if (logic) { code.push(tmp); } } }); code.forEach((v, i) => { const parts = v.content.split(" "); const first = parts[0]; if (first === "if" || first === "each") { for (let j = code.length - 1; j > i; j--) { if (!code[j].binded && new RegExp("^/" + first).test(code[j].content)) { code[j].binded = true; v.bind = code[j].position; break; } } } }); code.forEach((v, i) => { const parts = v.content.split(" "); const first = parts[0]; if (first === "else") { for (let j = i - 1; j >= 0; j--) { if (code[j].bind && code[j].bind > v.position && /^if\s+/.test(code[j].content)) { v.belong = code[j].position; break; } } } }); const makeExprWithData = function(expr, suffix) { return ` ${suffix ? "var $e" + suffix + ";" : ""} with( $data ) { $e${suffix || ""} = ${expr}; } `; }; const parseEach = (expr) => { const parts = expr.split(" as "); if (parts.length === 2) { let tmp = parts[1].split(","); let i = tmp[1] || "$i"; let v = tmp[0] || "$v"; return { items: parts[0], v, i }; } }; const joinEachExpr = (items, i) => { return `var ${i} = 0, len = ${items}.length; ${i} < len; ${i}++`; }; let output = []; output.push(` var $o = ""; var $util = this; var $escape = $util.escape; var $filter = $util.filter; var $each = $util.each; $data = $data || {}; `); all.forEach((v) => { if (v.type === "html") { output.push("$o += " + JSON.stringify(v.content) + ";"); } else if (v.type === "code") { const content = v.content.trim(); const parts = content.split(" "); const first = parts[0]; const rest = parts.slice(1); if (first === "if") { v.declare = []; v.declare.push(makeExprWithData(rest.join(" "), counter)); output.push(v.declare); output.push(`if( $e${counter} ) {`); counter++; } else if (first === "else") { let matched; if (rest[0] === "if") { all.forEach((v2) => { if (v2.position === v.refer.belong) { matched = v2; return false; } }); matched.declare.push(makeExprWithData(rest.slice(1).join(" "), counter)); output.push(`} else if( $e${counter} ) {`); counter++; } else { output.push("} else {"); } } else if (first === "each") { let parsed = parseEach(rest.join(" ")); output.push(makeExprWithData(parsed.items, counter)); output.push(`$each($e${counter}, function(${parsed.v}, ${parsed.i}) { `); counter++; } else if (first === "/if") { output.push("}"); } else if (first === "/each") { output.push(`});`); } else { let parts2 = content.split("|"); let expr = parts2[0]; let filters = parts2.slice(1); if (expr[0] !== "=") { output.push(makeExprWithData(expr, counter)); expr = `$e${counter}`; for (let i = 0, len = filters.length; i < len; i++) { let nameAndArgs = filters[i].split(":"); let name = nameAndArgs[0].trim(); let args = nameAndArgs.slice(1).join(""); expr = `$filter( ${JSON.stringify(name)}, ${expr} ${args ? "," + args : ""} )`; } if (ESCAPE) { output.push(`$o += $escape(${expr});`); } else { output.push(`$o += ${expr};`); } counter++; } else { output.push(makeExprWithData(expr.slice(1), counter)); output.push(`$o += $e${counter};`); counter++; } } } }); output.push("return $o;"); output = output.map(function(v) { if (!Array.isArray(v)) { return v; } else { return v.join(""); } }); return new Function("$data", output.join("\n")).bind(util); }; // src/index.js var src_default = { config: config_default, compile: compile_default, registerFilter }; export { src_default as default }; //# sourceMappingURL=index.js.map