feat: implement error handling for v-html (#30)

This commit is contained in:
Rizumu Ayaka 2023-12-02 15:59:09 +08:00 committed by GitHub
parent 89cefda3ad
commit 886d16f458
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 54 additions and 4 deletions

View File

@ -30,7 +30,21 @@ export function render(_ctx) {
}"
`;
exports[`compile > directives > v-html > no expression 1`] = `
exports[`compile > directives > v-html > should raise error and ignore children when v-html is present 1`] = `
"import { template as _template, children as _children, effect as _effect, setHtml as _setHtml } from 'vue/vapor';
export function render(_ctx) {
const t0 = _template(\\"<div></div>\\")
const n0 = t0()
const { 0: [n1],} = _children(n0)
_effect(() => {
_setHtml(n1, undefined, test)
})
return n0
}"
`;
exports[`compile > directives > v-html > should raise error if has no expression 1`] = `
"import { template as _template, children as _children, setHtml as _setHtml } from 'vue/vapor';
export function render(_ctx) {

View File

@ -1,4 +1,9 @@
import { type RootNode, BindingTypes, ErrorCodes } from '@vue/compiler-dom'
import {
type RootNode,
BindingTypes,
ErrorCodes,
DOMErrorCodes,
} from '@vue/compiler-dom'
import { type CompilerOptions, compile as _compile } from '../src'
function compile(template: string | RootNode, options: CompilerOptions = {}) {
@ -133,9 +138,26 @@ describe('compile', () => {
expect(code).matchSnapshot()
})
test('no expression', async () => {
const code = await compile(`<div v-html></div>`)
test('should raise error and ignore children when v-html is present', async () => {
const onError = vi.fn()
const code = await compile(`<div v-html="test">hello</div>`, {
onError,
})
expect(code).matchSnapshot()
expect(onError.mock.calls).toMatchObject([
[{ code: DOMErrorCodes.X_V_HTML_WITH_CHILDREN }],
])
})
test('should raise error if has no expression', async () => {
const onError = vi.fn()
const code = await compile(`<div v-html></div>`, {
onError,
})
expect(code).matchSnapshot()
expect(onError.mock.calls).toMatchObject([
[{ code: DOMErrorCodes.X_V_HTML_NO_EXPRESSION }],
])
})
})

View File

@ -14,6 +14,8 @@ import {
defaultOnWarn,
ErrorCodes,
createCompilerError,
DOMErrorCodes,
createDOMCompilerError,
} from '@vue/compiler-dom'
import { EMPTY_OBJ, NOOP, isArray, isVoidTag } from '@vue/shared'
import {
@ -508,6 +510,18 @@ function transformProp(
break
}
case 'html': {
if (!exp) {
ctx.options.onError(
createDOMCompilerError(DOMErrorCodes.X_V_HTML_NO_EXPRESSION, loc),
)
}
if (ctx.node.children.length) {
ctx.options.onError(
createDOMCompilerError(DOMErrorCodes.X_V_HTML_WITH_CHILDREN, loc),
)
ctx.node.children.length = 0
}
ctx.registerEffect(
[exp],
[