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
+4 -4
View File
@@ -1,8 +1,8 @@
import assert from '../../util/assert'
import { assert } from '../../util/assert'
import { identifier } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import { TagToken } from '../../parser/tag-token'
import { Context } from '../../context/context'
import { ITagImplOptions } from '../../template/tag/itag-impl-options'
const re = new RegExp(`(${identifier.source})\\s*=([^]*)`)
+6 -6
View File
@@ -1,10 +1,10 @@
import BlockMode from '../../context/block-mode'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import ITemplate from '../../template/itemplate'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
import { TagToken } from '../../parser/tag-token'
import { Token } from '../../parser/token'
import { ITemplate } from '../../template/itemplate'
import { Context } from '../../context/context'
import { ITagImplOptions } from '../../template/tag/itag-impl-options'
import { ParseStream } from '../../parser/parse-stream'
export default {
parse: function (token: TagToken, remainTokens: Token[]) {
+3 -6
View File
@@ -1,9 +1,6 @@
import assert from '../../util/assert'
import { assert } from '../../util/assert'
import { identifier } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import { ITemplate, Context, ITagImplOptions, TagToken, Token } from '../../types'
const re = new RegExp(`(${identifier.source})`)
@@ -17,7 +14,7 @@ export default {
const stream = this.liquid.parser.parseStream(remainTokens)
stream.on('tag:endcapture', () => stream.stop())
.on('template', (tpl) => this.templates.push(tpl))
.on('template', (tpl: ITemplate) => this.templates.push(tpl))
.on('end', () => {
throw new Error(`tag ${tagToken.raw} not closed`)
})
+5 -9
View File
@@ -1,10 +1,5 @@
import { Hash, Emitter, TagToken, Token, Context, ITemplate, ITagImplOptions, ParseStream } from '../../types'
import { evalExp } from '../../render/syntax'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Context from '../../context/context'
import ITemplate from '../../template/itemplate'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
export default {
parse: function (tagToken: TagToken, remainTokens: Token[]) {
@@ -30,15 +25,16 @@ export default {
stream.start()
},
render: async function (ctx: Context) {
render: async function (ctx: Context, hash: Hash, emitter: Emitter) {
for (let i = 0; i < this.cases.length; i++) {
const branch = this.cases[i]
const val = await evalExp(branch.val, ctx)
const cond = await evalExp(this.cond, ctx)
if (val === cond) {
return this.liquid.renderer.renderTemplates(branch.templates, ctx)
this.liquid.renderer.renderTemplates(branch.templates, ctx, emitter)
return
}
}
return this.liquid.renderer.renderTemplates(this.elseTemplates, ctx)
this.liquid.renderer.renderTemplates(this.elseTemplates, ctx, emitter)
}
} as ITagImplOptions
+3 -3
View File
@@ -1,6 +1,6 @@
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import { TagToken } from '../../parser/tag-token'
import { Token } from '../../parser/token'
import { ITagImplOptions } from '../../template/tag/itag-impl-options'
export default {
parse: function (tagToken: TagToken, remainTokens: Token[]) {
+4 -4
View File
@@ -1,9 +1,9 @@
import assert from '../../util/assert'
import { assert } from '../../util/assert'
import { value as rValue } from '../../parser/lexical'
import { evalValue } from '../../render/syntax'
import TagToken from '../../parser/tag-token'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import { TagToken } from '../../parser/tag-token'
import { Context } from '../../context/context'
import { ITagImplOptions } from '../../template/tag/itag-impl-options'
const groupRE = new RegExp(`^(?:(${rValue.source})\\s*:\\s*)?(.*)$`)
const candidatesRE = new RegExp(rValue.source, 'g')
+4 -4
View File
@@ -1,8 +1,8 @@
import assert from '../../util/assert'
import { assert } from '../../util/assert'
import { identifier } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import { TagToken } from '../../parser/tag-token'
import { Context } from '../../context/context'
import { ITagImplOptions } from '../../template/tag/itag-impl-options'
import { isNumber } from '../../util/underscore'
export default {
+7 -16
View File
@@ -1,15 +1,10 @@
import { Emitter, TagToken, Token, Context, ITemplate, ITagImplOptions, ParseStream } from '../../types'
import { isString, isObject, isArray } from '../../util/underscore'
import { parseExp } from '../../render/syntax'
import assert from '../../util/assert'
import { assert } from '../../util/assert'
import { identifier, value, hash } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Context from '../../context/context'
import Hash from '../../template/tag/hash'
import ITemplate from '../../template/itemplate'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
import { ForloopDrop } from '../../drop/forloop-drop'
import { Hash } from '../../template/tag/hash'
const re = new RegExp(`^(${identifier.source})\\s+in\\s+` +
`(${value.source})` +
@@ -41,7 +36,7 @@ export default {
stream.start()
},
render: async function (ctx: Context, hash: Hash) {
render: async function (ctx: Context, hash: Hash, emitter: Emitter) {
let collection = await parseExp(this.collection, ctx)
if (!isArray(collection)) {
@@ -63,20 +58,16 @@ export default {
const context = { forloop: new ForloopDrop(collection.length) }
ctx.push(context)
let html = ''
for (const item of collection) {
context[this.variable] = item
try {
html += await this.liquid.renderer.renderTemplates(this.templates, ctx)
await this.liquid.renderer.renderTemplates(this.templates, ctx, emitter)
} catch (e) {
if (e.name === 'RenderBreakError') {
html += e.resolvedHTML
if (e.message === 'break') break
} else throw e
if (e.name !== 'RenderBreakError') throw e
if (e.message === 'break') break
}
context.forloop.next()
}
ctx.pop()
return html
}
} as ITagImplOptions
+5 -10
View File
@@ -1,10 +1,4 @@
import { evalExp, isTruthy } from '../../render/syntax'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Context from '../../context/context'
import ITemplate from '../../template/itemplate'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
import { Hash, Emitter, evalExp, isTruthy, TagToken, Token, Context, ITemplate, ITagImplOptions, ParseStream } from '../../types'
export default {
parse: function (tagToken: TagToken, remainTokens: Token[]) {
@@ -33,13 +27,14 @@ export default {
stream.start()
},
render: async function (ctx: Context) {
render: async function (ctx: Context, hash: Hash, emitter: Emitter) {
for (const branch of this.branches) {
const cond = await evalExp(branch.cond, ctx)
if (isTruthy(cond)) {
return this.liquid.renderer.renderTemplates(branch.templates, ctx)
await this.liquid.renderer.renderTemplates(branch.templates, ctx, emitter)
return
}
}
return this.liquid.renderer.renderTemplates(this.elseTemplates, ctx)
await this.liquid.renderer.renderTemplates(this.elseTemplates, ctx, emitter)
}
} as ITagImplOptions
+4 -8
View File
@@ -1,11 +1,8 @@
import assert from '../../util/assert'
import { assert } from '../../util/assert'
import { Hash, Emitter, TagToken, Context, ITagImplOptions } from '../../types'
import { value, quotedLine } from '../../parser/lexical'
import { evalValue, parseValue } from '../../render/syntax'
import BlockMode from '../../context/block-mode'
import TagToken from '../../parser/tag-token'
import Context from '../../context/context'
import Hash from '../../template/tag/hash'
import ITagImplOptions from '../../template/tag/itag-impl-options'
const staticFileRE = /[^\s,]+/
const withRE = new RegExp(`with\\s+(${value.source})`)
@@ -21,7 +18,7 @@ export default {
match = withRE.exec(token.args)
if (match) this.with = match[1]
},
render: async function (ctx: Context, hash: Hash) {
render: async function (ctx: Context, hash: Hash, emitter: Emitter) {
let filepath
if (ctx.opts.dynamicPartials) {
if (quotedLine.exec(this.value)) {
@@ -45,10 +42,9 @@ export default {
}
const templates = await this.liquid.getTemplate(filepath, ctx.opts)
ctx.push(hash)
const html = await this.liquid.renderer.renderTemplates(templates, ctx)
await this.liquid.renderer.renderTemplates(templates, ctx, emitter)
ctx.pop()
ctx.setRegister('blocks', originBlocks)
ctx.setRegister('blockMode', originBlockMode)
return html
}
} as ITagImplOptions
+2 -2
View File
@@ -1,7 +1,7 @@
import assert from '../../util/assert'
import { assert } from '../../util/assert'
import { identifier } from '../../parser/lexical'
import { isNumber } from '../../util/underscore'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import { ITagImplOptions } from '../../template/tag/itag-impl-options'
export default {
parse: function (token) {
+1 -1
View File
@@ -15,7 +15,7 @@ import tablerow from './tablerow'
import unless from './unless'
import Break from './break'
import Continue from './continue'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import { ITagImplOptions } from '../../template/tag/itag-impl-options'
const tags: { [key: string]: ITagImplOptions } = {
assign, 'for': For, capture, 'case': Case, comment, include, decrement, increment, cycle, 'if': If, layout, block, raw, tablerow, unless, 'break': Break, 'continue': Continue
+3 -6
View File
@@ -1,12 +1,9 @@
import assert from '../../util/assert'
import { assert } from '../../util/assert'
import { value as rValue } from '../../parser/lexical'
import { evalValue } from '../../render/syntax'
import { TagToken, Token, Context, ITagImplOptions } from '../../types'
import BlockMode from '../../context/block-mode'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Context from '../../context/context'
import Hash from '../../template/tag/hash'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import { Hash } from '../../template/tag/hash'
const staticFileRE = /\S+/
+1 -3
View File
@@ -1,6 +1,4 @@
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import { TagToken, Token, ITagImplOptions } from '../../types'
export default {
parse: function (tagToken: TagToken, remainTokens: Token[]) {
+9 -18
View File
@@ -1,13 +1,6 @@
import assert from '../../util/assert'
import { evalExp } from '../../render/syntax'
import { assert } from '../../util/assert'
import { evalExp, Emitter, Hash, TagToken, Token, Context, ITemplate, ITagImplOptions, ParseStream } from '../../types'
import { identifier, value, hash } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import ITemplate from '../../template/itemplate'
import Context from '../../context/context'
import Hash from '../../template/tag/hash'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
import { TablerowloopDrop } from '../../drop/tablerowloop-drop'
const re = new RegExp(`^(${identifier.source})\\s+in\\s+` +
@@ -35,7 +28,7 @@ export default {
stream.start()
},
render: async function (ctx: Context, hash: Hash) {
render: async function (ctx: Context, hash: Hash, emitter: Emitter) {
let collection = await evalExp(this.collection, ctx) || []
const offset = hash.offset || 0
const limit = (hash.limit === undefined) ? collection.length : hash.limit
@@ -47,19 +40,17 @@ export default {
const scope = { tablerowloop }
ctx.push(scope)
let html = ''
for (let idx = 0; idx < collection.length; idx++, tablerowloop.next()) {
scope[this.variable] = collection[idx]
if (tablerowloop.col0() === 0) {
if (tablerowloop.row() !== 1) html += '</tr>'
html += `<tr class="row${tablerowloop.row()}">`
if (tablerowloop.row() !== 1) emitter.write('</tr>')
emitter.write(`<tr class="row${tablerowloop.row()}">`)
}
html += `<td class="col${tablerowloop.col()}">`
html += await this.liquid.renderer.renderTemplates(this.templates, ctx)
html += '</td>'
emitter.write(`<td class="col${tablerowloop.col()}">`)
await this.liquid.renderer.renderTemplates(this.templates, ctx, emitter)
emitter.write('</td>')
}
if (collection.length) html += '</tr>'
if (collection.length) emitter.write('</tr>')
ctx.pop()
return html
}
} as ITagImplOptions
+5 -10
View File
@@ -1,9 +1,4 @@
import { evalExp, isFalsy } from '../../render/syntax'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
import { Emitter, evalExp, isFalsy, ParseStream, Context, ITagImplOptions, Token, Hash , TagToken } from '../../types'
export default {
parse: function (tagToken: TagToken, remainTokens: Token[]) {
@@ -25,10 +20,10 @@ export default {
stream.start()
},
render: async function (ctx: Context) {
render: async function (ctx: Context, hash: Hash, emitter: Emitter) {
const cond = await evalExp(this.cond, ctx)
return isFalsy(cond)
? this.liquid.renderer.renderTemplates(this.templates, ctx)
: this.liquid.renderer.renderTemplates(this.elseTemplates, ctx)
isFalsy(cond)
? await this.liquid.renderer.renderTemplates(this.templates, ctx, emitter)
: await this.liquid.renderer.renderTemplates(this.elseTemplates, ctx, emitter)
}
} as ITagImplOptions