feat(context): null-prototype scope frames via createScope (#899)

- Add createScope() building Object.create(null) with optional own props

- Initialize context stack bottom with createScope() for assign/capture

- Push null-proto scopes from for, tablerow, block, layout, include (incl. Jekyll)

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Yang Jun
2026-05-16 02:20:03 +08:00
committed by GitHub
co-authored by Cursor
parent c20c0af02d
commit 47d3f1b1cf
7 changed files with 21 additions and 13 deletions
+2 -2
View File
@@ -2,7 +2,7 @@ import { getPerformance } from '../util/performance'
import { Drop } from '../drop/drop'
import { __assign } from 'tslib'
import { NormalizedFullOptions, defaultOptions, RenderOptions } from '../liquid-options'
import { Scope } from './scope'
import { createScope, Scope } from './scope'
import { hasOwnProperty, isArray, isNil, isUndefined, isString, isFunction, toLiquid, InternalUndefinedVariableError, toValueSync, isObject, Limiter, toValue } from '../util'
type PropertyKey = string | number;
@@ -12,7 +12,7 @@ export class Context {
* insert a Context-level empty scope,
* for tags like `{% capture %}` `{% assign %}` to operate
*/
private scopes: Scope[] = [{}]
private scopes: Scope[] = [createScope()]
private registers = {}
/**
* user passed in scope
+7 -1
View File
@@ -1,7 +1,13 @@
import { Drop } from '../drop/drop'
interface ScopeObject extends Record<string | number | symbol, any> {
export interface ScopeObject extends Record<string | number | symbol, any> {
toLiquid?: () => any;
}
export type Scope = ScopeObject | Drop
export function createScope (from?: ScopeObject): ScopeObject {
const scope = Object.create(null)
if (from) Object.assign(scope, from)
return scope
}