@@ -119,33 +119,35 @@ module.exports = function postHTMLExpressions (options) {
119
119
removeScriptLocals : false
120
120
} , options )
121
121
122
- // set tags
122
+ // Set tags
123
123
loops = options . loopTags
124
124
scopes = options . scopeTags
125
125
conditionals = options . conditionalTags
126
126
switches = options . switchTags
127
127
ignored = options . ignoredTag
128
128
129
- // make a RegExp's to search for placeholders
129
+ // Define regex to search for placeholders
130
130
let before = escapeRegexpString ( options . delimiters [ 0 ] )
131
131
let after = escapeRegexpString ( options . delimiters [ 1 ] )
132
132
133
- const delimitersRegexp = new RegExp ( `(?<!@)${ before } (.+?)${ after } ` , 'g' )
133
+ const delimitersRegexp = new RegExp ( `(?<!@${ options . delimiters [ 0 ] [ 0 ] } ? )${ before } (.+?)${ after } ` , 'g' )
134
134
135
135
before = escapeRegexpString ( options . unescapeDelimiters [ 0 ] )
136
136
after = escapeRegexpString ( options . unescapeDelimiters [ 1 ] )
137
137
138
- const unescapeDelimitersRegexp = new RegExp ( `(?<!@)${ before } (.+?)${ after } ` , 'g' )
138
+ const unescapeDelimitersRegexp = new RegExp ( `(?<!@${ options . unescapeDelimiters [ 0 ] [ 0 ] } ? )${ before } (.+?)${ after } ` , 'g' )
139
139
140
- // make array of delimiters
140
+ // Create an array of delimiters
141
141
const delimiters = [
142
142
{ text : options . delimiters , regexp : delimitersRegexp , escape : true } ,
143
143
{ text : options . unescapeDelimiters , regexp : unescapeDelimitersRegexp , escape : false }
144
144
]
145
145
146
- // we arrange delimiter search order by length, since it's possible that one
147
- // delimiter could 'contain' another delimiter, like '{{' and '{{{'. But if
148
- // you sort by length, the longer one will always match first.
146
+ /**
147
+ * We arrange delimiter search order by length, since it's possible that one
148
+ * delimiter could 'contain' another delimiter, like `{{{` contains `{{`.
149
+ * But if we sort by length, the longer one will always match first.
150
+ */
149
151
if ( options . delimiters . join ( ) . length > options . unescapeDelimiters . join ( ) . length ) {
150
152
delimitersSettings [ 0 ] = delimiters [ 0 ]
151
153
delimitersSettings [ 1 ] = delimiters [ 1 ]
@@ -157,7 +159,7 @@ module.exports = function postHTMLExpressions (options) {
157
159
delimitersReplace = new RegExp ( `@${ escapeRegexpString ( delimitersSettings [ 1 ] . text [ 0 ] ) } ` , 'g' )
158
160
unescapeDelimitersReplace = new RegExp ( `@${ escapeRegexpString ( delimitersSettings [ 0 ] . text [ 0 ] ) } ` , 'g' )
159
161
160
- // kick off the parsing
162
+ // Kick off the parsing
161
163
return function ( tree ) {
162
164
const { locals } = scriptDataLocals ( tree , options )
163
165
@@ -174,26 +176,28 @@ module.exports = function postHTMLExpressions (options) {
174
176
}
175
177
176
178
function walk ( opts , nodes ) {
177
- // the context in which expressions are evaluated
179
+ // The context in which expressions are evaluated
178
180
const ctx = vm . createContext ( opts . locals )
179
181
180
- // After a conditional has been resolved, we remove the conditional elements
181
- // from the tree. This variable determines how many to skip afterwards.
182
+ /**
183
+ * After a conditional has been resolved, we remove the conditional elements
184
+ * from the tree. This variable determines how many to skip afterwards.
185
+ * */
182
186
let skip
183
187
184
- // loop through each node in the tree
188
+ // Loop through each node in the tree
185
189
return [ ] . concat ( nodes ) . reduce ( ( m , node , i ) => {
186
- // if we're skipping this node, return immediately
190
+ // If we're skipping this node, return immediately
187
191
if ( skip ) { skip -- ; return m }
188
192
189
- // don 't parse ignoredTag
193
+ // Don 't parse ` ignoredTag` from options
190
194
if ( node . tag === ignored ) {
191
195
m . push ( node )
192
196
193
197
return m
194
198
}
195
199
196
- // if we have a string, match and replace it
200
+ // If we have a string, match and replace it
197
201
if ( typeof node === 'string' ) {
198
202
node = placeholders ( node , ctx , delimitersSettings , opts )
199
203
node = node
@@ -205,7 +209,7 @@ function walk (opts, nodes) {
205
209
return m
206
210
}
207
211
208
- // if not, we have an object, so we need to run the attributes and contents
212
+ // If not, we have an object, so we need to run the attributes and contents
209
213
if ( node . attrs ) {
210
214
for ( const key in node . attrs ) {
211
215
if ( typeof node . attrs [ key ] === 'string' ) {
@@ -215,7 +219,7 @@ function walk (opts, nodes) {
215
219
. replace ( delimitersReplace , delimitersSettings [ 1 ] . text [ 0 ] )
216
220
}
217
221
218
- // if key is parametr
222
+ // If ` key` is a parameter
219
223
const _key = placeholders ( key , ctx , delimitersSettings , opts )
220
224
if ( key !== _key ) {
221
225
node . attrs [ _key ] = node . attrs [ key ]
@@ -224,27 +228,31 @@ function walk (opts, nodes) {
224
228
}
225
229
}
226
230
227
- // if the node has content, recurse (unless it's a loop, handled later)
231
+ // If the node has content, recurse (unless it's a loop, which we handle later)
228
232
if ( node . content && loops . includes ( node . tag ) === false && node . tag !== scopes [ 0 ] ) {
229
233
node . content = walk ( opts , node . content )
230
234
}
231
235
232
- // if we have an element matching "if", we've got a conditional
233
- // this comes after the recursion to correctly handle nested loops
236
+ /**
237
+ * If we have an element matching `<if>`, we've got a conditional; this
238
+ * comes after the recursion, to correctly handle nested loops.
239
+ * */
234
240
if ( node . tag === conditionals [ 0 ] ) {
235
- // throw an error if it's missing the "condition" attribute
241
+ // Throw an error if it's missing the "condition" attribute
236
242
if ( ! ( node . attrs && node . attrs . condition ) ) {
237
243
throw new Error ( `the "${ conditionals [ 0 ] } " tag must have a "condition" attribute` )
238
244
}
239
245
240
- // сalculate the first path of condition expression
246
+ // Calculate the first path of condition expression
241
247
let expressionIndex = 1
242
248
let expression = `if (${ node . attrs . condition } ) { 0 } `
243
249
244
250
const branches = [ node . content ]
245
251
246
- // move through the nodes and collect all others that are part of the same
247
- // conditional statement
252
+ /**
253
+ * Move through the nodes and collect all others that
254
+ * are part of the same conditional statement
255
+ * */
248
256
let computedNextTag = getNextTag ( nodes , ++ i )
249
257
250
258
let current = computedNextTag [ 0 ]
@@ -254,24 +262,26 @@ function walk (opts, nodes) {
254
262
let statement = nextTag . tag
255
263
let condition = ''
256
264
257
- // ensure the "else" tag is represented in our little AST as 'else',
258
- // even if a custom tag was used
265
+ /**
266
+ * Ensure the "else" tag is represented in our little AST as 'else',
267
+ * even if a custom tag was used.
268
+ * */
259
269
if ( nextTag . tag === conditionals [ 2 ] ) statement = 'else'
260
270
261
- // add the condition if it's an else if
271
+ // Add the condition if it's an else if
262
272
if ( nextTag . tag === conditionals [ 1 ] ) {
263
- // throw an error if an "else if" is missing a condition
273
+ // Throw an error if an "else if" is missing a condition
264
274
if ( ! ( nextTag . attrs && nextTag . attrs . condition ) ) {
265
275
throw new Error ( `the "${ conditionals [ 1 ] } " tag must have a "condition" attribute` )
266
276
}
267
277
condition = nextTag . attrs . condition
268
278
269
- // while we're here, expand "elseif" to "else if"
279
+ // While we're here, expand "elseif" to "else if"
270
280
statement = 'else if'
271
281
}
272
282
branches . push ( nextTag . content )
273
283
274
- // calculate next part of condition expression
284
+ // Calculate next part of condition expression
275
285
expression += statement + ( condition ? ` (${ condition } )` : '' ) + ` { ${ expressionIndex ++ } } `
276
286
277
287
computedNextTag = getNextTag ( nodes , ++ current )
@@ -280,7 +290,7 @@ function walk (opts, nodes) {
280
290
nextTag = computedNextTag [ 1 ]
281
291
}
282
292
283
- // evaluate the expression, get the winning condition branch
293
+ // Evaluate the expression and get the winning condition branch
284
294
let branch
285
295
try {
286
296
branch = branches [ vm . runInContext ( expression , ctx ) ]
@@ -290,25 +300,27 @@ function walk (opts, nodes) {
290
300
}
291
301
}
292
302
293
- // remove all of the conditional tags from the tree
294
- // we subtract 1 from i as it's incremented from the initial if statement
295
- // in order to get the next node
303
+ /**
304
+ * Remove all of the conditional tags from the tree.
305
+ * We subtract 1 from i as it's incremented from the initial if statement
306
+ * in order to get the next node.
307
+ * */
296
308
skip = current - i
297
309
298
- // recursive evaluate of condition branch
310
+ // Recursive evaluate of condition branch
299
311
if ( branch ) Array . prototype . push . apply ( m , walk ( opts , branch ) )
300
312
301
313
return m
302
314
}
303
315
304
- // switch tag
316
+ // Switch tag
305
317
if ( node . tag === switches [ 0 ] ) {
306
- // throw an error if it's missing the "expression" attribute
318
+ // Throw an error if it's missing the "expression" attribute
307
319
if ( ! ( node . attrs && node . attrs . expression ) ) {
308
320
throw new Error ( `the "${ switches [ 0 ] } " tag must have a "expression" attribute` )
309
321
}
310
322
311
- // сalculate the first path of condition expression
323
+ // Calculate the first path of condition expression
312
324
let expressionIndex = 0
313
325
let expression = `switch(${ node . attrs . expression } ) {`
314
326
@@ -321,7 +333,7 @@ function walk (opts, nodes) {
321
333
}
322
334
323
335
if ( currentNode . tag === switches [ 1 ] ) {
324
- // throw an error if it's missing the "n" attribute
336
+ // Throw an error if it's missing the "n" attribute
325
337
if ( ! ( currentNode . attrs && currentNode . attrs . n ) ) {
326
338
throw new Error ( `the "${ switches [ 1 ] } " tag must have a "n" attribute` )
327
339
}
@@ -336,23 +348,23 @@ function walk (opts, nodes) {
336
348
337
349
expression += '}'
338
350
339
- // evaluate the expression, get the winning switch branch
351
+ // Evaluate the expression, get the winning switch branch
340
352
const branch = branches [ vm . runInContext ( expression , ctx ) ]
341
353
342
- // recursive evaluate of branch
354
+ // Recursive evaluate of branch
343
355
Array . prototype . push . apply ( m , walk ( opts , branch . content ) )
344
356
345
357
return m
346
358
}
347
359
348
- // parse loops
360
+ // Parse loops
349
361
if ( loops . includes ( node . tag ) ) {
350
- // handle syntax error
362
+ // Handle syntax error
351
363
if ( ! ( node . attrs && node . attrs . loop ) ) {
352
364
throw new Error ( `the "${ node . tag } " tag must have a "loop" attribute` )
353
365
}
354
366
355
- // parse the "loop" param
367
+ // Parse the "loop" param
356
368
const loopParams = parseLoopStatement ( node . attrs . loop )
357
369
let target = { }
358
370
try {
@@ -363,7 +375,7 @@ function walk (opts, nodes) {
363
375
}
364
376
}
365
377
366
- // handle additional syntax errors
378
+ // Handle additional syntax errors
367
379
if ( typeof target !== 'object' && opts . strictMode ) {
368
380
throw new Error ( 'You must provide an array or object to loop through' )
369
381
}
@@ -372,14 +384,14 @@ function walk (opts, nodes) {
372
384
throw new Error ( 'You must provide at least one loop argument' )
373
385
}
374
386
375
- // converts nodes to a string. These nodes will be changed within the loop
387
+ // Converts nodes to a string. These nodes will be changed within the loop
376
388
const treeString = JSON . stringify ( node . content )
377
389
const keys = loopParams . keys
378
390
379
- // creates a copy of the keys that will be changed within the loop
391
+ // Creates a copy of the keys that will be changed within the loop
380
392
const localsBackup = makeLocalsBackup ( keys , opts . locals )
381
393
382
- // run the loop, different types of loops for arrays and objects
394
+ // Run the loop, different types of loops for arrays and objects
383
395
if ( Array . isArray ( target ) ) {
384
396
for ( let index = 0 ; index < target . length ; index ++ ) {
385
397
opts . locals . loop = getLoopMeta ( index , target )
@@ -392,42 +404,42 @@ function walk (opts, nodes) {
392
404
}
393
405
}
394
406
395
- // returns the original keys values that was changed within the loop
407
+ // Returns the original keys values that was changed within the loop
396
408
opts . locals = revertBackupedLocals ( keys , opts . locals , localsBackup )
397
409
398
- // return directly out of the loop, which will skip the "each" tag
410
+ // Return directly out of the loop, which will skip the "each" tag
399
411
return m
400
412
}
401
413
402
- // parse scopes
414
+ // Parse scopes
403
415
if ( node . tag === scopes [ 0 ] ) {
404
- // handle syntax error
416
+ // Handle syntax error
405
417
if ( ! node . attrs || ! node . attrs . with ) {
406
418
throw new Error ( `the "${ scopes [ 0 ] } " tag must have a "with" attribute` )
407
419
}
408
420
409
421
const target = vm . runInContext ( node . attrs . with , ctx )
410
422
411
- // handle additional syntax errors
423
+ // Handle additional syntax errors
412
424
if ( typeof target !== 'object' || Array . isArray ( target ) ) {
413
425
throw new Error ( 'You must provide an object to make scope' )
414
426
}
415
427
416
428
const keys = Object . keys ( target )
417
429
418
- // creates a copy of the keys that will be changed within the loop
430
+ // Creates a copy of the keys that will be changed within the loop
419
431
const localsBackup = makeLocalsBackup ( keys , opts . locals )
420
432
421
433
m . push ( executeScope ( target , opts . locals , node ) )
422
434
423
- // returns the original keys values that was changed within the loop
435
+ // Returns the original keys values that was changed within the loop
424
436
opts . locals = revertBackupedLocals ( keys , opts . locals , localsBackup )
425
437
426
- // return directly out of the loop, which will skip the "scope" tag
438
+ // Return directly out of the loop, which will skip the "scope" tag
427
439
return m
428
440
}
429
441
430
- // return the node
442
+ // Return the node
431
443
m . push ( node )
432
444
433
445
return m
0 commit comments