Skip to content

Commit

Permalink
Merge branch 'v4.10.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
aui committed Jun 3, 2017
2 parents 0296c10 + 767b1ab commit 65c4f74
Show file tree
Hide file tree
Showing 16 changed files with 199 additions and 189 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,10 @@
# CHANGELOG

## v4.10.0

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

## v4.9.1

1. 修复模板内部 `$escape``$each` 变量可能没有定义的问题 [#3](https://github.com/aui/express-art-template/issues/3) [#1](https://github.com/aui/express-art-template/issues/1)
Expand Down
12 changes: 1 addition & 11 deletions lib/compile/adapter/rule.art.js
Expand Up @@ -21,7 +21,7 @@ var artRule = {

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

// v3 compat: #value
Expand Down Expand Up @@ -141,16 +141,6 @@ var artRule = {
filter.unshift(accumulator);
return code = '$imports.' + name + '(' + filter.join(',') + ')';
}, target);
} else if (options.imports[key]) {

// ... v3 compat ...
warn('filterName value', 'value | filterName');

group = artRule._split(esTokens);
group.shift();

code = key + '(' + group.join(',') + ')';
output = 'raw';
} else {
code = '' + key + values.join('');
}
Expand Down
4 changes: 2 additions & 2 deletions lib/compile/adapter/rule.native.js
Expand Up @@ -5,7 +5,7 @@
*/
var nativeRule = {
test: /<%(#?)((?:==|=#|[=-])?)([\w\W]*?)(-?)%>/,
use: function use(match, comment, output, code) {
use: function use(match, comment, output, code /*, trimMode*/) {

output = {
'-': 'raw',
Expand All @@ -23,7 +23,7 @@ var nativeRule = {
}

// ejs compat: trims following newline
// if (trtimMode) {}
// if (trimMode) {}

return {
code: code,
Expand Down
8 changes: 6 additions & 2 deletions lib/compile/compiler.js
Expand Up @@ -38,6 +38,9 @@ var LINE = '$$line';
/** 所有“模板块”变量 */
var BLOCKS = '$$blocks';

/** 截取模版输出“流”的函数 */
var SLICE = '$$slice';

/** 继承的布局模板的文件地址变量 */
var FROM = '$$from';

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

// 按需编译到模板渲染函数的内置变量
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.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);

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

this.importContext(OUT);

Expand Down Expand Up @@ -448,6 +451,7 @@ Compiler.CONSTS = {
OUT: OUT,
LINE: LINE,
BLOCKS: BLOCKS,
SLICE: SLICE,
FROM: FROM,
ESCAPE: ESCAPE,
EACH: EACH
Expand Down
70 changes: 32 additions & 38 deletions lib/compile/error.js
Expand Up @@ -8,61 +8,55 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"

/**
* 模板错误处理类
* @param {Object} options
*/
var TemplateError = function (_Error) {
_inherits(TemplateError, _Error);

function TemplateError(error) {
function TemplateError(options) {
_classCallCheck(this, TemplateError);

var _this = _possibleConstructorReturn(this, _Error.call(this, error));

var message = error.message;

if (TemplateError.debugTypes[error.name]) {

if (error.source) {
message = TemplateError.debug(error);
}

_this.path = error.path;
}
var _this = _possibleConstructorReturn(this, _Error.call(this, options.message));

_this.name = 'TemplateError';
_this.message = message;
_this.message = formatMessage(options);
if (Error.captureStackTrace) {
Error.captureStackTrace(_this, _this.constructor);
}
return _this;
}

TemplateError.debug = function debug(error) {
var source = error.source,
path = error.path,
line = error.line,
column = error.column;
return TemplateError;
}(Error);

;

var lines = source.split(/\n/);
var start = Math.max(line - 3, 0);
var end = Math.min(lines.length, line + 3);
function formatMessage(_ref) {
var name = _ref.name,
source = _ref.source,
path = _ref.path,
line = _ref.line,
column = _ref.column,
message = _ref.message;

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

// Alter exception message
return (path || 'anonymous') + ':' + line + ':' + column + '\n' + (context + '\n\n') + ('' + error.message);
};
if (!source) {
return message;
}

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

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

TemplateError.debugTypes = {
'RuntimeError': true,
'CompileError': true
};
// Alter exception message
return (path || 'anonymous') + ':' + line + ':' + column + '\n' + (context + '\n\n') + (name + ': ' + message);
}

module.exports = TemplateError;
61 changes: 29 additions & 32 deletions lib/compile/runtime.js
Expand Up @@ -4,9 +4,36 @@

var detectNode = require('detect-node');
var runtime = Object.create(detectNode ? global : window);
var ESCAPE_REG = /["&'<>]/;

/**
* 编码模板输出的内容
* @param {any} content
* @return {string}
*/
runtime.$escape = function (content) {
return xmlEscape(toString(content));
};

/**
* 迭代器,支持数组与对象
* @param {array|Object} data
* @param {function} callback
*/
runtime.$each = function (data, callback) {
if (Array.isArray(data)) {
for (var i = 0, len = data.length; i < len; i++) {
callback(data[i], i);
}
} else {
for (var _i in data) {
callback(data[_i], _i);
}
}
};

// 将目标转成字符
var toString = function toString(value) {
function toString(value) {
if (typeof value !== 'string') {
if (value === undefined || value === null) {
value = '';
Expand All @@ -21,8 +48,7 @@ var toString = function toString(value) {
};

// 编码 HTML 内容
var ESCAPE_REG = /["&'<>]/;
var xmlEscape = function xmlEscape(content) {
function xmlEscape(content) {
var html = '' + content;
var regexResult = ESCAPE_REG.exec(html);
if (!regexResult) {
Expand Down Expand Up @@ -70,33 +96,4 @@ var xmlEscape = function xmlEscape(content) {
}
};

/**
* 编码模板输出的内容
* @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;

module.exports = runtime;
16 changes: 15 additions & 1 deletion lib/compile/tpl-tokenizer.js
Expand Up @@ -5,14 +5,27 @@ var TYPE_EXPRESSION = 'expression';
var TYPE_RAW = 'raw';
var TYPE_ESCAPE = 'escape';

function Match(content, line, start, end) {
this.content = content;
this.line = line;
this.start = start;
this.end = end;
};

Match.prototype.toString = function () {
return this.content;
};

/**
* 将模板转换为 Tokens
* @param {string} source
* @param {Object[]} rules @see defaults.rules
* @param {Object} context
* @return {Object[]}
*/
var tplTokenizer = function tplTokenizer(source, rules, context) {
var tplTokenizer = function tplTokenizer(source, rules) {
var context = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};


var tokens = [{
type: TYPE_STRING,
Expand Down Expand Up @@ -74,6 +87,7 @@ var tplTokenizer = function tplTokenizer(source, rules, context) {
}
} else {

values[0] = new Match(values[0], line, start, end);
var script = rule.use.apply(context, values);
token.script = script;
substitute.push(token);
Expand Down

0 comments on commit 65c4f74

Please sign in to comment.