Skip to content

Commit 87c5443

Browse files
authored
fix(compiler-core): should set <math> tag as block to retain MathML namespace after patching (#10891)
Co-authored-by: linzhe141 <[email protected]>
1 parent 521988d commit 87c5443

File tree

4 files changed

+51
-4
lines changed

4 files changed

+51
-4
lines changed

packages/compiler-core/__tests__/transforms/transformElement.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,18 @@ describe('compiler: element transform', () => {
12841284
})
12851285
})
12861286

1287+
test('<math> should be forced into blocks', () => {
1288+
const ast = parse(`<div><math/></div>`)
1289+
transform(ast, {
1290+
nodeTransforms: [transformElement],
1291+
})
1292+
expect((ast as any).children[0].children[0].codegenNode).toMatchObject({
1293+
type: NodeTypes.VNODE_CALL,
1294+
tag: `"math"`,
1295+
isBlock: true,
1296+
})
1297+
})
1298+
12871299
test('force block for runtime custom directive w/ children', () => {
12881300
const { node } = parseWithElementTransform(`<div v-foo>hello</div>`)
12891301
expect(node.isBlock).toBe(true)

packages/compiler-core/src/transforms/hoistStatic.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ export function getConstantType(
174174
if (
175175
codegenNode.isBlock &&
176176
node.tag !== 'svg' &&
177-
node.tag !== 'foreignObject'
177+
node.tag !== 'foreignObject' &&
178+
node.tag !== 'math'
178179
) {
179180
return ConstantTypes.NOT_CONSTANT
180181
}

packages/compiler-core/src/transforms/transformElement.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export const transformElement: NodeTransform = (node, context) => {
117117
// updates inside get proper isSVG flag at runtime. (#639, #643)
118118
// This is technically web-specific, but splitting the logic out of core
119119
// leads to too much unnecessary complexity.
120-
(tag === 'svg' || tag === 'foreignObject'))
120+
(tag === 'svg' || tag === 'foreignObject' || tag === 'math'))
121121

122122
// props
123123
if (props.length > 0) {

packages/runtime-dom/__tests__/nodeOps.spec.ts

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { nodeOps, svgNS } from '../src/nodeOps'
2-
1+
import { defineComponent, h, nextTick, ref } from 'vue'
2+
import { mathmlNS, nodeOps, svgNS } from '../src/nodeOps'
3+
import { render } from '@vue/runtime-dom'
34
describe('runtime-dom: node-ops', () => {
45
test("the <select>'s multiple attr should be set in createElement", () => {
56
const el = nodeOps.createElement('select', undefined, undefined, {
@@ -106,5 +107,38 @@ describe('runtime-dom: node-ops', () => {
106107
expect(nodes[0]).toBe(parent.firstChild)
107108
expect(nodes[1]).toBe(parent.childNodes[parent.childNodes.length - 2])
108109
})
110+
111+
test('The math elements should keep their MathML namespace', async () => {
112+
let root = document.createElement('div') as any
113+
114+
let countRef: any
115+
const component = defineComponent({
116+
data() {
117+
return { value: 0 }
118+
},
119+
setup() {
120+
const count = ref(0)
121+
countRef = count
122+
return {
123+
count,
124+
}
125+
},
126+
template: `
127+
<div>
128+
<math>
129+
<mrow class="bar" v-if="count % 2">Bar</mrow>
130+
<msup class="foo" v-else>Foo</msup>
131+
</math>
132+
</div>
133+
`,
134+
})
135+
render(h(component), root)
136+
const foo = root.querySelector('.foo')
137+
expect(foo.namespaceURI).toBe(mathmlNS)
138+
countRef.value++
139+
await nextTick()
140+
const bar = root.querySelector('.bar')
141+
expect(bar.namespaceURI).toBe(mathmlNS)
142+
})
109143
})
110144
})

0 commit comments

Comments
 (0)