From a1028877c0bd34cdca501914acbf94c539ead10b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Thu, 4 May 2017 23:25:18 +0800 Subject: [PATCH 01/12] rebuild --- lib/compile/runtime.js | 93 +++++++++++++++++++++++++++++++++- test/compile/adapter/escape.js | 55 -------------------- 2 files changed, 91 insertions(+), 57 deletions(-) delete mode 100644 test/compile/adapter/escape.js diff --git a/lib/compile/runtime.js b/lib/compile/runtime.js index 7f79a922..87f06a19 100644 --- a/lib/compile/runtime.js +++ b/lib/compile/runtime.js @@ -3,10 +3,99 @@ /*! art-template@runtime | https://github.com/aui/art-template */ var detectNode = require('detect-node'); -var each = require('./adapter/each'); -var escape = require('./adapter/escape'); var runtime = Object.create(detectNode ? global : window); +// 将目标转成字符 +var toString = function toString(value) { + if (typeof value !== 'string') { + if (value === undefined || value === null) { + value = ''; + } else if (typeof value === 'function') { + value = toString(value.call(value)); + } else { + value = JSON.stringify(value); + } + } + + return value; +}; + +// 编码 HTML 内容 +var ESCAPE_REG = /["&'<>]/; +var xmlEscape = function xmlEscape(content) { + var html = '' + content; + var regexResult = ESCAPE_REG.exec(html); + if (!regexResult) { + return content; + } + + var result = ''; + var i = void 0, + lastIndex = void 0, + char = void 0; + for (i = regexResult.index, lastIndex = 0; i < html.length; i++) { + + switch (html.charCodeAt(i)) { + case 34: + char = '"'; + break; + case 38: + char = '&'; + break; + case 39: + char = '''; + break; + case 60: + char = '<'; + break; + case 62: + char = '>'; + break; + default: + continue; + } + + if (lastIndex !== i) { + result += html.substring(lastIndex, i); + } + + lastIndex = i + 1; + result += char; + } + + if (lastIndex !== i) { + return result + html.substring(lastIndex, i); + } else { + return result; + } +}; + +/** + * 编码模板输出的内容 + * @param {any} content + * @return {string} + */ +var escape = function escape(content) { + return xmlEscape(toString(content)); +}; + +/** + * 迭代器,支持数组与对象 + * @param {array|Object} data + * @param {function} callback + */ +var each = function each(data, callback) { + if (Array.isArray(data)) { + for (var i = 0, len = data.length; i < len; i++) { + callback(data[i], i, data); + } + } else { + for (var _i in data) { + callback(data[_i], _i); + } + } +}; + runtime.$each = each; runtime.$escape = escape; diff --git a/test/compile/adapter/escape.js b/test/compile/adapter/escape.js deleted file mode 100644 index 35ab6ad6..00000000 --- a/test/compile/adapter/escape.js +++ /dev/null @@ -1,55 +0,0 @@ -const assert = require('assert'); -const escape = require('../../../lib/compile/adapter/escape'); - -module.exports = { - before: () => { - console.log('#compile/adapter/escape'); - }, - - 'escape': { - 'basic': () => { - const test = (content, result) => { - assert.deepEqual(result, escape(content)); - }; - - // basic - test('string', 'string'); - test(1, '1'); - test(0, '0'); - test(function() { return 'value' }, 'value'); - test(() => 'value', 'value'); - test(null, ''); - test(undefined, ''); - test([0, 1, 2, {}], JSON.stringify([0, 1, 2, {}])); - test({}, JSON.stringify({})); - } - }, - - 'html': () => { - const test = (content, result) => { - assert.deepEqual(result, escape(content)); - }; - - test('<', '<'); - test('>', '>'); - test('"', '"'); - test("'", '''); - test('&', '&') - }, - - 'mixing': () => { - const test = (content, result) => { - assert.deepEqual(result, escape(content)); - }; - - test('', '<img onerror="alert(0)">'); - test({ - "<": "<", - ">": ">", - '"': """, - "'": "'", - "&": "&" - }, '{"<":"&#60;",">":"&#62;","\\"":"&#34;","'":"&#39;","&":"&#38;"}'); - - } -}; \ No newline at end of file From 90304709a2a510c69aaaee87b89b8b046b79b2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Thu, 4 May 2017 23:30:19 +0800 Subject: [PATCH 02/12] rebuild --- lib/template-web.js | 4 +- package.json | 2 +- src/compile/defaults.js | 4 +- src/compile/runtime.js | 93 ++++++++++++++++++++++++++++++++++++++++- src/precompile.js | 11 ++--- test/compile/runtime.js | 57 +++++++++++++++++++++++++ 6 files changed, 158 insertions(+), 13 deletions(-) create mode 100644 test/compile/runtime.js diff --git a/lib/template-web.js b/lib/template-web.js index f8625577..fff7747c 100644 --- a/lib/template-web.js +++ b/lib/template-web.js @@ -1,3 +1,3 @@ /*! art-template@4.8.1 for browser | https://github.com/aui/art-template */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=23)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(18),i=n(2),o=n(21),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";var r=n(0),i=n(20),o=n(10),s=n(14),a=n(7),c=n(13),u=n(12),p=n(16),l=n(17),f=n(11),h=n(15),m={source:null,filename:null,rules:[l,p],escape:!0,debug:!!r&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:h,htmlMinifier:f,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:s,loader:c,caches:a,root:"/",extname:".art",ignore:[],imports:i};m.$extend=function(){var e=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};return o(e,m)},i.$include=u,e.exports=m},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=function(e,t){if(Array.isArray(e))for(var n=0,r=e.length;n]/,o=function(e){var t=""+e,n=i.exec(t);if(!n)return e;var r="",o=void 0,s=void 0,a=void 0;for(o=n.index,s=0;o>>","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,x=[],b=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==b[0];)y+=b.shift();b.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?x.push([]):x[x.length-1].push(e)}),x.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(19),o=n(22),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$layout",g="$$options",y=function(e,t){return e.hasOwnProperty(t)},x=JSON.stringify,b=function(){function e(t){var n,i,y,x=this;r(this,e);var b=t.source,k=t.minimize,w=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[g]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[v]="function(){return "+a+".$include("+d+","+s+","+m+","+g+")}",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data,block){"+f+"+="+a+".$include(src,data||"+s+",block,"+g+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(y={},y[c]=[f],y[u]=[f,a,s,g],y[p]=[d,v],y[l]=[d,f,m],y[v]=[a,d,s,m,g],y),this.importContext(f),t.compileDebug&&this.importContext(h),k)try{b=w(b,t)}catch(E){}this.source=b,this.getTplTokens(b,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?x.parseString(e):x.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!y(f,e)&&!y(o,e)&&p.indexOf(e)<0&&(y(r,e)?(n=r[e],y(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=y(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+x(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\s*function\s*\([\w\W]*?\)\s*{[\s;]*$)/,"$1})"],[/(^.*?\(\s*[\w\W]*?=>\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,o=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t},s=function(e){return e.match(i).map(function(e){return i.lastIndex=0,o(i.exec(e))}).map(function(e){return"name"===e.type&&r(e.value)&&(e.type="keyword"),e})};e.exports=s},function(e,t,n){"use strict";(function(t){/*! art-template@runtime | https://github.com/aui/art-template */ -var r=n(0),i=n(8),o=n(9),s=Object.create(r?t:window);s.$each=i,s.$escape=o,e.exports=s}).call(t,n(4))},function(e,t,n){"use strict";function r(e){var t=e.stack;delete e.stack,this.name="TemplateError",this.message=JSON.stringify(e,null,4),this.stack=t}r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,e.exports=r},function(e,t,n){"use strict";var r=function(e,t,n){for(var r=[{type:"string",value:e,line:0,start:0,end:e.length}],i=0;i1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(8),s=n(12),a=n(7),c=n(11),u=n(10),p=n(14),l=n(15),f=n(9),h=n(13),m={source:null,filename:null,rules:[l,p],escape:!0,debug:!!r&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:h,htmlMinifier:f,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:s,loader:c,caches:a,root:"/",extname:".art",ignore:[],imports:i};m.$extend=function(){var e=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};return o(e,m)},i.$include=u,e.exports=m},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(22).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}",">>>","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(17),o=n(20),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$layout",g="$$options",y=function(e,t){return e.hasOwnProperty(t)},b=JSON.stringify,x=function(){function e(t){var n,i,y,b=this;r(this,e);var x=t.source,k=t.minimize,w=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[g]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[v]="function(){return "+a+".$include("+d+","+s+","+m+","+g+")}",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data,block){"+f+"+="+a+".$include(src,data||"+s+",block,"+g+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(y={},y[c]=[f],y[u]=[f,a,s,g],y[p]=[d,v],y[l]=[d,f,m],y[v]=[a,d,s,m,g],y),this.importContext(f),t.compileDebug&&this.importContext(h),k)try{x=w(x,t)}catch(E){}this.source=x,this.getTplTokens(x,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?b.parseString(e):b.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!y(f,e)&&!y(o,e)&&p.indexOf(e)<0&&(y(r,e)?(n=r[e],y(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=y(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+b(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\s*function\s*\([\w\W]*?\)\s*{[\s;]*$)/,"$1})"],[/(^.*?\(\s*[\w\W]*?=>\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,o=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t},s=function(e){return e.match(i).map(function(e){return i.lastIndex=0,o(i.exec(e))}).map(function(e){return"name"===e.type&&r(e.value)&&(e.type="keyword"),e})};e.exports=s},function(e,t,n){"use strict";(function(t){/*! art-template@runtime | https://github.com/aui/art-template */ +var r=n(0),i=Object.create(r?t:window),o=function p(e){return"string"!=typeof e&&(e=e===undefined||null===e?"":"function"==typeof e?p(e.call(e)):JSON.stringify(e)),e},s=/["&'<>]/,a=function(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i extend(options, defaults); +defaults.$extend = function (options) { + return extend(options || {}, this); +}; // 载入子模板的方法 diff --git a/src/compile/runtime.js b/src/compile/runtime.js index 4de920ea..d520d94f 100644 --- a/src/compile/runtime.js +++ b/src/compile/runtime.js @@ -1,10 +1,99 @@ /*! art-template@runtime | https://github.com/aui/art-template */ const detectNode = require('detect-node'); -const each = require('./adapter/each'); -const escape = require('./adapter/escape'); const runtime = Object.create(detectNode ? global : window); + +// 将目标转成字符 +const toString = value => { + if (typeof value !== 'string') { + if (value === undefined || value === null) { + value = ''; + } else if (typeof value === 'function') { + value = toString(value.call(value)); + } else { + value = JSON.stringify(value); + } + } + + return value; +}; + + +// 编码 HTML 内容 +const ESCAPE_REG = /["&'<>]/; +const xmlEscape = content => { + const html = '' + content; + const regexResult = ESCAPE_REG.exec(html); + if (!regexResult) { + return content; + } + + let result = ''; + let i, lastIndex, char; + for (i = regexResult.index, lastIndex = 0; i < html.length; i++) { + + switch (html.charCodeAt(i)) { + case 34: + char = '"'; + break; + case 38: + char = '&'; + break; + case 39: + char = '''; + break; + case 60: + char = '<'; + break; + case 62: + char = '>'; + break; + default: + continue; + } + + if (lastIndex !== i) { + result += html.substring(lastIndex, i); + } + + lastIndex = i + 1; + result += char; + } + + if (lastIndex !== i) { + return result + html.substring(lastIndex, i); + } else { + return result; + } +}; + + +/** + * 编码模板输出的内容 + * @param {any} content + * @return {string} + */ +const escape = content => xmlEscape(toString(content)); + + +/** + * 迭代器,支持数组与对象 + * @param {array|Object} data + * @param {function} callback + */ +const each = (data, callback) => { + if (Array.isArray(data)) { + for (let i = 0, len = data.length; i < len; i++) { + callback(data[i], i, data); + } + } else { + for (let i in data) { + callback(data[i], i); + } + } +}; + runtime.$each = each; runtime.$escape = escape; diff --git a/src/precompile.js b/src/precompile.js index 542e65e1..d5f81b0c 100644 --- a/src/precompile.js +++ b/src/precompile.js @@ -84,8 +84,7 @@ const getOldSourceMap = (mappings, { * @param {Object} options 编译选项 * @return {Object} */ -const precompile = options => { - options = options || {}; +const precompile = (options = {}) => { if (typeof options.filename !== 'string') { throw Error('template.precompile(): "options.filename" required'); @@ -173,8 +172,8 @@ const precompile = options => { case CONSTS.INCLUDE: - var filenameNode = convertFilenameNode(node.arguments[0], options); - var dataNode = node.arguments[1] || { + const filenameNode = convertFilenameNode(node.arguments[0], options); + const dataNode = node.arguments[1] || { "type": "Identifier", "name": CONSTS.DATA }; @@ -248,9 +247,7 @@ const precompile = options => { code, ast, sourceMap, - toString: function () { - return code; - } + toString: () => code }; }; diff --git a/test/compile/runtime.js b/test/compile/runtime.js new file mode 100644 index 00000000..e764edc4 --- /dev/null +++ b/test/compile/runtime.js @@ -0,0 +1,57 @@ +const assert = require('assert'); +const runtime = require('../../lib/compile/runtime'); + +module.exports = { + before: () => { + console.log('#compile/runtime'); + }, + + 'escape': { + 'basic': () => { + const test = (content, result) => { + assert.deepEqual(result, runtime.$escape(content)); + }; + + // basic + test('string', 'string'); + test(1, '1'); + test(0, '0'); + test(function () { + return 'value' + }, 'value'); + test(() => 'value', 'value'); + test(null, ''); + test(undefined, ''); + test([0, 1, 2, {}], JSON.stringify([0, 1, 2, {}])); + test({}, JSON.stringify({})); + }, + + 'html': () => { + const test = (content, result) => { + assert.deepEqual(result, runtime.$escape(content)); + }; + + test('<', '<'); + test('>', '>'); + test('"', '"'); + test("'", '''); + test('&', '&') + }, + + 'mixing': () => { + const test = (content, result) => { + assert.deepEqual(result, runtime.$escape(content)); + }; + + test('', '<img onerror="alert(0)">'); + test({ + "<": "<", + ">": ">", + '"': """, + "'": "'", + "&": "&" + }, '{"<":"&#60;",">":"&#62;","\\"":"&#34;","'":"&#39;","&":"&#38;"}'); + + } + } +}; \ No newline at end of file From e625f157ee097a34f52877161480180af0952442 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Thu, 4 May 2017 23:31:06 +0800 Subject: [PATCH 03/12] rebuild --- lib/compile/defaults.js | 5 ++--- lib/precompile.js | 5 +++-- lib/template-web.js | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/compile/defaults.js b/lib/compile/defaults.js index 357b4e90..1025eebe 100644 --- a/lib/compile/defaults.js +++ b/lib/compile/defaults.js @@ -87,9 +87,8 @@ var defaults = { * @param {Object} options * @return {Object} */ -defaults.$extend = function () { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return extend(options, defaults); +defaults.$extend = function (options) { + return extend(options || {}, this); }; // 载入子模板的方法 diff --git a/lib/precompile.js b/lib/precompile.js index d2752b1c..1e71a76c 100644 --- a/lib/precompile.js +++ b/lib/precompile.js @@ -78,8 +78,9 @@ var getOldSourceMap = function getOldSourceMap(mappings, _ref) { * @param {Object} options 编译选项 * @return {Object} */ -var precompile = function precompile(options) { - options = options || {}; +var precompile = function precompile() { + var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + if (typeof options.filename !== 'string') { throw Error('template.precompile(): "options.filename" required'); diff --git a/lib/template-web.js b/lib/template-web.js index fff7747c..188f1c4e 100644 --- a/lib/template-web.js +++ b/lib/template-web.js @@ -1,3 +1,3 @@ -/*! art-template@4.8.1 for browser | https://github.com/aui/art-template */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=21)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(16),i=n(2),o=n(19),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(8),s=n(12),a=n(7),c=n(11),u=n(10),p=n(14),l=n(15),f=n(9),h=n(13),m={source:null,filename:null,rules:[l,p],escape:!0,debug:!!r&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:h,htmlMinifier:f,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:s,loader:c,caches:a,root:"/",extname:".art",ignore:[],imports:i};m.$extend=function(){var e=arguments.length>0&&arguments[0]!==undefined?arguments[0]:{};return o(e,m)},i.$include=u,e.exports=m},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(22).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}",">>>","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(17),o=n(20),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$layout",g="$$options",y=function(e,t){return e.hasOwnProperty(t)},b=JSON.stringify,x=function(){function e(t){var n,i,y,b=this;r(this,e);var x=t.source,k=t.minimize,w=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[g]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[v]="function(){return "+a+".$include("+d+","+s+","+m+","+g+")}",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data,block){"+f+"+="+a+".$include(src,data||"+s+",block,"+g+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(y={},y[c]=[f],y[u]=[f,a,s,g],y[p]=[d,v],y[l]=[d,f,m],y[v]=[a,d,s,m,g],y),this.importContext(f),t.compileDebug&&this.importContext(h),k)try{x=w(x,t)}catch(E){}this.source=x,this.getTplTokens(x,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?b.parseString(e):b.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!y(f,e)&&!y(o,e)&&p.indexOf(e)<0&&(y(r,e)?(n=r[e],y(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=y(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+b(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\s*function\s*\([\w\W]*?\)\s*{[\s;]*$)/,"$1})"],[/(^.*?\(\s*[\w\W]*?=>\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,o=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t},s=function(e){return e.match(i).map(function(e){return i.lastIndex=0,o(i.exec(e))}).map(function(e){return"name"===e.type&&r(e.value)&&(e.type="keyword"),e})};e.exports=s},function(e,t,n){"use strict";(function(t){/*! art-template@runtime | https://github.com/aui/art-template */ +/*! art-template@4.9.0 for browser | https://github.com/aui/art-template */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=21)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(16),i=n(2),o=n(19),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(8),s=n(12),a=n(7),c=n(11),u=n(10),p=n(14),l=n(15),f=n(9),h=n(13),m={source:null,filename:null,rules:[l,p],escape:!0,debug:!!r&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:h,htmlMinifier:f,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:s,loader:c,caches:a,root:"/",extname:".art",ignore:[],imports:i};m.$extend=function(e){return o(e||{},this)},i.$include=u,e.exports=m},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(22).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}",">>>","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(17),o=n(20),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$layout",g="$$options",y=function(e,t){return e.hasOwnProperty(t)},b=JSON.stringify,x=function(){function e(t){var n,i,y,b=this;r(this,e);var x=t.source,k=t.minimize,w=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[g]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[v]="function(){return "+a+".$include("+d+","+s+","+m+","+g+")}",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data,block){"+f+"+="+a+".$include(src,data||"+s+",block,"+g+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(y={},y[c]=[f],y[u]=[f,a,s,g],y[p]=[d,v],y[l]=[d,f,m],y[v]=[a,d,s,m,g],y),this.importContext(f),t.compileDebug&&this.importContext(h),k)try{x=w(x,t)}catch(E){}this.source=x,this.getTplTokens(x,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?b.parseString(e):b.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!y(f,e)&&!y(o,e)&&p.indexOf(e)<0&&(y(r,e)?(n=r[e],y(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=y(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+b(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\s*function\s*\([\w\W]*?\)\s*{[\s;]*$)/,"$1})"],[/(^.*?\(\s*[\w\W]*?=>\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,o=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t},s=function(e){return e.match(i).map(function(e){return i.lastIndex=0,o(i.exec(e))}).map(function(e){return"name"===e.type&&r(e.value)&&(e.type="keyword"),e})};e.exports=s},function(e,t,n){"use strict";(function(t){/*! art-template@runtime | https://github.com/aui/art-template */ var r=n(0),i=Object.create(r?t:window),o=function p(e){return"string"!=typeof e&&(e=e===undefined||null===e?"":"function"==typeof e?p(e.call(e)):JSON.stringify(e)),e},s=/["&'<>]/,a=function(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i Date: Sat, 6 May 2017 11:06:14 +0800 Subject: [PATCH 04/12] =?UTF-8?q?=E9=87=8D=E6=9E=84checkExpression?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compile/compiler.js | 11 ++++++----- test/compile/compiler.js | 28 ++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/compile/compiler.js b/src/compile/compiler.js index 7c781a0a..34ae03ae 100644 --- a/src/compile/compiler.js +++ b/src/compile/compiler.js @@ -281,6 +281,8 @@ class Compiler { checkExpression(script) { // 没有闭合的块级模板语句规则 + // 基于正则规则来补全语法不能保证 100% 准确, + // 但是在绝大多数情况下足以满足辅助开发调试的需要 const rules = [ // <% } %> @@ -288,11 +290,10 @@ class Compiler { // <% }else if(a){ %> [/^\s*}[\w\W]*?{?[\s;]*$/, ''], - // <% list.forEach(function(a,b){ %> - [/(^[\w\W]*?\s*function\s*\([\w\W]*?\)\s*{[\s;]*$)/, '$1})'], - - // <% list.forEach((a,b)=>{ %> - [/(^.*?\(\s*[\w\W]*?=>\s*{[\s;]*$)/, '$1})'], + // <% fn(c,function(a,b){ %> + // <% fn(c, a=>{ %> + // <% fn(c,(a,b)=>{ %> + [/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/, '$1})'], // <% if(a){ %> // <% for(var i in d){ %> diff --git a/test/compile/compiler.js b/test/compile/compiler.js index 44350406..7787312c 100644 --- a/test/compile/compiler.js +++ b/test/compile/compiler.js @@ -200,22 +200,38 @@ module.exports = { test('if(a){', true); test('for(var i in d){', true); - test('list.forEach(function(a,b){', true); - test('list.forEach((a,b)=>{', true); + test('fn(function(a,b){', true); + test('fn ( function ( a, b ) { ', true); + test('fn(1,function(a,b){', true); + test('fn ( 1, function ( a, b ) { ', true); + test('fn(function(){', true); + test('fn ( function ( ) { ', true); + test('fn(1,function(){', true); + test('fn ( 1, function ( ) { ', true); + test('fn((a,b)=>{', true); + test('fn ( ( a , b ) => { ', true); + test('fn(1,(a,b)=>{', true); + test('fn ( 1, ( a , b ) => { ', true); + test('fn(()=>{', true); + test('fn ( ( ) => { ', true); + test('fn(1,()=>{', true); + test('fn ( 1 , ( ) => { ', true); test('$each(user.tags,function($value,$index){;', true); test('}else if(a){', true); test('}else{', true); test('}', true); + //test('(a,b)=>{', true); + test('if(a){}', true); test('for(var i in d){}', true); - test('list.forEach(function(a,b){})', true); - test('list.forEach((a,b)=>{})', true); + test('fn(function(a,b){})', true); + test('fn((a,b)=>{})', true); test('@if(a){', false); test('@for(var i in d){', false); - test('@list.forEach(function(a,b){', false); - test('@list.forEach((a,b)=>{', false); + test('@fn(function(a,b){', false); + test('@fn((a,b)=>{', false); } }, From 9a3cfb79a0c24509a6fd3e2874429505cf60c03b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Sat, 6 May 2017 11:07:12 +0800 Subject: [PATCH 05/12] =?UTF-8?q?=E6=B8=B2=E6=9F=93=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=8F=AF=E4=BB=A5=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++++ src/compile/compiler.js | 1 + test/compile/compiler.js | 18 +++++++++--------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6410b9b..72e5b28a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v4.9.0 + +1. 渲染函数参数可以为空 + ## v4.8.1 1. 修复低版本 NodeJS 报错问题 diff --git a/src/compile/compiler.js b/src/compile/compiler.js index 34ae03ae..f944e383 100644 --- a/src/compile/compiler.js +++ b/src/compile/compiler.js @@ -369,6 +369,7 @@ class Compiler { stacks.push(`function(${DATA}){`); stacks.push(`'use strict'`); + stacks.push(`${DATA}=${DATA}||{}`); stacks.push(`var ` + context.map(({ name, value diff --git a/test/compile/compiler.js b/test/compile/compiler.js index 7787312c..c8f1d839 100644 --- a/test/compile/compiler.js +++ b/test/compile/compiler.js @@ -250,7 +250,7 @@ module.exports = { test(`{{value}}`, [{ generated: { - line: 4, + line: 5, column: 1 }, original: { @@ -261,7 +261,7 @@ module.exports = { test(`abc{{value}}`, [{ generated: { - line: 4, + line: 5, column: 1 }, original: { @@ -270,7 +270,7 @@ module.exports = { } }, { generated: { - line: 5, + line: 6, column: 1 }, original: { @@ -281,7 +281,7 @@ module.exports = { test(`abc\n{{value}}`, [{ generated: { - line: 4, + line: 5, column: 1 }, original: { @@ -290,7 +290,7 @@ module.exports = { } }, { generated: { - line: 5, + line: 6, column: 1 }, original: { @@ -302,7 +302,7 @@ module.exports = { test(`abc\n<%\n print('s') \n eeee(2) %>\n{{a}}`, [{ generated: { - line: 4, + line: 5, column: 1 }, original: { @@ -311,7 +311,7 @@ module.exports = { } }, { generated: { - line: 5, + line: 6, column: 1 }, original: { @@ -320,7 +320,7 @@ module.exports = { } }, { generated: { - line: 8, + line: 9, column: 1 }, original: { @@ -329,7 +329,7 @@ module.exports = { } }, { generated: { - line: 9, + line: 10, column: 1 }, original: { From 65909c462cc82fbc14cd079fecbb72c61118837c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Sat, 6 May 2017 11:07:33 +0800 Subject: [PATCH 06/12] rebuild --- lib/compile/compiler.js | 12 +++++++----- lib/template-web.js | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/compile/compiler.js b/lib/compile/compiler.js index e4b8d48b..671e300d 100644 --- a/lib/compile/compiler.js +++ b/lib/compile/compiler.js @@ -270,6 +270,8 @@ var Compiler = function () { Compiler.prototype.checkExpression = function checkExpression(script) { // 没有闭合的块级模板语句规则 + // 基于正则规则来补全语法不能保证 100% 准确, + // 但是在绝大多数情况下足以满足辅助开发调试的需要 var rules = [ // <% } %> @@ -277,11 +279,10 @@ var Compiler = function () { // <% }else if(a){ %> [/^\s*}[\w\W]*?{?[\s;]*$/, ''], - // <% list.forEach(function(a,b){ %> - [/(^[\w\W]*?\s*function\s*\([\w\W]*?\)\s*{[\s;]*$)/, '$1})'], - - // <% list.forEach((a,b)=>{ %> - [/(^.*?\(\s*[\w\W]*?=>\s*{[\s;]*$)/, '$1})'], + // <% fn(c,function(a,b){ %> + // <% fn(c, a=>{ %> + // <% fn(c,(a,b)=>{ %> + [/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/, '$1})'], // <% if(a){ %> // <% for(var i in d){ %> @@ -353,6 +354,7 @@ var Compiler = function () { stacks.push('function(' + DATA + '){'); stacks.push('\'use strict\''); + stacks.push(DATA + '=' + DATA + '||{}'); stacks.push('var ' + context.map(function (_ref2) { var name = _ref2.name, value = _ref2.value; diff --git a/lib/template-web.js b/lib/template-web.js index 188f1c4e..5a357bbb 100644 --- a/lib/template-web.js +++ b/lib/template-web.js @@ -1,3 +1,3 @@ /*! art-template@4.9.0 for browser | https://github.com/aui/art-template */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=21)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(16),i=n(2),o=n(19),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(8),s=n(12),a=n(7),c=n(11),u=n(10),p=n(14),l=n(15),f=n(9),h=n(13),m={source:null,filename:null,rules:[l,p],escape:!0,debug:!!r&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:h,htmlMinifier:f,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:s,loader:c,caches:a,root:"/",extname:".art",ignore:[],imports:i};m.$extend=function(e){return o(e||{},this)},i.$include=u,e.exports=m},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(22).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}",">>>","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(17),o=n(20),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$layout",g="$$options",y=function(e,t){return e.hasOwnProperty(t)},b=JSON.stringify,x=function(){function e(t){var n,i,y,b=this;r(this,e);var x=t.source,k=t.minimize,w=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[g]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[v]="function(){return "+a+".$include("+d+","+s+","+m+","+g+")}",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data,block){"+f+"+="+a+".$include(src,data||"+s+",block,"+g+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(y={},y[c]=[f],y[u]=[f,a,s,g],y[p]=[d,v],y[l]=[d,f,m],y[v]=[a,d,s,m,g],y),this.importContext(f),t.compileDebug&&this.importContext(h),k)try{x=w(x,t)}catch(E){}this.source=x,this.getTplTokens(x,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?b.parseString(e):b.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!y(f,e)&&!y(o,e)&&p.indexOf(e)<0&&(y(r,e)?(n=r[e],y(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=y(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+b(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\s*function\s*\([\w\W]*?\)\s*{[\s;]*$)/,"$1})"],[/(^.*?\(\s*[\w\W]*?=>\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,o=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t},s=function(e){return e.match(i).map(function(e){return i.lastIndex=0,o(i.exec(e))}).map(function(e){return"name"===e.type&&r(e.value)&&(e.type="keyword"),e})};e.exports=s},function(e,t,n){"use strict";(function(t){/*! art-template@runtime | https://github.com/aui/art-template */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=21)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(16),i=n(2),o=n(19),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(8),s=n(12),a=n(7),c=n(11),u=n(10),p=n(14),l=n(15),f=n(9),h=n(13),m={source:null,filename:null,rules:[l,p],escape:!0,debug:!!r&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:h,htmlMinifier:f,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:s,loader:c,caches:a,root:"/",extname:".art",ignore:[],imports:i};m.$extend=function(e){return o(e||{},this)},i.$include=u,e.exports=m},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(22).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}",">>>","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(17),o=n(20),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$layout",g="$$options",y=function(e,t){return e.hasOwnProperty(t)},b=JSON.stringify,x=function(){function e(t){var n,i,y,b=this;r(this,e);var x=t.source,k=t.minimize,w=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[g]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[v]="function(){return "+a+".$include("+d+","+s+","+m+","+g+")}",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data,block){"+f+"+="+a+".$include(src,data||"+s+",block,"+g+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(y={},y[c]=[f],y[u]=[f,a,s,g],y[p]=[d,v],y[l]=[d,f,m],y[v]=[a,d,s,m,g],y),this.importContext(f),t.compileDebug&&this.importContext(h),k)try{x=w(x,t)}catch(E){}this.source=x,this.getTplTokens(x,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?b.parseString(e):b.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!y(f,e)&&!y(o,e)&&p.indexOf(e)<0&&(y(r,e)?(n=r[e],y(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=y(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+b(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,o=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t},s=function(e){return e.match(i).map(function(e){return i.lastIndex=0,o(i.exec(e))}).map(function(e){return"name"===e.type&&r(e.value)&&(e.type="keyword"),e})};e.exports=s},function(e,t,n){"use strict";(function(t){/*! art-template@runtime | https://github.com/aui/art-template */ var r=n(0),i=Object.create(r?t:window),o=function p(e){return"string"!=typeof e&&(e=e===undefined||null===e?"":"function"==typeof e?p(e.call(e)):JSON.stringify(e)),e},s=/["&'<>]/,a=function(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i Date: Sat, 6 May 2017 17:17:53 +0800 Subject: [PATCH 07/12] rebuild --- src/compile/adapter/rule.art.js | 2 +- src/compile/es-tokenizer.js | 20 ++------------------ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/compile/adapter/rule.art.js b/src/compile/adapter/rule.art.js index 10c71051..5ff532f4 100644 --- a/src/compile/adapter/rule.art.js +++ b/src/compile/adapter/rule.art.js @@ -20,7 +20,7 @@ const artRule = { // 旧版语法升级提示 const warn = (oldSyntax, newSyntax) => { console.warn('Template upgrade:', - `{{${oldSyntax}}}`, `>>>`, `{{${newSyntax}}}`, + `{{${oldSyntax}}}`, `->`, `{{${newSyntax}}}`, `\n`, options.filename || ''); }; diff --git a/src/compile/es-tokenizer.js b/src/compile/es-tokenizer.js index 317d31c1..f5110003 100644 --- a/src/compile/es-tokenizer.js +++ b/src/compile/es-tokenizer.js @@ -1,22 +1,6 @@ const isKeyword = require('is-keyword-js'); - -// js-tokens@3.0.1 -// Copyright 2014, 2015, 2016, 2017 Simon Lydell -// License: MIT. (See LICENSE.) -const jsTokens = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g; - -const matchToToken = function(match) { - var token = {type: "invalid", value: match[0]} - if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4]) - else if (match[ 5]) token.type = "comment" - else if (match[ 6]) token.type = "comment", token.closed = !!match[7] - else if (match[ 8]) token.type = "regex" - else if (match[ 9]) token.type = "number" - else if (match[10]) token.type = "name" - else if (match[11]) token.type = "punctuator" - else if (match[12]) token.type = "whitespace" - return token -}; +const jsTokens = require('js-tokens').default; +const matchToToken = require('js-tokens').matchToToken; /** From 6a132169c80a5eb194f11dd12eb3d6c7a11ec332 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Sat, 6 May 2017 19:47:11 +0800 Subject: [PATCH 08/12] rebuild include() --- lib/compile/adapter/include.js | 20 ------------------- lib/compile/index.js | 1 + lib/precompile.js | 32 ++++--------------------------- lib/template-web.js | 4 ++-- src/compile/adapter/include.js | 19 ------------------ src/compile/compiler.js | 25 ++++++++++++------------ src/compile/defaults.js | 5 ----- src/compile/index.js | 1 + src/precompile.js | 34 ++++----------------------------- test/compile/adapter/include.js | 29 ---------------------------- test/compile/compiler.js | 11 ++++------- test/compile/index.js | 3 ++- 12 files changed, 30 insertions(+), 154 deletions(-) delete mode 100644 lib/compile/adapter/include.js delete mode 100644 src/compile/adapter/include.js delete mode 100644 test/compile/adapter/include.js diff --git a/lib/compile/adapter/include.js b/lib/compile/adapter/include.js deleted file mode 100644 index 8279a272..00000000 --- a/lib/compile/adapter/include.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -/** - * 载入子模板 - * @param {string} filename - * @param {Object} data - * @param {Object} blocks - * @param {Object} options - * @return {string} - */ -var include = function include(filename, data, blocks, options) { - var compile = require('../index'); - options = options.$extend({ - filename: options.resolveFilename(filename, options), - source: null - }); - return compile(options)(data, blocks); -}; - -module.exports = include; \ No newline at end of file diff --git a/lib/compile/index.js b/lib/compile/index.js index 84784301..2d315136 100644 --- a/lib/compile/index.js +++ b/lib/compile/index.js @@ -33,6 +33,7 @@ var compile = function compile(source) { // 合并默认配置 options = defaults.$extend(options); source = options.source; + options.$$compile = compile; // debug 模式 /* istanbul ignore if */ diff --git a/lib/precompile.js b/lib/precompile.js index 1e71a76c..0a894111 100644 --- a/lib/precompile.js +++ b/lib/precompile.js @@ -133,35 +133,11 @@ var precompile = function precompile() { }; break; - case CONSTS.LAYOUT: - - replaceNode = { - "type": "CallExpression", - "callee": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "require" - }, - "arguments": [extendNode] - }, - "arguments": [{ - "type": "Identifier", - "name": CONSTS.DATA - }, { - "type": "Identifier", - "name": CONSTS.BLOCKS - }] - }; - break; - case CONSTS.INCLUDE: - var filenameNode = convertFilenameNode(node.arguments[0], options); - var dataNode = node.arguments[1] || { - "type": "Identifier", - "name": CONSTS.DATA - }; + var filename = node.arguments[0].shift(); + var filenameNode = convertFilenameNode(filename, options); + var argsNode = node.arguments; replaceNode = { "type": "AssignmentExpression", @@ -180,7 +156,7 @@ var precompile = function precompile() { }, "arguments": [filenameNode] }, - "arguments": [dataNode] + "arguments": [argsNode] } }; break; diff --git a/lib/template-web.js b/lib/template-web.js index 5a357bbb..a1d22fba 100644 --- a/lib/template-web.js +++ b/lib/template-web.js @@ -1,3 +1,3 @@ /*! art-template@4.9.0 for browser | https://github.com/aui/art-template */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=21)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(16),i=n(2),o=n(19),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(8),s=n(12),a=n(7),c=n(11),u=n(10),p=n(14),l=n(15),f=n(9),h=n(13),m={source:null,filename:null,rules:[l,p],escape:!0,debug:!!r&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:h,htmlMinifier:f,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:s,loader:c,caches:a,root:"/",extname:".art",ignore:[],imports:i};m.$extend=function(e){return o(e||{},this)},i.$include=u,e.exports=m},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(22).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}",">>>","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(17),o=n(20),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$layout",g="$$options",y=function(e,t){return e.hasOwnProperty(t)},b=JSON.stringify,x=function(){function e(t){var n,i,y,b=this;r(this,e);var x=t.source,k=t.minimize,w=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[g]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[v]="function(){return "+a+".$include("+d+","+s+","+m+","+g+")}",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data,block){"+f+"+="+a+".$include(src,data||"+s+",block,"+g+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(y={},y[c]=[f],y[u]=[f,a,s,g],y[p]=[d,v],y[l]=[d,f,m],y[v]=[a,d,s,m,g],y),this.importContext(f),t.compileDebug&&this.importContext(h),k)try{x=w(x,t)}catch(E){}this.source=x,this.getTplTokens(x,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?b.parseString(e):b.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!y(f,e)&&!y(o,e)&&p.indexOf(e)<0&&(y(r,e)?(n=r[e],y(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=y(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+b(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,o=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t},s=function(e){return e.match(i).map(function(e){return i.lastIndex=0,o(i.exec(e))}).map(function(e){return"name"===e.type&&r(e.value)&&(e.type="keyword"),e})};e.exports=s},function(e,t,n){"use strict";(function(t){/*! art-template@runtime | https://github.com/aui/art-template */ -var r=n(0),i=Object.create(r?t:window),o=function p(e){return"string"!=typeof e&&(e=e===undefined||null===e?"":"function"==typeof e?p(e.call(e)):JSON.stringify(e)),e},s=/["&'<>]/,a=function(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.$$compile=c,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(9),s=n(12),a=n(8),c=n(11),u=n(14),p=n(15),l=n(10),f=n(13),h={source:null,filename:null,rules:[p,u],escape:!0,debug:!!r&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:f,htmlMinifier:l,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:s,loader:c,caches:a,root:"/",extname:".art",ignore:[],imports:i};h.$extend=function(e){return o(e||{},this)},e.exports=h},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=/((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,t.matchToToken=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t}},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(22).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}","->","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(17),o=n(20),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$options",g=function(e,t){return e.hasOwnProperty(t)},y=JSON.stringify,b=function(){function e(t){var n,i,g,y=this;r(this,e);var b=t.source,x=t.minimize,k=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[v]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data,blocks){"+f+"+="+v+".$$compile("+v+".$extend({filename:"+v+".resolveFilename(src,"+v+"),source:null}))(data||"+s+",blocks||"+m+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(g={},g[c]=[f],g[u]=[f,v,s,m],g[p]=[d,u],g[l]=[d,f,m],g),this.importContext(f),t.compileDebug&&this.importContext(h),x)try{b=k(b,t)}catch(w){}this.source=b,this.getTplTokens(b,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?y.parseString(e):y.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!g(f,e)&&!g(o,e)&&p.indexOf(e)<0&&(g(r,e)?(n=r[e],g(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=g(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+y(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n]/,a=function(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i { - const compile = require('../index'); - options = options.$extend({ - filename: options.resolveFilename(filename, options), - source: null - }); - return compile(options)(data, blocks); -}; - - -module.exports = include; \ No newline at end of file diff --git a/src/compile/compiler.js b/src/compile/compiler.js index f944e383..251108bb 100644 --- a/src/compile/compiler.js +++ b/src/compile/compiler.js @@ -35,9 +35,6 @@ const BLOCKS = `$$blocks`; /** 继承的布局模板的文件地址变量 */ const FROM = `$$from`; -/** 导出布局模板函数 */ -const LAYOUT = `$$layout`; - /** 编译设置变量 */ const OPTIONS = `$$options`; @@ -87,9 +84,8 @@ class Compiler { [LINE]: `[0,0,'']`, [BLOCKS]: `arguments[1]||{}`, [FROM]: `null`, - [LAYOUT]: `function(){return ${IMPORTS}.$include(${FROM},${DATA},${BLOCKS},${OPTIONS})}`, [PRINT]: `function(){${OUT}+=''.concat.apply('',arguments)}`, - [INCLUDE]: `function(src,data,block){${OUT}+=${IMPORTS}.$include(src,data||${DATA},block,${OPTIONS})}`, + [INCLUDE]: `function(src,data,blocks){${OUT}+=${OPTIONS}.$$compile(${OPTIONS}.$extend({filename:${OPTIONS}.resolveFilename(src,${OPTIONS}),source:null}))(data||${DATA},blocks||${BLOCKS})}`, [EXTEND]: `function(from){${FROM}=from}`, [BLOCK]: `function(name,callback){if(${FROM}){${OUT}='';callback();${BLOCKS}[name]=${OUT}}else{if(typeof ${BLOCKS}[name]==='string'){${OUT}+=${BLOCKS}[name]}else{callback()}}}` }; @@ -97,10 +93,9 @@ class Compiler { // 内置函数依赖关系声明 this.dependencies = { [PRINT]: [OUT], - [INCLUDE]: [OUT, IMPORTS, DATA, OPTIONS], - [EXTEND]: [FROM, /*[*/ LAYOUT /*]*/ ], - [BLOCK]: [FROM, OUT, BLOCKS], - [LAYOUT]: [IMPORTS, FROM, DATA, BLOCKS, OPTIONS] + [INCLUDE]: [OUT, OPTIONS, DATA, BLOCKS], + [EXTEND]: [FROM, /*[*/ INCLUDE /*]*/ ], + [BLOCK]: [FROM, OUT, BLOCKS] }; @@ -198,8 +193,8 @@ class Compiler { if (has(dependencies, name)) { dependencies[name].forEach(name => this.importContext(name)); } - - // imports 继承了 Global,但是继承的属性不分配到顶级变量中,避免占用了模板内部的变量名称 + + // imports 继承了 Global,但是继承的属性不分配到顶级变量中,避免占用了模板内部的变量名称 } else if (has(imports, name)) { value = `${IMPORTS}.${name}`; } else { @@ -416,7 +411,12 @@ class Compiler { } - stacks.push(extendMode ? `return ${LAYOUT}()` : `return ${OUT}`); + if (extendMode) { + stacks.push(`${OUT}=''`); + stacks.push(`${INCLUDE}(${FROM},${DATA},${BLOCKS})`); + } + + stacks.push(`return ${OUT}`); stacks.push(`}`); @@ -476,7 +476,6 @@ Compiler.CONSTS = { LINE, BLOCKS, FROM, - LAYOUT, ESCAPE }; diff --git a/src/compile/defaults.js b/src/compile/defaults.js index dc2c2c3c..c7c2a7b1 100644 --- a/src/compile/defaults.js +++ b/src/compile/defaults.js @@ -4,7 +4,6 @@ const extend = require('./adapter/extend'); const onerror = require('./adapter/onerror'); const caches = require('./adapter/caches'); const loader = require('./adapter/loader'); -const include = require('./adapter/include'); const artRule = require('./adapter/rule.art'); const nativeRule = require('./adapter/rule.native'); const htmlMinifier = require('./adapter/html-minifier'); @@ -91,8 +90,4 @@ defaults.$extend = function (options) { }; -// 载入子模板的方法 -runtime.$include = include; - - module.exports = defaults; \ No newline at end of file diff --git a/src/compile/index.js b/src/compile/index.js index 67f32189..b057ecd2 100644 --- a/src/compile/index.js +++ b/src/compile/index.js @@ -29,6 +29,7 @@ const compile = (source, options = {}) => { // 合并默认配置 options = defaults.$extend(options); source = options.source; + options.$$compile = compile; // debug 模式 diff --git a/src/precompile.js b/src/precompile.js index d5f81b0c..07a119e1 100644 --- a/src/precompile.js +++ b/src/precompile.js @@ -146,37 +146,11 @@ const precompile = (options = {}) => { }; break; - case CONSTS.LAYOUT: - - replaceNode = { - "type": "CallExpression", - "callee": { - "type": "CallExpression", - "callee": { - "type": "Identifier", - "name": "require" - }, - "arguments": [extendNode] - }, - "arguments": [{ - "type": "Identifier", - "name": CONSTS.DATA - }, - { - "type": "Identifier", - "name": CONSTS.BLOCKS - } - ] - }; - break; - case CONSTS.INCLUDE: - const filenameNode = convertFilenameNode(node.arguments[0], options); - const dataNode = node.arguments[1] || { - "type": "Identifier", - "name": CONSTS.DATA - }; + const filename = node.arguments[0].shift(); + const filenameNode = convertFilenameNode(filename, options); + const argsNode = node.arguments; replaceNode = { "type": "AssignmentExpression", @@ -195,7 +169,7 @@ const precompile = (options = {}) => { }, "arguments": [filenameNode] }, - "arguments": [dataNode] + "arguments": [argsNode] } }; break; diff --git a/test/compile/adapter/include.js b/test/compile/adapter/include.js deleted file mode 100644 index c618ed49..00000000 --- a/test/compile/adapter/include.js +++ /dev/null @@ -1,29 +0,0 @@ -const assert = require('assert'); -const include = require('../../../lib/compile/adapter/include'); -const defaults = require('../../../lib/compile/defaults'); -const path = require('path'); - - -module.exports = { - before: () => { - console.log('#compile/adapter/escape'); - }, - 'include': { - 'read file': () => { - const root = path.resolve(__dirname, '..', '..', 'res');; - const base = path.resolve(root, 'index.html'); - const data = {}; - - assert.deepEqual('hello world', include('./file.html', data, null, defaults.$extend({ - filename: base, - root: '/' - }))); - - assert.deepEqual('hello world', include('./file.html', data, null, defaults.$extend({ - filename: base, - root - }))); - - } - } -}; \ No newline at end of file diff --git a/test/compile/compiler.js b/test/compile/compiler.js index c8f1d839..255d2440 100644 --- a/test/compile/compiler.js +++ b/test/compile/compiler.js @@ -72,17 +72,14 @@ module.exports = { print: "function(){$$out+=''.concat.apply('',arguments)}" }); - test('include', { - $$out: `''`, - include: "function(src,data,block){$$out+=$imports.$include(src,data||$data,block,$$options)}" - }) + // test('include', { + // $$out: `''`, + // include: "function(src,data,block){$$out+=$imports.$include(src,data||$data,block,$$options)}" + // }); test('$escape', { $escape: '$imports.$escape' }); - test('$include', { - $include: '$imports.$include' - }); }, diff --git a/test/compile/index.js b/test/compile/index.js index 4df389a2..8d4a8a8f 100644 --- a/test/compile/index.js +++ b/test/compile/index.js @@ -255,7 +255,8 @@ module.exports = { }); render = compile(`{{include 'header.html'}}\ncontent: {{content}}`, { - minimize: false + minimize: false, + bail: true }); data = { title: 'hello', From cdbcf65e46954945f510afc17865727d863e70f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Sun, 7 May 2017 03:03:48 +0800 Subject: [PATCH 09/12] fix bug --- src/precompile.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/precompile.js b/src/precompile.js index 07a119e1..b11b304c 100644 --- a/src/precompile.js +++ b/src/precompile.js @@ -148,9 +148,12 @@ const precompile = (options = {}) => { case CONSTS.INCLUDE: - const filename = node.arguments[0].shift(); + const filename = node.arguments.shift(); const filenameNode = convertFilenameNode(filename, options); - const argsNode = node.arguments; + const paramNodes = node.arguments.length ? node.arguments : [{ + "type": "Identifier", + "name": CONSTS.DATA + }]; replaceNode = { "type": "AssignmentExpression", @@ -169,7 +172,7 @@ const precompile = (options = {}) => { }, "arguments": [filenameNode] }, - "arguments": [argsNode] + "arguments": paramNodes } }; break; From 863a01f3917d60536208c57f3b6e40c1829b32b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Sun, 7 May 2017 12:38:42 +0800 Subject: [PATCH 10/12] rebuild --- CHANGELOG.md | 3 +- README.md | 69 ++++++++--------- _config.yml | 1 - example/web-test-speed/index.html | 2 +- lib/compile/adapter/include.js | 20 +++++ lib/compile/adapter/rule.art.js | 2 +- lib/compile/compiler.js | 15 ++-- lib/compile/defaults.js | 25 +++--- lib/compile/{template-error.js => error.js} | 0 lib/compile/es-tokenizer.js | 15 +--- lib/compile/index.js | 3 +- lib/precompile.js | 17 ++-- lib/template-web.js | 4 +- package.json | 7 +- src/compile/adapter/include.js | 19 +++++ src/compile/compiler.js | 2 +- src/compile/defaults.js | 22 +++--- src/compile/{template-error.js => error.js} | 0 src/compile/index.js | 4 +- src/precompile.js | 8 +- test/compile/compiler.js | 9 --- test/compile/index.js | 86 +++++++++++++++------ test/res/extend-options/file.art | 1 + test/res/extend-options/file2.art | 1 + test/res/extend-options/include.art | 1 + 25 files changed, 202 insertions(+), 134 deletions(-) delete mode 100644 _config.yml create mode 100644 lib/compile/adapter/include.js rename lib/compile/{template-error.js => error.js} (100%) create mode 100644 src/compile/adapter/include.js rename src/compile/{template-error.js => error.js} (100%) create mode 100644 test/res/extend-options/file.art create mode 100644 test/res/extend-options/file2.art create mode 100644 test/res/extend-options/include.art diff --git a/CHANGELOG.md b/CHANGELOG.md index 72e5b28a..9180f9ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ ## v4.9.0 -1. 渲染函数参数可以为空 +1. 修复子模板没有继承父模板编译 options 问题 +2. 渲染函数参数可以为空 ## v4.8.1 diff --git a/README.md b/README.md index 5d8f82b9..0566b93a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ art-template 是一个渲染性能出众模板引擎,无论在 NodeJS 还是在浏览器中都可以运行。 -[![chart](https://cloud.githubusercontent.com/assets/1791748/25561182/52b7c176-2d98-11e7-8270-da1aca0a80e4.png)](https://aui.github.io/art-template/example/web-test-speed/) +[![chart](https://cloud.githubusercontent.com/assets/1791748/25769656/13d09cb2-3252-11e7-9b31-b91110908bce.png)](https://aui.github.io/art-template/example/web-test-speed/) [在线速度测试](https://aui.github.io/art-template/example/web-test-speed/) @@ -17,11 +17,11 @@ art-template 是一个渲染性能出众模板引擎,无论在 NodeJS 还是 * 拥有接近 JavaScript 渲染极限的的性能 * 调试友好:语法、运行时错误日志精确到模板所在行;支持支持在模板文件上打断点(Webpack Loader) * 支持压缩输出页面中的 HTML、CSS、JS 代码 -* 支持 NodeJS 与 浏览器。支持 Express、Koa、Webpack +* 支持 Express、Koa、Webpack * 支持模板继承与子模板 * 兼容 [EJS](http://ejs.co)、[Underscore](http://underscorejs.org/#template)、[LoDash](https://lodash.com/docs/#template) 模板语法 -* 支持 ES 严格模式环境运行 -* 支持原生 JavaScript 语法与简约语法混合书写 +* 模板编译后的代码支持在严格模式下运行 +* 支持 JavaScript 语句与模板语法混合书写 * 支持自定义模板的语法解析规则 * 浏览器版本仅 6KB 大小 @@ -32,15 +32,15 @@ art-template 是一个渲染性能出众模板引擎,无论在 NodeJS 还是 ### 模板语法 ```html -<% if (user) { %> -

