@@ -43,8 +43,8 @@ window.Template7 = (function () {
4343 var helperName = helperSlices [ 0 ] ;
4444 var helperContext = helperSlices [ 1 ] ;
4545 var helperHash = { } ;
46-
47- if ( helperSlices . length > 2 ) {
46+
47+ if ( helperSlices . length > 1 ) {
4848 var hashRes ;
4949 var reg = new RegExp ( / \b ( \w + ) = [ " ' ] ( [ ^ " ' ] + ) (? = [ " ' ] ) / g) ;
5050 while ( ( hashRes = reg . exec ( block ) ) !== null ) {
@@ -122,176 +122,92 @@ window.Template7 = (function () {
122122 t . template = template ;
123123 t . context = data ;
124124
125- function getContext ( contextName , context , privateData ) {
126- if ( contextName === 'this' || typeof contextName === 'undefined' ) {
127- return context ;
128- }
129-
130- if ( contextName . indexOf ( '@' ) >= 0 ) {
131- //private data
132- var privateVarName = contextName . replace ( / [ @ ] / g , '' ) ;
133- if ( privateData && typeof privateData [ privateVarName ] !== 'undefined' ) return privateData [ privateVarName ] ;
134- }
125+ function getCompileFn ( block , depth ) {
126+ if ( block . content ) return compile ( block . content , depth ) ;
127+ else return function ( ) { return '' ; } ;
128+ }
129+ function getCompileInverse ( block , depth ) {
130+ if ( block . inverseContent ) return compile ( block . inverseContent , depth ) ;
131+ else return function ( ) { return '' ; } ;
132+ }
133+ function getCompileVar ( name , ctx ) {
134+ var parents , variable , context ;
135135
136- if ( contextName . indexOf ( '.' ) > 0 && contextName . indexOf ( '../' ) < 0 ) {
137- var dataPath = contextName . split ( '.' ) ;
138- var _context = context ;
139- for ( var j = 0 ; j < dataPath . length ; j ++ ) {
140- if ( dataPath [ j ] === 'this' ) {
141- _context = context ;
142- }
143- else if ( typeof _context !== 'undefined' && isObject ( context ) && dataPath [ j ] in _context ) {
144- _context = _context [ dataPath [ j ] ] ;
145- }
146- else {
147- _context = undefined ;
148- }
149- }
150- context = _context ;
151- }
152- else if ( contextName . indexOf ( '../' ) >= 0 ) {
136+ if ( name . indexOf ( '.' ) > 0 ) {
137+ if ( name . indexOf ( 'this' ) === 0 ) variable = name . replace ( 'this' , ctx ) ;
138+ else variable = ctx + '.' + name ;
153139 }
154- else if ( context [ contextName ] ) {
155- context = context [ contextName ] ;
140+ else if ( name . indexOf ( '../' ) === 0 ) {
141+ var levelUp = name . split ( '../' ) . length - 1 ;
142+ var newName = name . split ( '../' ) [ name . split ( '../' ) . length - 1 ] ;
143+ var newDepth = ctx . split ( '_' ) [ 1 ] - levelUp ;
144+ variable = 'ctx_' + ( newDepth >= 1 ? newDepth : 1 ) + '.' + newName ;
156145 }
157146 else {
158- context = undefined ;
159- }
160- return context ;
161- }
162- function createOptions ( block , privateData ) {
163- return {
164- fn : function ( newContext , privateData ) {
165- return render ( block . content , newContext , privateData ) ;
166- } ,
167- inverse : function ( newContext , privateData ) {
168- return block . inverseContent ? render ( block . inverseContent , newContext , privateData ) : '' ;
169- } ,
170- hash : block . hash || { } ,
171- helpers : t . helpers ,
172- data : privateData
173- } ;
174- }
175- function render ( template , data , privateData ) {
176- template = template || t . template ;
177- if ( typeof template !== 'string' ) {
178- throw new Error ( 'Template7: Template must be a string' ) ;
179- }
180- var scope = data || t . context ;
181- var blocks = stringToBlocks ( template ) ;
182- var resultString = '' ;
183- var i , j , context ;
184- for ( i = 0 ; i < blocks . length ; i ++ ) {
185- var block = blocks [ i ] ;
186- // Plain block
187- if ( block . type === 'plain' ) {
188- resultString += block . content ;
189- continue ;
190- }
191- // Variable block
192- if ( block . type === 'variable' ) {
193- context = getContext ( block . contextName , scope , privateData ) ;
194- if ( typeof context !== 'undefined' ) {
195- resultString += context . toString ( ) ;
196- }
197- }
198- // Helpers block
199- if ( block . type === 'helper' ) {
200- context = getContext ( block . contextName , scope , privateData ) ;
201- // Create options
202- var options = createOptions ( block , privateData ) ;
203- var helperResult ;
204- var helperName = block . helperName ;
205- if ( block . helperName in t . helpers ) {
206- helperResult = t . helpers [ helperName ] . call ( scope , context , options ) ;
207- }
208- else {
209- if ( ! block . contextName && ( helperName === 'this' || ( isObject ( context ) && helperName in context ) ) ) {
210- var _context = helperName === 'this' ? context : context [ helperName ] ;
211- if ( isArray ( _context ) ) helperResult = t . helpers . each . call ( scope , context [ helperName ] , options ) ;
212- else helperResult = render ( block . content , context [ helperName ] ) ;
213- }
214- else {
215- throw new Error ( 'Template7: Missing helper: "' + helperName + '"' ) ;
216- }
217- }
218- if ( typeof helperResult !== 'undefined' ) {
219- resultString += helperResult . toString ( ) ;
220- }
221- }
147+ variable = name === 'this' ? ctx : ctx + '.' + name ;
222148 }
223- return resultString ;
224- }
225-
226- var depth = 0 ;
227- function getCompileFn ( block ) {
228- if ( block . content ) return compile ( block . content ) ;
229- else return function ( ) { return '' ; } ;
230- }
231- function getCompileInverse ( block ) {
232- if ( block . inverseContent ) return compile ( block . inverseContent ) ;
233- else return function ( ) { return '' ; } ;
234- }
235- function getCompileVar ( name ) {
236- var variable = name === 'this' ? 'ctx' : 'ctx.' + name ;
237149 if ( name && name . indexOf ( '@' ) >= 0 ) {
238150 variable = '(data && data.' + name . replace ( '@' , '' ) + ')' ;
239151 }
152+
240153 return variable ;
241154 }
242- function compile ( template ) {
155+ function compile ( template , depth ) {
156+ depth = depth || 1 ;
243157 template = template || t . template ;
244158 if ( typeof template !== 'string' ) {
245159 throw new Error ( 'Template7: Template must be a string' ) ;
246160 }
247161 var blocks = stringToBlocks ( template ) ;
162+
248163 if ( blocks . length === 0 ) {
249164 return function ( ) { return '' ; } ;
250165 }
251- var resultString = '(function (ctx, data) {\n' ;
252- if ( depth === 0 ) {
253- resultString += 'function c(val) { if (typeof val !== "undefined") return val; else return ""}\n' ;
166+ var ctx = 'ctx_' + depth ;
167+ var resultString = '(function (' + ctx + ', data ) {\n' ;
168+ if ( depth === 1 ) {
254169 resultString += 'function isArray(arr){return Object.prototype.toString.apply(arr) === \'[object Array]\';}\n' ;
170+ resultString += 'function isFunction(func){return (typeof func === \'function\');}\n' ;
171+ resultString += 'function c(val, ctx) {if (typeof val !== "undefined") {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n' ;
255172 }
256- depth ++ ;
257- resultString += 'var ret = \'\';\n' ;
173+ resultString += 'var r = \'\';\n' ;
258174 var i , j , context ;
259175 for ( i = 0 ; i < blocks . length ; i ++ ) {
260176 var block = blocks [ i ] ;
261177 // Plain block
262178 if ( block . type === 'plain' ) {
263- resultString += 'ret +=\'' + ( block . content ) . replace ( / \n / g, '\\n' ) . replace ( / ' / g, '\\' + '\'' ) + '\';' ;
179+ resultString += 'r +=\'' + ( block . content ) . replace ( / \n / g, '\\n' ) . replace ( / ' / g, '\\' + '\'' ) + '\';' ;
264180 continue ;
265181 }
266182 var variable ;
267183 // Variable block
268184 if ( block . type === 'variable' ) {
269- variable = getCompileVar ( block . contextName ) ;
270- resultString += 'ret += c(' + variable + ');' ;
185+ variable = getCompileVar ( block . contextName , ctx ) ;
186+ resultString += 'r += c(' + variable + ', ' + ctx + ');' ;
271187 }
272188 // Helpers block
273189 if ( block . type === 'helper' ) {
274190 if ( block . helperName in t . helpers ) {
275- variable = getCompileVar ( block . contextName ) ;
276- resultString += 'ret += (Template7.helpers.' + block . helperName + ').call(ctx, ' + variable + ', {hash:' + JSON . stringify ( block . hash ) + ', data: data || {}, fn: ' + getCompileFn ( block ) + ', inverse: ' + getCompileInverse ( block ) + '});' ;
191+ variable = getCompileVar ( block . contextName , ctx ) ;
192+ resultString += 'r += (Template7.helpers.' + block . helperName + ').call(' + ctx + ' , ' + variable + ', {hash:' + JSON . stringify ( block . hash ) + ', data: data || {}, fn: ' + getCompileFn ( block , depth + 1 ) + ', inverse: ' + getCompileInverse ( block , depth + 1 ) + '});' ;
277193 }
278194 else {
279195 if ( block . contextName ) {
280196 throw new Error ( 'Template7: Missing helper: "' + block . helperName + '"' ) ;
281197 }
282198 else {
283- variable = getCompileVar ( block . helperName ) ;
199+ variable = getCompileVar ( block . helperName , ctx ) ;
284200 resultString += 'if (' + variable + ') {' ;
285201 resultString += 'if (isArray(' + variable + ')) {' ;
286- resultString += 'ret += (Template7.helpers.each).call(ctx, ' + variable + ', {hash:' + JSON . stringify ( block . hash ) + ', data: data || {}, fn: ' + getCompileFn ( block ) + ', inverse: ' + getCompileInverse ( block ) + '});' ;
202+ resultString += 'r += (Template7.helpers.each).call(' + ctx + ' , ' + variable + ', {hash:' + JSON . stringify ( block . hash ) + ', data: data || {}, fn: ' + getCompileFn ( block , depth + 1 ) + ', inverse: ' + getCompileInverse ( block , depth + 1 ) + '});' ;
287203 resultString += '}else {' ;
288- resultString += 'ret += (Template7.helpers.with).call(ctx, ' + variable + ', {hash:' + JSON . stringify ( block . hash ) + ', data: data || {}, fn: ' + getCompileFn ( block ) + ', inverse: ' + getCompileInverse ( block ) + '});' ;
204+ resultString += 'r += (Template7.helpers.with).call(' + ctx + ' , ' + variable + ', {hash:' + JSON . stringify ( block . hash ) + ', data: data || {}, fn: ' + getCompileFn ( block , depth + 1 ) + ', inverse: ' + getCompileInverse ( block , depth + 1 ) + '});' ;
289205 resultString += '}}' ;
290206 }
291207 }
292208 }
293209 }
294- resultString += '\nreturn ret ;})' ;
210+ resultString += '\nreturn r ;})' ;
295211 return eval . call ( window , resultString ) ;
296212 }
297213 t . compile = function ( template ) {
@@ -300,32 +216,10 @@ window.Template7 = (function () {
300216 }
301217 return t . compiled ;
302218 } ;
303- t . render = function ( data ) {
304- t . context = data ;
305- t . prevContext = undefined ;
306- var rendered , cached , id ;
307- if ( t . options . cache ) {
308- for ( var key in cache ) {
309- if ( key . indexOf ( 'template_' ) >= 0 && cache [ key ] === t . template ) {
310- id = key . split ( 'template_' ) [ 1 ] ;
311- if ( cache [ 'data_' + id ] === JSON . stringify ( data ) ) cached = cache [ 'rendered_' + id ] ;
312- }
313- }
314- if ( cached ) return cached ;
315- }
316- rendered = render ( t . template , data ) ;
317- if ( t . options . cache ) {
318- id = new Date ( ) . getTime ( ) ;
319- cache [ 'template_' + id ] = t . template ;
320- cache [ 'data_' + id ] = JSON . stringify ( data ) ;
321- cache [ 'rendered_' + id ] = rendered ;
322- }
323- return rendered ;
324- } ;
325219 } ;
326220 Template7 . prototype = {
327221 options : {
328- cache : false
222+ // cache: false
329223 } ,
330224 helpers : {
331225 'if' : function ( context , options ) {
@@ -384,7 +278,7 @@ window.Template7 = (function () {
384278 var t7 = function ( template , data ) {
385279 if ( arguments . length === 2 ) {
386280 var instance = new Template7 ( template ) ;
387- var rendered = instance . render ( data ) ;
281+ var rendered = instance . compile ( ) ( data ) ;
388282 instance = null ;
389283 return ( rendered ) ;
390284 }
@@ -393,34 +287,12 @@ window.Template7 = (function () {
393287 t7 . registerHelper = function ( name , fn ) {
394288 Template7 . prototype . helpers [ name ] = fn ;
395289 } ;
396- t7 . render = function ( template , data ) {
397- var instance = t7 ( template , data ) ;
398- } ;
290+
399291 t7 . compile = function ( template ) {
400292 var instance = new Template7 ( template ) ;
401293 return instance . compile ( ) ;
402294 } ;
403- t7 . cache = cache ;
404- t7 . clearCache = function ( arg ) {
405- if ( arguments . length === 0 ) {
406- cache = { } ;
407- return ;
408- }
409- var key , id ;
410- // Clear by passed data
411- for ( key in cache ) {
412- var lookFor = typeof arg === 'string' ? 'template_' : 'data_' ;
413- var compareWith = typeof arg === 'string' ? arg : JSON . strigify ( arg ) ;
414- if ( key . indexOf ( lookFor ) >= 0 && cache [ key ] === arg ) {
415- id = key . split ( '_' ) [ 1 ] ;
416- }
417- }
418- if ( id ) {
419- delete cache [ 'template_' + id ] ;
420- delete cache [ 'data_' + id ] ;
421- delete cache [ 'rendered_' + id ] ;
422- }
423- } ;
295+
424296 t7 . options = Template7 . prototype . options ;
425297 t7 . helpers = Template7 . prototype . helpers ;
426298 return t7 ;
0 commit comments