Skip to content

Commit 88058d1

Browse files
committed
feat(index): add switch statement
1 parent c865969 commit 88058d1

File tree

1 file changed

+47
-2
lines changed

1 file changed

+47
-2
lines changed

lib/index.js

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ const revertBackupedLocals = require('./backup').revert
1010
const placeholders = require('./placeholders')
1111

1212
let 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
@@ -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,6 +226,50 @@ 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 "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+
228273
// parse loops
229274
if (node.tag === loops[0]) {
230275
// handle syntax error

0 commit comments

Comments
 (0)