mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 04:10:40 -07:00
fix: incorrect scope when using assign with for, fixes #115
* remove AssignScope, CaptureScope, IncrementScope, DecrementScope concepts * introduce Scope.environments for decrement/increment * assign to scopes[0] for assign/capture
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import assert from '../../util/assert'
|
||||
import { identifier } from '../../parser/lexical'
|
||||
import { AssignScope } from '../../scope/scopes'
|
||||
import TagToken from '../../parser/tag-token'
|
||||
import Scope from '../../scope/scope'
|
||||
import ITagImplOptions from '../../template/tag/itag-impl-options'
|
||||
@@ -15,8 +14,6 @@ export default {
|
||||
this.value = match[2]
|
||||
},
|
||||
render: async function (scope: Scope) {
|
||||
const ctx = new AssignScope()
|
||||
ctx[this.key] = await this.liquid.evalValue(this.value, scope)
|
||||
scope.push(ctx)
|
||||
scope.contexts[0][this.key] = await this.liquid.evalValue(this.value, scope)
|
||||
}
|
||||
} as ITagImplOptions
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import assert from '../../util/assert'
|
||||
import { identifier } from '../../parser/lexical'
|
||||
import { CaptureScope } from '../../scope/scopes'
|
||||
import TagToken from '../../parser/tag-token'
|
||||
import Token from '../../parser/token'
|
||||
import Scope from '../../scope/scope'
|
||||
@@ -26,8 +25,6 @@ export default {
|
||||
},
|
||||
render: async function (scope: Scope) {
|
||||
const html = await this.liquid.renderer.renderTemplates(this.templates, scope)
|
||||
const ctx = new CaptureScope()
|
||||
ctx[this.variable] = html
|
||||
scope.push(ctx)
|
||||
scope.contexts[0][this.variable] = html
|
||||
}
|
||||
} as ITagImplOptions
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import assert from '../../util/assert'
|
||||
import { identifier } from '../../parser/lexical'
|
||||
import { CaptureScope, AssignScope, DecrementScope } from '../../scope/scopes'
|
||||
import TagToken from '../../parser/tag-token'
|
||||
import Scope from '../../scope/scope'
|
||||
import ITagImplOptions from '../../template/tag/itag-impl-options'
|
||||
@@ -11,20 +10,11 @@ export default {
|
||||
assert(match, `illegal identifier ${token.args}`)
|
||||
this.variable = match[0]
|
||||
},
|
||||
render: function (scope: Scope) {
|
||||
let context = scope.findContextFor(
|
||||
this.variable,
|
||||
ctx => {
|
||||
return !(ctx instanceof CaptureScope) && !(ctx instanceof AssignScope)
|
||||
}
|
||||
)
|
||||
if (!context) {
|
||||
context = new DecrementScope()
|
||||
scope.unshift(context)
|
||||
render: function (context: Scope) {
|
||||
const scope = context.environments
|
||||
if (typeof scope[this.variable] !== 'number') {
|
||||
scope[this.variable] = 0
|
||||
}
|
||||
if (typeof context[this.variable] !== 'number') {
|
||||
context[this.variable] = 0
|
||||
}
|
||||
return --context[this.variable]
|
||||
return --scope[this.variable]
|
||||
}
|
||||
} as ITagImplOptions
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import assert from '../../util/assert'
|
||||
import { identifier } from '../../parser/lexical'
|
||||
import { CaptureScope, AssignScope, IncrementScope } from '../../scope/scopes'
|
||||
import ITagImplOptions from '../../template/tag/itag-impl-options'
|
||||
|
||||
export default {
|
||||
@@ -9,22 +8,13 @@ export default {
|
||||
assert(match, `illegal identifier ${token.args}`)
|
||||
this.variable = match![0]
|
||||
},
|
||||
render: function (scope) {
|
||||
let context = scope.findContextFor(
|
||||
this.variable,
|
||||
ctx => {
|
||||
return !(ctx instanceof CaptureScope) && !(ctx instanceof AssignScope)
|
||||
}
|
||||
)
|
||||
if (!context) {
|
||||
context = new IncrementScope()
|
||||
scope.unshift(context)
|
||||
render: function (context) {
|
||||
const scope = context.environments
|
||||
if (typeof scope[this.variable] !== 'number') {
|
||||
scope[this.variable] = 0
|
||||
}
|
||||
if (typeof context[this.variable] !== 'number') {
|
||||
context[this.variable] = 0
|
||||
}
|
||||
const val = context[this.variable]
|
||||
context[this.variable]++
|
||||
const val = scope[this.variable]
|
||||
scope[this.variable]++
|
||||
return val
|
||||
}
|
||||
} as ITagImplOptions
|
||||
|
||||
+7
-27
@@ -8,20 +8,22 @@ import { Context } from './context'
|
||||
|
||||
export default class Scope {
|
||||
opts: NormalizedFullOptions
|
||||
contexts: Array<Context>
|
||||
contexts: Array<Context> = [{}]
|
||||
environments: Context
|
||||
blocks: object = {}
|
||||
groups: {[key: string]: number} = {}
|
||||
blockMode: BlockMode = BlockMode.OUTPUT
|
||||
constructor (ctx: object = {}, opts?: NormalizedFullOptions) {
|
||||
this.opts = applyDefault(opts)
|
||||
this.contexts = [ctx || {}]
|
||||
this.environments = ctx
|
||||
}
|
||||
getAll () {
|
||||
return this.contexts.reduce((ctx, val) => __assign(ctx, val), {})
|
||||
return [this.environments, ...this.contexts]
|
||||
.reduce((ctx, val) => __assign(ctx, val), {})
|
||||
}
|
||||
async get (path: string) {
|
||||
const paths = await this.propertyAccessSeq(path)
|
||||
let ctx = this.findContextFor(paths[0]) || _.last(this.contexts)
|
||||
let ctx = this.findContextFor(paths[0]) || this.environments
|
||||
for (const path of paths) {
|
||||
ctx = this.readProperty(ctx, path)
|
||||
if (_.isNil(ctx) && this.opts.strictVariables) {
|
||||
@@ -30,27 +32,6 @@ export default class Scope {
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
async set (path: string, v: any) {
|
||||
const paths = await this.propertyAccessSeq(path)
|
||||
let scope = this.findContextFor(paths[0]) || _.last(this.contexts)
|
||||
paths.some((key, i) => {
|
||||
if (!_.isObject(scope)) {
|
||||
return true
|
||||
}
|
||||
if (i === paths.length - 1) {
|
||||
scope[key] = v
|
||||
return true
|
||||
}
|
||||
if (undefined === scope[key]) {
|
||||
scope[key] = {}
|
||||
}
|
||||
scope = scope[key]
|
||||
return false
|
||||
})
|
||||
}
|
||||
unshift (ctx: object) {
|
||||
return this.contexts.unshift(ctx)
|
||||
}
|
||||
push (ctx: object) {
|
||||
return this.contexts.push(ctx)
|
||||
}
|
||||
@@ -64,10 +45,9 @@ export default class Scope {
|
||||
}
|
||||
return this.contexts.splice(i, 1)[0]
|
||||
}
|
||||
findContextFor (key: string, filter: ((conttext: object) => boolean) = () => true) {
|
||||
findContextFor (key: string) {
|
||||
for (let i = this.contexts.length - 1; i >= 0; i--) {
|
||||
const candidate = this.contexts[i]
|
||||
if (!filter(candidate)) continue
|
||||
if (key in candidate) {
|
||||
return candidate
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
export class CaptureScope {}
|
||||
export class AssignScope {}
|
||||
export class IncrementScope {}
|
||||
export class DecrementScope {}
|
||||
@@ -1,3 +1,2 @@
|
||||
export { AssignScope, CaptureScope, IncrementScope, DecrementScope } from './scope/scopes'
|
||||
export { ParseError, TokenizationError, RenderBreakError, AssertionError } from './util/error'
|
||||
export { Drop } from './drop/drop'
|
||||
|
||||
Reference in New Issue
Block a user