Text,
ref,
nextTick,
- markRaw
+ markRaw,
+ defineComponent
} from '@vue/runtime-test'
import { createVNode, Fragment } from '../../src/vnode'
-import { compile } from 'vue'
+import { compile, render as domRender } from 'vue'
describe('renderer: teleport', () => {
test('should work', () => {
)
})
+ 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 () => {
const targetA = nodeOps.createElement('div')
const targetB = nodeOps.createElement('div')
export const isTeleportDisabled = (props: VNode['props']): boolean =>
props && (props.disabled || props.disabled === '')
+const isTargetSVG = (target: RendererElement): boolean =>
+ typeof SVGElement !== 'undefined' && target instanceof SVGElement
+
const resolveTarget = <T = RendererElement>(
props: TeleportProps | null,
select: RendererOptions['querySelector']
const disabled = isTeleportDisabled(n2.props)
const { shapeFlag, children } = n2
+
if (n1 == null) {
// insert anchors in the main view
const placeholder = (n2.el = __DEV__
: createText(''))
insert(placeholder, container, anchor)
insert(mainAnchor, container, anchor)
-
const target = (n2.target = resolveTarget(n2.props, querySelector))
const targetAnchor = (n2.targetAnchor = createText(''))
if (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) {
warn('Invalid Teleport target on mount:', target, `(${typeof target})`)
}
const wasDisabled = isTeleportDisabled(n1.props)
const currentContainer = wasDisabled ? container : target
const currentAnchor = wasDisabled ? mainAnchor : targetAnchor
+ isSVG = isSVG || isTargetSVG(target)
if (n2.dynamicChildren) {
// fast path when the teleport happens to be a block root