fix: break/continue omitting output before them, #123

BREAKING CHANGE: remove default export, now should be used like import
{Liquid} from 'liquidjs'
This commit is contained in:
harttle
2019-08-26 10:15:43 -05:00
committed by Jun Yang
parent 854e12ba53
commit ae45c4622e
99 changed files with 373 additions and 407 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
import Context from '../../context/context'
import { Context } from '../../context/context'
export interface FilterImpl {
context: Context;
+4 -4
View File
@@ -1,5 +1,5 @@
import { parseValue } from '../../render/syntax'
import Context from '../../context/context'
import { Context } from '../../context/context'
import { isArray } from '../../util/underscore'
import { FilterImplOptions } from './filter-impl-options'
@@ -21,11 +21,11 @@ export class Filter {
this.impl = impl || (x => x)
this.args = args
}
public async render (value: any, context: Context) {
public render (value: any, context: Context) {
const argv: any[] = []
for (const arg of this.args) {
if (isKeyValuePair(arg)) argv.push([arg[0], await parseValue(arg[1], context)])
else argv.push(await parseValue(arg, context))
if (isKeyValuePair(arg)) argv.push([arg[0], parseValue(arg[1], context)])
else argv.push(parseValue(arg, context))
}
return this.impl.apply({ context }, [value, ...argv])
}
+8 -6
View File
@@ -1,14 +1,16 @@
import Template from '../template/template'
import ITemplate from '../template/itemplate'
import HTMLToken from '../parser/html-token'
import { Template } from '../template/template'
import { ITemplate } from '../template/itemplate'
import { HTMLToken } from '../parser/html-token'
import { Context } from '../context/context'
import { Emitter } from '../render/emitter'
export default class extends Template<HTMLToken> implements ITemplate {
export class HTML extends Template<HTMLToken> implements ITemplate {
private str: string
public constructor (token: HTMLToken) {
super(token)
this.str = token.value
}
public async render (): Promise<string> {
return this.str
public render (ctx: Context, emitter: Emitter) {
emitter.write(this.str)
}
}
+4 -4
View File
@@ -1,8 +1,8 @@
import Context from '../context/context'
import Token from '../parser/token'
import { Context } from '../context/context'
import { Token } from '../parser/token'
import { Emitter } from '../render/emitter'
export default interface ITemplate {
export interface ITemplate {
token: Token;
render(ctx: Context, emitter: Emitter): Promise<string>;
render(ctx: Context, emitter: Emitter): Promise<void> | void;
}
+9 -8
View File
@@ -1,18 +1,19 @@
import Value from './value'
import { Value } from './value'
import { stringify, toValue } from '../util/underscore'
import Template from '../template/template'
import ITemplate from '../template/itemplate'
import Context from '../context/context'
import OutputToken from '../parser/output-token'
import { Template } from '../template/template'
import { ITemplate } from '../template/itemplate'
import { Context } from '../context/context'
import { Emitter } from '../render/emitter'
import { OutputToken } from '../parser/output-token'
export default class Output extends Template<OutputToken> implements ITemplate {
export class Output extends Template<OutputToken> implements ITemplate {
private value: Value
public constructor (token: OutputToken, strictFilters: boolean) {
super(token)
this.value = new Value(token.value, strictFilters)
}
public async render (ctx: Context): Promise<string> {
public async render (ctx: Context, emitter: Emitter) {
const val = await this.value.value(ctx)
return stringify(toValue(val))
emitter.write(stringify(toValue(val)))
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
import { hashCapture } from '../../parser/lexical'
import { parseValue } from '../../render/syntax'
import Context from '../../context/context'
import { Context } from '../../context/context'
/**
* Key-Value Pairs Representing Tag Arguments
@@ -8,7 +8,7 @@ import Context from '../../context/context'
* For the markup `{% include 'head.html' foo='bar' %}`,
* hash['foo'] === 'bar'
*/
export default class Hash {
export class Hash {
[key: string]: any
public static async create (markup: string, ctx: Context) {
const instance = new Hash()
+8 -7
View File
@@ -1,10 +1,11 @@
import Context from '../../context/context'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Hash from '../../template/tag/hash'
import ITagImpl from './itag-impl'
import { Context } from '../../context/context'
import { TagToken } from '../../parser/tag-token'
import { Token } from '../../parser/token'
import { ITagImpl } from './itag-impl'
import { Hash } from '../../template/tag/hash'
import { Emitter } from '../../render/emitter'
export default interface ITagImplOptions {
export interface ITagImplOptions {
parse?: (this: ITagImpl, token: TagToken, remainingTokens: Token[]) => void;
render?: (this: ITagImpl, ctx: Context, hash: Hash) => any | Promise<any>;
render: (this: ITagImpl, ctx: Context, hash: Hash, emitter: Emitter) => void;
}
+3 -3
View File
@@ -1,7 +1,7 @@
import Liquid from '../../liquid'
import ITagImplOptions from './itag-impl-options'
import { Liquid } from '../../liquid'
import { ITagImplOptions } from './itag-impl-options'
export default interface ITagImpl extends ITagImplOptions {
export interface ITagImpl extends ITagImplOptions {
liquid: Liquid;
[key: string]: any;
}
+9 -13
View File
@@ -1,16 +1,11 @@
import { stringify, isFunction } from '../../util/underscore'
import assert from '../../util/assert'
import Context from '../../context/context'
import ITagImpl from './itag-impl'
import ITagImplOptions from './itag-impl-options'
import Liquid from '../../liquid'
import Hash from './hash'
import Template from '../../template/template'
import ITemplate from '../../template/itemplate'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import { assert } from '../../util/assert'
import { Liquid } from '../../liquid'
import { Template } from '../../template/template'
import { Emitter, Hash, Context, ITagImplOptions, TagToken, ITemplate, Token } from '../../types'
import { ITagImpl } from './itag-impl'
export default class Tag extends Template<TagToken> implements ITemplate {
export class Tag extends Template<TagToken> implements ITemplate {
public name: string
private impl: ITagImpl
private static impls: { [key: string]: ITagImplOptions } = {}
@@ -28,10 +23,11 @@ export default class Tag extends Template<TagToken> implements ITemplate {
this.impl.parse(token, tokens)
}
}
public async render (ctx: Context) {
public async render (ctx: Context, emitter: Emitter) {
const hash = await Hash.create(this.token.args, ctx)
const impl = this.impl
return isFunction(impl.render) ? stringify(await impl.render(ctx, hash)) : ''
const html = isFunction(impl.render) ? stringify(await impl.render(ctx, hash, emitter)) : ''
html && emitter.write(html)
}
public static register (name: string, tag: ITagImplOptions) {
Tag.impls[name] = tag
+1 -1
View File
@@ -1,4 +1,4 @@
export default abstract class Template<T> {
export abstract class Template<T> {
public token: T;
public constructor (token: T) {
this.token = token
+5 -5
View File
@@ -1,8 +1,8 @@
import { parseExp } from '../render/syntax'
import { FilterArgs, Filter } from './filter/filter'
import Context from '../context/context'
import { Context } from '../context/context'
export default class Value {
export class Value {
private strictFilters: boolean
private initial: string
private filters: Filter[] = []
@@ -47,10 +47,10 @@ export default class Value {
}
this.filters.push(new Filter(name, args, this.strictFilters))
}
public async value (ctx: Context) {
let val = await parseExp(this.initial, ctx)
public value (ctx: Context) {
let val = parseExp(this.initial, ctx)
for (const filter of this.filters) {
val = await filter.render(val, ctx)
val = filter.render(val, ctx)
}
return val
}