doT.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. // doT.js
  2. // 2011-2014, Laura Doktorova, https://github.com/olado/doT
  3. // Licensed under the MIT license.
  4. (function() {
  5. "use strict";
  6. var doT = {
  7. name: "doT",
  8. version: "1.1.1",
  9. templateSettings: {
  10. evaluate: /\{\{([\s\S]+?(\}?)+)\}\}/g,
  11. interpolate: /\{\{=([\s\S]+?)\}\}/g,
  12. encode: /\{\{!([\s\S]+?)\}\}/g,
  13. use: /\{\{#([\s\S]+?)\}\}/g,
  14. useParams: /(^|[^\w$])def(?:\.|\[[\'\"])([\w$\.]+)(?:[\'\"]\])?\s*\:\s*([\w$\.]+|\"[^\"]+\"|\'[^\']+\'|\{[^\}]+\})/g,
  15. define: /\{\{##\s*([\w\.$]+)\s*(\:|=)([\s\S]+?)#\}\}/g,
  16. defineParams: /^\s*([\w$]+):([\s\S]+)/,
  17. conditional: /\{\{\?(\?)?\s*([\s\S]*?)\s*\}\}/g,
  18. iterate: /\{\{~\s*(?:\}\}|([\s\S]+?)\s*\:\s*([\w$]+)\s*(?:\:\s*([\w$]+))?\s*\}\})/g,
  19. varname: "it",
  20. strip: true,
  21. append: true,
  22. selfcontained: false,
  23. doNotSkipEncoded: false
  24. },
  25. template: undefined, //fn, compile template
  26. compile: undefined, //fn, for express
  27. log: true
  28. },
  29. _globals;
  30. doT.encodeHTMLSource = function(doNotSkipEncoded) {
  31. var encodeHTMLRules = {
  32. "&": "&",
  33. "<": "&#60;",
  34. ">": "&#62;",
  35. '"': "&#34;",
  36. "'": "&#39;",
  37. "/": "&#47;"
  38. },
  39. matchHTML = doNotSkipEncoded ? /[&<>"'\/]/g : /&(?!#?\w+;)|<|>|"|'|\//g;
  40. return function(code) {
  41. return code ? code.toString().replace(matchHTML, function(m) {
  42. return encodeHTMLRules[m] || m;
  43. }) : "";
  44. };
  45. };
  46. _globals = (function() {
  47. return this || (0, eval)("this");
  48. }());
  49. /* istanbul ignore else */
  50. if(typeof module !== "undefined" && module.exports) {
  51. module.exports = doT;
  52. } else if(typeof define === "function" && define.amd) {
  53. define(function() {
  54. return doT;
  55. });
  56. } else {
  57. _globals.doT = doT;
  58. }
  59. var startend = {
  60. append: {
  61. start: "'+(",
  62. end: ")+'",
  63. startencode: "'+encodeHTML("
  64. },
  65. split: {
  66. start: "';out+=(",
  67. end: ");out+='",
  68. startencode: "';out+=encodeHTML("
  69. }
  70. },
  71. skip = /$^/;
  72. function resolveDefs(c, block, def) {
  73. return((typeof block === "string") ? block : (block + "") )//.toString()
  74. .replace(c.define || skip, function(m, code, assign, value) {
  75. if(code.indexOf("def.") === 0) {
  76. code = code.substring(4);
  77. }
  78. if(!(code in def)) {
  79. if(assign === ":") {
  80. if(c.defineParams) value.replace(c.defineParams, function(m, param, v) {
  81. def[code] = {
  82. arg: param,
  83. text: v
  84. };
  85. });
  86. if(!(code in def)) def[code] = value;
  87. } else {
  88. new Function("def", "def['" + code + "']=" + value)(def);
  89. }
  90. }
  91. return "";
  92. })
  93. .replace(c.use || skip, function(m, code) {
  94. if(c.useParams) code = code.replace(c.useParams, function(m, s, d, param) {
  95. if(def[d] && def[d].arg && param) {
  96. var rw = (d + ":" + param).replace(/'|\\/g, "_");
  97. def.__exp = def.__exp || {};
  98. def.__exp[rw] = def[d].text.replace(new RegExp("(^|[^\\w$])" + def[d].arg + "([^\\w$])", "g"), "$1" + param + "$2");
  99. return s + "def.__exp['" + rw + "']";
  100. }
  101. });
  102. var v = new Function("def", "return " + code)(def);
  103. return v ? resolveDefs(c, v, def) : v;
  104. });
  105. }
  106. function unescape(code) {
  107. return code.replace(/\\('|\\)/g, "$1").replace(/[\r\t\n]/g, " ");
  108. }
  109. doT.template = function(tmpl, c, def) {
  110. c = c || doT.templateSettings;
  111. var cse = c.append ? startend.append : startend.split,
  112. needhtmlencode, sid = 0,
  113. indv,
  114. str = (c.use || c.define) ? resolveDefs(c, tmpl, def || {}) : tmpl;
  115. str = ("var out='" + (c.strip ? str.replace(/(^|\r|\n)\t* +| +\t*(\r|\n|$)/g, " ")
  116. .replace(/\r|\n|\t|\/\*[\s\S]*?\*\//g, "") : str)
  117. .replace(/'|\\/g, "\\$&")
  118. .replace(c.interpolate || skip, function(m, code) {
  119. return cse.start + unescape(code) + cse.end;
  120. })
  121. .replace(c.encode || skip, function(m, code) {
  122. needhtmlencode = true;
  123. return cse.startencode + unescape(code) + cse.end;
  124. })
  125. .replace(c.conditional || skip, function(m, elsecase, code) {
  126. return elsecase ?
  127. (code ? "';}else if(" + unescape(code) + "){out+='" : "';}else{out+='") :
  128. (code ? "';if(" + unescape(code) + "){out+='" : "';}out+='");
  129. })
  130. .replace(c.iterate || skip, function(m, iterate, vname, iname) {
  131. if(!iterate) return "';} } out+='";
  132. sid += 1;
  133. indv = iname || "i" + sid;
  134. iterate = unescape(iterate);
  135. return "';var arr" + sid + "=" + iterate + ";if(arr" + sid + "){var " + vname + "," + indv + "=-1,l" + sid + "=arr" + sid + ".length-1;while(" + indv + "<l" + sid + "){" +
  136. vname + "=arr" + sid + "[" + indv + "+=1];out+='";
  137. })
  138. .replace(c.evaluate || skip, function(m, code) {
  139. return "';" + unescape(code) + "out+='";
  140. }) +
  141. "';return out;")
  142. .replace(/\n/g, "\\n").replace(/\t/g, '\\t').replace(/\r/g, "\\r")
  143. .replace(/(\s|;|\}|^|\{)out\+='';/g, '$1').replace(/\+''/g, "");
  144. //.replace(/(\s|;|\}|^|\{)out\+=''\+/g,'$1out+=');
  145. if(needhtmlencode) {
  146. if(!c.selfcontained && _globals && !_globals._encodeHTML) _globals._encodeHTML = doT.encodeHTMLSource(c.doNotSkipEncoded);
  147. str = "var encodeHTML = typeof _encodeHTML !== 'undefined' ? _encodeHTML : (" +
  148. doT.encodeHTMLSource.toString() + "(" + (c.doNotSkipEncoded || '') + "));" +
  149. str;
  150. }
  151. try {
  152. return new Function(c.varname, str);
  153. } catch(e) {
  154. /* istanbul ignore else */
  155. if(typeof console !== "undefined") console.log("无法创建模板函数: " + str);
  156. throw e;
  157. }
  158. };
  159. doT.compile = function(tmpl, def) {
  160. return doT.template(tmpl, null, def);
  161. };
  162. }());