feat(compiler): preserve whitespace in pre tag, add tests
This commit is contained in:
parent
9298f46f92
commit
eb20730a67
@ -1600,6 +1600,55 @@ foo
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('whitespace management', () => {
|
||||||
|
it('should remove whitespaces at start/end inside an element', () => {
|
||||||
|
const ast = parse(`<div> <span/> </div>`)
|
||||||
|
expect((ast.children[0] as ElementNode).children.length).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should remove whitespaces w/ newline between elements', () => {
|
||||||
|
const ast = parse(`<div/> \n <div/> \n <div/>`)
|
||||||
|
expect(ast.children.length).toBe(3)
|
||||||
|
expect(ast.children.every(c => c.type === NodeTypes.ELEMENT)).toBe(true)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should remove whitespaces w/ newline between comments and elements', () => {
|
||||||
|
const ast = parse(`<div/> \n <!--foo--> \n <div/>`)
|
||||||
|
expect(ast.children.length).toBe(3)
|
||||||
|
expect(ast.children[0].type).toBe(NodeTypes.ELEMENT)
|
||||||
|
expect(ast.children[1].type).toBe(NodeTypes.COMMENT)
|
||||||
|
expect(ast.children[2].type).toBe(NodeTypes.ELEMENT)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should NOT remove whitespaces w/ newline between interpolations', () => {
|
||||||
|
const ast = parse(`{{ foo }} \n {{ bar }}`)
|
||||||
|
expect(ast.children.length).toBe(3)
|
||||||
|
expect(ast.children[0].type).toBe(NodeTypes.INTERPOLATION)
|
||||||
|
expect(ast.children[1]).toMatchObject({
|
||||||
|
type: NodeTypes.TEXT,
|
||||||
|
content: ' '
|
||||||
|
})
|
||||||
|
expect(ast.children[2].type).toBe(NodeTypes.INTERPOLATION)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should NOT remove whitespaces w/o newline between elements', () => {
|
||||||
|
const ast = parse(`<div/> <div/> <div/>`)
|
||||||
|
expect(ast.children.length).toBe(5)
|
||||||
|
expect(ast.children.map(c => c.type)).toMatchObject([
|
||||||
|
NodeTypes.ELEMENT,
|
||||||
|
NodeTypes.TEXT,
|
||||||
|
NodeTypes.ELEMENT,
|
||||||
|
NodeTypes.TEXT,
|
||||||
|
NodeTypes.ELEMENT
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should condense consecutive whitespaces in text', () => {
|
||||||
|
const ast = parse(` foo \n bar baz `)
|
||||||
|
expect((ast.children[0] as TextNode).content).toBe(` foo bar baz `)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('Errors', () => {
|
describe('Errors', () => {
|
||||||
const patterns: {
|
const patterns: {
|
||||||
[key: string]: Array<{
|
[key: string]: Array<{
|
||||||
|
@ -32,6 +32,7 @@ import { extend } from '@vue/shared'
|
|||||||
export interface ParserOptions {
|
export interface ParserOptions {
|
||||||
isVoidTag?: (tag: string) => boolean // e.g. img, br, hr
|
isVoidTag?: (tag: string) => boolean // e.g. img, br, hr
|
||||||
isNativeTag?: (tag: string) => boolean // e.g. loading-indicator in weex
|
isNativeTag?: (tag: string) => boolean // e.g. loading-indicator in weex
|
||||||
|
isPreTag?: (tag: string) => boolean // e.g. <pre> where whitespace is intact
|
||||||
isCustomElement?: (tag: string) => boolean
|
isCustomElement?: (tag: string) => boolean
|
||||||
getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace
|
getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace
|
||||||
getTextMode?: (tag: string, ns: Namespace) => TextModes
|
getTextMode?: (tag: string, ns: Namespace) => TextModes
|
||||||
@ -53,6 +54,7 @@ export const defaultParserOptions: MergedParserOptions = {
|
|||||||
getNamespace: () => Namespaces.HTML,
|
getNamespace: () => Namespaces.HTML,
|
||||||
getTextMode: () => TextModes.DATA,
|
getTextMode: () => TextModes.DATA,
|
||||||
isVoidTag: NO,
|
isVoidTag: NO,
|
||||||
|
isPreTag: NO,
|
||||||
isCustomElement: NO,
|
isCustomElement: NO,
|
||||||
namedCharacterReferences: {
|
namedCharacterReferences: {
|
||||||
'gt;': '>',
|
'gt;': '>',
|
||||||
@ -207,6 +209,7 @@ function parseChildren(
|
|||||||
// Whitespace management for more efficient output
|
// Whitespace management for more efficient output
|
||||||
// (same as v2 whitespance: 'condense')
|
// (same as v2 whitespance: 'condense')
|
||||||
let removedWhitespace = false
|
let removedWhitespace = false
|
||||||
|
if (!parent || !context.options.isPreTag(parent.tag)) {
|
||||||
for (let i = 0; i < nodes.length; i++) {
|
for (let i = 0; i < nodes.length; i++) {
|
||||||
const node = nodes[i]
|
const node = nodes[i]
|
||||||
if (node.type === NodeTypes.TEXT) {
|
if (node.type === NodeTypes.TEXT) {
|
||||||
@ -238,6 +241,7 @@ function parseChildren(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return removedWhitespace ? nodes.filter(node => node !== null) : nodes
|
return removedWhitespace ? nodes.filter(node => node !== null) : nodes
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,15 @@ describe('DOM parser', () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('<pre> tag should preserve raw whitespace', () => {
|
||||||
|
const rawText = ` \na b \n c`
|
||||||
|
const ast = parse(`<pre>${rawText}</pre>`, parserOptions)
|
||||||
|
expect((ast.children[0] as ElementNode).children[0]).toMatchObject({
|
||||||
|
type: NodeTypes.TEXT,
|
||||||
|
content: rawText
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('Interpolation', () => {
|
describe('Interpolation', () => {
|
||||||
|
@ -15,8 +15,8 @@ export const enum DOMNamespaces {
|
|||||||
|
|
||||||
export const parserOptionsMinimal: ParserOptions = {
|
export const parserOptionsMinimal: ParserOptions = {
|
||||||
isVoidTag,
|
isVoidTag,
|
||||||
|
|
||||||
isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
|
isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
|
||||||
|
isPreTag: tag => tag === 'pre',
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
|
// https://html.spec.whatwg.org/multipage/parsing.html#tree-construction-dispatcher
|
||||||
getNamespace(tag: string, parent: ElementNode | undefined): DOMNamespaces {
|
getNamespace(tag: string, parent: ElementNode | undefined): DOMNamespaces {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user