diff --git a/demos/template/template4.1/index.html b/demos/template/template4.1/index.html new file mode 100644 index 00000000..b3a5397c --- /dev/null +++ b/demos/template/template4.1/index.html @@ -0,0 +1,22 @@ + + + + + template + + + +
+ + + + + \ No newline at end of file diff --git a/demos/template/template4.1/template.js b/demos/template/template4.1/template.js new file mode 100644 index 00000000..dc5862d6 --- /dev/null +++ b/demos/template/template4.1/template.js @@ -0,0 +1,49 @@ +/** + * 这是文章中的原版实现,文章中对代码进行了简化 + */ +(function() { + var cache = {}; + + this.tmpl = function tmpl(str, data) { + // Figure out if we're getting a template, or if we need to + // load the template - and be sure to cache the result. + var fn = !/\W/.test(str) ? + cache[str] = cache[str] || + tmpl(document.getElementById(str).innerHTML) : + + // Generate a reusable function that will serve as a template + // generator (and which will be cached). + new Function("obj", + "var p=[],print=function(){p.push.apply(p,arguments);};" + + + // Introduce the data as local variables using with(){} + "with(obj){p.push('" + + + // Convert the template into pure JavaScript + str + .replace(/[\r\t\n]/g, " ") + .split("<%").join("\t") + .replace(/((^|%>)[^\t]*)'/g, "$1\r") + .replace(/\t=(.*?)%>/g, "',$1,'") + .split("\t").join("');") + .split("%>").join("p.push('") + .split("\r").join("\\'") + + "');}return p.join('');"); + + // Provide some basic currying to the user + return data ? fn(data) : fn; + }; +})(); + +var results = document.getElementById("container"); + +var data2 = { + users: [ + { "name": "Byron", "url": "http://localhost" }, + { "name": "Casper", "url": "http://localhost" }, + { "name": "Frank", "url": "http://localhost" } + ] +} + +var compiled = tmpl("user_tmpl", data2); +results.innerHTML = compiled; \ No newline at end of file diff --git a/demos/template/template5/index.html b/demos/template/template5/index.html index b3a5397c..ad5c5cf9 100644 --- a/demos/template/template5/index.html +++ b/demos/template/template5/index.html @@ -8,13 +8,9 @@
diff --git a/demos/template/template5/template.js b/demos/template/template5/template.js index 5f8cb927..1a93c9a2 100644 --- a/demos/template/template5/template.js +++ b/demos/template/template5/template.js @@ -1,42 +1,55 @@ -(function(){ - var cache = {}; - - this.tmpl = function tmpl(str, data){ - // Figure out if we're getting a template, or if we need to - // load the template - and be sure to cache the result. - var fn = !/\W/.test(str) ? - cache[str] = cache[str] || - tmpl(document.getElementById(str).innerHTML) : - - // Generate a reusable function that will serve as a template - // generator (and which will be cached). - new Function("obj", - "var p=[],print=function(){p.push.apply(p,arguments);};" + - - // Introduce the data as local variables using with(){} - "with(obj){p.push('" + - - // Convert the template into pure JavaScript - str - .replace(/[\r\t\n]/g, " ") - .split("<%").join("\t") - .replace(/((^|%>)[^\t]*)'/g, "$1\r") - .replace(/\t=(.*?)%>/g, "',$1,'") - .split("\t").join("');") - .split("%>").join("p.push('") - .split("\r").join("\\'") - + "');}return p.join('');"); - - // Provide some basic currying to the user - return data ? fn( data ) : fn; - }; -})(); +/** + * 模板引擎第五版 + */ +var settings = { + // 求值 + evaluate: /<%([\s\S]+?)%>/g, + // 插入 + interpolate: /<%=([\s\S]+?)%>/g, +}; +var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' +}; + +var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; + + +var template = function(text) { + + var source = "var __p='';\n"; + source = source + "with(obj){\n" + source = source + "__p+='"; + + var main = text + .replace(escapeRegExp, function(match) { + return '\\' + escapes[match]; + }) + .replace(settings.interpolate, function(match, interpolate){ + return "'+\n" + interpolate + "+\n'" + }) + .replace(settings.evaluate, function(match, evaluate){ + return "';\n " + evaluate + "\n__p+='" + }) + + source = source + main + "';\n }; \n return __p;"; + + console.log(source) + + var render = new Function('obj', source); + + return render; +}; var results = document.getElementById("container"); -var data2 = { +var data = { users: [ { "name": "Byron", "url": "http://localhost" }, { "name": "Casper", "url": "http://localhost" }, @@ -44,10 +57,6 @@ var data2 = { ] } - -// var compiled = tmpl("user_tmpl"); -// results.innerHTML = compiled(data2); -// -// -var compiled = tmpl("user_tmpl", data2); -results.innerHTML = compiled; \ No newline at end of file +var text = document.getElementById("user_tmpl").innerHTML +var compiled = template(text); +results.innerHTML = compiled(data); \ No newline at end of file diff --git a/demos/template/template6/index.html b/demos/template/template6/index.html new file mode 100644 index 00000000..ad5c5cf9 --- /dev/null +++ b/demos/template/template6/index.html @@ -0,0 +1,18 @@ + + + + + template + + + +
+ + + + + \ No newline at end of file diff --git a/demos/template/template6/template.js b/demos/template/template6/template.js new file mode 100644 index 00000000..cbe262fa --- /dev/null +++ b/demos/template/template6/template.js @@ -0,0 +1,62 @@ +/** + * 模板引擎第六版 + */ + +var settings = { + // 求值 + evaluate: /<%([\s\S]+?)%>/g, + // 插入 + interpolate: /<%=([\s\S]+?)%>/g, +}; + +var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' +}; + +var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; + + +var template = function(text) { + + var source = "var __t, __p='';\n"; + source = source + "with(obj){\n" + source = source + "__p+='"; + + var main = text + .replace(escapeRegExp, function(match) { + return '\\' + escapes[match]; + }) + .replace(settings.interpolate, function(match, interpolate){ + return "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'" + }) + .replace(settings.evaluate, function(match, evaluate){ + return "';\n " + evaluate + "\n__p+='" + }) + + source = source + main + "';\n }; \n return __p;"; + + console.log(source) + + var render = new Function('obj', source); + + return render; +}; + +var results = document.getElementById("container"); + +var data = { + users: [ + { "url": "http://localhost" }, + { "name": "Casper", "url": "http://localhost" }, + { "name": "Frank", "url": "http://localhost" } + ] +} + +var text = document.getElementById("user_tmpl").innerHTML +var compiled = template(text); +results.innerHTML = compiled(data); \ No newline at end of file diff --git a/demos/template/template7/index.html b/demos/template/template7/index.html new file mode 100644 index 00000000..ad5c5cf9 --- /dev/null +++ b/demos/template/template7/index.html @@ -0,0 +1,18 @@ + + + + + template + + + +
+ + + + + \ No newline at end of file diff --git a/demos/template/template7/template.js b/demos/template/template7/template.js new file mode 100644 index 00000000..f860ca9b --- /dev/null +++ b/demos/template/template7/template.js @@ -0,0 +1,77 @@ +/** + * 模板引擎第七版 + */ + +var settings = { + // 求值 + evaluate: /<%([\s\S]+?)%>/g, + // 插入 + interpolate: /<%=([\s\S]+?)%>/g, +}; + +var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' +}; + +var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; + + +var template = function(text) { + + var matcher = RegExp([ + (settings.interpolate).source, + (settings.evaluate).source + ].join('|') + '|$', 'g'); + + var index = 0; + var source = "__p+='"; + + text.replace(matcher, function(match, interpolate, evaluate, offset) { + + source += text.slice(index, offset).replace(escapeRegExp, function(match) { + return '\\' + escapes[match]; + }); + + index = offset + match.length; + + if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + return match; + }); + + source += "';\n"; + + source = 'with(obj||{}){\n' + source + '}\n' + + source = "var __t, __p='';" + + source + 'return __p;\n'; + + console.log(source) + + var render = new Function('obj', source); + + return render; +}; + +var results = document.getElementById("container"); + +var data = { + users: [ + { "url": "http://localhost" }, + { "name": "Casper", "url": "http://localhost" }, + { "name": "Frank", "url": "http://localhost" } + ] +} + +var text = document.getElementById("user_tmpl").innerHTML +var compiled = template(text); +results.innerHTML = compiled(data); \ No newline at end of file diff --git a/demos/template/template8/index.html b/demos/template/template8/index.html new file mode 100644 index 00000000..b3a5397c --- /dev/null +++ b/demos/template/template8/index.html @@ -0,0 +1,22 @@ + + + + + template + + + +
+ + + + + \ No newline at end of file diff --git a/demos/template/template8/template.js b/demos/template/template8/template.js new file mode 100644 index 00000000..83cc0ea1 --- /dev/null +++ b/demos/template/template8/template.js @@ -0,0 +1,100 @@ +/** + * 模板引擎第八版 + */ +var _ = {}; + +_.templateSettings = { + // 求值 + evaluate: /<%([\s\S]+?)%>/g, + // 插入 + interpolate: /<%=([\s\S]+?)%>/g, + // 转义 + escape: /<%-([\s\S]+?)%>/g +}; + +var noMatch = /(.)^/; + +var escapes = { + "'": "'", + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' +}; + +var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; + +var escapeChar = function(match) { + return '\\' + escapes[match]; +}; + +_.template = function(text, settings) { + + settings = Object.assign({}, _.templateSettings, settings); + + var matcher = RegExp([ + (settings.escape || noMatch).source, + (settings.interpolate || noMatch).source, + (settings.evaluate || noMatch).source + ].join('|') + '|$', 'g'); + + var index = 0; + var source = "__p+='"; + text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { + + source += text.slice(index, offset).replace(escapeRegExp, escapeChar); + + index = offset + match.length; + + if (escape) { + source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; + } else if (interpolate) { + source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; + } else if (evaluate) { + source += "';\n" + evaluate + "\n__p+='"; + } + + return match; + }); + source += "';\n"; + + if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; + + source = "var __t,__p='',__j=Array.prototype.join," + + "print=function(){__p+=__j.call(arguments,'');};\n" + + source + 'return __p;\n'; + + var render; + try { + render = new Function(settings.variable || 'obj', '_', source); + } catch (e) { + e.source = source; + throw e; + } + + var template = function(data) { + return render.call(this, data, _); + }; + + var argument = settings.variable || 'obj'; + template.source = 'function(' + argument + '){\n' + source + '}'; + + return template; +}; + +var results = document.getElementById("container"); + +var data = { + users: [ + { "name": "Byron", "url": "http://localhost" }, + { "name": "Casper", "url": "http://localhost" }, + { "name": "Frank", "url": "http://localhost" } + ] +} + +var text = document.getElementById("user_tmpl").innerHTML +var compiled = _.template(text); + +console.log(compiled.source) +results.innerHTML = compiled(data); \ No newline at end of file