Comparing version 0.3.3 to 0.4.0
var compile = (function(){ | ||
"use strict"; | ||
var fs = null, dirname; | ||
var __fest_log_error = (typeof __fest_error !== 'undefined' ? __fest_error : console.error); | ||
var __log_error = (typeof __fest_error !== 'undefined' ? __fest_error : console.error); | ||
@@ -16,7 +16,7 @@ if (typeof require === 'function'){ | ||
}catch (e){ | ||
__fest_log_error('error open file "' + file + '", ' + e.message); | ||
__log_error('error open file "' + file + '", ' + e.message); | ||
return ''; | ||
} | ||
if (typeof result === 'undefined'){ | ||
__fest_log_error('error check file "' + file + '"'); | ||
__log_error('error check file "' + file + '"'); | ||
return ''; | ||
@@ -30,4 +30,2 @@ } | ||
var sax = (new Function(readFileSync(__dirname + '/sax.js').toString() + ' return sax;'))(); | ||
@@ -39,4 +37,4 @@ var js_beautify = (new Function(readFileSync(__dirname + '/beautify.js').toString() + ' return js_beautify;'))(); | ||
var short_tags = {area: true, base: true, br: true, col: true, command: true, | ||
embed: true, hr: true, img: true, input: true, keygen: true, | ||
link: true, meta: true, param: true, source: true, wbr: true }; | ||
embed: true, hr: true, img: true, input: true, keygen: true, | ||
link: true, meta: true, param: true, source: true, wbr: true }; | ||
@@ -50,3 +48,3 @@ var jschars=/[\\'"\/\n\r\t\b\f<>]/g; | ||
"\n":"\\n", | ||
"\r":"", | ||
"\r":"\\r", | ||
"\t":"\\t", | ||
@@ -105,35 +103,2 @@ "\b":"\\b", | ||
function callback(type, data, section, callbacks){ | ||
if (typeof callbacks[type] !== 'function'){ | ||
return false; | ||
} | ||
var result = callbacks[type](data); | ||
if (result === false){ | ||
return false; | ||
} | ||
if (typeof result === 'string'){ | ||
section.source += result; | ||
} | ||
return true; | ||
} | ||
function closetag(stack, name, section, opentag, context_name){ | ||
if (!opentag){ | ||
return false; | ||
} | ||
if (stack.indexOf('attributes') >= 0 || name === 'attributes'){ | ||
return opentag; | ||
} | ||
if (stack[stack.length - 1] === 'shorttag'){ | ||
section.source += '__fest_pushstr(' + context_name + ',"/>");'; | ||
} else if (stack[stack.length - 1] === 'element') { | ||
section.source += '__fest_elementName = __fest_element_stack[__fest_element_stack.length - 1];'; | ||
section.source += 'if(__fest_elementName in __fest_short_tags){__fest_pushstr(' + context_name + ',"/")}'; | ||
section.source += '__fest_pushstr(' + context_name + ',">");'; | ||
} else { | ||
section.source += '__fest_pushstr(' + context_name + ',">");'; | ||
} | ||
return false; | ||
} | ||
function errorMessage(msg, badLine, file) { | ||
@@ -229,3 +194,3 @@ function zeroPadding(s, len) { | ||
} | ||
section.source += '__fest_debug_file="' + compile_file + '";'; | ||
section.source += '__fest_debug_file="' + escapeJS(compile_file) + '";'; | ||
section.source += '__fest_debug_line="' + parser.line + '";'; | ||
@@ -235,3 +200,3 @@ section.source += '__fest_debug_block="' + block + '";'; | ||
function _compile (file, context_name, callbacks, options, output){ | ||
function _compile (file, options, output){ | ||
output = output || {sections: [], uses: {}}; | ||
@@ -252,2 +217,20 @@ | ||
function closetag(name, opentag){ | ||
if (!opentag){ | ||
return false; | ||
} | ||
if (stack.indexOf('attributes') >= 0 || name === 'attributes'){ | ||
return opentag; | ||
} | ||
if (stack[stack.length - 1] === 'shorttag'){ | ||
section.source += '__fest_pushstr(__fest_context,"/>");'; | ||
} else if (stack[stack.length - 1] === 'element') { | ||
section.source += '__fest_element=__fest_element_stack[__fest_element_stack.length-1];'; | ||
section.source += '__fest_pushstr(__fest_context,__fest_element in __fest_short_tags?"/>":">");'; | ||
} else { | ||
section.source += '__fest_pushstr(__fest_context,">");'; | ||
} | ||
return false; | ||
} | ||
function flush(name) { | ||
@@ -263,7 +246,5 @@ var section = { | ||
parser.onopentag = function (node) { | ||
if (callback('opentag', node, section, callbacks)) return; | ||
push_debug_info(section, parser, file, node.name, options.debug); | ||
opentag = closetag(stack, node.local, section, opentag, context_name); | ||
opentag = closetag(node.local, opentag); | ||
@@ -290,3 +271,3 @@ if (!opentag && node.local == 'attributes') { | ||
opentag = true; | ||
section.source += '__fest_pushstr(' + context_name + ',"<' + node.name + attrs.text + '");'; | ||
section.source += '__fest_pushstr(__fest_context,"<' + node.name + attrs.text + '");'; | ||
return; | ||
@@ -299,33 +280,31 @@ } | ||
opentag = true; | ||
section.source += '__fest_elementName="";'; | ||
section.source += 'try{__fest_elementName=' + _getAttr(node, 'select', 'expr') + ';'; | ||
section.source += 'if(typeof __fest_elementName !== "string"){__fest_log_error("Element name must be a string");__fest_elementName="div"}'; | ||
section.source += '}catch(e){__fest_elementName="div";__fest_log_error(e.message);}'; | ||
section.source += '__fest_element_stack.push(__fest_elementName);'; | ||
section.source += '__fest_pushstr(' + context_name + ',"<" + __fest_elementName);'; | ||
section.source += 'try{__fest_element=' + _getAttr(node, 'select', 'expr') + ';'; | ||
section.source += 'if(typeof __fest_element !== "string"){__fest_log_error("Element name must be a string");__fest_element="div"}'; | ||
section.source += '}catch(e){__fest_element="div";__fest_log_error(e.message);}'; | ||
section.source += '__fest_element_stack.push(__fest_element);'; | ||
section.source += '__fest_pushstr(__fest_context,"<" + __fest_element);'; | ||
return; | ||
case 'template': | ||
node.context_name = context_name; | ||
context_name = (node.attributes.context_name ? _getAttr(node, 'context_name', 'var') : context_name); | ||
if (context_name !== node.context_name){ | ||
section.source += 'var ' + context_name + '=' + node.context_name + ';'; | ||
var context_name = (node.attributes.context_name ? _getAttr(node, 'context_name', 'var') : '__fest_context'); | ||
if (context_name !== '__fest_context'){ | ||
section.source += 'var ' + context_name + '=__fest_context;'; | ||
} | ||
return; | ||
case 'doctype': | ||
section.source += '__fest_pushstr(' + context_name + ',"<!DOCTYPE ");'; | ||
section.source += '__fest_pushstr(__fest_context,"<!DOCTYPE ");'; | ||
return; | ||
case 'attribute': | ||
section.source += '__fest_pushstr(' + context_name + '," ' + escapeJS(_getAttr(node, 'name')) + '=\\"");'; | ||
section.source += '__fest_pushstr(__fest_context," ' + escapeJS(_getAttr(node, 'name')) + '=\\"");'; | ||
return; | ||
case 'comment': | ||
section.source += '__fest_pushstr(' + context_name + ',"<!--");'; | ||
section.source += '__fest_pushstr(__fest_context,"<!--");'; | ||
return; | ||
case 'cdata': | ||
section.source += '__fest_pushstr(' + context_name + ',"<![CDATA[");'; | ||
section.source += '__fest_pushstr(__fest_context,"<![CDATA[");'; | ||
return; | ||
case 'text': | ||
section.source += node.attributes.value ? '__fest_pushstr(' + context_name + ',"' + escapeJS(_getAttr(node, 'value')) + '");' : ''; | ||
section.source += node.attributes.value ? '__fest_pushstr(__fest_context,"' + escapeJS(_getAttr(node, 'value')) + '");' : ''; | ||
return; | ||
case 'space': | ||
section.source += '__fest_pushstr(' + context_name + '," ");'; | ||
section.source += '__fest_pushstr(__fest_context," ");'; | ||
return; | ||
@@ -341,3 +320,3 @@ case 'if': | ||
choose[choose.length - 1]++; | ||
section.source += 'try{__fest_if=' + _getAttr(node, 'test', 'expr') + '}catch(e){__fest_if=false; __fest_log_error(e.message);}'; | ||
section.source += 'try{__fest_if=' + _getAttr(node, 'test', 'expr') + '}catch(e){__fest_if=false;__fest_log_error(e.message);}'; | ||
section.source += 'if(__fest_if){'; | ||
@@ -353,9 +332,9 @@ return; | ||
if (node.__fest_output === 'text'){ | ||
section.source += '__fest_pushstr(' + context_name + ','; | ||
section.source += '__fest_pushstr(__fest_context,'; | ||
} else if(node.__fest_output === 'html' && stack.indexOf('html:script') != -1) { | ||
section.source += '__fest_pushstr(' + context_name + ',__fest_escapeJS('; | ||
section.source += '__fest_pushstr(__fest_context,__fest_escapeJS('; | ||
} else if(node.__fest_output === 'js') { | ||
section.source += '__fest_pushstr(' + context_name + ',__fest_escapeJS('; | ||
section.source += '__fest_pushstr(__fest_context,__fest_escapeJS('; | ||
} else { | ||
section.source += '__fest_pushstr(' + context_name + ',__fest_escapeHTML('; | ||
section.source += '__fest_pushstr(__fest_context,__fest_escapeHTML('; | ||
} | ||
@@ -372,30 +351,29 @@ return; | ||
case 'call': | ||
section.source += 'try{__fest_pushstr(' + context_name + ',' + _getAttr(node, 'name', 'expr') + '(' + _getAttr(node, 'data', 'expr') + '))}catch(e){__fest_log_error(e.message)}'; | ||
section.source += 'try{' + '__fest_pushstr(__fest_context,' + _getAttr(node, 'name', 'expr') + '(' + _getAttr(node, 'data', 'expr') + '))}catch(e){__fest_log_error(e.message)}'; | ||
return; | ||
case 'insert': | ||
section.source += '__fest_pushstr(' + context_name + ',"' + escapeJS(readFileSync(dirname(file) + '/' + _getAttr(node, 'src'), 'utf-8')) + '");'; | ||
section.source += '__fest_pushstr(__fest_context,"' + escapeJS(readFileSync(dirname(file) + '/' + _getAttr(node, 'src'), 'utf-8')) + '");'; | ||
return; | ||
case 'each': | ||
section.source += 'var ' + _getAttr(node, 'index', 'var') + (node.attributes.value ? ',' + _getAttr(node, 'value', 'var') : '') + ';'; | ||
section.source += 'try{__fest_foreach=' + _getAttr(node, 'iterate', 'expr') + ' || {};}catch(e){__fest_foreach={};__fest_log_error(e.message);}'; | ||
section.source += 'for(' + _getAttr(node, 'index') + ' in __fest_foreach){'; | ||
section.source += 'if(!__fest_foreach.hasOwnProperty(' + _getAttr(node, 'index') + ')){ continue; };'; | ||
section.source += 'var ' + _getAttr(node, 'index', 'var') + (node.attributes.value ? ',' + _getAttr(node, 'value', 'var') : '') + ',__fest_iterator' + counters.counter + ';'; | ||
section.source += 'try{__fest_iterator' + counters.counter + '=' + _getAttr(node, 'iterate', 'expr') + ' || {};}catch(e){__fest_iterator={};__fest_log_error(e.message);}'; | ||
section.source += 'for(' + _getAttr(node, 'index') + ' in __fest_iterator' + counters.counter + '){'; | ||
if (node.attributes.value) { | ||
section.source += _getAttr(node, 'value') + '=' + _getAttr(node, 'iterate') + '[' + _getAttr(node, 'index') + '];'; | ||
section.source += _getAttr(node, 'value') + '=__fest_iterator' + counters.counter + '[' + _getAttr(node, 'index') + '];'; | ||
} | ||
counters.counter++; | ||
return; | ||
case 'foreach': | ||
__fest_log_error('forearch deprecated use for'); | ||
case 'for': | ||
section.source += 'var ' + _getAttr(node, 'index', 'var') + (node.attributes.value ? ',' + _getAttr(node, 'value', 'var') : '') + ',__fest_l' + counters.counter + ',__fest_from' + counters.counter + ',__fest_to' + counters.counter + ',__fest_foreach' + counters.counter + ';'; | ||
section.source += 'var ' + _getAttr(node, 'index', 'var') + (node.attributes.value ? ',' + _getAttr(node, 'value', 'var') : '') + ',__fest_to' + counters.counter + (node.attributes.iterate ? '' : ',__fest_from' + counters.counter) + ',__fest_iterator' + counters.counter + ';'; | ||
if (node.attributes.iterate){ | ||
section.source += 'try{__fest_foreach' + counters.counter + '=' + _getAttr(node, 'iterate', 'expr') + ' || [];}catch(e){__fest_foreach' + counters.counter + '=[];__fest_log_error(e.message);}'; | ||
section.source += '__fest_l' + counters.counter + ' = (typeof __fest_foreach' + counters.counter + ' === "number" ? __fest_foreach' + counters.counter + ' : typeof __fest_foreach' + counters.counter + ' === "string" ? parseInt(__fest_foreach' + counters.counter + ', 10) : __fest_foreach' + counters.counter + '.length || 0);'; | ||
section.source += 'for(' + _getAttr(node, 'index') + ' = 0;' + _getAttr(node, 'index') + '<__fest_l' + counters.counter + ';' + node.attributes.index.value + '++){'; | ||
section.source += 'try{__fest_iterator' + counters.counter + '=' + _getAttr(node, 'iterate', 'expr') + ' || [];'; | ||
section.source += '__fest_to' + counters.counter + '=__fest_iterator' + counters.counter + '.length;'; | ||
section.source += '}catch(e){__fest_iterator' + counters.counter + '=[];__fest_to' + counters.counter + '=0;__fest_log_error(e.message);}'; | ||
section.source += 'for(' + _getAttr(node, 'index') + '=0;' + _getAttr(node, 'index') + '<__fest_to' + counters.counter + ';' + node.attributes.index.value + '++){'; | ||
if (node.attributes.value) { | ||
section.source += _getAttr(node, 'value') + '=__fest_foreach' + counters.counter + '[' + _getAttr(node, 'index') + '];'; | ||
section.source += _getAttr(node, 'value') + '=__fest_iterator' + counters.counter + '[' + _getAttr(node, 'index') + '];'; | ||
} | ||
} else { | ||
section.source += 'try{__fest_from' + counters.counter + '=' + _getAttr(node, 'from', 'expr') + ';}catch(e){__fest_from' + counters.counter + '=0;__fest_log_error(e.message);}'; | ||
section.source += 'try{__fest_to' + counters.counter + '=' + _getAttr(node, 'to', 'expr') + ';}catch(e){__fest_to' + counters.counter + '=0;__fest_log_error(e.message);}'; | ||
section.source += 'try{__fest_from' + counters.counter + '=' + _getAttr(node, 'from', 'expr') + ';'; | ||
section.source += '__fest_to' + counters.counter + '=' + _getAttr(node, 'to', 'expr') + ';}catch(e){__fest_from' + counters.counter + '=0;__fest_to' + counters.counter + '=0;__fest_log_error(e.message);}'; | ||
section.source += 'for(' + _getAttr(node, 'index') + ' = __fest_from' + counters.counter + ';' + _getAttr(node, 'index') + '<=__fest_to' + counters.counter + ';' + _getAttr(node, 'index') + '++){'; | ||
@@ -406,19 +384,15 @@ } | ||
case 'set': | ||
// if (options.mode === 'function') throw new Error(file + "\n" + errorMessage('fest:set is not allowed in async mode', parser.line, compile_file)); // TODO warning | ||
section = flush(_getAttr(node, 'name')); | ||
if (node.attributes.test){ | ||
section.source += 'try{__fest_if=' + _getAttr(node, 'test', 'expr') + '}catch(e){__fest_if=false; __fest_log_error(e.message)}'; | ||
} else { | ||
section.source += '__fest_if=true;'; | ||
section.source += 'try{__fest_if=' + _getAttr(node, 'test', 'expr') + '}catch(e){__fest_if=false;__fest_log_error(e.message)}'; | ||
section.source += 'if(__fest_if){'; | ||
} | ||
section.source += 'if(__fest_if){'; | ||
section.source += '__fest_blocks' + getName(_getAttr(node, 'name')) + '=function(' + context_name + ',params){'; | ||
section.source += 'if (typeof document === "undefined"){var document = {write:function(string){__fest_pushstr(' + context_name + ',string);}};}'; | ||
section.source += 'var __fest_result=[],__fest_str="",__fest_pushstr;'; | ||
section.source += '__fest_pushstr=function(ctx,str){__fest_str+=str};'; | ||
section.source += '__fest_blocks' + getName(_getAttr(node, 'name')) + '=function(params){'; | ||
section.source += 'var __fest_buf=""' + (options.mode === 'function' ? ',__fest_pushstr=function(_,s){__fest_buf+=s}' : '') + ';'; | ||
return; | ||
case 'get': | ||
section.source += '__fest_result[__fest_result.length]=__fest_str;'; | ||
section.source += '__fest_str="";'; | ||
// if (options.mode === 'function') throw new Error(file + "\n" + errorMessage('fest:set is not allowed in async mode', parser.line, compile_file)); // TODO warning | ||
if (node.attributes.select){ | ||
section.source += 'try{__fest_select=' + _getAttr(node, 'select', 'expr') + '}catch(e){__fest_select==="__error__";__fest_log_error(e.message)}'; | ||
section.source += 'try{__fest_select=' + _getAttr(node, 'select', 'expr') + '}catch(e){__fest_select==="";__fest_log_error(e.message)}'; | ||
output.disable_sgo = true; | ||
@@ -429,11 +403,7 @@ } else { | ||
} | ||
section.source += '__fest_result[__fest_result.length]=function(' + context_name + ',params, __fest_select){'; | ||
section.source += 'return function(){'; | ||
section.source += 'return (__fest_select in __fest_blocks) ? __fest_blocks[__fest_select].call(__fest_self,' + context_name + ', params) : [];'; | ||
section.source += '};'; | ||
section.source += '};'; | ||
section.source += 'try{__fest_params=false'; | ||
section.source += '__fest_params={};'; | ||
return; | ||
case 'include': | ||
var inner_context_name = context_name; | ||
// TODO subtemplates is named functions | ||
var inner_context_name = '__fest_context'; | ||
if (node.attributes.context){ | ||
@@ -445,3 +415,3 @@ inner_context_name = '__fest_context' + counters.counter; | ||
section.source += '(function(__fest_context){' | ||
_compile(dirname(file) + '/' + _getAttr(node, 'src'), '__fest_context', callbacks, options, output); | ||
_compile(dirname(file) + '/' + _getAttr(node, 'src'), options, output); | ||
section = flush(); | ||
@@ -456,6 +426,4 @@ section.source += '})(' + inner_context_name +');'; | ||
if (callback('closetag', node, section, callbacks) !== false) return; | ||
opentag = closetag(node.local, opentag); | ||
opentag = closetag(stack, node.local, section, opentag, context_name); | ||
stack.pop(); | ||
@@ -466,3 +434,3 @@ | ||
if (!(node.name in short_tags)){ | ||
section.source += '__fest_pushstr(' + context_name + ',"</' + node.name + '>");'; | ||
section.source += '__fest_pushstr(__fest_context,"</' + node.name + '>");'; | ||
} | ||
@@ -473,17 +441,17 @@ return; | ||
case 'element': | ||
section.source += '__fest_elementName = __fest_element_stack[__fest_element_stack.length - 1];'; | ||
section.source += 'if(!(__fest_elementName in __fest_short_tags)){__fest_pushstr(' + context_name + ',"</" + __fest_elementName + ">")}'; | ||
section.source += '__fest_element = __fest_element_stack[__fest_element_stack.length - 1];'; | ||
section.source += 'if(!(__fest_element in __fest_short_tags)){__fest_pushstr(__fest_context,"</" + __fest_element + ">")}'; | ||
section.source += '__fest_element_stack.pop();'; | ||
return; | ||
case 'doctype': | ||
section.source += '__fest_pushstr(' + context_name + ',">");'; | ||
section.source += '__fest_pushstr(__fest_context,">");'; | ||
return; | ||
case 'comment': | ||
section.source += '__fest_pushstr(' + context_name + ',"-->");'; | ||
section.source += '__fest_pushstr(__fest_context,"-->");'; | ||
return; | ||
case 'attribute': | ||
section.source += '__fest_pushstr(' + context_name + ',"\\"");'; | ||
section.source += '__fest_pushstr(__fest_context,"\\"");'; | ||
return; | ||
case 'cdata': | ||
section.source += '__fest_pushstr(' + context_name + ',"]]>");'; | ||
section.source += '__fest_pushstr(__fest_context,"]]>");'; | ||
return; | ||
@@ -495,3 +463,3 @@ case 'if': | ||
return; | ||
case 'foreach': | ||
// case 'foreach': | ||
case 'each': | ||
@@ -512,3 +480,2 @@ case 'for': | ||
case 'value': | ||
section.source += ')'; | ||
if (node.__fest_output !== 'text'){ | ||
@@ -518,16 +485,25 @@ section.source += ')'; | ||
if (!node.attributes.safe){ | ||
section.source += ';}catch(e){__fest_log_error(e.message);}'; | ||
section.source += ')}catch(e){__fest_log_error(e.message + "' + this.line + '");}'; | ||
} else { | ||
section.source += ';'; | ||
section.source += ');'; | ||
} | ||
return; | ||
case 'set': | ||
section.source += '__fest_result[__fest_result.length]=__fest_str;'; | ||
section.source += 'return __fest_result;'; | ||
section.source += '};}'; | ||
section.source += 'return __fest_buf;'; | ||
section.source += '};'; | ||
if (node.attributes.test){ | ||
section.source += '}'; | ||
} | ||
section = flush(); | ||
return; | ||
case 'get': | ||
section.source += ';}catch(e){__fest_params={};__fest_log_error(e.message);}'; | ||
section.source += '__fest_result[__fest_result.length - 1]=__fest_result[__fest_result.length - 1](' + context_name + ',__fest_params, __fest_select);'; | ||
if (stack.indexOf('set') !== -1) { | ||
section.source += '__fest_fn=__fest_blocks[__fest_select];'; | ||
section.source += 'if (__fest_fn)' + ( | ||
options.mode === 'array' ? '__fest_buf.push(__fest_fn.call(__fest_self,__fest_params));' : '__fest_buf+=__fest_fn.call(__fest_self,__fest_params);' | ||
); | ||
} else { | ||
section.source += '__fest_chunks.push(__fest_buf,{name:__fest_select,params:__fest_params});'; | ||
section.source += '__fest_buf="";'; | ||
} | ||
return; | ||
@@ -541,3 +517,2 @@ case 'script': | ||
templateClosed = true; | ||
context_name = node.context_name; | ||
return; | ||
@@ -548,8 +523,7 @@ } | ||
parser.ontext = function (text) { | ||
if (callback('text', text, section, callbacks) !== false) return; | ||
opentag = closetag(stack, 'text', section, opentag, context_name); | ||
opentag = closetag('text', opentag); | ||
if (evallist.indexOf(stack[stack.length - 1]) === -1){ | ||
section.source += '__fest_pushstr(' + context_name + ',"' + escapeJS(text) + '");'; | ||
section.source += '__fest_pushstr(__fest_context,"' + escapeJS(text) + '");'; | ||
} else if (stack[stack.length - 1] === 'get') { | ||
section.source += ' || ' + _getExpr(text); | ||
section.source += 'try{__fest_params=' + _getExpr(text) + '}catch(e){__fest_log_error(e.message)}'; | ||
} else if (stack[stack.length - 1] === 'value') { | ||
@@ -562,8 +536,7 @@ section.source += _getExpr(text); | ||
parser.oncdata = function (cdata) { | ||
if (callback('cdata', cdata, section, callbacks) !== false) return; | ||
opentag = closetag(stack, 'cdata', section, opentag, context_name); | ||
opentag = closetag('cdata', opentag); | ||
if (evallist.indexOf(stack[stack.length - 1]) === -1){ | ||
section.source += '__fest_pushstr(' + context_name + ',"' + escapeJS(cdata) + '");'; | ||
section.source += '__fest_pushstr(__fest_context,"' + escapeJS(cdata) + '");'; | ||
} else if (stack[stack.length - 1] === 'get') { | ||
section.source += ' || ' + _getExpr(cdata); | ||
section.source += 'try{__fest_params=' + _getExpr(cdata) + '}catch(e){__fest_log_error(e.message)}'; | ||
} else if (stack[stack.length - 1] === 'value') { | ||
@@ -590,3 +563,3 @@ section.source += _getExpr(cdata); | ||
function finish_compile(file, options, name){ | ||
var callbacks = {}, template; | ||
var template; | ||
name = name || ''; | ||
@@ -597,2 +570,3 @@ | ||
options.sax.strict = options.sax.strict || true; | ||
options.mode = options.mode || 'string'; // `function` for __fest_pushstr with +=, `array` for push() and join(), `string` for += | ||
@@ -607,46 +581,82 @@ function build_template(output) { | ||
}); | ||
source = source.replace(/"\);__fest_pushstr\([^,]*,"/g, ''); | ||
if (options.mode === 'array') { | ||
source = source | ||
.replace(/__fest_pushstr\(__fest_context,/g, '__fest_buf.push\(') | ||
.replace(/"\);__fest_buf\.push\("/g, '') | ||
.replace(/__fest_buf=""/g, '__fest_buf=[]') | ||
.replace(/return __fest_buf/g, 'return __fest_buf.join("")') // set-blocks and template must return joined buffer | ||
.replace(/__fest_chunks.push\(__fest_buf/g, '__fest_chunks.push(__fest_buf.join("")'); // join buffer before pushing chunk | ||
} else if (options.mode === 'string') { | ||
source = source | ||
.replace(/__fest_pushstr\(__fest_context,/g, '__fest_buf+=\(') | ||
.replace(/"\);__fest_buf\+=\("/g, ''); | ||
} else { | ||
source = source.replace(/"\)\;__fest_pushstr\(__fest_context,"/g, ''); | ||
} | ||
template = 'function ' + name + '(__fest_context){"use strict";' + | ||
'var __fest_self=this,__fest_str="",__fest_result=[],__fest_contexts=[],__fest_attrs=[],__fest_select,__fest_if,__fest_foreach,__fest_from,__fest_to,__fest_html = "",' + | ||
'__fest_blocks={},__fest_params,__fest_log_error,___fest_log_error,__fest_elementName,__fest_pushstr,' + | ||
'__fest_debug_file="",__fest_debug_line="",__fest_debug_block="",' + | ||
'__fest_htmlchars=/[&<>\\"]/g,' + | ||
'__fest_short_tags = ' + JSON.stringify(short_tags) + ',' + | ||
'__fest_element_stack = [],' + | ||
'__fest_htmlhash=' + JSON.stringify(htmlhash) + ',' + | ||
'__fest_jschars=/' + jschars.source + '/g,' + | ||
'__fest_jshash=' + JSON.stringify(jshash) + ';' + | ||
'__fest_pushstr=function(ctx, str){__fest_str+=str};' + | ||
'if(typeof __fest_error === "undefined"){___fest_log_error = function(){return Function.prototype.apply.call(console.error, console, arguments);};}else{___fest_log_error=__fest_error}' + | ||
'function __fest_replaceHTML(chr){return __fest_htmlhash[chr];}' + | ||
'function __fest_replaceJS(chr){return __fest_jshash[chr];}' + | ||
'function __fest_escapeJS(s){' + | ||
'if (typeof s==="string") {' + | ||
'if (__fest_jschars.test(s))return s.replace(__fest_jschars,__fest_replaceJS);' + | ||
'} else if (typeof s==="undefined")return "";' + | ||
'return s;}' + | ||
'function __fest_escapeHTML(s){' + | ||
'if (typeof s==="string") {' + | ||
'if (__fest_htmlchars.test(s))return s.replace(__fest_htmlchars,__fest_replaceHTML);' + | ||
'} else if (typeof s==="undefined")return "";' + | ||
'return s;}' + | ||
'if (typeof document === "undefined"){var document = {write:function(string){__fest_pushstr(__fest_context, string);}};}' + | ||
'function __fest_log_error(message,line,file){___fest_log_error(message+"\\nin block \\""+__fest_debug_block+"\\" at line: "+line+"\\nfile: "+file)}'; | ||
template += source; | ||
template += '__fest_result[__fest_result.length]=__fest_str;' + | ||
'if(__fest_result.length === 1){return __fest_result[0]}' + | ||
'function setblocks(list){' + | ||
'var __fest_i,__fest_l;' + | ||
'for (__fest_i=0,__fest_l=list.length;__fest_i<__fest_l;__fest_i++){' + | ||
'if (typeof list[__fest_i]==="string"){__fest_html+=list[__fest_i];}' + | ||
'else{setblocks(list[__fest_i]());}' + | ||
'}}' + | ||
'setblocks(__fest_result);' + | ||
'return __fest_html;}'; | ||
template = | ||
'function ' + name + '(__fest_context){' + | ||
'"use strict";' + | ||
'var __fest_self=this,' + | ||
'__fest_buf=' + (options.mode === 'array' ? '[]' : '""') + ',' + | ||
'__fest_chunks=[],' + | ||
'__fest_chunk,' + | ||
'__fest_attrs=[],' + | ||
'__fest_select,' + | ||
'__fest_if,' + | ||
'__fest_iterator,' + | ||
'__fest_to,' + | ||
'__fest_fn,' + | ||
'__fest_html=' + (options.mode === 'array' ? '[]' : '""') + ',' + | ||
'__fest_blocks={},' + | ||
'__fest_params,' + | ||
'__fest_element,' + | ||
'__fest_debug_file="",' + | ||
'__fest_debug_line="",' + | ||
'__fest_debug_block="",' + | ||
'__fest_htmlchars=/[&<>\\"]/g,' + | ||
'__fest_short_tags = ' + JSON.stringify(short_tags) + ',' + | ||
'__fest_element_stack = [],' + | ||
'__fest_htmlhash=' + JSON.stringify(htmlhash) + ',' + | ||
'__fest_jschars=/' + jschars.source + '/g,' + | ||
'__fest_jshash=' + JSON.stringify(jshash) + ',' + | ||
'___fest_log_error;' + | ||
(options.mode === 'function' ? 'function __fest_pushstr(_,s){__fest_buf+=s}' : '') + | ||
'if(typeof __fest_error === "undefined"){___fest_log_error = function(){return Function.prototype.apply.call(console.error, console, arguments)}}else{___fest_log_error=__fest_error};' + | ||
'function __fest_log_error(msg){___fest_log_error(msg+"\\nin block \\""+__fest_debug_block+"\\" at line: "+__fest_debug_line+"\\nfile: "+__fest_debug_file)}' + // TODO remove debug info for production code | ||
'function __fest_replaceHTML(chr){return __fest_htmlhash[chr]}' + | ||
'function __fest_replaceJS(chr){return __fest_jshash[chr]}' + | ||
'function __fest_escapeJS(s){' + | ||
'if (typeof s==="string") {' + | ||
'if (__fest_jschars.test(s))return s.replace(__fest_jschars,__fest_replaceJS);' + | ||
'} else if (typeof s==="undefined")return "";' + | ||
'return s;}' + | ||
'function __fest_escapeHTML(s){' + | ||
'if (typeof s==="string") {' + | ||
'if (__fest_htmlchars.test(s))return s.replace(__fest_htmlchars,__fest_replaceHTML);' + | ||
'} else if (typeof s==="undefined")return "";' + | ||
'return s;}' + | ||
source + | ||
'__fest_to=__fest_chunks.length;' + | ||
'if (__fest_to) {' + | ||
'__fest_iterator = 0;' + | ||
'for (;__fest_iterator<__fest_to;__fest_iterator++) {' + | ||
'__fest_chunk=__fest_chunks[__fest_iterator];'+ | ||
'if (typeof __fest_chunk==="string") {' + | ||
(options.mode === 'array' ? '__fest_html.push(__fest_chunk);' : '__fest_html+=__fest_chunk;') + | ||
'} else {' + | ||
'__fest_fn=__fest_blocks[__fest_chunk.name];' + | ||
'if (__fest_fn) ' + | ||
(options.mode === 'array' ? '__fest_html.push(__fest_fn.call(__fest_self,__fest_chunk.params));' : '__fest_html+=__fest_fn.call(__fest_self,__fest_chunk.params);') + | ||
'}' + | ||
'}' + | ||
(options.mode === 'array' ? '__fest_html.push(__fest_buf.join(""));return __fest_html.join("")' : 'return __fest_html+__fest_buf;') + | ||
'} else {' + | ||
'return __fest_buf' + (options.mode === 'array' ? '.join("")' : '') + ';' + | ||
'}' + | ||
'}'; | ||
} | ||
try { | ||
build_template(_compile(file, '__fest_context', callbacks, options)); | ||
build_template(_compile(file, options)); | ||
if (options.beautify) template = js_beautify(template); | ||
@@ -657,4 +667,4 @@ } catch (e) { | ||
} | ||
__fest_log_error(e.message); | ||
template = 'function() { return "' + e.message.replace(/\\/g, '\\\\').replace(/\n/g, "\\n").replace(/\r/g, '').replace(/"/g, '\\"') + '"; }'; | ||
__log_error(e.message); | ||
template = 'function() { return "' + escapeJS(e.message) + '"; }'; | ||
} | ||
@@ -661,0 +671,0 @@ |
@@ -5,3 +5,3 @@ { | ||
"keywords": ["template", "templating", "html", "xml"], | ||
"version": "0.3.3", | ||
"version": "0.4.0", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
@@ -331,7 +331,7 @@ # Fest | ||
<!-- Значением iterate может быть любое js-выражение --> | ||
<fest:foreach iterate="json.people.reverse()" index="i"> | ||
<fest:for iterate="json.people.reverse()" index="i"> | ||
<!-- Передаваемые значения будут доступны в контексте params --> | ||
<fest:get name="person">json.people[i]</fest:get> | ||
</fest:foreach> | ||
</fest:for> | ||
</fest:template> | ||
@@ -338,0 +338,0 @@ ``` |
Sorry, the diff of this file is not supported yet
184950
2816