@@ -61,19 +61,22 @@ function getValueFromContext(exp, context) {
6161function extractElseif ( ifExps , sourcesInsideBlock ) {
6262 var exps = [ ifExps ] ;
6363 var sourcesInsideIf = [ ] ;
64-
64+ var otherIfCount = 0 ;
6565 var start = 0 ;
66- var i , len , source ;
67-
68- for ( i = 0 , len = sourcesInsideBlock . length ; i < len ; i += 1 ) {
69- source = sourcesInsideBlock [ i ] ;
7066
71- if ( source . indexOf ( 'elseif' ) > - 1 || source === 'else' ) {
67+ // eslint-disable-next-line complexity
68+ forEach ( sourcesInsideBlock , function ( source , index ) {
69+ if ( source . indexOf ( 'if' ) === 0 ) {
70+ otherIfCount += 1 ;
71+ } else if ( source === '/if' ) {
72+ otherIfCount -= 1 ;
73+ } else if ( ! otherIfCount && ( source . indexOf ( 'elseif' ) === 0 || source === 'else' ) ) {
7274 exps . push ( source === 'else' ? [ 'true' ] : source . split ( ' ' ) . slice ( 1 ) ) ;
73- sourcesInsideIf . push ( sourcesInsideBlock . slice ( start , i ) ) ;
74- start = i + 1 ;
75+ sourcesInsideIf . push ( sourcesInsideBlock . slice ( start , index ) ) ;
76+ start = index + 1 ;
7577 }
76- }
78+ } ) ;
79+
7780 sourcesInsideIf . push ( sourcesInsideBlock . slice ( start ) ) ;
7881
7982 return {
@@ -124,9 +127,9 @@ function handleEach(exps, sourcesInsideBlock, context) {
124127 forEach ( collection , function ( item , key ) {
125128 additionalContext [ additionalKey ] = key ;
126129 additionalContext [ '@this' ] = item ;
127- extend ( additionalContext , context ) ;
130+ extend ( context , additionalContext ) ;
128131
129- result += compile ( sourcesInsideBlock . slice ( ) , additionalContext ) ;
132+ result += compile ( sourcesInsideBlock . slice ( ) , context ) ;
130133 } ) ;
131134
132135 return result ;
@@ -148,7 +151,7 @@ function handleWith(exps, sourcesInsideBlock, context) {
148151 var additionalContext = { } ;
149152 additionalContext [ alias ] = result ;
150153
151- return compile ( sourcesInsideBlock , extend ( additionalContext , context ) ) || '' ;
154+ return compile ( sourcesInsideBlock , extend ( context , additionalContext ) ) || '' ;
152155}
153156
154157/**
@@ -166,25 +169,6 @@ function extractSourcesInsideBlock(sources, start, end) {
166169 return sourcesInsideBlock ;
167170}
168171
169- /**
170- * Concatenate the strings between previous and next of the base string in place.
171- * @param {Array.<string> } sources - array of sources
172- * @param {number } index - index of base string
173- * @private
174- */
175- function concatPrevAndNextString ( source , index ) {
176- var start = Math . max ( index - 1 , 0 ) ;
177- var end = Math . min ( index + 1 , source . length - 1 ) ;
178- var deletedCount = end - start + 1 ;
179- var result = source . splice ( start , deletedCount ) . join ( '' ) ;
180-
181- if ( deletedCount < 3 ) {
182- source . splice ( start , 0 , '' , result ) ;
183- } else {
184- source . splice ( start , 0 , result ) ;
185- }
186- }
187-
188172/**
189173 * Handle block helper function
190174 * @param {string } helperKeyword - helper keyword (ex. if, each, with)
@@ -195,37 +179,34 @@ function concatPrevAndNextString(source, index) {
195179 */
196180function handleBlockHelper ( helperKeyword , sourcesToEnd , context ) {
197181 var executeBlockHelper = BLOCK_HELPERS [ helperKeyword ] ;
198- var startBlockIndices = [ ] ;
199- var helperCount = 0 ;
200- var index = 0 ;
182+ var helperCount = 1 ;
183+ var startBlockIndex = 0 ;
184+ var endBlockIndex ;
185+ var index = startBlockIndex + EXPRESSION_INTERVAL ;
201186 var expression = sourcesToEnd [ index ] ;
202- var startBlockIndex ;
203187
204- do {
188+ while ( helperCount && isString ( expression ) ) {
205189 if ( expression . indexOf ( helperKeyword ) === 0 ) {
206190 helperCount += 1 ;
207- startBlockIndices . push ( index ) ;
208191 } else if ( expression . indexOf ( '/' + helperKeyword ) === 0 ) {
209192 helperCount -= 1 ;
210- startBlockIndex = startBlockIndices . pop ( ) ;
211-
212- sourcesToEnd [ startBlockIndex ] = executeBlockHelper (
213- sourcesToEnd [ startBlockIndex ] . split ( ' ' ) . slice ( 1 ) ,
214- extractSourcesInsideBlock ( sourcesToEnd , startBlockIndex , index ) ,
215- context
216- ) ;
217- concatPrevAndNextString ( sourcesToEnd , startBlockIndex ) ;
218- index = startBlockIndex - EXPRESSION_INTERVAL ;
193+ endBlockIndex = index ;
219194 }
220195
221196 index += EXPRESSION_INTERVAL ;
222197 expression = sourcesToEnd [ index ] ;
223- } while ( helperCount && isString ( expression ) ) ;
198+ }
224199
225200 if ( helperCount ) {
226201 throw Error ( helperKeyword + ' needs {{/' + helperKeyword + '}} expression.' ) ;
227202 }
228203
204+ sourcesToEnd [ startBlockIndex ] = executeBlockHelper (
205+ sourcesToEnd [ startBlockIndex ] . split ( ' ' ) . slice ( 1 ) ,
206+ extractSourcesInsideBlock ( sourcesToEnd , startBlockIndex , endBlockIndex ) ,
207+ context
208+ ) ;
209+
229210 return sourcesToEnd ;
230211}
231212
0 commit comments