@@ -10,7 +10,7 @@ const revertBackupedLocals = require('./backup').revert
1010const placeholders = require ( './placeholders' )
1111
1212let delimitersSettings = [ ]
13- let conditionals , loops , scopes
13+ let conditionals , switches , loops , scopes
1414
1515/**
1616 * @description Creates a set of local variables within the loop, and evaluates all nodes within the loop, returning their contents
@@ -57,7 +57,7 @@ function executeScope (scope, locals, node) {
5757
5858/**
5959 * @author Jeff Escalante Denis (@jescalan),
60- * Malinochkin (mrmlnc),
60+ * Denis Malinochkin (mrmlnc),
6161 * Michael Ciniawsky (@michael-ciniawsky)
6262 * @description Expressions Plugin for PostHTML
6363 * @license MIT
@@ -84,6 +84,7 @@ module.exports = function postHTMLExpressions (options) {
8484 delimiters : [ '{{' , '}}' ] ,
8585 unescapeDelimiters : [ '{{{' , '}}}' ] ,
8686 conditionalTags : [ 'if' , 'elseif' , 'else' ] ,
87+ switchTags : [ 'switch' , 'case' , 'default' ] ,
8788 loopTags : [ 'each' ] ,
8889 scopeTags : [ 'scope' ]
8990 } , options )
@@ -92,6 +93,7 @@ module.exports = function postHTMLExpressions (options) {
9293 loops = options . loopTags
9394 scopes = options . scopeTags
9495 conditionals = options . conditionalTags
96+ switches = options . switchTags
9597
9698 // make a RegExp's to search for placeholders
9799 let before = escapeRegexpString ( options . delimiters [ 0 ] )
@@ -169,7 +171,6 @@ function walk (opts, nodes) {
169171
170172 // сalculate the first path of condition expression
171173 let expressionIndex = 1
172-
173174 let expression = `if (${ node . attrs . condition } ) { 0 } `
174175
175176 const branches = [ node . content ]
@@ -225,11 +226,55 @@ function walk (opts, nodes) {
225226 return m
226227 }
227228
229+ // switch tag
230+ if ( node . tag === switches [ 0 ] ) {
231+ // throw an error if it's missing the "expression" 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+
228273 // parse loops
229274 if ( node . tag === loops [ 0 ] ) {
230275 // handle syntax error
231276 if ( ! ( node . attrs && node . attrs . loop ) ) {
232- throw new Error ( `the "${ conditionals [ 1 ] } " tag must have a "loop" attribute` )
277+ throw new Error ( `the "${ loops [ 0 ] } " tag must have a "loop" attribute` )
233278 }
234279
235280 // parse the "loop" param
0 commit comments