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

SVG tag is shown in "Elements", but invisible on a page #2290

Closed
maciejjankowski opened this Issue Mar 13, 2017 · 14 comments

Comments

Projects
None yet
5 participants
@maciejjankowski

maciejjankowski commented Mar 13, 2017

  1. Describe your issue:

I want to use a tag for rendering svg paths.
I have built the tag but it doesn't show on a page.
One problem could be that enclosing <path> with <my-path> tag causes svg to neglect the contents.
So I tried workaround: <virtual data-is="my-path"> but it does not render the tag in the DOM at all.

  1. Can you reproduce the issue?
    There are two examples showing original problem and attemted workaround, which neither work:
    http://plnkr.co/edit/DvSkw0CGjyCIbjfbMY4F?p=preview

Now, view elements in the inspector:

  1. navigate to <path> element inside <my-path>
  2. drag it one level up, below svg tag
  3. modify the <path> tag in Edit HTML mode
  4. Ctrl + enter to save modifications. This should make the tag show up.

Unfortunately, when using <virtual> the tag never renders

When rendering the whole <svg> from within riot tag, then it works:
http://jsbin.com/piboju/edit?html,js,output

  1. On which browser/OS does the issue appear?
    chrome, firefox
  2. Which version of Riot does it affect?
    3.2
  3. How would you tag this issue?
  • Bug
  • Question
    • Discussion
    • Feature request
    • Tip
    • Enhancement
    • Performance
@jakubrpawlowski

This comment has been minimized.

Show comment
Hide comment
@jakubrpawlowski

jakubrpawlowski Mar 14, 2017

Not a bug. This is not the issue with Riot. Even in vanilla html any foreign tag inside <svg> tag will not render. You can't even put <div> inside <svg>. In your jsbin example you are using native <svg> subtag <g> but as soon as you change it to <div> it will disappear. I will think of a possible solution for your case and get back to you in 10 hours maciej.

Not a bug. This is not the issue with Riot. Even in vanilla html any foreign tag inside <svg> tag will not render. You can't even put <div> inside <svg>. In your jsbin example you are using native <svg> subtag <g> but as soon as you change it to <div> it will disappear. I will think of a possible solution for your case and get back to you in 10 hours maciej.

@GianlucaGuarini

This comment has been minimized.

Show comment
Hide comment
@GianlucaGuarini

GianlucaGuarini Mar 14, 2017

Member

This solution may be a good temporary workaround http://plnkr.co/edit/N27O9uw2iBLXlwme4Y1P?p=preview even if am not sure riot should cover such an edge case

Member

GianlucaGuarini commented Mar 14, 2017

This solution may be a good temporary workaround http://plnkr.co/edit/N27O9uw2iBLXlwme4Y1P?p=preview even if am not sure riot should cover such an edge case

@maciejjankowski

This comment has been minimized.

Show comment
Hide comment
@maciejjankowski

maciejjankowski Mar 14, 2017

@jakubrpawlowski virtual tag should allow for such a replacement when I don't want to introduce a foreign tag as described at the bottom of 'Loops advanced tips' section

In this case <virtual> does not even insert the riot tag where it is supposed to go.

@GianlucaGuarini sure, I am using the workaround with generating the complete <svg> tag from the riot component, but I would love to see riot behave consistently with html and svg.

@jakubrpawlowski virtual tag should allow for such a replacement when I don't want to introduce a foreign tag as described at the bottom of 'Loops advanced tips' section

In this case <virtual> does not even insert the riot tag where it is supposed to go.

@GianlucaGuarini sure, I am using the workaround with generating the complete <svg> tag from the riot component, but I would love to see riot behave consistently with html and svg.

@jakubrpawlowski

This comment has been minimized.

Show comment
Hide comment
@jakubrpawlowski

jakubrpawlowski Mar 14, 2017

I like the workaround so I continued of @GianlucaGuarini plunker.
I learned 2 things:

  1. The reason why you cannot remove <svg> in my-path1 and my-path2 files is that <path> tag loses it's XML reference and becomes pretty much regular HTML tag and that is the issue with browser engines and w3 rather than Riot. I moved path definition from HTML to Javascript to avoid <svg> in <svg> and ended up with this: http://plnkr.co/edit/4zVGYIbLTpQvJkt4KHzO?p=preview.
  2. Unexpectedly virtual tags remain in DOM :/ (thank you @maciejjankowski for pointing it out).

