123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- var template = require("./index")
- var whitespaceRegex = /["'\\\n\r\u2028\u2029]/g
- var nargs = /\{[0-9a-zA-Z]+\}/g
- var replaceTemplate =
- " var args\n" +
- " var result\n" +
- " if (arguments.length === 1 && typeof arguments[0] === \"object\") {\n" +
- " args = arguments[0]\n" +
- " } else {\n" +
- " args = arguments" +
- " }\n\n" +
- " if (!args || !(\"hasOwnProperty\" in args)) {\n" +
- " args = {}\n" +
- " }\n\n" +
- " return {0}"
- var literalTemplate = "\"{0}\""
- var argTemplate = "(result = args.hasOwnProperty(\"{0}\") ? " +
- "args[\"{0}\"] : null, \n " +
- "(result === null || result === undefined) ? \"\" : result)"
- module.exports = compile
- function compile(string, inline) {
- var replacements = string.match(nargs)
- var interleave = string.split(nargs)
- var replace = []
- for (var i = 0; i < interleave.length; i++) {
- var current = interleave[i];
- var replacement = replacements[i];
- var escapeLeft = current.charAt(current.length - 1)
- var escapeRight = (interleave[i + 1] || "").charAt(0)
- if (replacement) {
- replacement = replacement.substring(1, replacement.length - 1)
- }
- if (escapeLeft === "{" && escapeRight === "}") {
- replace.push(current + replacement)
- } else {
- replace.push(current);
- if (replacement) {
- replace.push({ name: replacement })
- }
- }
- }
- var prev = [""]
- for (var j = 0; j < replace.length; j++) {
- var curr = replace[j]
- if (String(curr) === curr) {
- var top = prev[prev.length - 1]
- if (String(top) === top) {
- prev[prev.length - 1] = top + curr
- } else {
- prev.push(curr)
- }
- } else {
- prev.push(curr)
- }
- }
- replace = prev
- if (inline) {
- for (var k = 0; k < replace.length; k++) {
- var token = replace[k]
- if (String(token) === token) {
- replace[k] = template(literalTemplate, escape(token))
- } else {
- replace[k] = template(argTemplate, escape(token.name))
- }
- }
- var replaceCode = replace.join(" +\n ")
- var compiledSource = template(replaceTemplate, replaceCode)
- return new Function(compiledSource)
- }
- return function template() {
- var args
- if (arguments.length === 1 && typeof arguments[0] === "object") {
- args = arguments[0]
- } else {
- args = arguments
- }
- if (!args || !("hasOwnProperty" in args)) {
- args = {}
- }
- var result = []
- for (var i = 0; i < replace.length; i++) {
- if (i % 2 === 0) {
- result.push(replace[i])
- } else {
- var argName = replace[i].name
- var arg = args.hasOwnProperty(argName) ? args[argName] : null
- if (arg !== null || arg !== undefined) {
- result.push(arg)
- }
- }
- }
- return result.join("")
- }
- }
- function escape(string) {
- string = '' + string;
- return string.replace(whitespaceRegex, escapedWhitespace);
- }
- function escapedWhitespace(character) {
- // Escape all characters not included in SingleStringCharacters and
- // DoubleStringCharacters on
- // http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
- switch (character) {
- case '"':
- case "'":
- case '\\':
- return '\\' + character
- // Four possible LineTerminator characters need to be escaped:
- case '\n':
- return '\\n'
- case '\r':
- return '\\r'
- case '\u2028':
- return '\\u2028'
- case '\u2029':
- return '\\u2029'
- }
- }
|