feat: renderSync, parseAndRenderSync and renderFileSync, see #48

This commit is contained in:
harttle
2019-08-26 10:15:43 -05:00
committed by Jun Yang
parent 8028f82499
commit 7fb01ad69a
66 changed files with 896 additions and 272 deletions
+11 -3
View File
@@ -21,11 +21,19 @@ export class Filter {
this.impl = impl || (x => x)
this.args = args
}
public render (value: any, context: Context) {
public async render (value: any, context: Context) {
const argv: any[] = []
for (const arg of this.args) {
if (isKeyValuePair(arg)) argv.push([arg[0], new Expression(arg[1]).evaluate(context)])
else argv.push(new Expression(arg).evaluate(context))
if (isKeyValuePair(arg)) argv.push([arg[0], await new Expression(arg[1]).evaluate(context)])
else argv.push(await new Expression(arg).evaluate(context))
}
return this.impl.apply({ context }, [value, ...argv])
}
public renderSync (value: any, context: Context) {
const argv: any[] = []
for (const arg of this.args) {
if (isKeyValuePair(arg)) argv.push([arg[0], new Expression(arg[1]).evaluateSync(context)])
else argv.push(new Expression(arg).evaluateSync(context))
}
return this.impl.apply({ context }, [value, ...argv])
}
+4 -1
View File
@@ -10,7 +10,10 @@ export class HTML extends Template<HTMLToken> implements ITemplate {
super(token)
this.str = token.value
}
public render (ctx: Context, emitter: Emitter) {
public renderSync (ctx: Context, emitter: Emitter) {
emitter.write(this.str)
}
public async render (ctx: Context, emitter: Emitter) {
this.renderSync(ctx, emitter)
}
}
+2 -1
View File
@@ -4,5 +4,6 @@ import { Emitter } from '../render/emitter'
export interface ITemplate {
token: Token;
render(ctx: Context, emitter: Emitter): Promise<void> | void;
render(ctx: Context, emitter: Emitter): Promise<any>;
renderSync(ctx: Context, emitter: Emitter): any;
}
+4
View File
@@ -12,6 +12,10 @@ export class Output extends Template<OutputToken> implements ITemplate {
super(token)
this.value = new Value(token.value, strictFilters)
}
public renderSync (ctx: Context, emitter: Emitter) {
const val = this.value.valueSync(ctx)
emitter.write(stringify(toValue(val)))
}
public async render (ctx: Context, emitter: Emitter) {
const val = await this.value.value(ctx)
emitter.write(stringify(toValue(val)))
+16 -2
View File
@@ -10,14 +10,28 @@ import { Context } from '../../context/context'
*/
export class Hash {
[key: string]: any
public static async create (markup: string, ctx: Context) {
private static parse (markup: string) {
const instance = new Hash()
let match
hashCapture.lastIndex = 0
while ((match = hashCapture.exec(markup))) {
const k = match[1]
const v = match[2]
instance[k] = new Expression(v).evaluate(ctx)
instance[k] = v
}
return instance
}
public static createSync (markup: string, ctx: Context) {
const instance = Hash.parse(markup)
for (const key of Object.keys(instance)) {
instance[key] = new Expression(instance[key]).evaluateSync(ctx)
}
return instance
}
public static async create (markup: string, ctx: Context) {
const instance = Hash.parse(markup)
for (const key of Object.keys(instance)) {
instance[key] = await new Expression(instance[key]).evaluate(ctx)
}
return instance
}
+1
View File
@@ -8,4 +8,5 @@ import { Emitter } from '../../render/emitter'
export interface ITagImplOptions {
parse?: (this: ITagImpl, token: TagToken, remainingTokens: Token[]) => void;
render: (this: ITagImpl, ctx: Context, hash: Hash, emitter: Emitter) => void;
renderSync?: (this: ITagImpl, ctx: Context, hash: Hash, emitter: Emitter) => void;
}
+7 -1
View File
@@ -23,10 +23,16 @@ export class Tag extends Template<TagToken> implements ITemplate {
this.impl.parse(token, tokens)
}
}
public renderSync (ctx: Context, emitter: Emitter) {
const hash = Hash.createSync(this.token.args, ctx)
const impl = this.impl
if (isFunction(impl.renderSync)) return impl.renderSync(ctx, hash, emitter)
if (isFunction(impl.render)) return impl.render(ctx, hash, emitter)
}
public async render (ctx: Context, emitter: Emitter) {
const hash = await Hash.create(this.token.args, ctx)
const impl = this.impl
if (isFunction(impl.render)) await impl.render(ctx, hash, emitter)
if (isFunction(impl.render)) return impl.render(ctx, hash, emitter)
}
public static register (name: string, tag: ITagImplOptions) {
Tag.impls[name] = tag
+10 -3
View File
@@ -47,10 +47,17 @@ export class Value {
}
this.filters.push(new Filter(name, args, this.strictFilters))
}
public value (ctx: Context) {
let val = new Expression(this.initial).evaluate(ctx)
public async value (ctx: Context) {
let val = await new Expression(this.initial).evaluate(ctx)
for (const filter of this.filters) {
val = filter.render(val, ctx)
val = await filter.render(val, ctx)
}
return val
}
public valueSync (ctx: Context) {
let val = new Expression(this.initial).evaluateSync(ctx)
for (const filter of this.filters) {
val = filter.renderSync(val, ctx)
}
return val
}