jakubrpawlowski commented Mar 14, 2017

I like the workaround so I continued of @GianlucaGuarini plunker.
I learned 2 things:

  1. The reason why you cannot remove <svg> in my-path1 and my-path2 files is that <path> tag loses it's XML reference and becomes pretty much regular HTML tag and that is the issue with browser engines and w3 rather than Riot. I moved path definition from HTML to Javascript to avoid <svg> in <svg> and ended up with this: http://plnkr.co/edit/4zVGYIbLTpQvJkt4KHzO?p=preview.
  2. Unexpectedly virtual tags remain in DOM :/ (thank you @maciejjankowski for pointing it out).
@sbrandtb

This comment has been minimized.

Show comment
Hide comment
@sbrandtb

sbrandtb May 1, 2017

I experienced similar issues when rendering SVG with riot. According to @jakubrpawlowski last answer, adding a wrapping <svg> tag around the custom tag and mounting it with <g data-is="tag-name"> did the trick for me: http://plnkr.co/edit/rr4vdHmHXvZ0d1q1mihU?p=preview

  • If this is caused by w3 standards, does it deserve a FAQ entry somewhere? I'm pretty sure others will encounter this issue, too
  • What makes me wonder is that for riot <= 3.3.1, when used with data-is and each, it works without wrapping SVG: http://plnkr.co/edit/dNvMHeYMvyl2OPBWKaPI?p=preview. Change Riot's version to 3.3.2 and it stops working, add <svg> wrapper in <my-rect> and it starts working again. It does not work without each, though.

sbrandtb commented May 1, 2017

I experienced similar issues when rendering SVG with riot. According to @jakubrpawlowski last answer, adding a wrapping <svg> tag around the custom tag and mounting it with <g data-is="tag-name"> did the trick for me: http://plnkr.co/edit/rr4vdHmHXvZ0d1q1mihU?p=preview

  • If this is caused by w3 standards, does it deserve a FAQ entry somewhere? I'm pretty sure others will encounter this issue, too
  • What makes me wonder is that for riot <= 3.3.1, when used with data-is and each, it works without wrapping SVG: http://plnkr.co/edit/dNvMHeYMvyl2OPBWKaPI?p=preview. Change Riot's version to 3.3.2 and it stops working, add <svg> wrapper in <my-rect> and it starts working again. It does not work without each, though.
@GianlucaGuarini

This comment has been minimized.

Show comment
Hide comment
@GianlucaGuarini

GianlucaGuarini May 1, 2017

Member

I guess the easiest way to fix this issue is to inform our users that tags like svg,table and select are kind of special and don't allow the use of custom riot tags in them. For these tags you will need to use data-is for custom children and the use of the virtual tags is not allowed.

Member

GianlucaGuarini commented May 1, 2017

I guess the easiest way to fix this issue is to inform our users that tags like svg,table and select are kind of special and don't allow the use of custom riot tags in them. For these tags you will need to use data-is for custom children and the use of the virtual tags is not allowed.

@sbrandtb

This comment has been minimized.

Show comment
Hide comment
@sbrandtb

sbrandtb May 1, 2017

As you can see, when wrapping the contents of a custom tag with <svg> inside the tag and mounting it with data-is, SVG does work

sbrandtb commented May 1, 2017

As you can see, when wrapping the contents of a custom tag with <svg> inside the tag and mounting it with data-is, SVG does work

@GianlucaGuarini

This comment has been minimized.

Show comment
Hide comment
@GianlucaGuarini

GianlucaGuarini May 1, 2017

Member

yea it's a bit like using a option tag somewhere in the DOM and trying to clone it in a select tag afterwards.. it simply doesn't work. Before riot used a check to understand if the root tag was an svg tag or normal DOM but I realized that the amount of code and the complexity added to the core was not worth

Member

GianlucaGuarini commented May 1, 2017

yea it's a bit like using a option tag somewhere in the DOM and trying to clone it in a select tag afterwards.. it simply doesn't work. Before riot used a check to understand if the root tag was an svg tag or normal DOM but I realized that the amount of code and the complexity added to the core was not worth

@maciejjankowski

This comment has been minimized.

Show comment
Hide comment
@maciejjankowski

