]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-core): should set `<math>` tag as block to retain MathML namespace after...
authorlinzhe <40790268+linzhe141@users.noreply.github.com>
Tue, 28 May 2024 06:26:29 +0000 (14:26 +0800)
committerGitHub <noreply@github.com>
Tue, 28 May 2024 06:26:29 +0000 (14:26 +0800)
Co-authored-by: linzhe141 <linzhe141@qq.com>
packages/compiler-core/__tests__/transforms/transformElement.spec.ts
packages/compiler-core/src/transforms/hoistStatic.ts
packages/compiler-core/src/transforms/transformElement.ts
packages/runtime-dom/__tests__/nodeOps.spec.ts

index 6c2dab9625fe27d9c62caef30efcf5af318cd986..10b9747d1eef710749c051aba3fba2cc2b790d98 100644 (file)
@@ -1284,6 +1284,18 @@ describe('compiler: element transform', () => {
     })
   })
 
+  test('<math> should be forced into blocks', () => {
+    const ast = parse(`<div><math/></div>`)
+    transform(ast, {
+      nodeTransforms: [transformElement],
+    })
+    expect((ast as any).children[0].children[0].codegenNode).toMatchObject({
+      type: NodeTypes.VNODE_CALL,
+      tag: `"math"`,
+      isBlock: true,
+    })
+  })
+
   test('force block for runtime custom directive w/ children', () => {
     const { node } = parseWithElementTransform(`<div v-foo>hello</div>`)
     expect(node.isBlock).toBe(true)
index 70a0468e5196893ff059d75ab028eda5fc6ba545..67bdaa887bf5f1d7c06af7a411f5b633b2b04d2f 100644 (file)
@@ -174,7 +174,8 @@ export function getConstantType(
       if (
         codegenNode.isBlock &&
         node.tag !== 'svg' &&
-        node.tag !== 'foreignObject'
+        node.tag !== 'foreignObject' &&
+        node.tag !== 'math'
       ) {
         return ConstantTypes.NOT_CONSTANT
       }
index 5c431f9d4dacb94958dd35308e92a9a2ba4cd663..b1be06db7030227f6deba53c7e696b2a10e9872e 100644 (file)
@@ -117,7 +117,7 @@ export const transformElement: NodeTransform = (node, context) => {
         // updates inside get proper isSVG flag at runtime. (#639, #643)
         // This is technically web-specific, but splitting the logic out of core
         // leads to too much unnecessary complexity.
-        (tag === 'svg' || tag === 'foreignObject'))
+        (tag === 'svg' || tag === 'foreignObject' || tag === 'math'))
 
     // props
     if (props.length > 0) {
index e185f14d8dd414b13fdc9198f958eef42886b2d6..ed30e42adee44b2f0b34d955a9d3f7d1b87a7928 100644 (file)
@@ -1,5 +1,6 @@
-import { nodeOps, svgNS } from '../src/nodeOps'
-
+import { defineComponent, h, nextTick, ref } from 'vue'
+import { mathmlNS, nodeOps, svgNS } from '../src/nodeOps'
+import { render } from '@vue/runtime-dom'
 describe('runtime-dom: node-ops', () => {
   test("the <select>'s multiple attr should be set in createElement", () => {
     const el = nodeOps.createElement('select', undefined, undefined, {
@@ -106,5 +107,38 @@ describe('runtime-dom: node-ops', () => {
       expect(nodes[0]).toBe(parent.firstChild)
       expect(nodes[1]).toBe(parent.childNodes[parent.childNodes.length - 2])
     })
+
+    test('The math elements should keep their MathML namespace', async () => {
+      let root = document.createElement('div') as any
+
+      let countRef: any
+      const component = defineComponent({
+        data() {
+          return { value: 0 }
+        },
+        setup() {
+          const count = ref(0)
+          countRef = count
+          return {
+            count,
+          }
+        },
+        template: `
+          <div>
+            <math>
+              <mrow class="bar" v-if="count % 2">Bar</mrow>
+              <msup class="foo" v-else>Foo</msup>
+            </math>
+          </div>
+        `,
+      })
+      render(h(component), root)
+      const foo = root.querySelector('.foo')
+      expect(foo.namespaceURI).toBe(mathmlNS)
+      countRef.value++
+      await nextTick()
+      const bar = root.querySelector('.bar')
+      expect(bar.namespaceURI).toBe(mathmlNS)
+    })
   })
 })