mirror of https://github.com/vuejs/core.git
feat(runtime-vapor): support svg and MathML
This commit is contained in:
parent
f70f9d1a6b
commit
40b1e1e5de
|
@ -7,15 +7,15 @@ import { type CodeFragment, NEWLINE, buildCodeFragment, genCall } from './utils'
|
|||
export function genTemplates(
|
||||
templates: string[],
|
||||
rootIndex: number | undefined,
|
||||
{ helper }: CodegenContext,
|
||||
{ helper, ir: { templateNS } }: CodegenContext,
|
||||
): string {
|
||||
return templates
|
||||
.map(
|
||||
(template, i) =>
|
||||
`const t${i} = ${helper('template')}(${JSON.stringify(
|
||||
template,
|
||||
)}${i === rootIndex ? ', true' : ''})\n`,
|
||||
)
|
||||
.map((template, i) => {
|
||||
const ns = templateNS.get(template)
|
||||
return `const t${i} = ${helper('template')}(${JSON.stringify(
|
||||
template,
|
||||
)}${i === rootIndex ? ', true' : ns ? ', false' : ''}${ns ? `, ${ns}` : ''})\n`
|
||||
})
|
||||
.join('')
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ export interface RootIRNode {
|
|||
node: RootNode
|
||||
source: string
|
||||
template: string[]
|
||||
templateNS: Map<string, number>
|
||||
rootTemplateIndex?: number
|
||||
component: Set<string>
|
||||
directive: Set<string>
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
type ElementNode,
|
||||
ElementTypes,
|
||||
NodeTypes,
|
||||
type PlainElementNode,
|
||||
type RootNode,
|
||||
type SimpleExpressionNode,
|
||||
type TemplateChildNode,
|
||||
|
@ -73,6 +74,7 @@ export class TransformContext<T extends AllNode = AllNode> {
|
|||
>
|
||||
|
||||
template: string = ''
|
||||
templateNS: Map<string, number> = new Map<string, number>()
|
||||
childrenTemplate: (string | null)[] = []
|
||||
dynamic: IRDynamicInfo = this.ir.block.dynamic
|
||||
|
||||
|
@ -98,10 +100,12 @@ export class TransformContext<T extends AllNode = AllNode> {
|
|||
}
|
||||
|
||||
enterBlock(ir: BlockIRNode, isVFor: boolean = false): () => void {
|
||||
const { block, template, dynamic, childrenTemplate, slots } = this
|
||||
const { block, template, templateNS, dynamic, childrenTemplate, slots } =
|
||||
this
|
||||
this.block = ir
|
||||
this.dynamic = ir.dynamic
|
||||
this.template = ''
|
||||
this.templateNS = new Map<string, number>()
|
||||
this.childrenTemplate = []
|
||||
this.slots = []
|
||||
isVFor && this.inVFor++
|
||||
|
@ -110,6 +114,7 @@ export class TransformContext<T extends AllNode = AllNode> {
|
|||
this.registerTemplate()
|
||||
this.block = block
|
||||
this.template = template
|
||||
this.templateNS = templateNS
|
||||
this.dynamic = dynamic
|
||||
this.childrenTemplate = childrenTemplate
|
||||
this.slots = slots
|
||||
|
@ -130,6 +135,7 @@ export class TransformContext<T extends AllNode = AllNode> {
|
|||
)
|
||||
if (existing !== -1) return existing
|
||||
this.ir.template.push(content)
|
||||
this.ir.templateNS.set(content, (this.node as PlainElementNode).ns)
|
||||
return this.ir.template.length - 1
|
||||
}
|
||||
registerTemplate(): number {
|
||||
|
@ -215,6 +221,7 @@ export function transform(
|
|||
node,
|
||||
source: node.source,
|
||||
template: [],
|
||||
templateNS: new Map<string, number>(),
|
||||
component: new Set(),
|
||||
directive: new Set(),
|
||||
block: newBlock(node),
|
||||
|
|
|
@ -348,3 +348,7 @@ export {
|
|||
vModelSelectInit,
|
||||
vModelSetSelected,
|
||||
} from './directives/vModel'
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export { svgNS, mathmlNS } from './nodeOps'
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import { mathmlNS, svgNS } from '@vue/runtime-dom'
|
||||
import { adoptTemplate, currentHydrationNode, isHydrating } from './hydration'
|
||||
import { child, createTextNode } from './node'
|
||||
|
||||
let t: HTMLTemplateElement
|
||||
let st: HTMLTemplateElement
|
||||
let mt: HTMLTemplateElement
|
||||
|
||||
/*! #__NO_SIDE_EFFECTS__ */
|
||||
export function template(html: string, root?: boolean) {
|
||||
export function template(html: string, root?: boolean, ns?: number) {
|
||||
let node: Node
|
||||
return (): Node & { $root?: true } => {
|
||||
if (isHydrating) {
|
||||
|
@ -19,9 +22,19 @@ export function template(html: string, root?: boolean) {
|
|||
return createTextNode(html)
|
||||
}
|
||||
if (!node) {
|
||||
t = t || document.createElement('template')
|
||||
t.innerHTML = html
|
||||
node = child(t.content)
|
||||
if (!ns) {
|
||||
t = t || document.createElement('template')
|
||||
t.innerHTML = html
|
||||
node = child(t.content)
|
||||
} else if (ns === 1) {
|
||||
st = st || document.createElementNS(svgNS, 'template')
|
||||
st.innerHTML = html
|
||||
node = child(st)
|
||||
} else {
|
||||
mt = mt || document.createElementNS(mathmlNS, 'template')
|
||||
mt.innerHTML = html
|
||||
node = child(mt)
|
||||
}
|
||||
}
|
||||
const ret = node.cloneNode(true)
|
||||
if (root) (ret as any).$root = true
|
||||
|
|
Loading…
Reference in New Issue