diff --git a/README.md b/README.md index 688503c06..7a3463cc3 100644 --- a/README.md +++ b/README.md @@ -192,9 +192,9 @@ Otherwise, undefined variables will cause an exception. Defaults to `false`. * `trim_tag_left` is similiar to `trim_tag_right`, whereas the `\n` is exclusive. Defaults to `false`. See [Whitespace Control][whitespace control] for details. -* `trim_value_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of values (`{{ }}`) until `\n` (inclusive). Defaults to `false`. +* `trim_output_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of values (`{{ }}`) until `\n` (inclusive). Defaults to `false`. -* `trim_value_left` is similiar to `trim_value_right`, whereas the `\n` is exclusive. Defaults to `false`. See [Whitespace Control][whitespace control] for details. +* `trim_output_left` is similiar to `trim_output_right`, whereas the `\n` is exclusive. Defaults to `false`. See [Whitespace Control][whitespace control] for details. * `greedy` is used to specify whether `trim_left`/`trim_right` is greedy. When set to `true`, all consecutive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`. diff --git a/src/liquid-options.ts b/src/liquid-options.ts index 84d49f900..5088e55a1 100644 --- a/src/liquid-options.ts +++ b/src/liquid-options.ts @@ -1,3 +1,5 @@ +/* eslint-disable camelcase */ + import * as _ from './util/underscore' export interface LiquidOptions { @@ -10,17 +12,17 @@ export interface LiquidOptions { /** `dynamicPartials`: if set, treat `` parameter in `{%include filepath %}`, `{%layout filepath%}` as a variable, otherwise as a literal value. Defaults to `true`. */ dynamicPartials?: boolean /** `strict_filters` is used to enable strict filter existence. If set to `false`, undefined filters will be rendered as empty string. Otherwise, undefined filters will cause an exception. Defaults to `false`. */ - strict_filters?: boolean // eslint-disable-line + strict_filters?: boolean /** `strict_variables` is used to enable strict variable derivation. If set to `false`, undefined variables will be rendered as empty string. Otherwise, undefined variables will cause an exception. Defaults to `false`. */ - strict_variables?: boolean // eslint-disable-line + strict_variables?: boolean /** `trim_tag_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of tags (`{% %}`) until `\n` (inclusive). Defaults to `false`. */ - trim_tag_right?: boolean // eslint-disable-line + trim_tag_right?: boolean /** `trim_tag_left` is similar to `trim_tag_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */ - trim_tag_left?: boolean // eslint-disable-line - /** ``trim_value_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of values (`{{ }}`) until `\n` (inclusive). Defaults to `false`. */ - trim_value_right?: boolean // eslint-disable-line - /** `trim_value_left` is similar to `trim_value_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */ - trim_value_left?: boolean // eslint-disable-line + trim_tag_left?: boolean + /** ``trim_output_right` is used to strip blank characters (including ` `, `\t`, and `\r`) from the right of values (`{{ }}`) until `\n` (inclusive). Defaults to `false`. */ + trim_output_right?: boolean + /** `trim_output_left` is similar to `trim_output_right`, whereas the `\n` is exclusive. Defaults to `false`. See Whitespace Control for details. */ + trim_output_left?: boolean /** `greedy` is used to specify whether `trim_left`/`trim_right` is greedy. When set to `true`, all consecutive blank characters including `\n` will be trimed regardless of line breaks. Defaults to `true`. */ greedy?: boolean } @@ -29,15 +31,29 @@ export interface NormalizedOptions extends LiquidOptions { root?: string[] } -export const defaultOptions: NormalizedOptions = { +export interface NormalizedFullOptions extends NormalizedOptions { + root: string[] + extname: string + cache: boolean + dynamicPartials: boolean + strict_filters: boolean + strict_variables: boolean + trim_tag_right: boolean + trim_tag_left: boolean + trim_output_right: boolean + trim_output_left: boolean + greedy: boolean +} + +const defaultOptions: NormalizedFullOptions = { root: ['.'], cache: false, extname: '', dynamicPartials: true, trim_tag_right: false, trim_tag_left: false, - trim_value_right: false, - trim_value_left: false, + trim_output_right: false, + trim_output_left: false, greedy: true, strict_filters: false, strict_variables: false @@ -51,6 +67,10 @@ export function normalize (options: LiquidOptions): NormalizedOptions { return options as NormalizedOptions } +export function applyDefault (options: NormalizedOptions): NormalizedFullOptions { + return { ...defaultOptions, ...options } +} + function normalizeStringArray (value: string | string[]): string[] { if (_.isArray(value)) return value as string[] if (_.isString(value)) return [value as string] diff --git a/src/liquid.ts b/src/liquid.ts index e296688f0..7b86e6b60 100644 --- a/src/liquid.ts +++ b/src/liquid.ts @@ -13,21 +13,20 @@ import Value from './template/value' import { isTruthy, isFalsy, evalExp, evalValue } from './render/syntax' import builtinTags from './builtin/tags' import builtinFilters from './builtin/filters' -import { LiquidOptions, NormalizedOptions, defaultOptions, normalize } from './liquid-options' +import { LiquidOptions, NormalizedFullOptions, applyDefault, normalize } from './liquid-options' export default class Liquid { - public options: NormalizedOptions + public options: NormalizedFullOptions private cache: object private parser: Parser private renderer: Render private tokenizer: Tokenizer constructor (opts: LiquidOptions = {}) { - const options = { ...defaultOptions, ...normalize(opts) } - if (options.cache) { + this.options = applyDefault(normalize(opts)) + if (this.options.cache) { this.cache = {} } - this.options = options this.parser = new Parser(this) this.renderer = new Render() this.tokenizer = new Tokenizer(this.options) diff --git a/src/parser/tokenizer.ts b/src/parser/tokenizer.ts index bec3b2dbc..f38d1165c 100644 --- a/src/parser/tokenizer.ts +++ b/src/parser/tokenizer.ts @@ -4,14 +4,14 @@ import TagToken from './tag-token' import Token from './token' import OutputToken from './output-token' import { TokenizationError } from 'src/util/error' -import { LiquidOptions, defaultOptions } from 'src/liquid-options' +import { NormalizedFullOptions, applyDefault } from '../liquid-options' enum ParseState { HTML, OUTPUT, TAG } export default class Tokenizer { - options: LiquidOptions - constructor (options: LiquidOptions = defaultOptions) { - this.options = options + options: NormalizedFullOptions + constructor (options?: NormalizedFullOptions) { + this.options = applyDefault(options) } tokenize (input: string, file?: string) { const tokens = [] diff --git a/src/parser/whitespace-ctrl.ts b/src/parser/whitespace-ctrl.ts index 27667b48f..d5612116a 100644 --- a/src/parser/whitespace-ctrl.ts +++ b/src/parser/whitespace-ctrl.ts @@ -24,13 +24,13 @@ export default function whiteSpaceCtrl (tokens: Token[], options: LiquidOptions) function shouldTrimLeft (token: DelimitedToken, inRaw: boolean, options) { if (inRaw) return false if (token.type === 'tag') return token.trimLeft || options.trim_tag_left - if (token.type === 'output') return token.trimLeft || options.trim_value_left + if (token.type === 'output') return token.trimLeft || options.trim_output_left } function shouldTrimRight (token: DelimitedToken, inRaw: boolean, options) { if (inRaw) return false if (token.type === 'tag') return token.trimRight || options.trim_tag_right - if (token.type === 'output') return token.trimRight || options.trim_value_right + if (token.type === 'output') return token.trimRight || options.trim_output_right } function trimLeft (token: Token, greedy: boolean) { diff --git a/src/scope/scope.ts b/src/scope/scope.ts index f7f72ea50..f003bd474 100644 --- a/src/scope/scope.ts +++ b/src/scope/scope.ts @@ -1,16 +1,16 @@ import * as _ from '../util/underscore' import * as lexical from '../parser/lexical' import assert from '../util/assert' -import { NormalizedOptions, defaultOptions } from '../liquid-options' +import { NormalizedFullOptions, applyDefault } from '../liquid-options' import BlockMode from './block-mode' export default class Scope { - opts: NormalizedOptions + opts: NormalizedFullOptions contexts: Array blocks: object = {} blockMode: BlockMode = BlockMode.OUTPUT - constructor (ctx: object = {}, opts: NormalizedOptions = defaultOptions) { - this.opts = { ...defaultOptions, ...opts } + constructor (ctx: object = {}, opts?: NormalizedFullOptions) { + this.opts = applyDefault(opts) this.contexts = [ctx || {}] } getAll () { diff --git a/test/unit/liquid/trimming.ts b/test/unit/liquid/trimming.ts index 55e6d5043..331d0c40f 100644 --- a/test/unit/liquid/trimming.ts +++ b/test/unit/liquid/trimming.ts @@ -22,18 +22,18 @@ describe('LiquidOptions#trimming', function () { }) }) describe('value trimming', function () { - it('should respect trim_value_left', async function () { - const engine = new Liquid({ trim_value_left: true }) + it('should respect trim_output_left', async function () { + const engine = new Liquid({ trim_output_left: true }) const html = await engine.parseAndRender(' \n \t{{name}} ', ctx) return expect(html).to.equal('harttle ') }) - it('should respect trim_value_right', async function () { - const engine = new Liquid({ trim_value_right: true }) + it('should respect trim_output_right', async function () { + const engine = new Liquid({ trim_output_right: true }) const html = await engine.parseAndRender(' \n \t{{name}} ', ctx) return expect(html).to.equal(' \n \tharttle') }) it('should respect not trim tag', async function () { - const engine = new Liquid({ trim_value_left: true, trim_value_right: true }) + const engine = new Liquid({ trim_output_left: true, trim_output_right: true }) const html = await engine.parseAndRender('\t{% if true %} aha {%endif%}\t') return expect(html).to.equal('\t aha \t') }) diff --git a/test/unit/scope/scope.ts b/test/unit/scope/scope.ts index 5390891e7..0a7c7ec9f 100644 --- a/test/unit/scope/scope.ts +++ b/test/unit/scope/scope.ts @@ -173,7 +173,7 @@ describe('scope', function () { beforeEach(function () { scope = new Scope(ctx, { strict_variables: true - }) + } as any) }) it('should throw when variable not defined', function () { function fn () {