Skip to content

Commit 65c4f74

Browse files
committed
Merge branch 'v4.10.0'
2 parents 0296c10 + 767b1ab commit 65c4f74

16 files changed

Lines changed: 199 additions & 189 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# CHANGELOG
22

3+
## v4.10.0
4+
5+
1. 修复标准语法的 BUG [#408](https://github.com/aui/art-template/issues/408),并且不再兼容 v3 的辅助方法调用:`{{helper args}}`
6+
2. 修复 EJS `<%- include(src) %>` 语句兼容问题
7+
38
## v4.9.1
49

510
1. 修复模板内部 `$escape``$each` 变量可能没有定义的问题 [#3](https://github.com/aui/express-art-template/issues/3) [#1](https://github.com/aui/express-art-template/issues/1)

lib/compile/adapter/rule.art.js

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ var artRule = {
2121

2222
// 旧版语法升级提示
2323
var warn = function warn(oldSyntax, newSyntax) {
24-
console.warn('Template upgrade:', '{{' + oldSyntax + '}}', '->', '{{' + newSyntax + '}}', '\n', options.filename || '');
24+
console.warn((options.filename || 'anonymous') + ':' + (match.line + 1) + ':' + (match.start + 1) + '\n' + ('Template upgrade: {{' + oldSyntax + '}} -> {{' + newSyntax + '}}'));
2525
};
2626

2727
// v3 compat: #value
@@ -141,16 +141,6 @@ var artRule = {
141141
filter.unshift(accumulator);
142142
return code = '$imports.' + name + '(' + filter.join(',') + ')';
143143
}, target);
144-
} else if (options.imports[key]) {
145-
146-
// ... v3 compat ...
147-
warn('filterName value', 'value | filterName');
148-
149-
group = artRule._split(esTokens);
150-
group.shift();
151-
152-
code = key + '(' + group.join(',') + ')';
153-
output = 'raw';
154144
} else {
155145
code = '' + key + values.join('');
156146
}

lib/compile/adapter/rule.native.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66
var nativeRule = {
77
test: /<%(#?)((?:==|=#|[=-])?)([\w\W]*?)(-?)%>/,
8-
use: function use(match, comment, output, code) {
8+
use: function use(match, comment, output, code /*, trimMode*/) {
99

1010
output = {
1111
'-': 'raw',
@@ -23,7 +23,7 @@ var nativeRule = {
2323
}
2424

2525
// ejs compat: trims following newline
26-
// if (trtimMode) {}
26+
// if (trimMode) {}
2727

2828
return {
2929
code: code,

lib/compile/compiler.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ var LINE = '$$line';
3838
/** 所有“模板块”变量 */
3939
var BLOCKS = '$$blocks';
4040

41+
/** 截取模版输出“流”的函数 */
42+
var SLICE = '$$slice';
43+
4144
/** 继承的布局模板的文件地址变量 */
4245
var FROM = '$$from';
4346

@@ -85,10 +88,10 @@ var Compiler = function () {
8588
this.ignore = [DATA, IMPORTS, OPTIONS].concat(options.ignore);
8689

8790
// 按需编译到模板渲染函数的内置变量
88-
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);
91+
this.internal = (_internal = {}, _internal[OUT] = '\'\'', _internal[LINE] = '[0,0]', _internal[BLOCKS] = 'arguments[1]||{}', _internal[FROM] = 'null', _internal[PRINT] = 'function(){var s=\'\'.concat.apply(\'\',arguments);' + OUT + '+=s;return s}', _internal[INCLUDE] = 'function(src,data){var s=' + OPTIONS + '.include(src,data||' + DATA + ',arguments[2]||' + BLOCKS + ',' + OPTIONS + ');' + OUT + '+=s;return s}', _internal[EXTEND] = 'function(from){' + FROM + '=from}', _internal[SLICE] = 'function(c,p,s){p=' + OUT + ';' + OUT + '=\'\';c();s=' + OUT + ';' + OUT + '=p+s;return s}', _internal[BLOCK] = 'function(){var a=arguments,s;if(typeof a[0]===\'function\'){return ' + SLICE + '(a[0])}else if(' + FROM + '){' + BLOCKS + '[a[0]]=' + SLICE + '(a[1])}else{s=' + BLOCKS + '[a[0]];if(typeof s===\'string\'){' + OUT + '+=s}else{s=' + SLICE + '(a[1])}return s}}', _internal);
8992

9093
// 内置函数依赖关系声明
91-
this.dependencies = (_dependencies = {}, _dependencies[PRINT] = [OUT], _dependencies[INCLUDE] = [OUT, OPTIONS, DATA, BLOCKS], _dependencies[EXTEND] = [FROM, /*[*/INCLUDE /*]*/], _dependencies[BLOCK] = [FROM, OUT, BLOCKS], _dependencies);
94+
this.dependencies = (_dependencies = {}, _dependencies[PRINT] = [OUT], _dependencies[INCLUDE] = [OUT, OPTIONS, DATA, BLOCKS], _dependencies[EXTEND] = [FROM, /*[*/INCLUDE /*]*/], _dependencies[BLOCK] = [SLICE, FROM, OUT, BLOCKS], _dependencies);
9295

9396
this.importContext(OUT);
9497

@@ -448,6 +451,7 @@ Compiler.CONSTS = {
448451
OUT: OUT,
449452
LINE: LINE,
450453
BLOCKS: BLOCKS,
454+
SLICE: SLICE,
451455
FROM: FROM,
452456
ESCAPE: ESCAPE,
453457
EACH: EACH

lib/compile/error.js

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,61 +8,55 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
88

99
/**
1010
* 模板错误处理类
11+
* @param {Object} options
1112
*/
1213
var TemplateError = function (_Error) {
1314
_inherits(TemplateError, _Error);
1415

15-
function TemplateError(error) {
16+
function TemplateError(options) {
1617
_classCallCheck(this, TemplateError);
1718

18-
var _this = _possibleConstructorReturn(this, _Error.call(this, error));
19-
20-
var message = error.message;
21-
22-
if (TemplateError.debugTypes[error.name]) {
23-
24-
if (error.source) {
25-
message = TemplateError.debug(error);
26-
}
27-
28-
_this.path = error.path;
29-
}
19+
var _this = _possibleConstructorReturn(this, _Error.call(this, options.message));
3020

3121
_this.name = 'TemplateError';
32-
_this.message = message;
22+
_this.message = formatMessage(options);
23+
if (Error.captureStackTrace) {
24+
Error.captureStackTrace(_this, _this.constructor);
25+
}
3326
return _this;
3427
}
3528

36-
TemplateError.debug = function debug(error) {
37-
var source = error.source,
38-
path = error.path,
39-
line = error.line,
40-
column = error.column;
29+
return TemplateError;
30+
}(Error);
4131

32+
;
4233

43-
var lines = source.split(/\n/);
44-
var start = Math.max(line - 3, 0);
45-
var end = Math.min(lines.length, line + 3);
34+
function formatMessage(_ref) {
35+
var name = _ref.name,
36+
source = _ref.source,
37+
path = _ref.path,
38+
line = _ref.line,
39+
column = _ref.column,
40+
message = _ref.message;
4641

47-
// Error context
48-
var context = lines.slice(start, end).map(function (code, index) {
49-
var number = index + start + 1;
50-
var left = number === line ? ' >> ' : ' ';
51-
return '' + left + number + '| ' + code;
52-
}).join('\n');
5342

54-
// Alter exception message
55-
return (path || 'anonymous') + ':' + line + ':' + column + '\n' + (context + '\n\n') + ('' + error.message);
56-
};
43+
if (!source) {
44+
return message;
45+
}
5746

58-
return TemplateError;
59-
}(Error);
47+
var lines = source.split(/\n/);
48+
var start = Math.max(line - 3, 0);
49+
var end = Math.min(lines.length, line + 3);
6050

61-
;
51+
// Error context
52+
var context = lines.slice(start, end).map(function (code, index) {
53+
var number = index + start + 1;
54+
var left = number === line ? ' >> ' : ' ';
55+
return '' + left + number + '| ' + code;
56+
}).join('\n');
6257

63-
TemplateError.debugTypes = {
64-
'RuntimeError': true,
65-
'CompileError': true
66-
};
58+
// Alter exception message
59+
return (path || 'anonymous') + ':' + line + ':' + column + '\n' + (context + '\n\n') + (name + ': ' + message);
60+
}
6761

6862
module.exports = TemplateError;

lib/compile/runtime.js

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,36 @@
44

55
var detectNode = require('detect-node');
66
var runtime = Object.create(detectNode ? global : window);
7+
var ESCAPE_REG = /["&'<>]/;
8+
9+
/**
10+
* 编码模板输出的内容
11+
* @param {any} content
12+
* @return {string}
13+
*/
14+
runtime.$escape = function (content) {
15+
return xmlEscape(toString(content));
16+
};
17+
18+
/**
19+
* 迭代器,支持数组与对象
20+
* @param {array|Object} data
21+
* @param {function} callback
22+
*/
23+
runtime.$each = function (data, callback) {
24+
if (Array.isArray(data)) {
25+
for (var i = 0, len = data.length; i < len; i++) {
26+
callback(data[i], i);
27+
}
28+
} else {
29+
for (var _i in data) {
30+
callback(data[_i], _i);
31+
}
32+
}
33+
};
734

835
// 将目标转成字符
9-
var toString = function toString(value) {
36+
function toString(value) {
1037
if (typeof value !== 'string') {
1138
if (value === undefined || value === null) {
1239
value = '';
@@ -21,8 +48,7 @@ var toString = function toString(value) {
2148
};
2249

2350
// 编码 HTML 内容
24-
var ESCAPE_REG = /["&'<>]/;
25-
var xmlEscape = function xmlEscape(content) {
51+
function xmlEscape(content) {
2652
var html = '' + content;
2753
var regexResult = ESCAPE_REG.exec(html);
2854
if (!regexResult) {
@@ -70,33 +96,4 @@ var xmlEscape = function xmlEscape(content) {
7096
}
7197
};
7298

73-
/**
74-
* 编码模板输出的内容
75-
* @param {any} content
76-
* @return {string}
77-
*/
78-
var escape = function escape(content) {
79-
return xmlEscape(toString(content));
80-
};
81-
82-
/**
83-
* 迭代器,支持数组与对象
84-
* @param {array|Object} data
85-
* @param {function} callback
86-
*/
87-
var each = function each(data, callback) {
88-
if (Array.isArray(data)) {
89-
for (var i = 0, len = data.length; i < len; i++) {
90-
callback(data[i], i, data);
91-
}
92-
} else {
93-
for (var _i in data) {
94-
callback(data[_i], _i);
95-
}
96-
}
97-
};
98-
99-
runtime.$each = each;
100-
runtime.$escape = escape;
101-
10299
module.exports = runtime;

lib/compile/tpl-tokenizer.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,27 @@ var TYPE_EXPRESSION = 'expression';
55
var TYPE_RAW = 'raw';
66
var TYPE_ESCAPE = 'escape';
77

8+
function Match(content, line, start, end) {
9+
this.content = content;
10+
this.line = line;
11+
this.start = start;
12+
this.end = end;
13+
};
14+
15+
Match.prototype.toString = function () {
16+
return this.content;
17+
};
18+
819
/**
920
* 将模板转换为 Tokens
1021
* @param {string} source
1122
* @param {Object[]} rules @see defaults.rules
1223
* @param {Object} context
1324
* @return {Object[]}
1425
*/
15-
var tplTokenizer = function tplTokenizer(source, rules, context) {
26+
var tplTokenizer = function tplTokenizer(source, rules) {
27+
var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
28+
1629

1730
var tokens = [{
1831
type: TYPE_STRING,
@@ -74,6 +87,7 @@ var tplTokenizer = function tplTokenizer(source, rules, context) {
7487
}
7588
} else {
7689

90+
values[0] = new Match(values[0], line, start, end);
7791
var script = rule.use.apply(context, values);
7892
token.script = script;
7993
substitute.push(token);

0 commit comments

Comments
 (0)