<%= user.name %>

-<% } %> - -或: - {{if user}}

{{user.name}}

{{/if}} + +或: + +<% if (user) { %> +

<%= user.name %>

+<% } %> ``` ### NodeJS @@ -54,22 +54,17 @@ var html = template(__dirname + '/tpl-user.art', { }); ``` -### Web - -1\. 使用浏览器版本:[lib/template-web.js](https://raw.githubusercontent.com/aui/art-template/master/lib/template-web.js) - -2\. 在页面中存放模板: +### 浏览器 ```html + ``` -3\. 渲染模板: - ```js var html = template('tpl-user', { user: { @@ -103,8 +98,6 @@ npm install art-template --save 下载:[lib/template-web.js](https://raw.githubusercontent.com/aui/art-template/master/lib/template-web.js) -浏览器版本没有文件加载、HTML 压缩的特性。 - ### Express 主页:[express-art-template](https://github.com/aui/express-art-template) @@ -276,7 +269,7 @@ index.art: ### 过滤器 ```js -// 向模板中导入全局变量 +// 向模板中导入变量 template.defaults.imports.dateFormat = function(date, format){/*[code..]*/}; template.defaults.imports.timestamp = function(value){return value * 1000}; ``` @@ -297,7 +290,7 @@ template.defaults.imports.timestamp = function(value){return value * 1000}; template.defaults.minimize = true; ``` -art-template 的页面压缩功能是在编译阶段实现的,因此完全不影响渲染速度,并且能够加快网络传输速度。但也有一个限制,它会尝试“优化”未闭合的 HTML 标签,因此使用 `include` 语句载入模板片段请避免书写这样没有正确闭合的模板: +art-template 的页面压缩功能是在编译阶段实现的,因此完全不影响渲染速度,并且能够加快网络传输速度。但也有一个限制,它会尝试“优化”未闭合的 HTML 标签,因此请避免书写这样没有正确闭合的模板: ```html @@ -308,11 +301,11 @@ art-template 的页面压缩功能是在编译阶段实现的,因此完全不 ``` -使用 [模板继承](#模板继承) 代替 `include` 可以避免这样的问题出现。 +使用子模板载入网页头与底公共部分的时候很容易出现此问题,解决方案是使用 [模板继承](#模板继承) 代替子模板。 ## 调试 -设置 `template.defaults.debug=true` 后,它会设置如下选项: +设置 `template.defaults.debug=true` 后,它会设置如下 [选项](#选项): ```json { @@ -330,32 +323,32 @@ art-template 的页面压缩功能是在编译阶段实现的,因此完全不 ## 全局变量 -### 内置变量清单 +模板通过 `$imports` 可以访问到模板外部的全局变量。 -* `$data` 传入模板的数据 `{Object|array}` -* `$imports` 外部导入的所有变量,等同 `template.defaults.imports` `{Object}` -* `print` 字符串输出函数 `{function}` -* `include` 子模板载入函数 `{function}` -* `extend` 模板继承模板导入函数 `{function}` -* `block` 模板块声明函数 `{function}` +### 内置变量清单 -### 注入外部变量 +* `$data` 传入模板的数据 +* `$imports` 外部导入的变量以及全局变量 +* `print` 字符串输出函数 +* `include` 子模板载入函数 +* `extend` 模板继承模板导入函数 +* `block` 模板块声明函数 -模板外部所有的变量都需要添加到 `template.defaults.imports` 后,模板才能使用。 +### 导入变量 ```js -template.defaults.imports.console = console; +template.defaults.imports.log = console.log; ``` ```html -<% $imports.console.log('hello world') %> +<% $imports.log('hello world') %> ``` ## 配置语法规则 ### 修改界定符 -art-template 支持修改默认模板界定符 `{{}}` 与 `<%%>`: +art-template 支持修改默认模板界定符 `{{` `}}` 与 `<%` `%>`: ```js // 原生语法的界定符规则 diff --git a/_config.yml b/_config.yml deleted file mode 100644 index c4192631..00000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-cayman \ No newline at end of file diff --git a/example/web-test-speed/index.html b/example/web-test-speed/index.html index 180632ca..ffebfa45 100755 --- a/example/web-test-speed/index.html +++ b/example/web-test-speed/index.html @@ -203,7 +203,7 @@ duration: 150 }, renderTo: 'container', - height: categories.length * 40, + height: categories.length * 32, type: 'bar' }, diff --git a/lib/compile/adapter/include.js b/lib/compile/adapter/include.js new file mode 100644 index 00000000..8279a272 --- /dev/null +++ b/lib/compile/adapter/include.js @@ -0,0 +1,20 @@ +'use strict'; + +/** + * 载入子模板 + * @param {string} filename + * @param {Object} data + * @param {Object} blocks + * @param {Object} options + * @return {string} + */ +var include = function include(filename, data, blocks, options) { + var compile = require('../index'); + options = options.$extend({ + filename: options.resolveFilename(filename, options), + source: null + }); + return compile(options)(data, blocks); +}; + +module.exports = include; \ No newline at end of file diff --git a/lib/compile/adapter/rule.art.js b/lib/compile/adapter/rule.art.js index 2a71aec5..3e0deb25 100644 --- a/lib/compile/adapter/rule.art.js +++ b/lib/compile/adapter/rule.art.js @@ -21,7 +21,7 @@ var artRule = { // 旧版语法升级提示 var warn = function warn(oldSyntax, newSyntax) { - console.warn('Template upgrade:', '{{' + oldSyntax + '}}', '>>>', '{{' + newSyntax + '}}', '\n', options.filename || ''); + console.warn('Template upgrade:', '{{' + oldSyntax + '}}', '->', '{{' + newSyntax + '}}', '\n', options.filename || ''); }; // v3 compat: #value diff --git a/lib/compile/compiler.js b/lib/compile/compiler.js index 671e300d..5fbcf369 100644 --- a/lib/compile/compiler.js +++ b/lib/compile/compiler.js @@ -38,9 +38,6 @@ var BLOCKS = '$$blocks'; /** 继承的布局模板的文件地址变量 */ var FROM = '$$from'; -/** 导出布局模板函数 */ -var LAYOUT = '$$layout'; - /** 编译设置变量 */ var OPTIONS = '$$options'; @@ -86,10 +83,10 @@ var Compiler = function () { this.external = (_external = {}, _external[DATA] = true, _external[IMPORTS] = true, _external[OPTIONS] = true, _external); // 按需编译到模板渲染函数的内置变量 - this.internal = (_internal = {}, _internal[OUT] = '\'\'', _internal[LINE] = '[0,0,\'\']', _internal[BLOCKS] = 'arguments[1]||{}', _internal[FROM] = 'null', _internal[LAYOUT] = 'function(){return ' + IMPORTS + '.$include(' + FROM + ',' + DATA + ',' + BLOCKS + ',' + OPTIONS + ')}', _internal[PRINT] = 'function(){' + OUT + '+=\'\'.concat.apply(\'\',arguments)}', _internal[INCLUDE] = 'function(src,data,block){' + OUT + '+=' + IMPORTS + '.$include(src,data||' + DATA + ',block,' + OPTIONS + ')}', _internal[EXTEND] = 'function(from){' + FROM + '=from}', _internal[BLOCK] = 'function(name,callback){if(' + FROM + '){' + OUT + '=\'\';callback();' + BLOCKS + '[name]=' + OUT + '}else{if(typeof ' + BLOCKS + '[name]===\'string\'){' + OUT + '+=' + BLOCKS + '[name]}else{callback()}}}', _internal); + this.internal = (_internal = {}, _internal[OUT] = '\'\'', _internal[LINE] = '[0,0,\'\']', _internal[BLOCKS] = 'arguments[1]||{}', _internal[FROM] = 'null', _internal[PRINT] = 'function(){' + OUT + '+=\'\'.concat.apply(\'\',arguments)}', _internal[INCLUDE] = 'function(src,data){' + OUT + '+=' + OPTIONS + '.include(src,data||' + DATA + ',arguments[2]||' + BLOCKS + ',' + OPTIONS + ')}', _internal[EXTEND] = 'function(from){' + FROM + '=from}', _internal[BLOCK] = 'function(name,callback){if(' + FROM + '){' + OUT + '=\'\';callback();' + BLOCKS + '[name]=' + OUT + '}else{if(typeof ' + BLOCKS + '[name]===\'string\'){' + OUT + '+=' + BLOCKS + '[name]}else{callback()}}}', _internal); // 内置函数依赖关系声明 - this.dependencies = (_dependencies = {}, _dependencies[PRINT] = [OUT], _dependencies[INCLUDE] = [OUT, IMPORTS, DATA, OPTIONS], _dependencies[EXTEND] = [FROM, /*[*/LAYOUT /*]*/], _dependencies[BLOCK] = [FROM, OUT, BLOCKS], _dependencies[LAYOUT] = [IMPORTS, FROM, DATA, BLOCKS, OPTIONS], _dependencies); + this.dependencies = (_dependencies = {}, _dependencies[PRINT] = [OUT], _dependencies[INCLUDE] = [OUT, OPTIONS, DATA, BLOCKS], _dependencies[EXTEND] = [FROM, /*[*/INCLUDE /*]*/], _dependencies[BLOCK] = [FROM, OUT, BLOCKS], _dependencies); this.importContext(OUT); @@ -387,7 +384,12 @@ var Compiler = function () { }); } - stacks.push(extendMode ? 'return ' + LAYOUT + '()' : 'return ' + OUT); + if (extendMode) { + stacks.push(OUT + '=\'\''); + stacks.push(INCLUDE + '(' + FROM + ',' + DATA + ',' + BLOCKS + ')'); + } + + stacks.push('return ' + OUT); stacks.push('}'); var renderCode = stacks.join('\n'); @@ -448,7 +450,6 @@ Compiler.CONSTS = { LINE: LINE, BLOCKS: BLOCKS, FROM: FROM, - LAYOUT: LAYOUT, ESCAPE: ESCAPE }; diff --git a/lib/compile/defaults.js b/lib/compile/defaults.js index 1025eebe..5325fc7d 100644 --- a/lib/compile/defaults.js +++ b/lib/compile/defaults.js @@ -3,17 +3,17 @@ var detectNode = require('detect-node'); var runtime = require('./runtime'); var extend = require('./adapter/extend'); +var include = require('./adapter/include'); var onerror = require('./adapter/onerror'); var caches = require('./adapter/caches'); var loader = require('./adapter/loader'); -var include = require('./adapter/include'); var artRule = require('./adapter/rule.art'); var nativeRule = require('./adapter/rule.native'); var htmlMinifier = require('./adapter/html-minifier'); var resolveFilename = require('./adapter/resolve-filename'); /** 模板编译器默认配置 */ -var defaults = { +var settings = { // 模板内容。如果没有此字段,则会根据 filename 来加载模板内容 source: null, @@ -47,6 +47,9 @@ var defaults = { // 模板路径转换器 resolveFilename: resolveFilename, + // 子模板编译适配器 + include: include, + // HTML 压缩器。仅在 NodeJS 环境下有效 htmlMinifier: htmlMinifier, @@ -82,16 +85,12 @@ var defaults = { }; -/** - * 继承默认配置 - * @param {Object} options - * @return {Object} - */ -defaults.$extend = function (options) { - return extend(options || {}, this); +function Defaults() { + this.$extend = function (options) { + options = options || {}; + return extend(options, options instanceof Defaults ? options : this); + }; }; +Defaults.prototype = settings; -// 载入子模板的方法 -runtime.$include = include; - -module.exports = defaults; \ No newline at end of file +module.exports = new Defaults(); \ No newline at end of file diff --git a/lib/compile/template-error.js b/lib/compile/error.js similarity index 100% rename from lib/compile/template-error.js rename to lib/compile/error.js diff --git a/lib/compile/es-tokenizer.js b/lib/compile/es-tokenizer.js index 258b2bfe..372ecf7f 100644 --- a/lib/compile/es-tokenizer.js +++ b/lib/compile/es-tokenizer.js @@ -1,17 +1,8 @@ -"use strict"; +'use strict'; var isKeyword = require('is-keyword-js'); - -// js-tokens@3.0.1 -// Copyright 2014, 2015, 2016, 2017 Simon Lydell -// License: MIT. (See LICENSE.) -var jsTokens = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g; - -var matchToToken = function matchToToken(match) { - var token = { type: "invalid", value: match[0] }; - if (match[1]) token.type = "string", token.closed = !!(match[3] || match[4]);else if (match[5]) token.type = "comment";else if (match[6]) token.type = "comment", token.closed = !!match[7];else if (match[8]) token.type = "regex";else if (match[9]) token.type = "number";else if (match[10]) token.type = "name";else if (match[11]) token.type = "punctuator";else if (match[12]) token.type = "whitespace"; - return token; -}; +var jsTokens = require('js-tokens').default; +var matchToToken = require('js-tokens').matchToToken; /** * 将逻辑表达式解释为 Tokens diff --git a/lib/compile/index.js b/lib/compile/index.js index 2d315136..ecf81ad6 100644 --- a/lib/compile/index.js +++ b/lib/compile/index.js @@ -2,7 +2,7 @@ var Compiler = require('./compiler'); var defaults = require('./defaults'); -var TemplateError = require('./template-error'); +var TemplateError = require('./error'); var debugRender = function debugRender(error, options) { options.onerror(error, options); @@ -33,7 +33,6 @@ var compile = function compile(source) { // 合并默认配置 options = defaults.$extend(options); source = options.source; - options.$$compile = compile; // debug 模式 /* istanbul ignore if */ diff --git a/lib/precompile.js b/lib/precompile.js index 0a894111..0b98e532 100644 --- a/lib/precompile.js +++ b/lib/precompile.js @@ -129,15 +129,22 @@ var precompile = function precompile() { "type": "Identifier", "name": CONSTS.FROM }, - "right": extendNode + "right": { + "type": "Literal", + "value": true + } }; + break; case CONSTS.INCLUDE: - var filename = node.arguments[0].shift(); - var filenameNode = convertFilenameNode(filename, options); - var argsNode = node.arguments; + var filename = node.arguments.shift(); + var filenameNode = filename.name === CONSTS.FROM ? extendNode : convertFilenameNode(filename, options); + var paramNodes = node.arguments.length ? node.arguments : [{ + "type": "Identifier", + "name": CONSTS.DATA + }]; replaceNode = { "type": "AssignmentExpression", @@ -156,7 +163,7 @@ var precompile = function precompile() { }, "arguments": [filenameNode] }, - "arguments": [argsNode] + "arguments": paramNodes } }; break; diff --git a/lib/template-web.js b/lib/template-web.js index a1d22fba..f3a5b357 100644 --- a/lib/template-web.js +++ b/lib/template-web.js @@ -1,3 +1,3 @@ /*! art-template@4.9.0 for browser | https://github.com/aui/art-template */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=21)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(16),i=n(2),o=n(19),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.$$compile=c,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";var r=n(0),i=n(18),o=n(9),s=n(12),a=n(8),c=n(11),u=n(14),p=n(15),l=n(10),f=n(13),h={source:null,filename:null,rules:[p,u],escape:!0,debug:!!r&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:f,htmlMinifier:l,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:s,loader:c,caches:a,root:"/",extname:".art",ignore:[],imports:i};h.$extend=function(e){return o(e||{},this)},e.exports=h},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=/((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,t.matchToToken=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t}},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(22).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}","->","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(17),o=n(20),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$options",g=function(e,t){return e.hasOwnProperty(t)},y=JSON.stringify,b=function(){function e(t){var n,i,g,y=this;r(this,e);var b=t.source,x=t.minimize,k=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[v]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data,blocks){"+f+"+="+v+".$$compile("+v+".$extend({filename:"+v+".resolveFilename(src,"+v+"),source:null}))(data||"+s+",blocks||"+m+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(g={},g[c]=[f],g[u]=[f,v,s,m],g[p]=[d,u],g[l]=[d,f,m],g),this.importContext(f),t.compileDebug&&this.importContext(h),x)try{b=k(b,t)}catch(w){}this.source=b,this.getTplTokens(b,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?y.parseString(e):y.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!g(f,e)&&!g(o,e)&&p.indexOf(e)<0&&(g(r,e)?(n=r[e],g(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=g(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+y(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n]/,a=function(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";function r(){this.$extend=function(e){return e=e||{},s(e,e instanceof r?e:this)}}var i=n(0),o=n(20),s=n(9),a=n(11),c=n(13),u=n(8),p=n(12),l=n(15),f=n(16),h=n(10),m=n(14),d={source:null,filename:null,rules:[f,l],escape:!0,debug:!!i&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:m,include:a,htmlMinifier:h,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:c,loader:p,caches:u,root:"/",extname:".art",ignore:[],imports:o};r.prototype=d,e.exports=new r},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=/((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,t.matchToToken=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t}},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(23).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}","->","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(19),o=n(21),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$options",g=function(e,t){return e.hasOwnProperty(t)},y=JSON.stringify,b=function(){function e(t){var n,i,g,y=this;r(this,e);var b=t.source,x=t.minimize,k=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[v]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data){"+f+"+="+v+".include(src,data||"+s+",arguments[2]||"+m+","+v+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(g={},g[c]=[f],g[u]=[f,v,s,m],g[p]=[d,u],g[l]=[d,f,m],g),this.importContext(f),t.compileDebug&&this.importContext(h),x)try{b=k(b,t)}catch(w){}this.source=b,this.getTplTokens(b,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?y.parseString(e):y.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!g(f,e)&&!g(o,e)&&p.indexOf(e)<0&&(g(r,e)?(n=r[e],g(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=g(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+y(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n]/,a=function(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i { + const compile = require('../index'); + options = options.$extend({ + filename: options.resolveFilename(filename, options), + source: null + }); + return compile(options)(data, blocks); +}; + + +module.exports = include; \ No newline at end of file diff --git a/src/compile/compiler.js b/src/compile/compiler.js index 251108bb..e170d3fa 100644 --- a/src/compile/compiler.js +++ b/src/compile/compiler.js @@ -85,7 +85,7 @@ class Compiler { [BLOCKS]: `arguments[1]||{}`, [FROM]: `null`, [PRINT]: `function(){${OUT}+=''.concat.apply('',arguments)}`, - [INCLUDE]: `function(src,data,blocks){${OUT}+=${OPTIONS}.$$compile(${OPTIONS}.$extend({filename:${OPTIONS}.resolveFilename(src,${OPTIONS}),source:null}))(data||${DATA},blocks||${BLOCKS})}`, + [INCLUDE]: `function(src,data){${OUT}+=${OPTIONS}.include(src,data||${DATA},arguments[2]||${BLOCKS},${OPTIONS})}`, [EXTEND]: `function(from){${FROM}=from}`, [BLOCK]: `function(name,callback){if(${FROM}){${OUT}='';callback();${BLOCKS}[name]=${OUT}}else{if(typeof ${BLOCKS}[name]==='string'){${OUT}+=${BLOCKS}[name]}else{callback()}}}` }; diff --git a/src/compile/defaults.js b/src/compile/defaults.js index c7c2a7b1..17c4763c 100644 --- a/src/compile/defaults.js +++ b/src/compile/defaults.js @@ -1,6 +1,7 @@ const detectNode = require('detect-node'); const runtime = require('./runtime'); const extend = require('./adapter/extend'); +const include = require('./adapter/include'); const onerror = require('./adapter/onerror'); const caches = require('./adapter/caches'); const loader = require('./adapter/loader'); @@ -10,7 +11,7 @@ const htmlMinifier = require('./adapter/html-minifier'); const resolveFilename = require('./adapter/resolve-filename'); /** 模板编译器默认配置 */ -const defaults = { +const settings = { // 模板内容。如果没有此字段,则会根据 filename 来加载模板内容 source: null, @@ -44,6 +45,9 @@ const defaults = { // 模板路径转换器 resolveFilename: resolveFilename, + // 子模板编译适配器 + include: include, + // HTML 压缩器。仅在 NodeJS 环境下有效 htmlMinifier: htmlMinifier, @@ -80,14 +84,12 @@ const defaults = { }; -/** - * 继承默认配置 - * @param {Object} options - * @return {Object} - */ -defaults.$extend = function (options) { - return extend(options || {}, this); +function Defaults() { + this.$extend = function (options) { + options = options || {}; + return extend(options, options instanceof Defaults ? options : this); + } }; +Defaults.prototype = settings; - -module.exports = defaults; \ No newline at end of file +module.exports = new Defaults(); \ No newline at end of file diff --git a/src/compile/template-error.js b/src/compile/error.js similarity index 100% rename from src/compile/template-error.js rename to src/compile/error.js diff --git a/src/compile/index.js b/src/compile/index.js index b057ecd2..431077bd 100644 --- a/src/compile/index.js +++ b/src/compile/index.js @@ -1,6 +1,6 @@ const Compiler = require('./compiler'); const defaults = require('./defaults'); -const TemplateError = require('./template-error'); +const TemplateError = require('./error'); const debugRender = (error, options) => { @@ -29,8 +29,6 @@ const compile = (source, options = {}) => { // 合并默认配置 options = defaults.$extend(options); source = options.source; - options.$$compile = compile; - // debug 模式 /* istanbul ignore if */ diff --git a/src/precompile.js b/src/precompile.js index b11b304c..9b6587c3 100644 --- a/src/precompile.js +++ b/src/precompile.js @@ -142,14 +142,18 @@ const precompile = (options = {}) => { "type": "Identifier", "name": CONSTS.FROM }, - "right": extendNode + "right": { + "type": "Literal", + "value": true + } }; + break; case CONSTS.INCLUDE: const filename = node.arguments.shift(); - const filenameNode = convertFilenameNode(filename, options); + const filenameNode = filename.name === CONSTS.FROM ? extendNode : convertFilenameNode(filename, options); const paramNodes = node.arguments.length ? node.arguments : [{ "type": "Identifier", "name": CONSTS.DATA diff --git a/test/compile/compiler.js b/test/compile/compiler.js index 255d2440..a6db354e 100644 --- a/test/compile/compiler.js +++ b/test/compile/compiler.js @@ -68,15 +68,6 @@ module.exports = { test('$data', {}); test('$imports', {}); - test('print', { - print: "function(){$$out+=''.concat.apply('',arguments)}" - }); - - // test('include', { - // $$out: `''`, - // include: "function(src,data,block){$$out+=$imports.$include(src,data||$data,block,$$options)}" - // }); - test('$escape', { $escape: '$imports.$escape' }); diff --git a/test/compile/index.js b/test/compile/index.js index 8d4a8a8f..4e040914 100644 --- a/test/compile/index.js +++ b/test/compile/index.js @@ -318,7 +318,8 @@ module.exports = { 'layout': () => { render = compile({ filename: path.resolve(__dirname, '..', '..', 'example', 'node-layout', 'index.art'), - minimize: true + minimize: true, + bail: true }); data = { title: 'My Page' @@ -528,7 +529,9 @@ module.exports = { render = compile('
\n\n\n
{{value}}', { minimize: true }); - assert.deepEqual('
\n\n\n
aui', render({value: 'aui'})); + assert.deepEqual('
\n\n\n
aui', render({ + value: 'aui' + })); // TODO // render = compile('
\n\n<%=value%>
', { @@ -544,7 +547,9 @@ module.exports = { render = compile('{{value}}', { minimize: true }); - assert.deepEqual('aui', render({value: 'aui'})); + assert.deepEqual('aui', render({ + value: 'aui' + })); } }, @@ -583,6 +588,37 @@ module.exports = { }); html = render({}); assert.deepEqual('hello world', html); + }, + + 'include: extend options': () => { + let render, html; + + render = compile({ + bail: true, + filename: path.resolve(__dirname, '..', 'res', 'extend-options', 'file'), + rules: [{ + test: /\${([\w\W]*?)}/, + use: function (match, code) { + return { + code: code, + output: false + } + } + }] + }); + html = render({ + value: 'hello world' + }); + assert.deepEqual('hello world', html); + + render = compile({ + bail: true, + filename: path.resolve(__dirname, '..', 'res', 'extend-options', 'file2') + }); + html = render({ + value: 'hello world' + }); + assert.deepEqual('${value}hello world', html); } }, @@ -636,28 +672,28 @@ module.exports = { assert.deepEqual(undefined, render); }, -// 'error line': () => { -// const tpl = ` -// {{if user}} -//

