77
88export class TemplateHelper {
99 private static _expression = / { { \s * [ \w \. ] + \s * } } / g;
10+ private static _converterExpression = / { { { \s * [ \w \. ( ) ] + \s * } } } / g;
1011
1112 /**
1213 * Gets the value of an expanded key in an object
@@ -32,24 +33,31 @@ export class TemplateHelper {
3233 return value ;
3334 }
3435
35- private static replaceExpression ( str : string , context : object ) {
36- return str . replace ( this . _expression , match => {
37- let key = match . substring ( 2 , match . length - 2 ) ;
38- let value = this . getValueFromObject ( context , key ) ;
39- if ( value ) {
40- if ( typeof value == 'object' ) {
41- return JSON . stringify ( value ) ;
42- } else {
43- return ( < any > value ) . toString ( ) ;
36+ private static replaceExpression ( str : string , context : object , converters : object ) {
37+ return str
38+ . replace ( this . _converterExpression , match => {
39+ if ( ! converters ) {
40+ return '' ;
4441 }
45- }
46- return '' ;
47- } ) ;
42+ return this . evalInContext ( match . substring ( 3 , match . length - 3 ) . trim ( ) , { ...converters , ...context } ) ;
43+ } )
44+ . replace ( this . _expression , match => {
45+ let key = match . substring ( 2 , match . length - 2 ) ;
46+ let value = this . getValueFromObject ( context , key ) ;
47+ if ( value ) {
48+ if ( typeof value == 'object' ) {
49+ return JSON . stringify ( value ) ;
50+ } else {
51+ return ( < any > value ) . toString ( ) ;
52+ }
53+ }
54+ return '' ;
55+ } ) ;
4856 }
4957
50- private static renderNode ( node : Node , context : object ) {
58+ private static renderNode ( node : Node , context : object , converters : object ) {
5159 if ( node . nodeName === '#text' ) {
52- node . textContent = this . replaceExpression ( node . textContent , context ) ;
60+ node . textContent = this . replaceExpression ( node . textContent , context , converters ) ;
5361 return node ;
5462 }
5563
@@ -59,7 +67,7 @@ export class TemplateHelper {
5967 if ( nodeElement . attributes ) {
6068 for ( let i = 0 ; i < nodeElement . attributes . length ; i ++ ) {
6169 let attribute = nodeElement . attributes [ i ] ;
62- nodeElement . setAttribute ( attribute . name , this . replaceExpression ( attribute . value , context ) ) ;
70+ nodeElement . setAttribute ( attribute . name , this . replaceExpression ( attribute . value , context , converters ) ) ;
6371 }
6472 }
6573
@@ -81,7 +89,7 @@ export class TemplateHelper {
8189
8290 if ( childElement . dataset . if ) {
8391 let expression = childElement . dataset . if ;
84- if ( ! this . evalInContext ( expression , context ) ) {
92+ if ( ! this . evalBoolInContext ( expression , context ) ) {
8593 removeChildren . push ( childElement ) ;
8694 childWillBeRemoved = true ;
8795 } else {
@@ -101,10 +109,10 @@ export class TemplateHelper {
101109 if ( childElement . dataset . for && ! childWillBeRemoved ) {
102110 loopChildren . push ( childElement ) ;
103111 } else if ( ! childWillBeRemoved ) {
104- this . renderNode ( childNode , context ) ;
112+ this . renderNode ( childNode , context , converters ) ;
105113 }
106114 } else {
107- this . renderNode ( childNode , context ) ;
115+ this . renderNode ( childNode , context , converters ) ;
108116 }
109117
110118 // clear the flag if the current node wasn't data-if
@@ -145,7 +153,7 @@ export class TemplateHelper {
145153 newContext [ 'index' ] = j ;
146154
147155 let clone = childElement . cloneNode ( true ) ;
148- this . renderNode ( clone , newContext ) ;
156+ this . renderNode ( clone , newContext , converters ) ;
149157 nodeElement . appendChild ( clone ) ;
150158 }
151159 }
@@ -155,10 +163,21 @@ export class TemplateHelper {
155163 return node ;
156164 }
157165
158- static evalInContext ( expression , context ) {
166+ private static evalBoolInContext ( expression , context ) {
159167 return new Function ( 'with(this) { return !!(' + expression + ')}' ) . call ( context ) ;
160168 }
161169
170+ private static evalInContext ( expression , context ) {
171+ let func = new Function ( 'with(this) { return ' + expression + ';}' ) ;
172+ let result ;
173+ try {
174+ result = func . call ( context ) ;
175+ } catch ( e ) {
176+ console . log ( e ) ;
177+ }
178+ return result ;
179+ }
180+
162181 /**
163182 * Render a template into a HTMLElement with the appropriate data context
164183 *
@@ -174,17 +193,18 @@ export class TemplateHelper {
174193 *
175194 * @param template the template to render
176195 * @param context the data context to be applied
196+ * @param converters the converter functions used to transform the data
177197 */
178- public static renderTemplate ( template : HTMLTemplateElement , context : object ) {
198+ public static renderTemplate ( template : HTMLTemplateElement , context : object , converters ?: object ) {
179199 if ( template . content && template . content . childNodes . length ) {
180200 let templateContent = template . content . cloneNode ( true ) ;
181- return this . renderNode ( templateContent , context ) ;
201+ return this . renderNode ( templateContent , context , converters ) ;
182202 } else if ( template . childNodes . length ) {
183203 let div = document . createElement ( 'div' ) ;
184204 for ( let i = 0 ; i < template . childNodes . length ; i ++ ) {
185205 div . appendChild ( template . childNodes [ i ] . cloneNode ( true ) ) ;
186206 }
187- return this . renderNode ( div , context ) ;
207+ return this . renderNode ( div , context , converters ) ;
188208 }
189209 }
190210}
0 commit comments