You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
ymww_backend/public/assets/libs/art-template/test/js/template.js

250 lines
7.9 KiB

/*
Copyright 2012, KISSY UI Library v1.20
MIT Licensed
build time: Jan 10 19:03
*/
/**
* @fileoverview KISSY Template Engine.
* @author yyfrankyy@gmail.com
*/
KISSY.add('template/base', function(S) {
var // Template Cache
templateCache = {},
// start/end tag mark
tagStartEnd = {
'#': 'start',
'/': 'end'
},
// static string
KS_TEMPL_STAT_PARAM = 'KS_TEMPL_STAT_PARAM',
KS_TEMPL_STAT_PARAM_REG = new RegExp(KS_TEMPL_STAT_PARAM, "g"),
KS_TEMPL = 'KS_TEMPL',
KS_DATA = 'KS_DATA_',
KS_AS = 'as',
// note : double quote for generated code
PREFIX = '");',
SUFFIX = KS_TEMPL + '.push("',
PARSER_SYNTAX_ERROR = 'KISSY.Template: Syntax Error. ',
PARSER_RENDER_ERROR = 'KISSY.Template: Render Error. ',
PARSER_PREFIX = 'var ' + KS_TEMPL + '=[],' +
KS_TEMPL_STAT_PARAM + '=false;with(',
PARSER_MIDDLE = '||{}){try{' + KS_TEMPL + '.push("',
PARSER_SUFFIX = '");}catch(e){' + KS_TEMPL + '=["' +
PARSER_RENDER_ERROR + '" + e.message]}};return ' +
KS_TEMPL + '.join("");',
// restore double quote in logic template variable
restoreQuote = function(str) {
return str.replace(/\\"/g, '"');
},
// escape double quote in template
escapeQuote = function(str) {
return str.replace(/"/g, '\\"');
},
trim = S.trim,
// build a static parser
buildParser = function(tpl) {
var _parser,
_empty_index;
return escapeQuote(trim(tpl)
.replace(/[\r\t\n]/g, ' ')
// escape escape ... . in case \ is consumed when run tpl parser function
// '{{y}}\\x{{/y}}' =>tmpl.push('\x'); => tmpl.push('\\x');
.replace(/\\/g, '\\\\'))
.replace(/\{\{([#/]?)(?!\}\})([^}]*)\}\}/g,
function(all, expr, body) {
_parser = "";
// must restore quote , if str is used as code directly
body = restoreQuote(trim(body));
//body = trim(body);
// is an expression
if (expr) {
_empty_index = body.indexOf(' ');
body = _empty_index === -1 ?
[ body, '' ] :
[
body.substring(0, _empty_index),
body.substring(_empty_index)
];
var operator = body[0],
fn,
args = trim(body[1]),
opStatement = Statements[operator];
if (opStatement && tagStartEnd[expr]) {
// get expression definition function/string
fn = opStatement[tagStartEnd[expr]];
_parser = String(S.isFunction(fn) ?
fn.apply(this, args.split(/\s+/)) :
fn.replace(KS_TEMPL_STAT_PARAM_REG, args));
}
}
// return array directly
else {
_parser = KS_TEMPL +
'.push(' +
// prevent variable undefined error when look up in with ,simple variable substitution
// with({}){alert(x);} => ReferenceError: x is not defined
'typeof (' + body + ') ==="undefined"?"":' + body +
');';
}
return PREFIX + _parser + SUFFIX;
});
},
// expression
Statements = {
'if': {
start: 'if(typeof (' + KS_TEMPL_STAT_PARAM + ') !=="undefined" && ' + KS_TEMPL_STAT_PARAM + '){',
end: '}'
},
'else': {
start: '}else{'
},
'elseif': {
start: '}else if(' + KS_TEMPL_STAT_PARAM + '){'
},
// KISSY.each function wrap
'each': {
start: function(obj, as, v, k) {
var _ks_value = '_ks_value',
_ks_index = '_ks_index';
if (as === KS_AS && v) {
_ks_value = v || _ks_value,
_ks_index = k || _ks_index;
}
return 'KISSY.each(' + obj +
', function(' + _ks_value +
', ' + _ks_index + '){';
},
end: '});'
},
// comments
'!': {
start: '/*' + KS_TEMPL_STAT_PARAM + '*/'
}
};
/**
* Template
* @param {String} tpl template to be rendered.
* @return {Object} return this for chain.
*/
function Template(tpl) {
if (!(templateCache[tpl])) {
var _ks_data = S.guid(KS_DATA),
func,
o,
_parser = [
PARSER_PREFIX,
_ks_data,
PARSER_MIDDLE,
o = buildParser(tpl),
PARSER_SUFFIX
];
try {
func = new Function(_ks_data, _parser.join(""));
} catch (e) {
_parser[3] = PREFIX + SUFFIX +
PARSER_SYNTAX_ERROR + ',' +
e.message + PREFIX + SUFFIX;
func = new Function(_ks_data, _parser.join(""));
}
templateCache[tpl] = {
name: _ks_data,
o:o,
parser: _parser.join(""),
render: func
};
}
return templateCache[tpl];
}
S.mix(Template, {
/**
* Logging Compiled Template Codes
* @param {String} tpl template string.
*/
log: function(tpl) {
if (tpl in templateCache) {
if ('js_beautify' in window) {
// S.log(js_beautify(templateCache[tpl].parser, {
// indent_size: 4,
// indent_char: ' ',
// preserve_newlines: true,
// braces_on_own_line: false,
// keep_array_indentation: false,
// space_after_anon_function: true
// }), 'info');
} else {
S.log(templateCache[tpl].parser, 'info');
}
} else {
Template(tpl);
this.log(tpl);
}
},
/**
* add statement for extending template tags
* @param {String} statement tag name.
* @param {String} o extent tag object.
*/
addStatement: function(statement, o) {
if (S.isString(statement)) {
Statements[statement] = o;
} else {
S.mix(Statements, statement);
}
}
});
return Template;
});
/**
* 2011-09-20 note by yiminghe :
* - code style change
* - remove reg cache , ugly to see
* - fix escape by escape
* - expect(T('{{#if a=="a"}}{{b}}\\"{{/if}}').render({a:"a",b:"b"})).toBe('b\\"');
*/
/**
* @fileoverview KISSY.Template Node.
* @author 文河<wenhe@taobao.com>
*/
KISSY.add('template/node', function(S, Template, Node) {
var $ = Node.all;
S.mix(S, {
tmpl: function(selector, data) {
return $(Template($(selector).html()).render(data));
}
});
}, {requires:["./base",'node']});
KISSY.add("template", function(S, T) {
S.Template = T;
return T;
}, {
requires:["template/base","template/node"]
});