mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-15 04:10:40 -07:00
fix: allow string literals contain delimiters, fixes #288
This commit is contained in:
+16
-5
@@ -126,11 +126,10 @@ export class Tokenizer {
|
|||||||
return new HTMLToken(this.input, begin, this.p, this.file)
|
return new HTMLToken(this.input, begin, this.p, this.file)
|
||||||
}
|
}
|
||||||
|
|
||||||
readTagToken (options: NormalizedFullOptions): TagToken {
|
readTagToken (options: NormalizedFullOptions = defaultOptions): TagToken {
|
||||||
const { file, input } = this
|
const { file, input } = this
|
||||||
const { tagDelimiterRight } = options
|
|
||||||
const begin = this.p
|
const begin = this.p
|
||||||
if (this.readTo(tagDelimiterRight) === -1) {
|
if (this.readToDelimiter(options.tagDelimiterRight) === -1) {
|
||||||
throw this.mkError(`tag ${this.snapshot(begin)} not closed`, begin)
|
throw this.mkError(`tag ${this.snapshot(begin)} not closed`, begin)
|
||||||
}
|
}
|
||||||
const token = new TagToken(input, begin, this.p, options, file)
|
const token = new TagToken(input, begin, this.p, options, file)
|
||||||
@@ -138,11 +137,23 @@ export class Tokenizer {
|
|||||||
return token
|
return token
|
||||||
}
|
}
|
||||||
|
|
||||||
readOutputToken (options: NormalizedFullOptions): OutputToken {
|
readToDelimiter (delimiter: string) {
|
||||||
|
while (this.p < this.N) {
|
||||||
|
if ((this.peekType() & QUOTE)) {
|
||||||
|
this.readQuoted()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
++this.p
|
||||||
|
if (this.rmatch(delimiter)) return this.p
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
readOutputToken (options: NormalizedFullOptions = defaultOptions): OutputToken {
|
||||||
const { file, input } = this
|
const { file, input } = this
|
||||||
const { outputDelimiterRight } = options
|
const { outputDelimiterRight } = options
|
||||||
const begin = this.p
|
const begin = this.p
|
||||||
if (this.readTo(outputDelimiterRight) === -1) {
|
if (this.readToDelimiter(outputDelimiterRight) === -1) {
|
||||||
throw this.mkError(`output ${this.snapshot(begin)} not closed`, begin)
|
throw this.mkError(`output ${this.snapshot(begin)} not closed`, begin)
|
||||||
}
|
}
|
||||||
return new OutputToken(input, begin, this.p, options, file)
|
return new OutputToken(input, begin, this.p, options, file)
|
||||||
|
|||||||
+6
-1
@@ -56,7 +56,7 @@ describe('Issues', function () {
|
|||||||
})
|
})
|
||||||
it('#277 Passing liquid in FilterImpl', () => {
|
it('#277 Passing liquid in FilterImpl', () => {
|
||||||
const engine = new Liquid()
|
const engine = new Liquid()
|
||||||
engine.registerFilter('render', function (template: string, name: string) {
|
engine.registerFilter('render', function (this: any, template: string, name: string) {
|
||||||
return this.liquid.parseAndRenderSync(decodeURIComponent(template), { name })
|
return this.liquid.parseAndRenderSync(decodeURIComponent(template), { name })
|
||||||
})
|
})
|
||||||
const html = engine.parseAndRenderSync(
|
const html = engine.parseAndRenderSync(
|
||||||
@@ -65,4 +65,9 @@ describe('Issues', function () {
|
|||||||
)
|
)
|
||||||
expect(html).to.equal('hello foo')
|
expect(html).to.equal('hello foo')
|
||||||
})
|
})
|
||||||
|
it('#288 Unexpected behavior when string literals contain }}', async () => {
|
||||||
|
const engine = new Liquid()
|
||||||
|
const html = await engine.parseAndRender(`{{ '{{' }}{{ '}}' }}`)
|
||||||
|
expect(html).to.equal('{{}}')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { QuotedToken } from '../../../src/tokens/quoted-token'
|
|||||||
import { OutputToken } from '../../../src/tokens/output-token'
|
import { OutputToken } from '../../../src/tokens/output-token'
|
||||||
import { HTMLToken } from '../../../src/tokens/html-token'
|
import { HTMLToken } from '../../../src/tokens/html-token'
|
||||||
|
|
||||||
describe('Tokenize', function () {
|
describe('Tokenizer', function () {
|
||||||
it('should read quoted', () => {
|
it('should read quoted', () => {
|
||||||
expect(new Tokenizer('"foo" ff').readQuoted()!.getText()).to.equal('"foo"')
|
expect(new Tokenizer('"foo" ff').readQuoted()!.getText()).to.equal('"foo"')
|
||||||
expect(new Tokenizer(' "foo"ff').readQuoted()!.getText()).to.equal('"foo"')
|
expect(new Tokenizer(' "foo"ff').readQuoted()!.getText()).to.equal('"foo"')
|
||||||
@@ -84,6 +84,7 @@ describe('Tokenize', function () {
|
|||||||
expect(rols.name.content).to.equal('rows')
|
expect(rols.name.content).to.equal('rows')
|
||||||
expect(rols.value!.getText()).to.equal('data["rows"]')
|
expect(rols.value!.getText()).to.equal('data["rows"]')
|
||||||
})
|
})
|
||||||
|
describe('#readTopLevelTokens()', () => {
|
||||||
it('should read HTML token', function () {
|
it('should read HTML token', function () {
|
||||||
const html = '<html><body><p>Lorem Ipsum</p></body></html>'
|
const html = '<html><body><p>Lorem Ipsum</p></body></html>'
|
||||||
const tokenizer = new Tokenizer(html)
|
const tokenizer = new Tokenizer(html)
|
||||||
@@ -204,6 +205,29 @@ describe('Tokenize', function () {
|
|||||||
const tokenizer = new Tokenizer('{{name}')
|
const tokenizer = new Tokenizer('{{name}')
|
||||||
expect(() => tokenizer.readTopLevelTokens()).to.throw(/output "{{name}" not closed/)
|
expect(() => tokenizer.readTopLevelTokens()).to.throw(/output "{{name}" not closed/)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
describe('#readTagToken()', () => {
|
||||||
|
it('should skip quoted delimiters', function () {
|
||||||
|
const html = '{% assign a = "%} {% }} {{" %}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const token = tokenizer.readTagToken()
|
||||||
|
|
||||||
|
expect(token).instanceOf(TagToken)
|
||||||
|
expect(token.name).to.equal('assign')
|
||||||
|
expect(token.args).to.equal('a = "%} {% }} {{"')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
describe('#readOutputToken()', () => {
|
||||||
|
it('should skip quoted delimiters', function () {
|
||||||
|
const html = '{{ "%} {%" | append: "}} {{" }}'
|
||||||
|
const tokenizer = new Tokenizer(html)
|
||||||
|
const token = tokenizer.readOutputToken()
|
||||||
|
|
||||||
|
console.log(token)
|
||||||
|
expect(token).instanceOf(OutputToken)
|
||||||
|
expect(token.content).to.equal('"%} {%" | append: "}} {{"')
|
||||||
|
})
|
||||||
|
})
|
||||||
describe('#readRange()', () => {
|
describe('#readRange()', () => {
|
||||||
it('should read `(1..3)`', () => {
|
it('should read `(1..3)`', () => {
|
||||||
const range = new Tokenizer('(1..3)').readRange()
|
const range = new Tokenizer('(1..3)').readRange()
|
||||||
|
|||||||
Reference in New Issue
Block a user