maciejjankowski May 1, 2017

@GianlucaGuarini

This comment has been minimized.

Show comment
Hide comment
@GianlucaGuarini

GianlucaGuarini May 1, 2017

Member

@jakubrpawlowski maybe we can add an attribute is-svg to the tag for svg fragments?

Member

GianlucaGuarini commented May 1, 2017

@jakubrpawlowski maybe we can add an attribute is-svg to the tag for svg fragments?

@GianlucaGuarini

This comment has been minimized.

Show comment
Hide comment
@GianlucaGuarini

GianlucaGuarini May 1, 2017

Member

something like

<my-path is-svg>
   <path ...>
</my-path>
Member

GianlucaGuarini commented May 1, 2017

something like

<my-path is-svg>
   <path ...>
</my-path>
@GianlucaGuarini

This comment has been minimized.

Show comment
Hide comment
Member

GianlucaGuarini commented May 13, 2017

fixed in riot@3.5.0 http://plnkr.co/edit/uT3uY9PhFdL20QFGN2sM?p=preview

@amitguptagwl

This comment has been minimized.

Show comment
Hide comment
@amitguptagwl

amitguptagwl May 25, 2018

Contributor

Would it not pollute the svg? I mean surrounding each riot svg element tag with another svg tag.

As we do with vanilla JS to create an element dynamically.

var rect = document.createElementNS(ns, 'rect')
rect.setAttributeNS(null, 'width', 100)
rect.setAttributeNS(null, 'height', 100)
rect.setAttributeNS(null, 'fill', '#f06')
svgEl.appendChild(rect)

Can't we do something with riot svg tags?

Contributor

amitguptagwl commented May 25, 2018

Would it not pollute the svg? I mean surrounding each riot svg element tag with another svg tag.

As we do with vanilla JS to create an element dynamically.

var rect = document.createElementNS(ns, 'rect')
rect.setAttributeNS(null, 'width', 100)
rect.setAttributeNS(null, 'height', 100)
rect.setAttributeNS(null, 'fill', '#f06')
svgEl.appendChild(rect)

Can't we do something with riot svg tags?

@amitguptagwl

This comment has been minimized.

Show comment
Hide comment
@amitguptagwl

amitguptagwl May 26, 2018

Contributor

This snippet can add SVG element dynamically.

<r-svg>
    <svg ref="svgbox" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onmousedown={createElement}>
        <yield></yield>
    </svg>
    <script>
        createElement(e){
            var tag = document.createElementNS("http://www.w3.org/2000/svg",'rect');
            tag.setAttribute("x", e.x - this.root.offsetLeft );
            tag.setAttribute("y", e.y - this.root.offsetTop);
            tag.setAttribute("width", 100 );
            tag.setAttribute("height", 100 );

            this.refs.svgbox.appendChild(tag);
        }
    </script>
</r-svg>

Can't we do it completely with riot? Like this

<r-svg>
    <svg ref="svgbox" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onmousedown={createElement}>
        <yield></yield>
    </svg>
    <script>
        createElement(e){
            var tag = document.createElementNS("http://www.w3.org/2000/svg",'r-rect');
            this.refs.svgbox.appendChild(tag);
            riot.mount(tag,'r-rect',someopts);
        }
    </script>
</r-svg>
Contributor

amitguptagwl commented May 26, 2018

This snippet can add SVG element dynamically.

<r-svg>
    <svg ref="svgbox" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onmousedown={createElement}>
        <yield></yield>
    </svg>
    <script>
        createElement(e){
            var tag = document.createElementNS("http://www.w3.org/2000/svg",'rect');
            tag.setAttribute("x", e.x - this.root.offsetLeft );
            tag.setAttribute("y", e.y - this.root.offsetTop);
            tag.setAttribute("width", 100 );
            tag.setAttribute("height", 100 );

            this.refs.svgbox.appendChild(tag);
        }
    </script>
</r-svg>

Can't we do it completely with riot? Like this

<r-svg>
    <svg ref="svgbox" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onmousedown={createElement}>
        <yield></yield>
    </svg>
    <script>
        createElement(e){
            var tag = document.createElementNS("http://www.w3.org/2000/svg",'r-rect');
            this.refs.svgbox.appendChild(tag);
            riot.mount(tag,'r-rect',someopts);
        }
    </script>
</r-svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment