@@ -66,19 +66,22 @@ function getValueFromContext(exp, context) {
6666function extractElseif ( ifExps , sourcesInsideBlock ) {
6767 var exps = [ ifExps ] ;
6868 var sourcesInsideIf = [ ] ;
69-
69+ var otherIfCount = 0 ;
7070 var start = 0 ;
71- var i , len , source ;
72-
73- for ( i = 0 , len = sourcesInsideBlock . length ; i < len ; i += 1 ) {
74- source = sourcesInsideBlock [ i ] ;
7571
76- if ( source . indexOf ( 'elseif' ) > - 1 || source === 'else' ) {
72+ // eslint-disable-next-line complexity
73+ forEach ( sourcesInsideBlock , function ( source , index ) {
74+ if ( source . indexOf ( 'if' ) === 0 ) {
75+ otherIfCount += 1 ;
76+ } else if ( source === '/if' ) {
77+ otherIfCount -= 1 ;
78+ } else if ( ! otherIfCount && ( source . indexOf ( 'elseif' ) === 0 || source === 'else' ) ) {
7779 exps . push ( source === 'else' ? [ 'true' ] : source . split ( ' ' ) . slice ( 1 ) ) ;
78- sourcesInsideIf . push ( sourcesInsideBlock . slice ( start , i ) ) ;
79- start = i + 1 ;
80+ sourcesInsideIf . push ( sourcesInsideBlock . slice ( start , index ) ) ;
81+ start = index + 1 ;
8082 }
81- }
83+ } ) ;
84+
8285 sourcesInsideIf . push ( sourcesInsideBlock . slice ( start ) ) ;
8386
8487 return {
@@ -129,9 +132,9 @@ function handleEach(exps, sourcesInsideBlock, context) {
129132 forEach ( collection , function ( item , key ) {
130133 additionalContext [ additionalKey ] = key ;
131134 additionalContext [ '@this' ] = item ;
132- extend ( additionalContext , context ) ;
135+ extend ( context , additionalContext ) ;
133136
134- result += compile ( sourcesInsideBlock . slice ( ) , additionalContext ) ;
137+ result += compile ( sourcesInsideBlock . slice ( ) , context ) ;
135138 } ) ;
136139
137140 return result ;
@@ -153,7 +156,7 @@ function handleWith(exps, sourcesInsideBlock, context) {
153156 var additionalContext = { } ;
154157 additionalContext [ alias ] = result ;
155158
156- return compile ( sourcesInsideBlock , extend ( additionalContext , context ) ) || '' ;
159+ return compile ( sourcesInsideBlock , extend ( context , additionalContext ) ) || '' ;
157160}
158161
159162/**
@@ -171,25 +174,6 @@ function extractSourcesInsideBlock(sources, start, end) {
171174 return sourcesInsideBlock ;
172175}
173176
174- /**
175- * Concatenate the strings between previous and next of the base string in place.
176- * @param {Array.<string> } sources - array of sources
177- * @param {number } index - index of base string
178- * @private
179- */
180- function concatPrevAndNextString ( source , index ) {
181- var start = Math . max ( index - 1 , 0 ) ;
182- var end = Math . min ( index + 1 , source . length - 1 ) ;
183- var deletedCount = end - start + 1 ;
184- var result = source . splice ( start , deletedCount ) . join ( '' ) ;
185-
186- if ( deletedCount < 3 ) {
187- source . splice ( start , 0 , '' , result ) ;
188- } else {
189- source . splice ( start , 0 , result ) ;
190- }
191- }
192-
193177/**
194178 * Handle block helper function
195179 * @param {string } helperKeyword - helper keyword (ex. if, each, with)
@@ -200,37 +184,34 @@ function concatPrevAndNextString(source, index) {
200184 */
201185function handleBlockHelper ( helperKeyword , sourcesToEnd , context ) {
202186 var executeBlockHelper = BLOCK_HELPERS [ helperKeyword ] ;
203- var startBlockIndices = [ ] ;
204- var helperCount = 0 ;
205- var index = 0 ;
187+ var helperCount = 1 ;
188+ var startBlockIndex = 0 ;
189+ var endBlockIndex ;
190+ var index = startBlockIndex + EXPRESSION_INTERVAL ;
206191 var expression = sourcesToEnd [ index ] ;
207- var startBlockIndex ;
208192
209- do {
193+ while ( helperCount && isString ( expression ) ) {
210194 if ( expression . indexOf ( helperKeyword ) === 0 ) {
211195 helperCount += 1 ;
212- startBlockIndices . push ( index ) ;
213196 } else if ( expression . indexOf ( '/' + helperKeyword ) === 0 ) {
214197 helperCount -= 1 ;
215- startBlockIndex = startBlockIndices . pop ( ) ;
216-
217- sourcesToEnd [ startBlockIndex ] = executeBlockHelper (
218- sourcesToEnd [ startBlockIndex ] . split ( ' ' ) . slice ( 1 ) ,
219- extractSourcesInsideBlock ( sourcesToEnd , startBlockIndex , index ) ,
220- context
221- ) ;
222- concatPrevAndNextString ( sourcesToEnd , startBlockIndex ) ;
223- index = startBlockIndex - EXPRESSION_INTERVAL ;
198+ endBlockIndex = index ;
224199 }
225200
226201 index += EXPRESSION_INTERVAL ;
227202 expression = sourcesToEnd [ index ] ;
228- } while ( helperCount && isString ( expression ) ) ;
203+ }
229204
230205 if ( helperCount ) {
231206 throw Error ( helperKeyword + ' needs {{/' + helperKeyword + '}} expression.' ) ;
232207 }
233208
209+ sourcesToEnd [ startBlockIndex ] = executeBlockHelper (
210+ sourcesToEnd [ startBlockIndex ] . split ( ' ' ) . slice ( 1 ) ,
211+ extractSourcesInsideBlock ( sourcesToEnd , startBlockIndex , endBlockIndex ) ,
212+ context
213+ ) ;
214+
234215 return sourcesToEnd ;
235216}
236217
0 commit comments