refactor: switch Context <-> Scope concepts

This commit is contained in:
harttle
2019-03-25 10:36:23 +08:00
parent 76345a64c3
commit 45e3c2bb8e
34 changed files with 272 additions and 272 deletions
+3 -3
View File
@@ -1,7 +1,7 @@
import assert from '../../util/assert'
import { identifier } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
const re = new RegExp(`(${identifier.source})\\s*=([^]*)`)
@@ -13,7 +13,7 @@ export default {
this.key = match[1]
this.value = match[2]
},
render: async function (scope: Scope) {
scope.contexts[0][this.key] = await this.liquid.evalValue(this.value, scope)
render: async function (ctx: Context) {
ctx.scopes[0][this.key] = await this.liquid.evalValue(this.value, ctx)
}
} as ITagImplOptions
+7 -7
View File
@@ -1,8 +1,8 @@
import BlockMode from '../../scope/block-mode'
import BlockMode from '../../context/block-mode'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import ITemplate from '../../template/itemplate'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
@@ -19,14 +19,14 @@ export default {
})
stream.start()
},
render: async function (scope: Scope) {
const childDefined = scope.blocks[this.block]
render: async function (ctx: Context) {
const childDefined = ctx.blocks[this.block]
const html = childDefined !== undefined
? childDefined
: await this.liquid.renderer.renderTemplates(this.tpls, scope)
: await this.liquid.renderer.renderTemplates(this.tpls, ctx)
if (scope.blockMode === BlockMode.STORE) {
scope.blocks[this.block] = html
if (ctx.blockMode === BlockMode.STORE) {
ctx.blocks[this.block] = html
return ''
}
return html
+4 -4
View File
@@ -2,7 +2,7 @@ import assert from '../../util/assert'
import { identifier } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
const re = new RegExp(`(${identifier.source})`)
@@ -23,8 +23,8 @@ export default {
})
stream.start()
},
render: async function (scope: Scope) {
const html = await this.liquid.renderer.renderTemplates(this.templates, scope)
scope.contexts[0][this.variable] = html
render: async function (ctx: Context) {
const html = await this.liquid.renderer.renderTemplates(this.templates, ctx)
ctx.scopes[0][this.variable] = html
}
} as ITagImplOptions
+6 -6
View File
@@ -1,7 +1,7 @@
import { evalExp } from '../../render/syntax'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import ITemplate from '../../template/itemplate'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
@@ -30,15 +30,15 @@ export default {
stream.start()
},
render: async function (scope: Scope) {
render: async function (ctx: Context) {
for (let i = 0; i < this.cases.length; i++) {
const branch = this.cases[i]
const val = await evalExp(branch.val, scope)
const cond = await evalExp(this.cond, scope)
const val = await evalExp(branch.val, ctx)
const cond = await evalExp(this.cond, ctx)
if (val === cond) {
return this.liquid.renderer.renderTemplates(branch.templates, scope)
return this.liquid.renderer.renderTemplates(branch.templates, ctx)
}
}
return this.liquid.renderer.renderTemplates(this.elseTemplates, scope)
return this.liquid.renderer.renderTemplates(this.elseTemplates, ctx)
}
} as ITagImplOptions
+5 -5
View File
@@ -2,7 +2,7 @@ import assert from '../../util/assert'
import { value as rValue } from '../../parser/lexical'
import { evalValue } from '../../render/syntax'
import TagToken from '../../parser/tag-token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
const groupRE = new RegExp(`^(?:(${rValue.source})\\s*:\\s*)?(.*)$`)
@@ -24,10 +24,10 @@ export default <ITagImplOptions>{
assert(this.candidates.length, `empty candidates: ${tagToken.raw}`)
},
render: async function (scope: Scope) {
const group = await evalValue(this.group, scope)
render: async function (ctx: Context) {
const group = await evalValue(this.group, ctx)
const fingerprint = `cycle:${group}:` + this.candidates.join(',')
const groups = scope.groups
const groups = ctx.groups
let idx = groups[fingerprint]
if (idx === undefined) {
@@ -38,6 +38,6 @@ export default <ITagImplOptions>{
idx = (idx + 1) % this.candidates.length
groups[fingerprint] = idx
return evalValue(candidate, scope)
return evalValue(candidate, ctx)
}
}
+2 -2
View File
@@ -1,7 +1,7 @@
import assert from '../../util/assert'
import { identifier } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
export default {
@@ -10,7 +10,7 @@ export default {
assert(match, `illegal identifier ${token.args}`)
this.variable = match[0]
},
render: function (context: Scope) {
render: function (context: Context) {
const scope = context.environments
if (typeof scope[this.variable] !== 'number') {
scope[this.variable] = 0
+7 -7
View File
@@ -4,7 +4,7 @@ import assert from '../../util/assert'
import { identifier, value, hash } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import Hash from '../../template/tag/hash'
import ITemplate from '../../template/itemplate'
import ITagImplOptions from '../../template/tag/itag-impl-options'
@@ -41,8 +41,8 @@ export default <ITagImplOptions>{
stream.start()
},
render: async function (scope: Scope, hash: Hash) {
let collection = await evalExp(this.collection, scope)
render: async function (ctx: Context, hash: Hash) {
let collection = await evalExp(this.collection, ctx)
if (!isArray(collection)) {
if (isString(collection) && collection.length > 0) {
@@ -52,7 +52,7 @@ export default <ITagImplOptions>{
}
}
if (!isArray(collection) || !collection.length) {
return this.liquid.renderer.renderTemplates(this.elseTemplates, scope)
return this.liquid.renderer.renderTemplates(this.elseTemplates, ctx)
}
const offset = hash.offset || 0
@@ -62,12 +62,12 @@ export default <ITagImplOptions>{
if (this.reversed) collection.reverse()
const context = { forloop: new ForloopDrop(collection.length) }
scope.push(context)
ctx.push(context)
let html = ''
for (const item of collection) {
context[this.variable] = item
try {
html += await this.liquid.renderer.renderTemplates(this.templates, scope)
html += await this.liquid.renderer.renderTemplates(this.templates, ctx)
} catch (e) {
if (e.name === 'RenderBreakError') {
html += e.resolvedHTML
@@ -76,7 +76,7 @@ export default <ITagImplOptions>{
}
context.forloop.next()
}
scope.pop()
ctx.pop()
return html
}
}
+5 -5
View File
@@ -1,7 +1,7 @@
import { evalExp, isTruthy } from '../../render/syntax'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import ITemplate from '../../template/itemplate'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
@@ -33,13 +33,13 @@ export default {
stream.start()
},
render: async function (scope: Scope) {
render: async function (ctx: Context) {
for (const branch of this.branches) {
const cond = await evalExp(branch.cond, scope)
const cond = await evalExp(branch.cond, ctx)
if (isTruthy(cond)) {
return this.liquid.renderer.renderTemplates(branch.templates, scope)
return this.liquid.renderer.renderTemplates(branch.templates, ctx)
}
}
return this.liquid.renderer.renderTemplates(this.elseTemplates, scope)
return this.liquid.renderer.renderTemplates(this.elseTemplates, ctx)
}
} as ITagImplOptions
+17 -17
View File
@@ -1,9 +1,9 @@
import assert from '../../util/assert'
import { value, quotedLine } from '../../parser/lexical'
import { evalValue } from '../../render/syntax'
import BlockMode from '../../scope/block-mode'
import BlockMode from '../../context/block-mode'
import TagToken from '../../parser/tag-token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import Hash from '../../template/tag/hash'
import ITagImplOptions from '../../template/tag/itag-impl-options'
@@ -27,34 +27,34 @@ export default <ITagImplOptions>{
this.with = match[1]
}
},
render: async function (scope: Scope, hash: Hash) {
render: async function (ctx: Context, hash: Hash) {
let filepath
if (scope.opts.dynamicPartials) {
if (ctx.opts.dynamicPartials) {
if (quotedLine.exec(this.value)) {
const template = this.value.slice(1, -1)
filepath = await this.liquid.parseAndRender(template, scope.getAll(), scope.opts)
filepath = await this.liquid.parseAndRender(template, ctx.getAll(), ctx.opts)
} else {
filepath = await evalValue(this.value, scope)
filepath = await evalValue(this.value, ctx)
}
} else {
filepath = this.staticValue
}
assert(filepath, `cannot include with empty filename`)
const originBlocks = scope.blocks
const originBlockMode = scope.blockMode
const originBlocks = ctx.blocks
const originBlockMode = ctx.blockMode
scope.blocks = {}
scope.blockMode = BlockMode.OUTPUT
ctx.blocks = {}
ctx.blockMode = BlockMode.OUTPUT
if (this.with) {
hash[filepath] = await evalValue(this.with, scope)
hash[filepath] = await evalValue(this.with, ctx)
}
const templates = await this.liquid.getTemplate(filepath, scope.opts)
scope.push(hash)
const html = await this.liquid.renderer.renderTemplates(templates, scope)
scope.pop(hash)
scope.blocks = originBlocks
scope.blockMode = originBlockMode
const templates = await this.liquid.getTemplate(filepath, ctx.opts)
ctx.push(hash)
const html = await this.liquid.renderer.renderTemplates(templates, ctx)
ctx.pop(hash)
ctx.blocks = originBlocks
ctx.blockMode = originBlockMode
return html
}
}
+14 -14
View File
@@ -1,10 +1,10 @@
import assert from '../../util/assert'
import { value as rValue } from '../../parser/lexical'
import { evalValue } from '../../render/syntax'
import BlockMode from '../../scope/block-mode'
import BlockMode from '../../context/block-mode'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import Hash from '../../template/tag/hash'
import ITagImplOptions from '../../template/tag/itag-impl-options'
@@ -24,23 +24,23 @@ export default {
this.tpls = this.liquid.parser.parse(remainTokens)
},
render: async function (scope: Scope, hash: Hash) {
const layout = scope.opts.dynamicPartials
? await evalValue(this.layout, scope)
render: async function (ctx: Context, hash: Hash) {
const layout = ctx.opts.dynamicPartials
? await evalValue(this.layout, ctx)
: this.staticLayout
assert(layout, `cannot apply layout with empty filename`)
// render the remaining tokens immediately
scope.blockMode = BlockMode.STORE
const html = await this.liquid.renderer.renderTemplates(this.tpls, scope)
if (scope.blocks[''] === undefined) {
scope.blocks[''] = html
ctx.blockMode = BlockMode.STORE
const html = await this.liquid.renderer.renderTemplates(this.tpls, ctx)
if (ctx.blocks[''] === undefined) {
ctx.blocks[''] = html
}
const templates = await this.liquid.getTemplate(layout, scope.opts)
scope.push(hash)
scope.blockMode = BlockMode.OUTPUT
const partial = await this.liquid.renderer.renderTemplates(templates, scope)
scope.pop(hash)
const templates = await this.liquid.getTemplate(layout, ctx.opts)
ctx.push(hash)
ctx.blockMode = BlockMode.OUTPUT
const partial = await this.liquid.renderer.renderTemplates(templates, ctx)
ctx.pop(hash)
return partial
}
} as ITagImplOptions
+8 -8
View File
@@ -4,7 +4,7 @@ import { identifier, value, hash } from '../../parser/lexical'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import ITemplate from '../../template/itemplate'
import Scope from '../../scope/scope'
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'
@@ -35,8 +35,8 @@ export default {
stream.start()
},
render: async function (scope: Scope, hash: Hash) {
let collection = await evalExp(this.collection, scope) || []
render: async function (ctx: Context, hash: Hash) {
let collection = await evalExp(this.collection, ctx) || []
const offset = hash.offset || 0
const limit = (hash.limit === undefined) ? collection.length : hash.limit
@@ -44,22 +44,22 @@ export default {
const cols = hash.cols || collection.length
const tablerowloop = new TablerowloopDrop(collection.length, cols)
const ctx = { tablerowloop }
scope.push(ctx)
const scope = { tablerowloop }
ctx.push(scope)
let html = ''
for (let idx = 0; idx < collection.length; idx++, tablerowloop.next()) {
ctx[this.variable] = collection[idx]
scope[this.variable] = collection[idx]
if (tablerowloop.col0() === 0) {
if (tablerowloop.row() !== 1) html += '</tr>'
html += `<tr class="row${tablerowloop.row()}">`
}
html += `<td class="col${tablerowloop.col()}">`
html += await this.liquid.renderer.renderTemplates(this.templates, scope)
html += await this.liquid.renderer.renderTemplates(this.templates, ctx)
html += '</td>'
}
if (collection.length) html += '</tr>'
scope.pop(ctx)
ctx.pop(scope)
return html
}
} as ITagImplOptions
+5 -5
View File
@@ -1,7 +1,7 @@
import { evalExp, isFalsy } from '../../render/syntax'
import TagToken from '../../parser/tag-token'
import Token from '../../parser/token'
import Scope from '../../scope/scope'
import Context from '../../context/context'
import ITagImplOptions from '../../template/tag/itag-impl-options'
import ParseStream from '../../parser/parse-stream'
@@ -25,10 +25,10 @@ export default {
stream.start()
},
render: async function (scope: Scope) {
const cond = await evalExp(this.cond, scope)
render: async function (ctx: Context) {
const cond = await evalExp(this.cond, ctx)
return isFalsy(cond)
? this.liquid.renderer.renderTemplates(this.templates, scope)
: this.liquid.renderer.renderTemplates(this.elseTemplates, scope)
? this.liquid.renderer.renderTemplates(this.templates, ctx)
: this.liquid.renderer.renderTemplates(this.elseTemplates, ctx)
}
} as ITagImplOptions