fix(sfc): treat custom block content as raw text
This commit is contained in:
parent
90ddb7c260
commit
d6275a3c31
@ -10,7 +10,11 @@ export interface ParserOptions {
|
|||||||
isCustomElement?: (tag: string) => boolean
|
isCustomElement?: (tag: string) => boolean
|
||||||
isBuiltInComponent?: (tag: string) => symbol | void
|
isBuiltInComponent?: (tag: string) => symbol | void
|
||||||
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,
|
||||||
|
parent: ElementNode | undefined
|
||||||
|
) => TextModes
|
||||||
delimiters?: [string, string] // ['{{', '}}']
|
delimiters?: [string, string] // ['{{', '}}']
|
||||||
|
|
||||||
// Map to HTML entities. E.g., `{ "amp;": "&" }`
|
// Map to HTML entities. E.g., `{ "amp;": "&" }`
|
||||||
|
@ -365,7 +365,7 @@ function parseElement(
|
|||||||
|
|
||||||
// Children.
|
// Children.
|
||||||
ancestors.push(element)
|
ancestors.push(element)
|
||||||
const mode = context.options.getTextMode(element.tag, element.ns)
|
const mode = context.options.getTextMode(element.tag, element.ns, parent)
|
||||||
const children = parseChildren(context, mode, ancestors)
|
const children = parseChildren(context, mode, ancestors)
|
||||||
ancestors.pop()
|
ancestors.pop()
|
||||||
|
|
||||||
|
@ -78,8 +78,8 @@ h1 { color: red }
|
|||||||
<template v-if="ok">ok</template>
|
<template v-if="ok">ok</template>
|
||||||
<div><div></div></div>
|
<div><div></div></div>
|
||||||
`
|
`
|
||||||
const sfc = parse(`<template>${content}</template>`).descriptor
|
const { descriptor } = parse(`<template>${content}</template>`)
|
||||||
expect(sfc.template!.content).toBe(content)
|
expect(descriptor.template!.content).toBe(content)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('error tolerance', () => {
|
test('error tolerance', () => {
|
||||||
@ -102,6 +102,12 @@ h1 { color: red }
|
|||||||
expect(errors.length).toBe(1)
|
expect(errors.length).toBe(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('treat custom blocks as raw text', () => {
|
||||||
|
const { errors, descriptor } = parse(`<foo> <-& </foo>`)
|
||||||
|
expect(errors.length).toBe(0)
|
||||||
|
expect(descriptor.customBlocks[0].content).toBe(` <-& `)
|
||||||
|
})
|
||||||
|
|
||||||
describe('warnings', () => {
|
describe('warnings', () => {
|
||||||
test('should only allow single template element', () => {
|
test('should only allow single template element', () => {
|
||||||
parse(`<template><div/></template><template><div/></template>`)
|
parse(`<template><div/></template><template><div/></template>`)
|
||||||
|
@ -2,7 +2,8 @@ import {
|
|||||||
NodeTypes,
|
NodeTypes,
|
||||||
ElementNode,
|
ElementNode,
|
||||||
SourceLocation,
|
SourceLocation,
|
||||||
CompilerError
|
CompilerError,
|
||||||
|
TextModes
|
||||||
} from '@vue/compiler-core'
|
} from '@vue/compiler-core'
|
||||||
import { RawSourceMap, SourceMapGenerator } from 'source-map'
|
import { RawSourceMap, SourceMapGenerator } from 'source-map'
|
||||||
import LRUCache from 'lru-cache'
|
import LRUCache from 'lru-cache'
|
||||||
@ -89,6 +90,15 @@ export function parse(
|
|||||||
isNativeTag: () => true,
|
isNativeTag: () => true,
|
||||||
// preserve all whitespaces
|
// preserve all whitespaces
|
||||||
isPreTag: () => true,
|
isPreTag: () => true,
|
||||||
|
getTextMode: (tag, _ns, parent) => {
|
||||||
|
// all top level elements except <template> are parsed as raw text
|
||||||
|
// containers
|
||||||
|
if (!parent && tag !== 'template') {
|
||||||
|
return TextModes.RAWTEXT
|
||||||
|
} else {
|
||||||
|
return TextModes.DATA
|
||||||
|
}
|
||||||
|
},
|
||||||
onError: e => {
|
onError: e => {
|
||||||
errors.push(e)
|
errors.push(e)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user