]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat: implement error handling for v-html (#30)
authorRizumu Ayaka <rizumu@ayaka.moe>
Sat, 2 Dec 2023 07:59:09 +0000 (15:59 +0800)
committerGitHub <noreply@github.com>
Sat, 2 Dec 2023 07:59:09 +0000 (15:59 +0800)
packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap
packages/compiler-vapor/__tests__/compile.test.ts
packages/compiler-vapor/src/transform.ts

index d971c005bd3f17fb49b6506d6780acb55af9c174..515fc539b9601003bde2754bf62f5560d45ec4ef 100644 (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) {
index e718947758172ed7749ab6c256d01a398fe10f3c..197a1ecd7c9b6f0c8eb3b43ea2c62e414e5a3fb4 100644 (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 }],
+        ])
       })
     })
 
index edce93fae9f494635438d504c776b41738339776..9dfe6a15c41bde2ac93f495eda0cc1e4cf6f3d66 100644 (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],
         [