Subscribe on changes!

Teleport out of svg into html and vice versa doesnt fix namespaces

avatar
Aug 28th 2020

Version

3.0.0-rc.9

Reproduction link

https://codesandbox.io/s/jovial-driscoll-qkefc?file=/src/svg.vue

Steps to reproduce

The component svg.vue is just an svg with a rectangle and a portal. The namespace of the ported element (which is a div) is logged into the console periodically. By clicking the rectangle, the portal is disabled and enabled.

In both cases, the namespaceURI of the div is the one for svg elements. Since <div> has no meaning in svg, it is ignored by the browser and not displayed.

What is expected?

Porting an html element from svg context or vice versa should fix the namespaces so that the browser can make sense of it and display it.

What is actually happening?

The element is practically not there even though it is in the dom because the browser just ignores it.


This issue is already known from vue-portal: https://github.com/LinusBorg/portal-vue/issues/290

It is hard to fix from vue-portals site because it needs almost certainly to interact with the actual creation of components. However, it is quite possibly solvable in the realm of Vue itself.

Therefore vue needs to check the source context and the target context and adapt the namespace accordingly. It might be worthwhile to rerender the component with the target as context to resolve this problem. Furthermore, elements in the wrong namespace (e.g. a disabled portal which ports html out of svg) should be treated as if they would have an v-if of false.

avatar
Aug 28th 2020

Just use <foreignObject> to wrap the Teleport component.

avatar
Aug 28th 2020

Just use <foreignObject> to wrap the Teleport component.

I just wanted to answer that this is exactly what I proposed in the issue of vue-portal but I just realized its actually far better.

So this would be:

<svg>
 ...
 <foreignObject>
  <Teleport to="target">
    ...html content
  </Teleport>
 </foreignObject>
</svg>

Very nice!

// EDIT: Unfortunately this fix doesnt work for portal-vue

avatar
Aug 28th 2020

Closing since <foreignObject> works. Auto switching namespace isn't optimal since it means destroying and re-creating all the nodes.

avatar
Aug 29th 2020

@yyx990803 seems reasonable. One quick follow up tho: Is teleport only supposed to port content to an element which is NOT controlled by Vue? Whenever my teleport target is in the app itself, it is not working. Is this a bug or a feature limitation?