@@ -10,7 +10,7 @@ const revertBackupedLocals = require('./backup').revert
10
10
const placeholders = require ( './placeholders' )
11
11
12
12
let delimitersSettings = [ ]
13
- let conditionals , loops , scopes
13
+ let conditionals , switches , loops , scopes
14
14
15
15
/**
16
16
* @description Creates a set of local variables within the loop, and evaluates all nodes within the loop, returning their contents
@@ -84,6 +84,7 @@ module.exports = function postHTMLExpressions (options) {
84
84
delimiters : [ '{{' , '}}' ] ,
85
85
unescapeDelimiters : [ '{{{' , '}}}' ] ,
86
86
conditionalTags : [ 'if' , 'elseif' , 'else' ] ,
87
+ switchTags : [ 'switch' , 'case' , 'default' ] ,
87
88
loopTags : [ 'each' ] ,
88
89
scopeTags : [ 'scope' ]
89
90
} , options )
@@ -92,6 +93,7 @@ module.exports = function postHTMLExpressions (options) {
92
93
loops = options . loopTags
93
94
scopes = options . scopeTags
94
95
conditionals = options . conditionalTags
96
+ switches = options . switchTags
95
97
96
98
// make a RegExp's to search for placeholders
97
99
let before = escapeRegexpString ( options . delimiters [ 0 ] )
@@ -169,7 +171,6 @@ function walk (opts, nodes) {
169
171
170
172
// сalculate the first path of condition expression
171
173
let expressionIndex = 1
172
-
173
174
let expression = `if (${ node . attrs . condition } ) { 0 } `
174
175
175
176
const branches = [ node . content ]
@@ -225,6 +226,50 @@ function walk (opts, nodes) {
225
226
return m
226
227
}
227
228
229
+ // switch tag
230
+ if ( node . tag === switches [ 0 ] ) {
231
+ // throw an error if it's missing the "condition" attribute
232
+ if ( ! ( node . attrs && node . attrs . expression ) ) {
233
+ throw new Error ( `the "${ switches [ 0 ] } " tag must have a "expression" attribute` )
234
+ }
235
+
236
+ // сalculate the first path of condition expression
237
+ let expressionIndex = 0
238
+ let expression = `switch(${ node . attrs . expression } ) {`
239
+
240
+ const branches = [ ]
241
+
242
+ for ( let i = 0 ; i < node . content . length ; i ++ ) {
243
+ const currentNode = node . content [ i ]
244
+ if ( typeof currentNode === 'string' ) {
245
+ continue
246
+ }
247
+
248
+ if ( currentNode . tag === switches [ 1 ] ) {
249
+ // throw an error if it's missing the "n" attribute
250
+ if ( ! ( currentNode . attrs && currentNode . attrs . n ) ) {
251
+ throw new Error ( `the "${ switches [ 1 ] } " tag must have a "n" attribute` )
252
+ }
253
+ expression += `case ${ currentNode . attrs . n } : {${ expressionIndex ++ } }; break; `
254
+ } else if ( currentNode . tag === switches [ 2 ] ) {
255
+ expression += `default: {${ expressionIndex ++ } }`
256
+ } else {
257
+ throw new Error ( `the "${ switches [ 0 ] } " tag can contain only "${ switches [ 1 ] } " tags and one "${ switches [ 2 ] } " tag` )
258
+ }
259
+ branches . push ( currentNode )
260
+ }
261
+
262
+ expression += '}'
263
+
264
+ // evaluate the expression, get the winning switch branch
265
+ const branch = branches [ vm . runInContext ( expression , ctx ) ]
266
+
267
+ // recursive evaluate of branch
268
+ Array . prototype . push . apply ( m , walk ( opts , branch . content ) )
269
+
270
+ return m
271
+ }
272
+
228
273
// parse loops
229
274
if ( node . tag === loops [ 0 ] ) {
230
275
// handle syntax error
0 commit comments