mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 04:10:40 -07:00
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:
co-authored by
Jun Yang
parent
1937aa1f1d
commit
f816955704
+14
-2
@@ -10,8 +10,13 @@ export default class extends Tag {
|
|||||||
this.elseTemplates = []
|
this.elseTemplates = []
|
||||||
|
|
||||||
let p: Template[] = []
|
let p: Template[] = []
|
||||||
|
let elseCount = 0
|
||||||
const stream: ParseStream = this.liquid.parser.parseStream(remainTokens)
|
const stream: ParseStream = this.liquid.parser.parseStream(remainTokens)
|
||||||
.on('tag:when', (token: TagToken) => {
|
.on('tag:when', (token: TagToken) => {
|
||||||
|
if (elseCount > 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
p = []
|
p = []
|
||||||
|
|
||||||
const values: ValueToken[] = []
|
const values: ValueToken[] = []
|
||||||
@@ -29,9 +34,16 @@ export default class extends Tag {
|
|||||||
templates: p
|
templates: p
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.on('tag:else', () => (p = this.elseTemplates))
|
.on('tag:else', () => {
|
||||||
|
elseCount++
|
||||||
|
p = this.elseTemplates
|
||||||
|
})
|
||||||
.on('tag:endcase', () => stream.stop())
|
.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', () => {
|
.on('end', () => {
|
||||||
throw new Error(`tag ${tagToken.getText()} not closed`)
|
throw new Error(`tag ${tagToken.getText()} not closed`)
|
||||||
})
|
})
|
||||||
|
|||||||
+21
-7
@@ -6,19 +6,33 @@ export default class extends Tag {
|
|||||||
|
|
||||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(tagToken, remainTokens, liquid)
|
super(tagToken, remainTokens, liquid)
|
||||||
let p
|
let p: Template[] = []
|
||||||
|
let elseCount = 0
|
||||||
liquid.parser.parseStream(remainTokens)
|
liquid.parser.parseStream(remainTokens)
|
||||||
.on('start', () => this.branches.push({
|
.on('start', () => this.branches.push({
|
||||||
value: new Value(tagToken.args, this.liquid),
|
value: new Value(tagToken.args, this.liquid),
|
||||||
templates: (p = [])
|
templates: (p = [])
|
||||||
}))
|
}))
|
||||||
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
.on('tag:elsif', (token: TagToken) => {
|
||||||
value: new Value(token.args, this.liquid),
|
if (elseCount > 0) {
|
||||||
templates: (p = [])
|
p = []
|
||||||
}))
|
return
|
||||||
.on('tag:else', () => (p = this.elseTemplates))
|
}
|
||||||
|
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('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`) })
|
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
|
||||||
.start()
|
.start()
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-8
@@ -5,21 +5,35 @@ export default class extends Tag {
|
|||||||
elseTemplates: Template[] = []
|
elseTemplates: Template[] = []
|
||||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||||
super(tagToken, remainTokens, liquid)
|
super(tagToken, remainTokens, liquid)
|
||||||
let p
|
let p: Template[] = []
|
||||||
|
let elseCount = 0
|
||||||
this.liquid.parser.parseStream(remainTokens)
|
this.liquid.parser.parseStream(remainTokens)
|
||||||
.on('start', () => this.branches.push({
|
.on('start', () => this.branches.push({
|
||||||
value: new Value(tagToken.args, this.liquid),
|
value: new Value(tagToken.args, this.liquid),
|
||||||
test: isFalsy,
|
test: isFalsy,
|
||||||
templates: (p = [])
|
templates: (p = [])
|
||||||
}))
|
}))
|
||||||
.on('tag:elsif', (token: TagToken) => this.branches.push({
|
.on('tag:elsif', (token: TagToken) => {
|
||||||
value: new Value(token.args, this.liquid),
|
if (elseCount > 0) {
|
||||||
test: isTruthy,
|
p = []
|
||||||
templates: (p = [])
|
return
|
||||||
}))
|
}
|
||||||
.on('tag:else', () => (p = this.elseTemplates))
|
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('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`) })
|
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
|
||||||
.start()
|
.start()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -469,4 +469,20 @@ describe('Issues', function () {
|
|||||||
const result = engine.parseAndRenderSync('{{ÜLKE}}', { ÜLKE: 'Türkiye' })
|
const result = engine.parseAndRenderSync('{{ÜLKE}}', { ÜLKE: 'Türkiye' })
|
||||||
expect(result).toEqual('Türkiye')
|
expect(result).toEqual('Türkiye')
|
||||||
})
|
})
|
||||||
|
it('#670 Should not render anything after an else branch', () => {
|
||||||
|
const engine = new Liquid()
|
||||||
|
const result = engine.parseAndRenderSync('{% assign value = "this" %}' +
|
||||||
|
'{% if false %}don\'t show' +
|
||||||
|
'{% else %}show {{ value }}' +
|
||||||
|
'{% else %}don\'t show{% endif %}', {})
|
||||||
|
expect(result).toEqual('show this')
|
||||||
|
})
|
||||||
|
it('#672 Should not render an elseif after an else branch', () => {
|
||||||
|
const engine = new Liquid()
|
||||||
|
const result = engine.parseAndRenderSync('{% if false %}don\'t show' +
|
||||||
|
'{% else %}show' +
|
||||||
|
'{% elsif true %}don\'t show' +
|
||||||
|
'{% endif %}', {})
|
||||||
|
expect(result).toEqual('show')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -91,4 +91,32 @@ describe('tags/case', function () {
|
|||||||
const html = await liquid.parseAndRender(src)
|
const html = await liquid.parseAndRender(src)
|
||||||
return expect(html).toBe('and or or')
|
return expect(html).toBe('and or or')
|
||||||
})
|
})
|
||||||
|
it('should not render anything after an else branch', async function () {
|
||||||
|
const html = await liquid.parseAndRenderSync('{% assign value = "this" %}' +
|
||||||
|
'{% case true %}' +
|
||||||
|
'{% when false %}don\'t show' +
|
||||||
|
'{% else %}show {{ value }}' +
|
||||||
|
'{% else %}don\'t show' +
|
||||||
|
'{% endcase %}', {})
|
||||||
|
expect(html).toEqual('show this')
|
||||||
|
})
|
||||||
|
it('should not render anything after an else branch even when first else branch is empty', async function () {
|
||||||
|
const html = await liquid.parseAndRenderSync('{% case true %}' +
|
||||||
|
'{% when false %}don\'t show' +
|
||||||
|
'{% else %}' +
|
||||||
|
'{% else %}don\'t show' +
|
||||||
|
'{% endcase %}', {})
|
||||||
|
expect(html).toEqual('')
|
||||||
|
})
|
||||||
|
it('should not render anything after an else branch even when there are \'when\' conditions', () => {
|
||||||
|
const engine = new Liquid()
|
||||||
|
const result = engine.parseAndRenderSync('{% assign value = "this" %}' +
|
||||||
|
'{% case true -%}' +
|
||||||
|
'{% when false -%}don\'t show' +
|
||||||
|
'{% else %}show {{ value }}' +
|
||||||
|
'{% else %}don\'t show' +
|
||||||
|
'{%- when true -%}don\'t show' +
|
||||||
|
'{%- endcase %}', {})
|
||||||
|
expect(result).toEqual('show this')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -143,4 +143,12 @@ describe('tags/if', function () {
|
|||||||
const html = await liquid.parseAndRender(src, scope)
|
const html = await liquid.parseAndRender(src, scope)
|
||||||
return expect(html).toBe('success')
|
return expect(html).toBe('success')
|
||||||
})
|
})
|
||||||
|
it('should not render anything after an else branch even when first else branch is empty', () => {
|
||||||
|
const engine = new Liquid()
|
||||||
|
const result = engine.parseAndRenderSync('{% if false %}don\'t show' +
|
||||||
|
'{% else %}' +
|
||||||
|
'{% else %}don\'t show' +
|
||||||
|
'%{% endif %}', {})
|
||||||
|
expect(result).toEqual('')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,6 +47,29 @@ describe('tags/unless', function () {
|
|||||||
Inside wonderland
|
Inside wonderland
|
||||||
After wonderland`)
|
After wonderland`)
|
||||||
})
|
})
|
||||||
|
it('should not render anything after an else branch', async function () {
|
||||||
|
const html = await liquid.parseAndRenderSync('{% assign value = "this" %}' +
|
||||||
|
'{% unless true %}don\'t show' +
|
||||||
|
'{% else %}show {{ value }}' +
|
||||||
|
'{% else %}don\'t show' +
|
||||||
|
'{% endunless %}', {})
|
||||||
|
expect(html).toEqual('show this')
|
||||||
|
})
|
||||||
|
it('should not render anything after an else branch even when first else branch is empty', async function () {
|
||||||
|
const html = await liquid.parseAndRenderSync('{% unless true %}don\'t show' +
|
||||||
|
'{% else %}' +
|
||||||
|
'{% else %}don\'t show' +
|
||||||
|
'{% endunless %}', {})
|
||||||
|
expect(html).toEqual('')
|
||||||
|
})
|
||||||
|
it('should not render an elseif after an else branch', () => {
|
||||||
|
const engine = new Liquid()
|
||||||
|
const result = engine.parseAndRenderSync('{% unless true %}don\'t show' +
|
||||||
|
'{% else %}show' +
|
||||||
|
'{% elsif true %}don\'t show' +
|
||||||
|
'{% endunless %}', {})
|
||||||
|
expect(result).toEqual('show')
|
||||||
|
})
|
||||||
|
|
||||||
describe('sync support', function () {
|
describe('sync support', function () {
|
||||||
it('should render else when predicate yields true', function () {
|
it('should render else when predicate yields true', function () {
|
||||||
|
|||||||
Reference in New Issue
Block a user