refactor: add emitter for code generation

This commit is contained in:
harttle
2019-08-26 10:15:43 -05:00
committed by Jun Yang
parent ad8e2f7e63
commit 854e12ba53
4 changed files with 31 additions and 12 deletions
+7
View File
@@ -0,0 +1,7 @@
export class Emitter {
public html: string = '';
public write (html: string) {
this.html += html
}
}
+5 -4
View File
@@ -2,23 +2,24 @@ import { RenderError } from '../util/error'
import assert from '../util/assert' import assert from '../util/assert'
import Context from '../context/context' import Context from '../context/context'
import ITemplate from '../template/itemplate' import ITemplate from '../template/itemplate'
import { Emitter } from './emitter'
export default class Render { export default class Render {
public async renderTemplates (templates: ITemplate[], ctx: Context) { public async renderTemplates (templates: ITemplate[], ctx: Context) {
assert(ctx, 'unable to evalTemplates: context undefined') assert(ctx, 'unable to evalTemplates: context undefined')
let html = '' const emitter = new Emitter()
for (const tpl of templates) { for (const tpl of templates) {
try { try {
html += await tpl.render(ctx) emitter.write(await tpl.render(ctx, emitter))
} catch (e) { } catch (e) {
if (e.name === 'RenderBreakError') { if (e.name === 'RenderBreakError') {
e.resolvedHTML = html e.resolvedHTML = emitter.html
throw e throw e
} }
throw e.name === 'RenderError' ? e : new RenderError(e, tpl) throw e.name === 'RenderError' ? e : new RenderError(e, tpl)
} }
} }
return html return emitter.html
} }
} }
+2 -1
View File
@@ -1,7 +1,8 @@
import Context from '../context/context' import Context from '../context/context'
import Token from '../parser/token' import Token from '../parser/token'
import { Emitter } from '../render/emitter'
export default interface ITemplate { export default interface ITemplate {
token: Token; token: Token;
render(ctx: Context): Promise<string>; render(ctx: Context, emitter: Emitter): Promise<string>;
} }
+17 -7
View File
@@ -113,13 +113,23 @@ describe('tags/for', function () {
const html = await liquid.parseAndRender(src, ctx) const html = await liquid.parseAndRender(src, ctx)
return expect(html).to.equal('12345') return expect(html).to.equal('12345')
}) })
it('should support for with break', async function () { describe('break', function () {
const src = '{% for i in (one..5) %}' + it('should support break', async function () {
'{% if i == 4 %}{% break %}{% endif %}' + const src = '{% for i in (one..5) %}' +
'{{ i }}' + '{% if i == 4 %}{% break %}{% endif %}' +
'{% endfor %}' '{{ i }}' +
const html = await liquid.parseAndRender(src, ctx) '{% endfor %}'
return expect(html).to.equal('123') const html = await liquid.parseAndRender(src, ctx)
return expect(html).to.equal('123')
})
it('should output contents before break', async function () {
const src = '{% for i in (1..5) %}' +
'{% if i == 4 %}breaking{% break %}{% endif %}' +
'{{ i }}' +
'{% endfor %}'
const html = await liquid.parseAndRender(src, ctx)
return expect(html).to.equal('123breaking')
})
}) })
describe('limit', function () { describe('limit', function () {