mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-19 06:20:38 -07:00
fix: filters break when argument contains [()|, fixes #89
This commit is contained in:
@@ -12,29 +12,13 @@ export default class Filter {
|
||||
args: string[]
|
||||
private static impls: {[key: string]: FilterImpl} = {}
|
||||
|
||||
constructor (str: string, strictFilters: boolean = false) {
|
||||
const match = lexical.filterLine.exec(str) as string[]
|
||||
assert(match, 'illegal filter: ' + str)
|
||||
|
||||
const name = match[1]
|
||||
const argList = match[2] || ''
|
||||
constructor (name: string, args: string[], strictFilters: boolean) {
|
||||
const impl = Filter.impls[name]
|
||||
if (!impl && strictFilters) throw new TypeError(`undefined filter: ${name}`)
|
||||
|
||||
this.name = name
|
||||
this.impl = impl || (x => x)
|
||||
this.args = this.parseArgs(argList)
|
||||
}
|
||||
parseArgs (argList: string): string[] {
|
||||
let match; const args: string[] = []
|
||||
while ((match = valueRE.exec(argList.trim()))) {
|
||||
const v = match[0]
|
||||
const re = new RegExp(`${v}\\s*:`, 'g')
|
||||
const keyMatch = re.exec(match.input)
|
||||
const currentMatchIsKey = keyMatch && keyMatch.index === match.index
|
||||
currentMatchIsKey ? args.push(`'${v}'`) : args.push(v)
|
||||
}
|
||||
return args
|
||||
this.args = args
|
||||
}
|
||||
render (value: any, scope: Scope): any {
|
||||
const args = this.args.map(arg => evalValue(arg, scope))
|
||||
|
||||
@@ -7,7 +7,7 @@ import OutputToken from 'src/parser/output-token'
|
||||
|
||||
export default class Output extends Template<OutputToken> implements ITemplate {
|
||||
value: Value
|
||||
constructor (token: OutputToken, strictFilters?: boolean) {
|
||||
constructor (token: OutputToken, strictFilters: boolean) {
|
||||
super(token)
|
||||
this.value = new Value(token.value, strictFilters)
|
||||
}
|
||||
|
||||
+71
-8
@@ -1,21 +1,84 @@
|
||||
import { evalExp } from 'src/render/syntax'
|
||||
import * as lexical from 'src/parser/lexical'
|
||||
import assert from 'src/util/assert'
|
||||
import Filter from './filter/filter'
|
||||
import Scope from 'src/scope/scope'
|
||||
|
||||
|
||||
enum ParseState {
|
||||
INIT = 0,
|
||||
FILTER_NAME = 1,
|
||||
FILTER_ARG = 2
|
||||
}
|
||||
|
||||
export default class {
|
||||
initial: any
|
||||
filters: Array<Filter> = []
|
||||
constructor (str: string, strictFilters?: boolean) {
|
||||
let match: RegExpExecArray | null = lexical.matchValue(str) as RegExpExecArray
|
||||
assert(match, `illegal value string: ${str}`)
|
||||
|
||||
this.initial = match[0]
|
||||
str = str.substr(match.index + match[0].length)
|
||||
/**
|
||||
* @param str value string, like: "i have a dream | truncate: 3
|
||||
*/
|
||||
constructor (str: string, strictFilters: boolean) {
|
||||
const N = str.length
|
||||
let buffer = ''
|
||||
let quoted = ''
|
||||
let state = ParseState.INIT
|
||||
let sealed = false
|
||||
|
||||
while ((match = lexical.filter.exec(str))) {
|
||||
this.filters.push(new Filter(match[0].trim(), strictFilters))
|
||||
let filterName = ''
|
||||
let filterArgs: string[] = []
|
||||
|
||||
for(let i = 0; i < str.length; i++) {
|
||||
if (quoted) {
|
||||
if (str[i] == quoted) {
|
||||
quoted = ''
|
||||
sealed = true
|
||||
}
|
||||
buffer += str[i]
|
||||
}
|
||||
else if (/\s/.test(str[i])) {
|
||||
if (!buffer) continue
|
||||
else sealed = true
|
||||
}
|
||||
else if (str[i] === '|') {
|
||||
if (state === ParseState.INIT) {
|
||||
this.initial = buffer
|
||||
}
|
||||
else {
|
||||
if (state === ParseState.FILTER_NAME) filterName = buffer
|
||||
else filterArgs.push(buffer)
|
||||
this.filters.push(new Filter(filterName, filterArgs, strictFilters))
|
||||
filterName = ''
|
||||
filterArgs = []
|
||||
}
|
||||
state = ParseState.FILTER_NAME
|
||||
buffer = ''
|
||||
sealed = false
|
||||
}
|
||||
else if (state === ParseState.FILTER_NAME && str[i] === ':') {
|
||||
filterName = buffer
|
||||
state = ParseState.FILTER_ARG
|
||||
buffer = ''
|
||||
sealed = false
|
||||
}
|
||||
else if (state === ParseState.FILTER_ARG && str[i] === ',') {
|
||||
filterArgs.push(buffer)
|
||||
buffer = ''
|
||||
sealed = false
|
||||
}
|
||||
else if (sealed) continue
|
||||
else {
|
||||
if ((str[i] === '"' || str[i] === "'") && !quoted) quoted = str[i]
|
||||
buffer += str[i]
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
if (state === ParseState.INIT) this.initial = buffer
|
||||
else if (state === ParseState.FILTER_NAME) this.filters.push(new Filter(buffer, [], strictFilters))
|
||||
else {
|
||||
filterArgs.push(buffer)
|
||||
this.filters.push(new Filter(filterName, filterArgs, strictFilters))
|
||||
}
|
||||
}
|
||||
}
|
||||
value (scope: Scope) {
|
||||
|
||||
Reference in New Issue
Block a user