fix: in conditionals, don't render anything after an else branch (#671)

* fix: only render the first 'else' template in the case of multiples

* fix: empty else block and cases with when conditions

* fix: don't render elsif after else

* chore: Update src/tags/unless.ts

* chore: Update src/tags/if.ts

* chore: Update src/tags/case.ts

---------

Co-authored-by: Jun Yang <[email protected]>
This commit is contained in:
Joel Hamilton
2024-02-18 13:30:16 +08:00
committed by GitHub
co-authored by Jun Yang
parent 1937aa1f1d
commit f816955704
7 changed files with 132 additions and 17 deletions
+14 -2
View File
@@ -10,8 +10,13 @@ export default class extends Tag {
this.elseTemplates = []
let p: Template[] = []
let elseCount = 0
const stream: ParseStream = this.liquid.parser.parseStream(remainTokens)
.on('tag:when', (token: TagToken) => {
if (elseCount > 0) {
return
}
p = []
const values: ValueToken[] = []
@@ -29,9 +34,16 @@ export default class extends Tag {
templates: p
})
})
.on('tag:else', () => (p = this.elseTemplates))
.on('tag:else', () => {
elseCount++
p = this.elseTemplates
})
.on('tag:endcase', () => stream.stop())
.on('template', (tpl: Template) => p.push(tpl))
.on('template', (tpl: Template) => {
if (p !== this.elseTemplates || elseCount === 1) {
p.push(tpl)
}
})
.on('end', () => {
throw new Error(`tag ${tagToken.getText()} not closed`)
})
+21 -7
View File
@@ -6,19 +6,33 @@ export default class extends Tag {
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(tagToken, remainTokens, liquid)
let p
let p: Template[] = []
let elseCount = 0
liquid.parser.parseStream(remainTokens)
.on('start', () => this.branches.push({
value: new Value(tagToken.args, this.liquid),
templates: (p = [])
}))
.on('tag:elsif', (token: TagToken) => this.branches.push({
value: new Value(token.args, this.liquid),
templates: (p = [])
}))
.on('tag:else', () => (p = this.elseTemplates))
.on('tag:elsif', (token: TagToken) => {
if (elseCount > 0) {
p = []
return
}
this.branches.push({
value: new Value(token.args, this.liquid),
templates: (p = [])
})
})
.on('tag:else', () => {
elseCount++
p = this.elseTemplates
})
.on('tag:endif', function () { this.stop() })
.on('template', (tpl: Template) => p.push(tpl))
.on('template', (tpl: Template) => {
if (p !== this.elseTemplates || elseCount === 1) {
p.push(tpl)
}
})
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
.start()
}
+22 -8
View File
@@ -5,21 +5,35 @@ export default class extends Tag {
elseTemplates: Template[] = []
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
super(tagToken, remainTokens, liquid)
let p
let p: Template[] = []
let elseCount = 0
this.liquid.parser.parseStream(remainTokens)
.on('start', () => this.branches.push({
value: new Value(tagToken.args, this.liquid),
test: isFalsy,
templates: (p = [])
}))
.on('tag:elsif', (token: TagToken) => this.branches.push({
value: new Value(token.args, this.liquid),
test: isTruthy,
templates: (p = [])
}))
.on('tag:else', () => (p = this.elseTemplates))
.on('tag:elsif', (token: TagToken) => {
if (elseCount > 0) {
p = []
return
}
this.branches.push({
value: new Value(token.args, this.liquid),
test: isTruthy,
templates: (p = [])
})
})
.on('tag:else', () => {
elseCount++
p = this.elseTemplates
})
.on('tag:endunless', function () { this.stop() })
.on('template', (tpl: Template) => p.push(tpl))
.on('template', (tpl: Template) => {
if (p !== this.elseTemplates || elseCount === 1) {
p.push(tpl)
}
})
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
.start()
}