{{user.name}}

-//
    -// {{each user.tags}} -//
  • {{$value}} {{a b c d}}
  • -// {{/each}} -//
-// {{/if}}`; -// let render; -// try { -// render = compile(tpl, { -// bail: true, -// minimize: false -// }); -// render({}); -// } catch (e) { -// assert.deepEqual(6, e.line); -// } -// assert.deepEqual(undefined, render); -// }, + // 'error line': () => { + // const tpl = ` + // {{if user}} + //

{{user.name}}

+ //
    + // {{each user.tags}} + //
  • {{$value}} {{a b c d}}
  • + // {{/each}} + //
+ // {{/if}}`; + // let render; + // try { + // render = compile(tpl, { + // bail: true, + // minimize: false + // }); + // render({}); + // } catch (e) { + // assert.deepEqual(6, e.line); + // } + // assert.deepEqual(undefined, render); + // }, 'template not found': () => { const render = compile({ diff --git a/test/res/extend-options/file.art b/test/res/extend-options/file.art new file mode 100644 index 00000000..bcc3e003 --- /dev/null +++ b/test/res/extend-options/file.art @@ -0,0 +1 @@ +${include('./include')} \ No newline at end of file diff --git a/test/res/extend-options/file2.art b/test/res/extend-options/file2.art new file mode 100644 index 00000000..b2f5a54a --- /dev/null +++ b/test/res/extend-options/file2.art @@ -0,0 +1 @@ +${value}{{value}} \ No newline at end of file diff --git a/test/res/extend-options/include.art b/test/res/extend-options/include.art new file mode 100644 index 00000000..7b799a88 --- /dev/null +++ b/test/res/extend-options/include.art @@ -0,0 +1 @@ +${print(value)} \ No newline at end of file From 9c249559772f2cd9e35e79863b58fd4e2bf64094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Sun, 7 May 2017 15:23:05 +0800 Subject: [PATCH 11/12] =?UTF-8?q?=E4=BC=98=E5=8C=96=20compileDebug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/compile/index.js | 4 ++++ lib/template-web.js | 2 +- package.json | 2 -- src/compile/index.js | 5 +++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/compile/index.js b/lib/compile/index.js index ecf81ad6..282c6b72 100644 --- a/lib/compile/index.js +++ b/lib/compile/index.js @@ -43,6 +43,10 @@ var compile = function compile(source) { options.compileDebug = true; } + if (options.compileDebug) { + options.minimize = false; + } + // 转换成绝对路径 if (options.filename) { options.filename = options.resolveFilename(options.filename, options); diff --git a/lib/template-web.js b/lib/template-web.js index f3a5b357..9b92796f 100644 --- a/lib/template-web.js +++ b/lib/template-web.js @@ -1,3 +1,3 @@ /*! art-template@4.9.0 for browser | https://github.com/aui/art-template */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=22)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(17),i=n(2),o=n(18),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";function r(){this.$extend=function(e){return e=e||{},s(e,e instanceof r?e:this)}}var i=n(0),o=n(20),s=n(9),a=n(11),c=n(13),u=n(8),p=n(12),l=n(15),f=n(16),h=n(10),m=n(14),d={source:null,filename:null,rules:[f,l],escape:!0,debug:!!i&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:m,include:a,htmlMinifier:h,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:c,loader:p,caches:u,root:"/",extname:".art",ignore:[],imports:o};r.prototype=d,e.exports=new r},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=/((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,t.matchToToken=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t}},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(23).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}","->","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(19),o=n(21),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$options",g=function(e,t){return e.hasOwnProperty(t)},y=JSON.stringify,b=function(){function e(t){var n,i,g,y=this;r(this,e);var b=t.source,x=t.minimize,k=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[v]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data){"+f+"+="+v+".include(src,data||"+s+",arguments[2]||"+m+","+v+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(g={},g[c]=[f],g[u]=[f,v,s,m],g[p]=[d,u],g[l]=[d,f,m],g),this.importContext(f),t.compileDebug&&this.importContext(h),x)try{b=k(b,t)}catch(w){}this.source=b,this.getTplTokens(b,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?y.parseString(e):y.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!g(f,e)&&!g(o,e)&&p.indexOf(e)<0&&(g(r,e)?(n=r[e],g(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=g(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+y(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.compileDebug&&(t.minimize=!1),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";function r(){this.$extend=function(e){return e=e||{},s(e,e instanceof r?e:this)}}var i=n(0),o=n(20),s=n(9),a=n(11),c=n(13),u=n(8),p=n(12),l=n(15),f=n(16),h=n(10),m=n(14),d={source:null,filename:null,rules:[f,l],escape:!0,debug:!!i&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:m,include:a,htmlMinifier:h,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:c,loader:p,caches:u,root:"/",extname:".art",ignore:[],imports:o};r.prototype=d,e.exports=new r},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=/((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,t.matchToToken=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t}},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(23).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}","->","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(19),o=n(21),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$options",g=function(e,t){return e.hasOwnProperty(t)},y=JSON.stringify,b=function(){function e(t){var n,i,g,y=this;r(this,e);var b=t.source,x=t.minimize,k=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[v]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data){"+f+"+="+v+".include(src,data||"+s+",arguments[2]||"+m+","+v+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(g={},g[c]=[f],g[u]=[f,v,s,m],g[p]=[d,u],g[l]=[d,f,m],g),this.importContext(f),t.compileDebug&&this.importContext(h),x)try{b=k(b,t)}catch(w){}this.source=b,this.getTplTokens(b,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?y.parseString(e):y.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!g(f,e)&&!g(o,e)&&p.indexOf(e)<0&&(g(r,e)?(n=r[e],g(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=g(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+y(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n]/,a=function(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i { } + if (options.compileDebug) { + options.minimize = false; + } + + // 转换成绝对路径 if (options.filename) { options.filename = options.resolveFilename(options.filename, options); From 91fa949afd27e0372b09d1adc595ec810d5bd7a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B3=96=E9=A5=BC?= Date: Sun, 7 May 2017 15:41:44 +0800 Subject: [PATCH 12/12] v4.8.2 --- CHANGELOG.md | 2 +- lib/template-web.js | 2 +- package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9180f9ed..f8f86939 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## v4.9.0 +## v4.8.2 1. 修复子模板没有继承父模板编译 options 问题 2. 渲染函数参数可以为空 diff --git a/lib/template-web.js b/lib/template-web.js index 9b92796f..026d076f 100644 --- a/lib/template-web.js +++ b/lib/template-web.js @@ -1,3 +1,3 @@ -/*! art-template@4.9.0 for browser | https://github.com/aui/art-template */ +/*! art-template@4.8.2 for browser | https://github.com/aui/art-template */ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.template=t():e.template=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e["default"]}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=22)}([function(e,t,n){(function(t){e.exports=!1;try{e.exports="[object process]"===Object.prototype.toString.call(t.process)}catch(n){}}).call(t,n(4))},function(e,t,n){"use strict";var r=n(17),i=n(2),o=n(18),s=function(e,t){t.onerror(e,t);var n=function(){return"{Template Error}"};return n.mappings=[],n.sourcesContent=[],n},a=function c(e){var t=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};"string"!=typeof e?t=e:t.source=e,t=i.$extend(t),e=t.source,t.debug&&(t.cache=!1,t.bail=!1,t.minimize=!1,t.compileDebug=!0),t.compileDebug&&(t.minimize=!1),t.filename&&(t.filename=t.resolveFilename(t.filename,t));var n=t.filename,a=t.cache,u=t.caches;if(a&&n){var p=u.get(n);if(p)return p}if(!e)try{e=t.loader(n,t),t.source=e}catch(d){var l=new o({name:"CompileError",message:"template not found: "+d.message,stack:d.stack});if(t.bail)throw l;return s(l,t)}var f=void 0,h=new r(t);try{f=h.build()}catch(l){if(l=new o(l),t.bail)throw l;return s(l,t)}var m=function(e,n){try{return f(e,n)}catch(l){if(!t.compileDebug)return t.cache=!1,t.compileDebug=!0,c(t)(e,n);if(l=new o(l),t.bail)throw l;return s(l,t)()}};return m.mappings=f.mappings,m.toString=function(){return f.toString()},a&&n&&u.set(n,m),m};a.Compiler=r,e.exports=a},function(e,t,n){"use strict";function r(){this.$extend=function(e){return e=e||{},s(e,e instanceof r?e:this)}}var i=n(0),o=n(20),s=n(9),a=n(11),c=n(13),u=n(8),p=n(12),l=n(15),f=n(16),h=n(10),m=n(14),d={source:null,filename:null,rules:[f,l],escape:!0,debug:!!i&&"production"!==process.env.NODE_ENV,bail:!1,cache:!0,minimize:!0,compileDebug:!1,resolveFilename:m,include:a,htmlMinifier:h,htmlMinifierOptions:{collapseWhitespace:!0,minifyCSS:!0,minifyJS:!0,ignoreCustomFragments:[]},onerror:c,loader:p,caches:u,root:"/",extname:".art",ignore:[],imports:o};r.prototype=d,e.exports=new r},function(e,t){},function(e,t){var n;n=function(){return this}();try{n=n||Function("return this")()||(0,eval)("this")}catch(r){"object"==typeof window&&(n=window)}e.exports=n},function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=/((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyu]{1,5}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g,t.matchToToken=function(e){var t={type:"invalid",value:e[0]};return e[1]?(t.type="string",t.closed=!(!e[3]&&!e[4])):e[5]?t.type="comment":e[6]?(t.type="comment",t.closed=!!e[7]):e[8]?t.type="regex":e[9]?t.type="number":e[10]?t.type="name":e[11]?t.type="punctuator":e[12]&&(t.type="whitespace"),t}},function(e,t,n){"use strict";e.exports=n(2)},function(e,t,n){"use strict";var r=n(1),i=function(e,t,n){return r(e,n)(t)};e.exports=i},function(e,t,n){"use strict";var r={__data:Object.create(null),set:function(e,t){this.__data[e]=t},get:function(e){return this.__data[e]},reset:function(){this.__data={}}};e.exports=r},function(e,t,n){"use strict";var r=Object.prototype.toString,i=function(e){return null===e?"Null":r.call(e).slice(8,-1)},o=function s(e,t){var n=void 0,r=i(e);if("Object"===r?n=Object.create(t||{}):"Array"===r&&(n=[].concat(t||[])),n){for(var o in e)e.hasOwnProperty(o)&&(n[o]=s(e[o],n[o]));return n}return e};e.exports=o},function(e,t,n){"use strict";var r=n(0),i=function(e,t){if(r){var i,o=n(23).minify,s=t.htmlMinifierOptions,a=t.rules.map(function(e){return e.test});(i=s.ignoreCustomFragments).push.apply(i,a),e=o(e,s)}return e};e.exports=i},function(e,t,n){"use strict";var r=function(e,t,r,i){var o=n(1);return i=i.$extend({filename:i.resolveFilename(e,i),source:null}),o(i)(t,r)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=function(e){if(r){return n(3).readFileSync(e,"utf8")}var t=document.getElementById(e);return t.value||t.innerHTML};e.exports=i},function(e,t,n){"use strict";var r=function(e){console.error(e.name,e.message)};e.exports=r},function(e,t,n){"use strict";var r=n(0),i=/^\.+\//,o=function(e,t){if(r){var o=n(3),s=t.root,a=t.extname;if(i.test(e)){var c=t.filename,u=!c||e===c,p=u?s:o.dirname(c);e=o.resolve(p,e)}else e=o.resolve(s,e);o.extname(e)||(e+=a)}return e};e.exports=o},function(e,t,n){"use strict";var r={test:/{{[ \t]*([@#]?)(\/?)([\w\W]*?)[ \t]*}}/,use:function(e,t,n,i){var o=this,s=o.options,a=o.getEsTokens(i.trim()),c=a.map(function(e){return e.value}),u={},p=void 0,l=!!t&&"raw",f=n+c.shift(),h=function(e,t){console.warn("Template upgrade:","{{"+e+"}}","->","{{"+t+"}}","\n",s.filename||"")};switch("#"===t&&h("#value","@value"),f){case"set":i="var "+c.join("");break;case"if":i="if("+c.join("")+"){";break;case"else":var m=c.indexOf("if");m>-1?(c.splice(0,m+1),i="}else if("+c.join("")+"){"):i="}else{";break;case"/if":i="}";break;case"each":p=r._split(a),p.shift(),"as"===p[1]&&(h("each object as value index","each object value index"),p.splice(1,1));var d=p[0]||"$data",v=p[1]||"$value",g=p[2]||"$index";i="$each("+d+",function("+v+","+g+"){";break;case"/each":i="})";break;case"echo":f="print",h("echo value","value");case"print":case"include":case"extend":p=r._split(a),p.shift(),i=f+"("+p.join(",")+")";break;case"block":i="block("+c.join("")+",function(){";break;case"/block":i="})";break;default:if(-1!==c.indexOf("|")){for(var y=f,b=[],x=c.filter(function(e){return!/^\s+$/.test(e)});"|"!==x[0];)y+=x.shift();x.filter(function(e){return":"!==e}).forEach(function(e){"|"===e?b.push([]):b[b.length-1].push(e)}),b.reduce(function(e,t){var n=t.shift();return t.unshift(e),i="$imports."+n+"("+t.join(",")+")"},y)}else s.imports[f]?(h("filterName value","value | filterName"),p=r._split(a),p.shift(),i=f+"("+p.join(",")+")",l="raw"):i=""+f+c.join("");l||(l="escape")}return u.code=i,u.output=l,u},_split:function(e){for(var t=0,n=e.shift(),r=[[n]];t/,use:function(e,t,n,r){return n={"-":"raw","=":"escape","":!1,"==":"raw","=#":"raw"}[n],t&&(r="/*"+e+"*/",n=!1),{code:r,output:n}}};e.exports=r},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i=n(19),o=n(21),s="$data",a="$imports",c="print",u="include",p="extend",l="block",f="$$out",h="$$line",m="$$blocks",d="$$from",v="$$options",g=function(e,t){return e.hasOwnProperty(t)},y=JSON.stringify,b=function(){function e(t){var n,i,g,y=this;r(this,e);var b=t.source,x=t.minimize,k=t.htmlMinifier;if(this.options=t,this.stacks=[],this.context=[],this.scripts=[],this.CONTEXT_MAP={},this.external=(n={},n[s]=!0,n[a]=!0,n[v]=!0,n),this.internal=(i={},i[f]="''",i[h]="[0,0,'']",i[m]="arguments[1]||{}",i[d]="null",i[c]="function(){"+f+"+=''.concat.apply('',arguments)}",i[u]="function(src,data){"+f+"+="+v+".include(src,data||"+s+",arguments[2]||"+m+","+v+")}",i[p]="function(from){"+d+"=from}",i[l]="function(name,callback){if("+d+"){"+f+"='';callback();"+m+"[name]="+f+"}else{if(typeof "+m+"[name]==='string'){"+f+"+="+m+"[name]}else{callback()}}}",i),this.dependencies=(g={},g[c]=[f],g[u]=[f,v,s,m],g[p]=[d,u],g[l]=[d,f,m],g),this.importContext(f),t.compileDebug&&this.importContext(h),x)try{b=k(b,t)}catch(w){}this.source=b,this.getTplTokens(b,t.rules,this).forEach(function(e){e.type===o.TYPE_STRING?y.parseString(e):y.parseExpression(e)})}return e.prototype.getTplTokens=function(){return o.apply(undefined,arguments)},e.prototype.getEsTokens=function(e){return i(e)},e.prototype.getVariables=function(e){var t=!1;return e.filter(function(e){return"whitespace"!==e.type&&"comment"!==e.type}).filter(function(e){return"name"===e.type&&!t||(t="punctuator"===e.type&&"."===e.value,!1)}).map(function(e){return e.value})},e.prototype.importContext=function(e){var t=this,n="",r=this.internal,i=this.dependencies,o=this.external,c=this.context,u=this.options,p=u.ignore,l=u.imports,f=this.CONTEXT_MAP;!g(f,e)&&!g(o,e)&&p.indexOf(e)<0&&(g(r,e)?(n=r[e],g(i,e)&&i[e].forEach(function(e){return t.importContext(e)})):n=g(l,e)?a+"."+e:s+"."+e,f[e]=n,c.push({name:e,value:n}))},e.prototype.parseString=function(e){var t=e.value;if(t){var n=f+"+="+y(t);this.scripts.push({source:t,tplToken:e,code:n})}},e.prototype.parseExpression=function(e){var t=this,n=e.value,r=e.script,i=r.output,s=r.code;i&&(s=!1===escape||i===o.TYPE_RAW?f+"+="+r.code:f+"+=$escape("+r.code+")");var a=this.getEsTokens(s);this.getVariables(a).forEach(function(e){return t.importContext(e)}),this.scripts.push({source:n,tplToken:e,code:s})},e.prototype.checkExpression=function(e){for(var t=[[/^\s*}[\w\W]*?{?[\s;]*$/,""],[/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/,"$1})"],[/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/,"$1}"]],n=0;n]/,a=function(e){var t=""+e,n=s.exec(t);if(!n)return e;var r="",i=void 0,o=void 0,a=void 0;for(i=n.index,o=0;i