BREAKING CHANGE: trim_value_* -> trim_output_*

This commit is contained in:
harttle
2019-02-21 01:07:32 +08:00
parent d7d00421e2
commit 3dbab238ae
8 changed files with 53 additions and 34 deletions
+2 -2
View File
@@ -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`.
+31 -11
View File
@@ -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 `<filepath>` 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]
+4 -5
View File
@@ -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)
+4 -4
View File
@@ -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 = []
+2 -2
View File
@@ -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) {
+4 -4
View File
@@ -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<object>
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 () {
+5 -5
View File
@@ -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')
})
+1 -1
View File
@@ -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 () {