parent
7a1a782642
commit
cd92836223
@ -7,10 +7,11 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
ref,
|
ref,
|
||||||
nextTick,
|
nextTick,
|
||||||
markRaw
|
markRaw,
|
||||||
|
defineComponent
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
import { createVNode, Fragment } from '../../src/vnode'
|
import { createVNode, Fragment } from '../../src/vnode'
|
||||||
import { compile } from 'vue'
|
import { compile, render as domRender } from 'vue'
|
||||||
|
|
||||||
describe('renderer: teleport', () => {
|
describe('renderer: teleport', () => {
|
||||||
test('should work', () => {
|
test('should work', () => {
|
||||||
@ -33,6 +34,37 @@ describe('renderer: teleport', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should work with SVG', async () => {
|
||||||
|
const root = document.createElement('div')
|
||||||
|
const svg = ref()
|
||||||
|
const circle = ref()
|
||||||
|
|
||||||
|
const Comp = defineComponent({
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
svg,
|
||||||
|
circle
|
||||||
|
}
|
||||||
|
},
|
||||||
|
template: `
|
||||||
|
<svg ref="svg"></svg>
|
||||||
|
<teleport :to="svg" v-if="svg">
|
||||||
|
<circle ref="circle"></circle>
|
||||||
|
</teleport>`
|
||||||
|
})
|
||||||
|
|
||||||
|
domRender(h(Comp), root)
|
||||||
|
|
||||||
|
await nextTick()
|
||||||
|
|
||||||
|
expect(root.innerHTML).toMatchInlineSnapshot(
|
||||||
|
`"<svg><circle></circle></svg><!--teleport start--><!--teleport end-->"`
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(svg.value.namespaceURI).toBe('http://www.w3.org/2000/svg')
|
||||||
|
expect(circle.value.namespaceURI).toBe('http://www.w3.org/2000/svg')
|
||||||
|
})
|
||||||
|
|
||||||
test('should update target', async () => {
|
test('should update target', async () => {
|
||||||
const targetA = nodeOps.createElement('div')
|
const targetA = nodeOps.createElement('div')
|
||||||
const targetB = nodeOps.createElement('div')
|
const targetB = nodeOps.createElement('div')
|
||||||
|
@ -24,6 +24,9 @@ export const isTeleport = (type: any): boolean => type.__isTeleport
|
|||||||
export const isTeleportDisabled = (props: VNode['props']): boolean =>
|
export const isTeleportDisabled = (props: VNode['props']): boolean =>
|
||||||
props && (props.disabled || props.disabled === '')
|
props && (props.disabled || props.disabled === '')
|
||||||
|
|
||||||
|
const isTargetSVG = (target: RendererElement): boolean =>
|
||||||
|
typeof SVGElement !== 'undefined' && target instanceof SVGElement
|
||||||
|
|
||||||
const resolveTarget = <T = RendererElement>(
|
const resolveTarget = <T = RendererElement>(
|
||||||
props: TeleportProps | null,
|
props: TeleportProps | null,
|
||||||
select: RendererOptions['querySelector']
|
select: RendererOptions['querySelector']
|
||||||
@ -80,6 +83,7 @@ export const TeleportImpl = {
|
|||||||
|
|
||||||
const disabled = isTeleportDisabled(n2.props)
|
const disabled = isTeleportDisabled(n2.props)
|
||||||
const { shapeFlag, children } = n2
|
const { shapeFlag, children } = n2
|
||||||
|
|
||||||
if (n1 == null) {
|
if (n1 == null) {
|
||||||
// insert anchors in the main view
|
// insert anchors in the main view
|
||||||
const placeholder = (n2.el = __DEV__
|
const placeholder = (n2.el = __DEV__
|
||||||
@ -90,11 +94,12 @@ export const TeleportImpl = {
|
|||||||
: createText(''))
|
: createText(''))
|
||||||
insert(placeholder, container, anchor)
|
insert(placeholder, container, anchor)
|
||||||
insert(mainAnchor, container, anchor)
|
insert(mainAnchor, container, anchor)
|
||||||
|
|
||||||
const target = (n2.target = resolveTarget(n2.props, querySelector))
|
const target = (n2.target = resolveTarget(n2.props, querySelector))
|
||||||
const targetAnchor = (n2.targetAnchor = createText(''))
|
const targetAnchor = (n2.targetAnchor = createText(''))
|
||||||
if (target) {
|
if (target) {
|
||||||
insert(targetAnchor, target)
|
insert(targetAnchor, target)
|
||||||
|
// #2652 we could be teleporting from a non-SVG tree into an SVG tree
|
||||||
|
isSVG = isSVG || isTargetSVG(target)
|
||||||
} else if (__DEV__ && !disabled) {
|
} else if (__DEV__ && !disabled) {
|
||||||
warn('Invalid Teleport target on mount:', target, `(${typeof target})`)
|
warn('Invalid Teleport target on mount:', target, `(${typeof target})`)
|
||||||
}
|
}
|
||||||
@ -129,6 +134,7 @@ export const TeleportImpl = {
|
|||||||
const wasDisabled = isTeleportDisabled(n1.props)
|
const wasDisabled = isTeleportDisabled(n1.props)
|
||||||
const currentContainer = wasDisabled ? container : target
|
const currentContainer = wasDisabled ? container : target
|
||||||
const currentAnchor = wasDisabled ? mainAnchor : targetAnchor
|
const currentAnchor = wasDisabled ? mainAnchor : targetAnchor
|
||||||
|
isSVG = isSVG || isTargetSVG(target)
|
||||||
|
|
||||||
if (n2.dynamicChildren) {
|
if (n2.dynamicChildren) {
|
||||||
// fast path when the teleport happens to be a block root
|
// fast path when the teleport happens to be a block root
|
||||||
|
Loading…
x
Reference in New Issue
Block a user