portal-vue icon indicating copy to clipboard operation
portal-vue copied to clipboard

Can't portal content from svg

Open wolandec opened this issue 4 years ago • 15 comments

https://codesandbox.io/s/strange-keldysh-7pwk1

I expect to window appears, but it's not.

If I move <component :is="Second"></component> outside the svg tag, everything is ok then.

wolandec avatar Mar 06 '20 07:03 wolandec

Well, the portal content is moved to the portal-target:

image

As I'm not familiar with that window library that you are using, someone would have to guide me about why the dom is there but the window is not showing.

If that info can be provided we can judge wether/how this is related to portal-vue

LinusBorg avatar Mar 07 '20 13:03 LinusBorg

Edit: this seems to be related: #287

LinusBorg avatar Mar 07 '20 13:03 LinusBorg

Hello! Thank you for your time. I make it simpler and it doesn't work either, so as I see you've mentioned that #287 issue, guess that problem is the same as mine.

https://codesandbox.io/s/beautiful-bogdan-gucj4

wolandec avatar Mar 07 '20 14:03 wolandec

https://codesandbox.io/s/ecstatic-mclaren-u45lb

Even more simpler: with no component tag.

wolandec avatar Mar 07 '20 15:03 wolandec

I've got another interesting stuff. If I add anything in body tag using Chrome devtools, then ported content shows up.

https://youtu.be/TxL5olpWqT4

wolandec avatar Mar 07 '20 17:03 wolandec

Okay, this is getting weirder by the minute 🧐

Maybe a Chrome bug? Need to test other browsers...

LinusBorg avatar Mar 07 '20 18:03 LinusBorg

I've already tested in Firefox. The same result.

wolandec avatar Mar 07 '20 18:03 wolandec

Weird. Just - weird.

LinusBorg avatar Mar 07 '20 18:03 LinusBorg

May it be a Vue bug?

I remove portal-vue and just leave div inside svg in vue applcation. Div is invisible. https://codesandbox.io/s/prod-violet-4f5be

Dynamically create the same html with no Vue using. Div is visible. https://codesandbox.io/s/jovial-violet-qbok9

wolandec avatar Mar 07 '20 19:03 wolandec

Getting this issue as well. Static content in the SVG portaled outside of it works fine. Static content inside a transition-group (?) causes the :not(svg) CSS condition to be permanently applied to the element. Dynamic content shows up in the devtools but isn't visible unless I "Edit HTML", then it shows up but isn't bound to the VM anymore (presumably because it's a new/different Element object).

hamish-milne avatar Mar 11 '20 11:03 hamish-milne

It seems that Vue's h() is aware that it's curently in an SVG element and thus creates the HTML elements differently before they are portaled to outside of the SVG. There, the browser gets a hickup as the element looks like it belongs inside of an SVG,but it isn't - and after being nudged to update the page, the browser "realizes" that it's actually a normal HTML element.

I can't tell wether this is a browser bug, Vue bug or portal-vue issue, and have no idea how it could be fixed.

Will rate this a wontfix caveat.

LinusBorg avatar Jun 21 '20 10:06 LinusBorg

Although this issue is already closed, I'd like to add another finding:

This code works perfectly fine. It even works if the portal is nested into several <g>-elements

<div>
    <portal-target
       multiple
       name="tooltips"
    />
    <svg>
        <portal
          to="tooltips"
        >
            <div>ported</div>
        </portal>
    </svg>
</div>

But as soon as I put the portal inside a component, the teleported content exists in the DOM but is not shown anymore.

<div>
    <portal-target
       multiple
       name="tooltips"
    />
    <svg>
        <PortalSource />
    </svg>
</div>

// PortalSource.vue
<template>
    <portal
      to="tooltips"
    >
        <div>ported</div>
    </portal>
</tempate>

I suggest it to be a portal-vue or vue issue

phischdev avatar Aug 19 '20 13:08 phischdev

I have the same problem. I am trying to port several things out of an SVG into HTML. The problem is, that the ported element is in the SVG namespace and not HTML namespace. Since div-tags are not SVG elements, it doesn't know how to handle these.

This is an issue with portal-vue which has to make sure that the namespace of its members is fixed depending on where the portal is mounted. That means, that porting SVG elements into HTML needs to fix the namespace to HTML EXCEPT for the <svg> tag itself which is recognized by browsers as SVG and establishes a new namespace by itself. Fixing it would do no harm tho. HTML ported from SVG to HTML needs to be fixed the other way round.

The hack I tried and worked is:

<svg>
...
 <Portal to="target">
  <svg width="100%" height="100%">
   <foreignObject width="100%" height="100%">
     ...html content
   </foreignObject>
  </svg>
 </Portal>
</svg>

Fuzzyma avatar Aug 27 '20 23:08 Fuzzyma

@LinusBorg it turned out that vue 3 with Teleport can handle that in case the Teleport component is wrapped into a foreignObject-tag. Unfortunately, this does not work in portal-vue. However, if Teleport can do it, Portal should also be able to do it. Do you think this could be fixed?

Fuzzyma avatar Aug 28 '20 11:08 Fuzzyma

I may find some time to look into it but my impression so far is that this would require a change in Vue 2 core.

LinusBorg avatar Aug 28 '20 12:08 LinusBorg