From: Evan You Date: Mon, 26 Apr 2021 14:49:21 +0000 (-0400) Subject: refactor(compiler): improve whitespace: 'preserve' behavior from #1600 X-Git-Tag: v3.1.0-beta.1~59^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b047a0864cb053c415476fc31202d263b6f2f51f;p=thirdparty%2Fvuejs%2Fcore.git refactor(compiler): improve whitespace: 'preserve' behavior from #1600 - discard leading/ending whitespace inside an element - condense preserved whitesapce into single space --- diff --git a/packages/compiler-core/__tests__/parse.spec.ts b/packages/compiler-core/__tests__/parse.spec.ts index e0608fde46..1c7c878539 100644 --- a/packages/compiler-core/__tests__/parse.spec.ts +++ b/packages/compiler-core/__tests__/parse.spec.ts @@ -1837,9 +1837,9 @@ foo ...options }) - it('should preserve whitespaces at start/end inside an element', () => { + it('should still remove whitespaces at start/end inside an element', () => { const ast = parse(`
`) - expect((ast.children[0] as ElementNode).children.length).toBe(3) + expect((ast.children[0] as ElementNode).children.length).toBe(1) }) it('should preserve whitespaces w/ newline between elements', () => { @@ -1884,7 +1884,7 @@ foo expect(ast.children[0].type).toBe(NodeTypes.INTERPOLATION) expect(ast.children[1]).toMatchObject({ type: NodeTypes.TEXT, - content: ' \n ' + content: ' ' }) expect(ast.children[2].type).toBe(NodeTypes.INTERPOLATION) }) diff --git a/packages/compiler-core/src/parse.ts b/packages/compiler-core/src/parse.ts index cb5f618311..784d85fb45 100644 --- a/packages/compiler-core/src/parse.ts +++ b/packages/compiler-core/src/parse.ts @@ -38,6 +38,7 @@ import { } from './compat/compatConfig' type OptionalOptions = + | 'whitespace' | 'isNativeTag' | 'isBuiltInComponent' | keyof CompilerCompatOptions @@ -65,7 +66,6 @@ const decodeMap: Record = { export const defaultParserOptions: MergedParserOptions = { delimiters: [`{{`, `}}`], - whitespace: 'condense', getNamespace: () => Namespaces.HTML, getTextMode: () => TextModes.DATA, isVoidTag: NO, @@ -222,35 +222,37 @@ function parseChildren( // Whitespace handling strategy like v2 let removedWhitespace = false - if (context.options.whitespace === 'condense' && mode !== TextModes.RAWTEXT && mode !== TextModes.RCDATA) { + if (mode !== TextModes.RAWTEXT && mode !== TextModes.RCDATA) { + const preserve = context.options.whitespace === 'preserve' for (let i = 0; i < nodes.length; i++) { const node = nodes[i] if (!context.inPre && node.type === NodeTypes.TEXT) { if (!/[^\t\r\n\f ]/.test(node.content)) { const prev = nodes[i - 1] const next = nodes[i + 1] - // If: + // Remove if: // - the whitespace is the first or last node, or: - // - the whitespace is adjacent to a comment, or: - // - the whitespace is between two elements AND contains newline - // Then the whitespace is ignored. + // - (condense mode) the whitespace is adjacent to a comment, or: + // - (condense mode) the whitespace is between two elements AND contains newline if ( !prev || !next || - prev.type === NodeTypes.COMMENT || - next.type === NodeTypes.COMMENT || - (prev.type === NodeTypes.ELEMENT && - next.type === NodeTypes.ELEMENT && - /[\r\n]/.test(node.content)) + (!preserve && + (prev.type === NodeTypes.COMMENT || + next.type === NodeTypes.COMMENT || + (prev.type === NodeTypes.ELEMENT && + next.type === NodeTypes.ELEMENT && + /[\r\n]/.test(node.content)))) ) { removedWhitespace = true nodes[i] = null as any } else { - // Otherwise, condensed consecutive whitespace inside the text - // down to a single space + // Otherwise, the whitespace is condensed into a single space node.content = ' ' } - } else { + } else if (!preserve) { + // in condense mode, consecutive whitespaces in text are condensed + // down to a single space. node.content = node.content.replace(/[\t\r\n\f ]+/g, ' ') } }