diff --git a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap b/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap index d971c005b..515fc539b 100644 --- a/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap +++ b/packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap @@ -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(\\"
\\") + 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) { diff --git a/packages/compiler-vapor/__tests__/compile.test.ts b/packages/compiler-vapor/__tests__/compile.test.ts index e71894775..197a1ecd7 100644 --- a/packages/compiler-vapor/__tests__/compile.test.ts +++ b/packages/compiler-vapor/__tests__/compile.test.ts @@ -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(`
`) + test('should raise error and ignore children when v-html is present', async () => { + const onError = vi.fn() + const code = await compile(`
hello
`, { + 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(`
`, { + onError, + }) + expect(code).matchSnapshot() + expect(onError.mock.calls).toMatchObject([ + [{ code: DOMErrorCodes.X_V_HTML_NO_EXPRESSION }], + ]) }) }) diff --git a/packages/compiler-vapor/src/transform.ts b/packages/compiler-vapor/src/transform.ts index edce93fae..9dfe6a15c 100644 --- a/packages/compiler-vapor/src/transform.ts +++ b/packages/compiler-vapor/src/transform.ts @@ -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], [