/*! * jSmart Javascript template engine * https://github.com/umakantp/jsmart * * Copyright 2011-2015, Max Miroshnikov * Umakant Patil * jSmart is licensed under the GNU Lesser General Public License * http://opensource.org/licenses/LGPL-3.0 */ (function() { /** merges two or more objects into one shallow copy for objects */ function obMerge(ob1, ob2 /*, ...*/) { for (var i=1; i= 0 && s.substr(i-1,1).match(/\s/)) { continue; } if (!--openCount) { var sTag = s.slice(ldelim.length,i).replace(/[\r\n]/g, ' '); var found = sTag.match(reTag); if (found) { found.index = offset; found[0] = s.slice(0,i+rdelim.length); return found; } } if (openCount < 0) //ignore any number of unmatched right delimiters { openCount = 0; } } } return null; } function findCloseTag(reClose,reOpen,s) { var sInner = ''; var closeTag = null; var openTag = null; var findIndex = 0; do { if (closeTag) { findIndex += closeTag[0].length; } closeTag = findTag(reClose,s); if (!closeTag) { throw new Error('Unclosed {'+reOpen+'}'); } sInner += s.slice(0,closeTag.index); findIndex += closeTag.index; s = s.slice(closeTag.index+closeTag[0].length); openTag = findTag(reOpen,sInner); if (openTag) { sInner = sInner.slice(openTag.index+openTag[0].length); } } while (openTag); closeTag.index = findIndex; return closeTag; } function findElseTag(reOpen, reClose, reElse, s) { var offset = 0; for (var elseTag=findTag(reElse,s); elseTag; elseTag=findTag(reElse,s)) { var openTag = findTag(reOpen,s); if (!openTag || openTag.index > elseTag.index) { elseTag.index += offset; return elseTag; } else { s = s.slice(openTag.index+openTag[0].length); offset += openTag.index+openTag[0].length; var closeTag = findCloseTag(reClose,reOpen,s); s = s.slice(closeTag.index + closeTag[0].length); offset += closeTag.index + closeTag[0].length; } } return null; } function execute(code, data) { if (typeof(code) == 'string') { with ({'__code':code}) { with (modifiers) { with (data) { try { return eval(__code); } catch(e) { throw new Error(e.message + ' in \n' + code); } } } } } return code; } /** * Execute function when we have a object. * * @param object obj Object of the function to be called. * @param array args Arguments to pass to a function. * * @return * @throws Error If function obj does not exists. */ function executeByFuncObject(obj, args) { try { return obj.apply(this, args); } catch (e) { throw new Error(e.message); } } function assignVar(nm, val, data) { if (nm.match(/\[\]$/)) //ar[] = { data[ nm.replace(/\[\]$/,'') ].push(val); } else { data[nm] = val; } } var buildInFunctions = { expression: { parse: function(s, tree) { var e = parseExpression(s); tree.push({ type: 'build-in', name: 'expression', expression: e.tree, params: parseParams(s.slice(e.value.length).replace(/^\s+|\s+$/g,'')) }); return e.tree; }, process: function(node, data) { var params = getActualParamValues(node.params, data); var res = process([node.expression],data); if (findInArray(params, 'nofilter') < 0) { for (var i=0; i': return arg1>arg2; case '>=': return arg1>=arg2; case '===': return arg1===arg2; case '!==': return arg1!==arg2; } } else if (node.op == '!') { return !arg1; } else { var isVar = node.params.__parsed[0].type == 'var'; if (isVar) { arg1 = getVarValue(node.params.__parsed[0], data); } var v = arg1; if (node.optype == 'pre-unary') { switch (node.op) { case '-': v=-arg1; break; case '++': v=++arg1; break; case '--': v=--arg1; break; } if (isVar) { getVarValue(node.params.__parsed[0], data, arg1); } } else { switch (node.op) { case '++': arg1++; break; case '--': arg1--; break; } getVarValue(node.params.__parsed[0], data, arg1); } return v; } } }, section: { type: 'block', parse: function(params, tree, content) { var subTree = []; var subTreeElse = []; tree.push({ type: 'build-in', name: 'section', params: params, subTree: subTree, subTreeElse: subTreeElse }); var findElse = findElseTag('section [^}]+', '\/section', 'sectionelse', content); if (findElse) { parse(content.slice(0,findElse.index),subTree); parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse); } else { parse(content, subTree); } }, process: function(node, data) { var params = getActualParamValues(node.params, data); var props = {}; data.smarty.section[params.__get('name',null,0)] = props; var show = params.__get('show',true); props.show = show; if (!show) { return process(node.subTreeElse, data); } var from = parseInt(params.__get('start',0)); var to = (params.loop instanceof Object) ? countProperties(params.loop) : isNaN(params.loop) ? 0 : parseInt(params.loop); var step = parseInt(params.__get('step',1)); var max = parseInt(params.__get('max')); if (isNaN(max)) { max = Number.MAX_VALUE; } if (from < 0) { from += to; if (from < 0) { from = 0; } } else if (from >= to) { from = to ? to-1 : 0; } var count = 0; var loop = 0; var i = from; for (; i>=0 && i=0 && i=to); props.index = i; props.index_prev = i-step; props.index_next = i+step; props.iteration = props.rownum = count+1; s += process(node.subTree, data); data.smarty['continue'] = false; } data.smarty['break'] = false; if (count) { return s; } return process(node.subTreeElse, data); } }, setfilter: { type: 'block', parseParams: function(paramStr) { return [parseExpression('__t()|' + paramStr).tree]; }, parse: function(params, tree, content) { tree.push({ type: 'build-in', name: 'setfilter', params: params, subTree: parse(content,[]) }); }, process: function(node, data) { tpl_modifiers = node.params; var s = process(node.subTree, data); tpl_modifiers = []; return s; } }, 'for': { type: 'block', parseParams: function(paramStr) { var res = paramStr.match(/^\s*\$(\w+)\s*=\s*([^\s]+)\s*to\s*([^\s]+)\s*(?:step\s*([^\s]+))?\s*(.*)$/); if (!res) { throw new Error('Invalid {for} parameters: '+paramStr); } return parseParams("varName='"+res[1]+"' from="+res[2]+" to="+res[3]+" step="+(res[4]?res[4]:'1')+" "+res[5]); }, parse: function(params, tree, content) { var subTree = []; var subTreeElse = []; tree.push({ type: 'build-in', name: 'for', params: params, subTree: subTree, subTreeElse: subTreeElse }); var findElse = findElseTag('for\\s[^}]+', '\/for', 'forelse', content); if (findElse) { parse(content.slice(0,findElse.index),subTree); parse(content.slice(findElse.index+findElse[0].length), subTreeElse); } else { parse(content, subTree); } }, process: function(node, data) { var params = getActualParamValues(node.params, data); var from = parseInt(params.__get('from')); var to = parseInt(params.__get('to')); var step = parseInt(params.__get('step')); if (isNaN(step)) { step = 1; } var max = parseInt(params.__get('max')); if (isNaN(max)) { max = Number.MAX_VALUE; } var count = 0; var s = ''; var total = Math.min( Math.ceil( ((step > 0 ? to-from : from-to)+1) / Math.abs(step) ), max); for (var i=parseInt(params.from); count\s*[$](\w+))?\s*$/i); if (res) //Smarty 3.x syntax => Smarty 2.x syntax { paramStr = 'from='+res[1] + ' item='+(res[4]||res[2]); if (res[4]) { paramStr += ' key='+res[2]; } } return parseParams(paramStr); }, parse: function(params, tree, content) { var subTree = []; var subTreeElse = []; tree.push({ type: 'build-in', name: 'foreach', params: params, subTree: subTree, subTreeElse: subTreeElse }); var findElse = findElseTag('foreach\\s[^}]+', '\/foreach', 'foreachelse', content); if (findElse) { parse(content.slice(0,findElse.index),subTree); parse(content.slice(findElse.index+findElse[0].length).replace(/^[\r\n]/,''), subTreeElse); } else { parse(content, subTree); } }, process: function(node, data) { var params = getActualParamValues(node.params, data); var a = params.from; if (!(a instanceof Object)) { a = [a]; } var total = countProperties(a); data[params.item+'__total'] = total; if ('name' in params) { data.smarty.foreach[params.name] = {}; data.smarty.foreach[params.name].total = total; } var s = ''; var i=0; for (var key in a) { if (!a.hasOwnProperty(key)) { continue; } if (data.smarty['break']) { break; } data[params.item+'__key'] = isNaN(key) ? key : parseInt(key); if ('key' in params) { data[params.key] = data[params.item+'__key']; } data[params.item] = a[key]; data[params.item+'__index'] = parseInt(i); data[params.item+'__iteration'] = parseInt(i+1); data[params.item+'__first'] = (i===0); data[params.item+'__last'] = (i==total-1); if ('name' in params) { data.smarty.foreach[params.name].index = parseInt(i); data.smarty.foreach[params.name].iteration = parseInt(i+1); data.smarty.foreach[params.name].first = (i===0) ? 1 : ''; data.smarty.foreach[params.name].last = (i==total-1) ? 1 : ''; } ++i; s += process(node.subTree, data); data.smarty['continue'] = false; } data.smarty['break'] = false; data[params.item+'__show'] = (i>0); if (params.name) { data.smarty.foreach[params.name].show = (i>0) ? 1 : ''; } if (i>0) { return s; } return process(node.subTreeElse, data); } }, 'function': { type: 'block', parse: function(params, tree, content) { var subTree = []; plugins[trimQuotes(params.name?params.name:params[0])] = { type: 'function', subTree: subTree, defautParams: params, process: function(params, data) { var defaults = getActualParamValues(this.defautParams,data); delete defaults.name; return process(this.subTree, obMerge({},data,defaults,params)); } }; parse(content, subTree); } }, php: { type: 'block', parse: function(params, tree, content) {} }, 'extends': { type: 'function', parse: function(params, tree) { tree.splice(0,tree.length); getTemplate(trimQuotes(params.file?params.file:params[0]),tree); } }, block: { type: 'block', parse: function(params, tree, content) { tree.push({ type: 'build-in', name: 'block', params: params }); params.append = findInArray(params,'append') >= 0; params.prepend = findInArray(params,'prepend') >= 0; params.hide = findInArray(params,'hide') >= 0; params.hasChild = params.hasParent = false; onParseVar = function(nm) { if (nm.match(/^\s*[$]smarty.block.child\s*$/)) { params.hasChild = true; } if (nm.match(/^\s*[$]smarty.block.parent\s*$/)) { params.hasParent = true; } } var tree = parse(content, []); onParseVar = function(nm) {} var blockName = trimQuotes(params.name?params.name:params[0]); if (!(blockName in blocks)) { blocks[blockName] = []; } blocks[blockName].push({tree:tree, params:params}); }, process: function(node, data) { data.smarty.block.parent = data.smarty.block.child = ''; var blockName = trimQuotes(node.params.name?node.params.name:node.params[0]); this.processBlocks(blocks[blockName], blocks[blockName].length-1, data); return data.smarty.block.child; }, processBlocks: function(blockAncestry, i, data) { if (!i && blockAncestry[i].params.hide) { data.smarty.block.child = ''; return; } var append = true; var prepend = false; for (; i>=0; --i) { if (blockAncestry[i].params.hasParent) { var tmpChild = data.smarty.block.child; data.smarty.block.child = ''; this.processBlocks(blockAncestry, i-1, data); data.smarty.block.parent = data.smarty.block.child; data.smarty.block.child = tmpChild; } var tmpChild = data.smarty.block.child; var s = process(blockAncestry[i].tree, data); data.smarty.block.child = tmpChild; if (blockAncestry[i].params.hasChild) { data.smarty.block.child = s; } else if (append) { data.smarty.block.child = s + data.smarty.block.child; } else if (prepend) { data.smarty.block.child += s; } append = blockAncestry[i].params.append; prepend = blockAncestry[i].params.prepend; } } }, strip: { type: 'block', parse: function(params, tree, content) { parse(content.replace(/[ \t]*[\r\n]+[ \t]*/g, ''), tree); } }, literal: { type: 'block', parse: function(params, tree, content) { parseText(content, tree); } }, ldelim: { type: 'function', parse: function(params, tree) { parseText(jSmart.prototype.left_delimiter, tree); } }, rdelim: { type: 'function', parse: function(params, tree) { parseText(jSmart.prototype.right_delimiter, tree); } }, 'while': { type: 'block', parse: function(params, tree, content) { tree.push({ type: 'build-in', name: 'while', params: params, subTree: parse(content, []) }); }, process: function(node, data) { var s = ''; while (getActualParamValues(node.params,data)[0]) { if (data.smarty['break']) { break; } s += process(node.subTree, data); data.smarty['continue'] = false; } data.smarty['break'] = false; return s; } } }; var plugins = {}; var modifiers = {}; var files = {}; var blocks = null; var scripts = null; var tpl_modifiers = []; function parse(s, tree) { for (var openTag=findTag('',s); openTag; openTag=findTag('',s)) { if (openTag.index) { parseText(s.slice(0,openTag.index),tree); } s = s.slice(openTag.index + openTag[0].length); var res = openTag[1].match(/^\s*(\w+)(.*)$/); if (res) //function { var nm = res[1]; var paramStr = (res.length>2) ? res[2].replace(/^\s+|\s+$/g,'') : ''; if (nm in buildInFunctions) { var buildIn = buildInFunctions[nm]; var params = ('parseParams' in buildIn ? buildIn.parseParams : parseParams)(paramStr); if (buildIn.type == 'block') { s = s.replace(/^\n/,''); //remove new line after block open tag (like in Smarty) var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s); buildIn.parse(params, tree, s.slice(0,closeTag.index)); s = s.slice(closeTag.index+closeTag[0].length); } else { buildIn.parse(params, tree); if (nm == 'extends') { tree = []; //throw away further parsing except for {block} } } s = s.replace(/^\n/,''); } else if (nm in plugins) { var plugin = plugins[nm]; if (plugin.type == 'block') { var closeTag = findCloseTag('\/'+nm, nm+' +[^}]*', s); parsePluginBlock(nm, parseParams(paramStr), tree, s.slice(0,closeTag.index)); s = s.slice(closeTag.index+closeTag[0].length); } else if (plugin.type == 'function') { parsePluginFunc(nm, parseParams(paramStr), tree); } if (nm=='append' || nm=='assign' || nm=='capture' || nm=='eval' || nm=='include') { s = s.replace(/^\n/,''); } } else //variable { buildInFunctions.expression.parse(openTag[1],tree); } } else //variable { var node = buildInFunctions.expression.parse(openTag[1],tree); if (node.type=='build-in' && node.name=='operator' && node.op == '=') { s = s.replace(/^\n/,''); } } } if (s) { parseText(s, tree); } return tree; } function parseText(text, tree) { if (parseText.parseEmbeddedVars) { var re = /([$][\w@]+)|`([^`]*)`/; for (var found=re.exec(text); found; found=re.exec(text)) { tree.push({type: 'text', data: text.slice(0,found.index)}); tree.push( parseExpression(found[1] ? found[1] : found[2]).tree ); text = text.slice(found.index + found[0].length); } } tree.push({type: 'text', data: text}); return tree; } function parseFunc(name, params, tree) { params.__parsed.name = parseText(name,[])[0]; tree.push({ type: 'plugin', name: '__func', params: params }); return tree; } function parseOperator(op, type, precedence, tree) { tree.push({ type: 'build-in', name: 'operator', op: op, optype: type, precedence: precedence, params: {} }); } function parseVar(s, e, nm) { var rootName = e.token; var parts = [{type:'text', data:nm.replace(/^(\w+)@(key|index|iteration|first|last|show|total)/gi, "$1__$2")}]; var re = /^(?:\.|\s*->\s*|\[\s*)/; for (var op=s.match(re); op; op=s.match(re)) { e.token += op[0]; s = s.slice(op[0].length); var eProp = {value:'', tree:[]}; if (op[0].match(/\[/)) { eProp = parseExpression(s); if (eProp) { e.token += eProp.value; parts.push( eProp.tree ); s = s.slice(eProp.value.length); } var closeOp = s.match(/\s*\]/); if (closeOp) { e.token += closeOp[0]; s = s.slice(closeOp[0].length); } } else { var parseMod = parseModifiers.stop; parseModifiers.stop = true; if (lookUp(s,eProp)) { e.token += eProp.value; var part = eProp.tree[0]; if (part.type == 'plugin' && part.name == '__func') { part.hasOwner = true; } parts.push( part ); s = s.slice(eProp.value.length); } else { eProp = false; } parseModifiers.stop = parseMod; } if (!eProp) { parts.push({type:'text', data:''}); } } e.tree.push({type: 'var', parts: parts}); e.value += e.token.substr(rootName.length); onParseVar(e.token); return s; } function onParseVar(nm) {} var tokens = [ { re: /^\$([\w@]+)/, //var parse: function(e, s) { parseModifiers(parseVar(s, e, RegExp.$1), e); } }, { re: /^(true|false)/i, //bool parse: function(e, s) { parseText(e.token.match(/true/i) ? '1' : '', e.tree); } }, { re: /^'([^'\\]*(?:\\.[^'\\]*)*)'/, //single quotes parse: function(e, s) { parseText(evalString(RegExp.$1), e.tree); parseModifiers(s, e); } }, { re: /^"([^"\\]*(?:\\.[^"\\]*)*)"/, //double quotes parse: function(e, s) { var v = evalString(RegExp.$1); var isVar = v.match(tokens[0].re); if (isVar) { var eVar = {token:isVar[0], tree:[]}; parseVar(v, eVar, isVar[1]); if (eVar.token.length == v.length) { e.tree.push( eVar.tree[0] ); return; } } parseText.parseEmbeddedVars = true; e.tree.push({ type: 'plugin', name: '__quoted', params: {__parsed: parse(v,[])} }); parseText.parseEmbeddedVars = false; parseModifiers(s, e); } }, { re: /^(\w+)\s*[(]([)]?)/, //func() parse: function(e, s) { var fnm = RegExp.$1; var noArgs = RegExp.$2; var params = parseParams(noArgs?'':s,/^\s*,\s*/); parseFunc(fnm, params, e.tree); e.value += params.toString(); parseModifiers(s.slice(params.toString().length), e); } }, { re: /^\s*\(\s*/, //expression in parentheses parse: function(e, s) { var parens = []; e.tree.push(parens); parens.parent = e.tree; e.tree = parens; } }, { re: /^\s*\)\s*/, parse: function(e, s) { if (e.tree.parent) //it may be the end of func() or (expr) { e.tree = e.tree.parent; } } }, { re: /^\s*(\+\+|--)\s*/, parse: function(e, s) { if (e.tree.length && e.tree[e.tree.length-1].type == 'var') { parseOperator(RegExp.$1, 'post-unary', 1, e.tree); } else { parseOperator(RegExp.$1, 'pre-unary', 1, e.tree); } } }, { re: /^\s*(===|!==|==|!=)\s*/, parse: function(e, s) { parseOperator(RegExp.$1, 'binary', 6, e.tree); } }, { re: /^\s+(eq|ne|neq)\s+/i, parse: function(e, s) { var op = RegExp.$1.replace(/ne(q)?/,'!=').replace(/eq/,'=='); parseOperator(op, 'binary', 6, e.tree); } }, { re: /^\s*!\s*/, parse: function(e, s) { parseOperator('!', 'pre-unary', 2, e.tree); } }, { re: /^\s+not\s+/i, parse: function(e, s) { parseOperator('!', 'pre-unary', 2, e.tree); } }, { re: /^\s*(=|\+=|-=|\*=|\/=|%=)\s*/, parse: function(e, s) { parseOperator(RegExp.$1, 'binary', 10, e.tree); } }, { re: /^\s*(\*|\/|%)\s*/, parse: function(e, s) { parseOperator(RegExp.$1, 'binary', 3, e.tree); } }, { re: /^\s+mod\s+/i, parse: function(e, s) { parseOperator('%', 'binary', 3, e.tree); } }, { re: /^\s*(\+|-)\s*/, parse: function(e, s) { if (!e.tree.length || e.tree[e.tree.length-1].name == 'operator') { parseOperator(RegExp.$1, 'pre-unary', 4, e.tree); } else { parseOperator(RegExp.$1, 'binary', 4, e.tree); } } }, { re: /^\s*(<=|>=|<>|<|>)\s*/, parse: function(e, s) { parseOperator(RegExp.$1.replace(/<>/,'!='), 'binary', 5, e.tree); } }, { re: /^\s+(lt|lte|le|gt|gte|ge)\s+/i, parse: function(e, s) { var op = RegExp.$1.replace(/lt/,'<').replace(/l(t)?e/,'<=').replace(/gt/,'>').replace(/g(t)?e/,'>='); parseOperator(op, 'binary', 5, e.tree); } }, { re: /^\s+(is\s+(not\s+)?div\s+by)\s+/i, parse: function(e, s) { parseOperator(RegExp.$2?'div_not':'div', 'binary', 7, e.tree); } }, { re: /^\s+is\s+(not\s+)?(even|odd)(\s+by\s+)?\s*/i, parse: function(e, s) { var op = RegExp.$1 ? ((RegExp.$2=='odd')?'even':'even_not') : ((RegExp.$2=='odd')?'even_not':'even'); parseOperator(op, 'binary', 7, e.tree); if (!RegExp.$3) { parseText('1', e.tree); } } }, { re: /^\s*(&&)\s*/, parse: function(e, s) { parseOperator(RegExp.$1, 'binary', 8, e.tree); } }, { re: /^\s*(\|\|)\s*/, parse: function(e, s) { parseOperator(RegExp.$1, 'binary', 9, e.tree); } }, { re: /^\s+and\s+/i, parse: function(e, s) { parseOperator('&&', 'binary', 11, e.tree); } }, { re: /^\s+xor\s+/i, parse: function(e, s) { parseOperator('xor', 'binary', 12, e.tree); } }, { re: /^\s+or\s+/i, parse: function(e, s) { parseOperator('||', 'binary', 13, e.tree); } }, { re: /^#(\w+)#/, //config variable parse: function(e, s) { var eVar = {token:'$smarty',tree:[]}; parseVar('.config.'+RegExp.$1, eVar, 'smarty'); e.tree.push( eVar.tree[0] ); parseModifiers(s, e); } }, { re: /^\s*\[\s*/, //array parse: function(e, s) { var params = parseParams(s, /^\s*,\s*/, /^('[^'\\]*(?:\\.[^'\\]*)*'|"[^"\\]*(?:\\.[^"\\]*)*"|\w+)\s*=>\s*/); parsePluginFunc('__array',params,e.tree); e.value += params.toString(); var paren = s.slice(params.toString().length).match(/\s*\]/); if (paren) { e.value += paren[0]; } } }, { re: /^[\d.]+/, //number parse: function(e, s) { if (e.token.indexOf('.') > -1) { e.token = parseFloat(e.token); } else { e.token = parseInt(e.token, 10); } parseText(e.token, e.tree); parseModifiers(s, e); } }, { re: /^\w+/, //static parse: function(e, s) { parseText(e.token, e.tree); parseModifiers(s, e); } } ]; function parseModifiers(s, e) { if (parseModifiers.stop) { return; } var modifier = s.match(/^\|(\w+)/); if (!modifier) { return; } e.value += modifier[0]; var fnm = modifier[1]=='default' ? 'defaultValue' : modifier[1]; s = s.slice(modifier[0].length).replace(/^\s+/,''); parseModifiers.stop = true; var params = []; for (var colon=s.match(/^\s*:\s*/); colon; colon=s.match(/^\s*:\s*/)) { e.value += s.slice(0,colon[0].length); s = s.slice(colon[0].length); var param = {value:'', tree:[]}; if (lookUp(s, param)) { e.value += param.value; params.push(param.tree[0]); s = s.slice(param.value.length); } else { parseText('',params); } } parseModifiers.stop = false; params.unshift(e.tree.pop()); //modifiers have the highest priority e.tree.push(parseFunc(fnm,{__parsed:params},[])[0]); parseModifiers(s, e); //modifiers can be combined } function lookUp(s,e) { if (!s) { return false; } if (s.substr(0,jSmart.prototype.left_delimiter.length)==jSmart.prototype.left_delimiter) { var tag = findTag('',s); if (tag) { e.token = tag[0]; e.value += tag[0]; parse(tag[0], e.tree); parseModifiers(s.slice(e.value.length), e); return true; } } for (var i=0; i0; --i) { i -= bundleOp(i-1, tree, precedence); } } else { for (i=0; i= data.smarty.cycle[name].arr.length || reset) { data.smarty.cycle[name].index = 0; } if (params.__get('assign',false)) { assignVar(params.assign, data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ], data); return ''; } if (params.__get('print',true)) { return data.smarty.cycle[name].arr[ data.smarty.cycle[name].index ]; } return ''; } ); jSmart.prototype.print_r = function(v,indent) { if (v instanceof Object) { var s = ((v instanceof Array) ? 'Array['+v.length+']' : 'Object') + '
'; for (var nm in v) { if (v.hasOwnProperty(nm)) { s += indent + '  ' + nm + ' : ' + jSmart.prototype.print_r(v[nm],indent+'   ') + '
'; } } return s; } return v; } jSmart.prototype.registerPlugin( 'function', 'debug', function(params, data) { if (typeof dbgWnd != 'undefined') { dbgWnd.close(); } dbgWnd = window.open('','','width=680,height=600,resizable,scrollbars=yes'); var sVars = ''; var i=0; for (var nm in data) { sVars += '' + nm + '' + jSmart.prototype.print_r(data[nm],'') + ''; } dbgWnd.document.write(" \ \ \ jSmart Debug Console \ \ \ \

jSmart Debug Console

\

assigned template variables

\ " + sVars + "
\ \ \ "); return ''; } ); jSmart.prototype.registerPlugin( 'function', 'eval', function(params, data) { var tree = []; parse(params.__get('var','',0), tree); var s = process(tree, data); if ('assign' in params) { assignVar(params.assign, s, data); return ''; } return s; } ); jSmart.prototype.registerPlugin( 'function', 'fetch', function(params, data) { var s = jSmart.prototype.getFile(params.__get('file',null,0)); if ('assign' in params) { assignVar(params.assign, s, data); return ''; } return s; } ); jSmart.prototype.registerPlugin( 'function', 'html_checkboxes', function (params, data) { var type = params.__get('type','checkbox'), name = params.__get('name',type), realName = params.__get('name',type), values = params.__get('values',params.options), output = params.__get('options',[]), useName = ('options' in params), selected = params.__get('selected',false), separator = params.__get('separator',''), labels = Boolean(params.__get('labels',true)), label_ids = Boolean(params.__get('label_ids',false)), p, res = [], i = 0, s = '', value, id; if (type == 'checkbox') { name += '[]'; } if (!useName) { for (p in params.output) { output.push(params.output[p]); } } for (p in values) { if (values.hasOwnProperty(p)) { value = (useName ? p : values[p]); id = realName + '_' + value; s = (labels ? ( label_ids ? '