Skip to content

Commit 6e6a496

Browse files
sto3pslyyx990803
authored andcommitted
feat: MathML support
1 parent 638f1ab commit 6e6a496

File tree

20 files changed

+351
-155
lines changed

20 files changed

+351
-155
lines changed

packages/compiler-dom/src/parserOptions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { ParserOptions, NodeTypes, Namespaces } from '@vue/compiler-core'
2-
import { isVoidTag, isHTMLTag, isSVGTag } from '@vue/shared'
2+
import { isVoidTag, isHTMLTag, isSVGTag, isMathMLTag } from '@vue/shared'
33
import { TRANSITION, TRANSITION_GROUP } from './runtimeHelpers'
44
import { decodeHtmlBrowser } from './decodeHtmlBrowser'
55

66
export const parserOptions: ParserOptions = {
77
parseMode: 'html',
88
isVoidTag,
9-
isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag),
9+
isNativeTag: tag => isHTMLTag(tag) || isSVGTag(tag) || isMathMLTag(tag),
1010
isPreTag: tag => tag === 'pre',
1111
decodeEntities: __BROWSER__ ? decodeHtmlBrowser : undefined,
1212

packages/runtime-core/src/apiCreateApp.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export interface App<HostElement = any> {
4747
mount(
4848
rootContainer: HostElement | string,
4949
isHydrate?: boolean,
50-
isSVG?: boolean
50+
namespace?: 'svg' | 'mathml'
5151
): ComponentPublicInstance
5252
unmount(): void
5353
provide<T>(key: InjectionKey<T> | string, value: T): this
@@ -297,7 +297,7 @@ export function createAppAPI<HostElement>(
297297
mount(
298298
rootContainer: HostElement,
299299
isHydrate?: boolean,
300-
isSVG?: boolean
300+
namespace?: 'svg' | 'mathml'
301301
): any {
302302
if (!isMounted) {
303303
// #5571
@@ -316,14 +316,14 @@ export function createAppAPI<HostElement>(
316316
// HMR root reload
317317
if (__DEV__) {
318318
context.reload = () => {
319-
render(cloneVNode(vnode), rootContainer, isSVG)
319+
render(cloneVNode(vnode), rootContainer, namespace)
320320
}
321321
}
322322

323323
if (isHydrate && hydrate) {
324324
hydrate(vnode as VNode<Node, Element>, rootContainer as any)
325325
} else {
326-
render(vnode, rootContainer, isSVG)
326+
render(vnode, rootContainer, namespace)
327327
}
328328
isMounted = true
329329
app._container = rootContainer

packages/runtime-core/src/compat/global.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,15 +503,17 @@ function installCompatMount(
503503
container = selectorOrEl || document.createElement('div')
504504
}
505505

506-
const isSVG = container instanceof SVGElement
506+
let namespace: 'svg' | 'mathml' | undefined
507+
if (container instanceof SVGElement) namespace = 'svg'
508+
if (container instanceof MathMLElement) namespace = 'mathml'
507509

508510
// HMR root reload
509511
if (__DEV__) {
510512
context.reload = () => {
511513
const cloned = cloneVNode(vnode)
512514
// compat mode will use instance if not reset to null
513515
cloned.component = null
514-
render(cloned, container, isSVG)
516+
render(cloned, container, namespace)
515517
}
516518
}
517519

@@ -538,7 +540,7 @@ function installCompatMount(
538540
container.innerHTML = ''
539541

540542
// TODO hydration
541-
render(vnode, container, isSVG)
543+
render(vnode, container, namespace)
542544

543545
if (container instanceof Element) {
544546
container.removeAttribute('v-cloak')

packages/runtime-core/src/components/KeepAlive.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export interface KeepAliveContext extends ComponentRenderContext {
6464
vnode: VNode,
6565
container: RendererElement,
6666
anchor: RendererNode | null,
67-
isSVG: boolean,
67+
namespace: 'svg' | 'mathml' | undefined,
6868
optimized: boolean
6969
) => void
7070
deactivate: (vnode: VNode) => void
@@ -125,7 +125,13 @@ const KeepAliveImpl: ComponentOptions = {
125125
} = sharedContext
126126
const storageContainer = createElement('div')
127127

128-
sharedContext.activate = (vnode, container, anchor, isSVG, optimized) => {
128+
sharedContext.activate = (
129+
vnode,
130+
container,
131+
anchor,
132+
namespace,
133+
optimized
134+
) => {
129135
const instance = vnode.component!
130136
move(vnode, container, anchor, MoveType.ENTER, parentSuspense)
131137
// in case props have changed
@@ -136,7 +142,7 @@ const KeepAliveImpl: ComponentOptions = {
136142
anchor,
137143
instance,
138144
parentSuspense,
139-
isSVG,
145+
namespace,
140146
vnode.slotScopeIds,
141147
optimized
142148
)

packages/runtime-core/src/components/Suspense.ts

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export const SuspenseImpl = {
6363
anchor: RendererNode | null,
6464
parentComponent: ComponentInternalInstance | null,
6565
parentSuspense: SuspenseBoundary | null,
66-
isSVG: boolean,
66+
namespace: 'svg' | 'mathml' | undefined,
6767
slotScopeIds: string[] | null,
6868
optimized: boolean,
6969
// platform-specific impl passed from renderer
@@ -76,7 +76,7 @@ export const SuspenseImpl = {
7676
anchor,
7777
parentComponent,
7878
parentSuspense,
79-
isSVG,
79+
namespace,
8080
slotScopeIds,
8181
optimized,
8282
rendererInternals
@@ -88,7 +88,7 @@ export const SuspenseImpl = {
8888
container,
8989
anchor,
9090
parentComponent,
91-
isSVG,
91+
namespace,
9292
slotScopeIds,
9393
optimized,
9494
rendererInternals
@@ -130,7 +130,7 @@ function mountSuspense(
130130
anchor: RendererNode | null,
131131
parentComponent: ComponentInternalInstance | null,
132132
parentSuspense: SuspenseBoundary | null,
133-
isSVG: boolean,
133+
namespace: 'svg' | 'mathml' | undefined,
134134
slotScopeIds: string[] | null,
135135
optimized: boolean,
136136
rendererInternals: RendererInternals
@@ -147,7 +147,7 @@ function mountSuspense(
147147
container,
148148
hiddenContainer,
149149
anchor,
150-
isSVG,
150+
namespace,
151151
slotScopeIds,
152152
optimized,
153153
rendererInternals
@@ -161,7 +161,7 @@ function mountSuspense(
161161
null,
162162
parentComponent,
163163
suspense,
164-
isSVG,
164+
namespace,
165165
slotScopeIds
166166
)
167167
// now check if we have encountered any async deps
@@ -179,7 +179,7 @@ function mountSuspense(
179179
anchor,
180180
parentComponent,
181181
null, // fallback tree will not have suspense context
182-
isSVG,
182+
namespace,
183183
slotScopeIds
184184
)
185185
setActiveBranch(suspense, vnode.ssFallback!)
@@ -195,7 +195,7 @@ function patchSuspense(
195195
container: RendererElement,
196196
anchor: RendererNode | null,
197197
parentComponent: ComponentInternalInstance | null,
198-
isSVG: boolean,
198+
namespace: 'svg' | 'mathml' | undefined,
199199
slotScopeIds: string[] | null,
200200
optimized: boolean,
201201
{ p: patch, um: unmount, o: { createElement } }: RendererInternals
@@ -218,7 +218,7 @@ function patchSuspense(
218218
null,
219219
parentComponent,
220220
suspense,
221-
isSVG,
221+
namespace,
222222
slotScopeIds,
223223
optimized
224224
)
@@ -232,7 +232,7 @@ function patchSuspense(
232232
anchor,
233233
parentComponent,
234234
null, // fallback tree will not have suspense context
235-
isSVG,
235+
namespace,
236236
slotScopeIds,
237237
optimized
238238
)
@@ -267,7 +267,7 @@ function patchSuspense(
267267
null,
268268
parentComponent,
269269
suspense,
270-
isSVG,
270+
namespace,
271271
slotScopeIds,
272272
optimized
273273
)
@@ -281,7 +281,7 @@ function patchSuspense(
281281
anchor,
282282
parentComponent,
283283
null, // fallback tree will not have suspense context
284-
isSVG,
284+
namespace,
285285
slotScopeIds,
286286
optimized
287287
)
@@ -296,7 +296,7 @@ function patchSuspense(
296296
anchor,
297297
parentComponent,
298298
suspense,
299-
isSVG,
299+
namespace,
300300
slotScopeIds,
301301
optimized
302302
)
@@ -311,7 +311,7 @@ function patchSuspense(
311311
null,
312312
parentComponent,
313313
suspense,
314-
isSVG,
314+
namespace,
315315
slotScopeIds,
316316
optimized
317317
)
@@ -330,7 +330,7 @@ function patchSuspense(
330330
anchor,
331331
parentComponent,
332332
suspense,
333-
isSVG,
333+
namespace,
334334
slotScopeIds,
335335
optimized
336336
)
@@ -349,7 +349,7 @@ function patchSuspense(
349349
null,
350350
parentComponent,
351351
suspense,
352-
isSVG,
352+
namespace,
353353
slotScopeIds,
354354
optimized
355355
)
@@ -376,7 +376,7 @@ export interface SuspenseBoundary {
376376
vnode: VNode<RendererNode, RendererElement, SuspenseProps>
377377
parent: SuspenseBoundary | null
378378
parentComponent: ComponentInternalInstance | null
379-
isSVG: boolean
379+
namespace: 'svg' | 'mathml' | undefined
380380
container: RendererElement
381381
hiddenContainer: RendererElement
382382
anchor: RendererNode | null
@@ -413,7 +413,7 @@ function createSuspenseBoundary(
413413
container: RendererElement,
414414
hiddenContainer: RendererElement,
415415
anchor: RendererNode | null,
416-
isSVG: boolean,
416+
namespace: 'svg' | 'mathml' | undefined,
417417
slotScopeIds: string[] | null,
418418
optimized: boolean,
419419
rendererInternals: RendererInternals,
@@ -455,7 +455,7 @@ function createSuspenseBoundary(
455455
vnode,
456456
parent: parentSuspense,
457457
parentComponent,
458-
isSVG,
458+
namespace,
459459
container,
460460
hiddenContainer,
461461
anchor,
@@ -576,7 +576,7 @@ function createSuspenseBoundary(
576576
return
577577
}
578578

579-
const { vnode, activeBranch, parentComponent, container, isSVG } =
579+
const { vnode, activeBranch, parentComponent, container, namespace } =
580580
suspense
581581

582582
// invoke @fallback event
@@ -594,7 +594,7 @@ function createSuspenseBoundary(
594594
next(activeBranch!),
595595
parentComponent,
596596
null, // fallback tree will not have suspense context
597-
isSVG,
597+
namespace,
598598
slotScopeIds,
599599
optimized
600600
)
@@ -675,7 +675,7 @@ function createSuspenseBoundary(
675675
// consider the comment placeholder case.
676676
hydratedEl ? null : next(instance.subTree),
677677
suspense,
678-
isSVG,
678+
namespace,
679679
optimized
680680
)
681681
if (placeholder) {
@@ -721,7 +721,7 @@ function hydrateSuspense(
721721
vnode: VNode,
722722
parentComponent: ComponentInternalInstance | null,
723723
parentSuspense: SuspenseBoundary | null,
724-
isSVG: boolean,
724+
namespace: 'svg' | 'mathml' | undefined,
725725
slotScopeIds: string[] | null,
726726
optimized: boolean,
727727
rendererInternals: RendererInternals,
@@ -742,7 +742,7 @@ function hydrateSuspense(
742742
node.parentNode!,
743743
document.createElement('div'),
744744
null,
745-
isSVG,
745+
namespace,
746746
slotScopeIds,
747747
optimized,
748748
rendererInternals,

0 commit comments

Comments
 (0)