mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-16 12:50:38 -07:00
fix: report error for malformed else/elsif/endif/endfor, #713
This commit is contained in:
+6
-8
@@ -1,10 +1,10 @@
|
||||
import { Hash, ValueToken, Liquid, Tag, evalToken, Emitter, TagToken, TopLevelToken, Context, Template, ParseStream } from '..'
|
||||
import { toEnumerable } from '../util'
|
||||
import { assertEmpty, toEnumerable } from '../util'
|
||||
import { ForloopDrop } from '../drop/forloop-drop'
|
||||
|
||||
const MODIFIERS = ['offset', 'limit', 'reversed']
|
||||
|
||||
type valueof<T> = T[keyof T]
|
||||
type valueOf<T> = T[keyof T]
|
||||
|
||||
export default class extends Tag {
|
||||
variable: string
|
||||
@@ -31,12 +31,10 @@ export default class extends Tag {
|
||||
let p
|
||||
const stream: ParseStream = this.liquid.parser.parseStream(remainTokens)
|
||||
.on('start', () => (p = this.templates))
|
||||
.on('tag:else', () => (p = this.elseTemplates))
|
||||
.on('tag:endfor', () => stream.stop())
|
||||
.on<TagToken>('tag:else', tag => { assertEmpty(tag.args); p = this.elseTemplates })
|
||||
.on<TagToken>('tag:endfor', tag => { assertEmpty(tag.args); stream.stop() })
|
||||
.on('template', (tpl: Template) => p.push(tpl))
|
||||
.on('end', () => {
|
||||
throw new Error(`tag ${token.getText()} not closed`)
|
||||
})
|
||||
.on('end', () => { throw new Error(`tag ${token.getText()} not closed`) })
|
||||
|
||||
stream.start()
|
||||
}
|
||||
@@ -58,7 +56,7 @@ export default class extends Tag {
|
||||
? Object.keys(hash).filter(x => MODIFIERS.includes(x))
|
||||
: MODIFIERS.filter(x => hash[x] !== undefined)
|
||||
|
||||
collection = modifiers.reduce((collection, modifier: valueof<typeof MODIFIERS>) => {
|
||||
collection = modifiers.reduce((collection, modifier: valueOf<typeof MODIFIERS>) => {
|
||||
if (modifier === 'offset') return offset(collection, hash['offset'])
|
||||
if (modifier === 'limit') return limit(collection, hash['limit'])
|
||||
return reversed(collection)
|
||||
|
||||
+11
-17
@@ -1,38 +1,32 @@
|
||||
import { Liquid, Tag, Value, Emitter, isTruthy, TagToken, TopLevelToken, Context, Template } from '..'
|
||||
import { assert, assertEmpty } from '../util'
|
||||
|
||||
export default class extends Tag {
|
||||
branches: { value: Value, templates: Template[] }[] = []
|
||||
elseTemplates: Template[] = []
|
||||
elseTemplates: Template[] | undefined
|
||||
|
||||
constructor (tagToken: TagToken, remainTokens: TopLevelToken[], liquid: Liquid) {
|
||||
super(tagToken, remainTokens, liquid)
|
||||
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) => {
|
||||
if (elseCount > 0) {
|
||||
p = []
|
||||
return
|
||||
}
|
||||
assert(!this.elseTemplates, 'unexpected elsif after else')
|
||||
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) => {
|
||||
if (p !== this.elseTemplates || elseCount === 1) {
|
||||
p.push(tpl)
|
||||
}
|
||||
})
|
||||
.on<TagToken>('tag:else', tag => {
|
||||
assertEmpty(tag.args)
|
||||
assert(!this.elseTemplates, 'duplicated else')
|
||||
p = this.elseTemplates = []
|
||||
})
|
||||
.on<TagToken>('tag:endif', function (tag) { assertEmpty(tag.args); this.stop() })
|
||||
.on('template', (tpl: Template) => p.push(tpl))
|
||||
.on('end', () => { throw new Error(`tag ${tagToken.getText()} not closed`) })
|
||||
.start()
|
||||
}
|
||||
@@ -47,6 +41,6 @@ export default class extends Tag {
|
||||
return
|
||||
}
|
||||
}
|
||||
yield r.renderTemplates(this.elseTemplates, ctx, emitter)
|
||||
yield r.renderTemplates(this.elseTemplates || [], ctx, emitter)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,3 +8,7 @@ export function assert <T> (predicate: T | null | undefined, message?: string |
|
||||
throw new AssertionError(msg)
|
||||
}
|
||||
}
|
||||
|
||||
export function assertEmpty<T> (predicate: T | null | undefined, message = `unexpected ${JSON.stringify(predicate)}`) {
|
||||
assert(!predicate, message)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user