Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Fuzzyma opened this issue Aug 28, 2020 · 4 comments
Closed

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

Fuzzyma opened this issue Aug 28, 2020 · 4 comments

Comments

@Fuzzyma
Copy link

Fuzzyma commented Aug 28, 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: LinusBorg/portal-vue#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.

@HcySunYang
Copy link
Member

Just use <foreignObject> to wrap the Teleport component.

@Fuzzyma
Copy link
Author

Fuzzyma commented Aug 28, 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

@yyx990803
Copy link
Member

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

@Fuzzyma
Copy link
Author

Fuzzyma commented Aug 29, 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?

@github-actions github-actions bot locked and limited conversation to collaborators Nov 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants