Skip to content

Commit d6275a3

Browse files
committed
fix(sfc): treat custom block content as raw text
1 parent 90ddb7c commit d6275a3

File tree

4 files changed

+25
-5
lines changed

4 files changed

+25
-5
lines changed

packages/compiler-core/src/options.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ export interface ParserOptions {
1010
isCustomElement?: (tag: string) => boolean
1111
isBuiltInComponent?: (tag: string) => symbol | void
1212
getNamespace?: (tag: string, parent: ElementNode | undefined) => Namespace
13-
getTextMode?: (tag: string, ns: Namespace) => TextModes
13+
getTextMode?: (
14+
tag: string,
15+
ns: Namespace,
16+
parent: ElementNode | undefined
17+
) => TextModes
1418
delimiters?: [string, string] // ['{{', '}}']
1519

1620
// Map to HTML entities. E.g., `{ "amp;": "&" }`

packages/compiler-core/src/parse.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ function parseElement(
365365

366366
// Children.
367367
ancestors.push(element)
368-
const mode = context.options.getTextMode(element.tag, element.ns)
368+
const mode = context.options.getTextMode(element.tag, element.ns, parent)
369369
const children = parseChildren(context, mode, ancestors)
370370
ancestors.pop()
371371

packages/compiler-sfc/__tests__/parse.spec.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ h1 { color: red }
7878
<template v-if="ok">ok</template>
7979
<div><div></div></div>
8080
`
81-
const sfc = parse(`<template>${content}</template>`).descriptor
82-
expect(sfc.template!.content).toBe(content)
81+
const { descriptor } = parse(`<template>${content}</template>`)
82+
expect(descriptor.template!.content).toBe(content)
8383
})
8484

8585
test('error tolerance', () => {
@@ -102,6 +102,12 @@ h1 { color: red }
102102
expect(errors.length).toBe(1)
103103
})
104104

105+
test('treat custom blocks as raw text', () => {
106+
const { errors, descriptor } = parse(`<foo> <-& </foo>`)
107+
expect(errors.length).toBe(0)
108+
expect(descriptor.customBlocks[0].content).toBe(` <-& `)
109+
})
110+
105111
describe('warnings', () => {
106112
test('should only allow single template element', () => {
107113
parse(`<template><div/></template><template><div/></template>`)

packages/compiler-sfc/src/parse.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import {
22
NodeTypes,
33
ElementNode,
44
SourceLocation,
5-
CompilerError
5+
CompilerError,
6+
TextModes
67
} from '@vue/compiler-core'
78
import { RawSourceMap, SourceMapGenerator } from 'source-map'
89
import LRUCache from 'lru-cache'
@@ -89,6 +90,15 @@ export function parse(
8990
isNativeTag: () => true,
9091
// preserve all whitespaces
9192
isPreTag: () => true,
93+
getTextMode: (tag, _ns, parent) => {
94+
// all top level elements except <template> are parsed as raw text
95+
// containers
96+
if (!parent && tag !== 'template') {
97+
return TextModes.RAWTEXT
98+
} else {
99+
return TextModes.DATA
100+
}
101+
},
92102
onError: e => {
93103
errors.push(e)
94104
}

0 commit comments

Comments
 (0)