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

template doesn't work inside svg elements #1976

Closed
bendavis78 opened this issue Jun 28, 2015 · 41 comments
Closed

template doesn't work inside svg elements #1976

bendavis78 opened this issue Jun 28, 2015 · 41 comments

Comments

@bendavis78
Copy link

For example:

    <dom-module id="test-element">
      <template>
        <svg class="clock" version="1.1" xmlns="http://www.w3.org/2000/svg">
          <template is="dom-repeat" items="{{positions}}" as="cx">
            <ellipse r="25" cx$="{{cx}}" cy="25" stroke="black"></ellipse> 
          </template>
        </svg>
      </template>
      <script>
        Polymer({
          is: 'test-element',
          ready: function() {
            this.positions = [0, 100, 200, 300];
          },
        });
      </script>
    </dom-module>

This produces the following JS error:

Uncaught TypeError: Cannot read property 'nodeType' of undefined

The problem seems to be that the dom template object doesn't have a content property. This worked fine in Polymer 0.5.

Demo here: http://jsbin.com/wiqowo/31/edit?html,output

@bendavis78
Copy link
Author

It looks like some code didn't make it over from 0.5 that explicitly addressed this issue. Template elements with a <svg> parent have the same namespaceURI (http://www.w3.org/2000/svg), so the browser doesn't implement HTMLTemplateElement. The bootstrap code in 0.5 basically transplanted all child nodes of any svg-namespaced template into a new html-namespaced template, and then inserted that node back in its place.

If anyone else is looking for a workaround, you can put this snippet at the top of your element's <script> tag (it must be evaluated before call to Polymer()). It basically performs the same operation as it was done it 0.5. note: this snippet only works in chrome atm -- not sure yet how to get firefox working

@nomego
Copy link

nomego commented Jun 29, 2015

We also hit this issue, thanks for the workaround @bendavis78 .

Will it be fixed in Polymer?

@canufeel
Copy link

canufeel commented Jul 9, 2015

@bendavis78 your snippet was a day saviour for me but it still has some problem. If you have more than one polymer element on the page and this svg element is not the first one the snippet breaks. This line:

var root = doc.querySelector('dom-module > template').content;

should be changed so dom-module becomes the actual #id-of-svg-element which is put in the <dom-module id="id-of-svg-element">

@kevinpschaaf kevinpschaaf added the p1 label Jul 9, 2015
@kevinpschaaf kevinpschaaf self-assigned this Jul 9, 2015
@kevinpschaaf kevinpschaaf added p2 and removed p1 labels Jul 10, 2015
@kevin-smets
Copy link

+1

1 similar comment
@shmendo
Copy link

shmendo commented Dec 4, 2015

+1

@ocampesato
Copy link

Same error in Chrome 49, even with the tweaked version of svg-template-support.js, and also:
svg-template-support.js:4 Uncaught TypeError: Cannot read property 'content' of null

@raghav135
Copy link

+1 same error in latest chrome

@brian-cruickshank
Copy link

+1

1 similar comment
@RossRothenstine
Copy link

+1

@christophe-g
Copy link

Thanks for the workaround - would be really nice to have templates within SVG work natively !

@joshuahiggins
Copy link

Does anyone know of a way to implement the workaround while still vulcanizing elements?

@christophe-g
Copy link

#3372
C.

@brian-cruickshank
Copy link

Note that the June 28, 2015 workaround does not work in Firefox 45.0.2 - it will actually prevent any of the svg from being rendered.

@boazhachlili
Copy link

Ran into this issue today. Any word on Polymer 1.0 support?

@andrewillard
Copy link

+1 same error

@fooloomanzoo
Copy link

fooloomanzoo commented Jun 12, 2016

Although there is already a pull-request #3372 that could fix the namespace issue, here would be a work-around, that would build up the svg-node recursivly node by node.

For that there could be a container-element:

<dom-module id="svg-container">
  <template>
    <svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg"></svg>
    <content select="svg-component"></content>
  </template>

  <script>
    Polymer({
      is: 'svg-container',

      attached: function() {
        for (var i = 0; i < this.attributes.length; i++) {
          this.$.svg.setAttribute(Polymer.CaseMap.dashToCamelCase(this.attributes[i].name), this.attributes[i].value);
        }
      }
    });
  </script>
</dom-module>

and a element as svg-component, that creates the kind of svg-element, to be attached:

<dom-module id="svg-component">
  <template>
    <content select="svg-component"></content>
  </template>
  <script>
    SvgComponent = Polymer({
      is: 'svg-component',

      _node: {},
      _namespace: 'http://www.w3.org/2000/svg',

      get rootElement () {
        if (this.parentNode.nodeName === 'SVG-CONTAINER')
          return this.parentNode.$.svg;
        else
          return this.parentNode._node;
      },

      factoryImpl: function(attributes) {
        for (var key in attributes)
          this.setAttribute(key, attributes[key]);
      },

      attached: function() {
        var is = this.attributes.is.value;

        if (is !== undefined) {
          this._node = document.createElementNS(this._namespace, is);
          for (var i = 0; i < this.attributes.length; i++) {
            if (this.attributes[i].name !== 'is')
              this._node.setAttribute(this.attributes[i].name, this.attributes[i].value);
          }
          this.rootElement.appendChild(this._node);
        }
      }
    });
  </script>
</dom-module>

Property binding would have to be formally and also event-binding, but you could use that to do it automatically. It would definitely be better, that SVG namespace is implemented in Polymer as an option for registration of new elements .

And in a test: plunker

@jonadeline
Copy link

@fooloomanzii Thanks a lot for the workaround. You saved me a lot of time !

+1 for native implementation.

@shahraship
Copy link

+1 for native implementation

@tjsavage tjsavage added the 1.x label Sep 8, 2016
@garryyao
Copy link

+1

@FlorianFe
Copy link

+1

1 similar comment
@LukeusMaximus
Copy link

+1

@lao-tseu-is-alive
Copy link

+1 amazing to see one year later and still an issue

@AlexanderLang
Copy link

+1

@bcopy
Copy link

bcopy commented Dec 16, 2016

+1

@loekup
Copy link

loekup commented Feb 2, 2017

@kevinpschaaf is this going to be possible in polymer 2 ?

@sz332
Copy link

sz332 commented Feb 15, 2017

This is still an issue :(

@garryyao
Copy link

garryyao commented Apr 6, 2017

Provided a workaround for now, tested in FF/Safari/IE, bundled/unbundled.
https://github.com/garryyao/polymer-svg-template

@alijaya
Copy link

alijaya commented Jun 24, 2017

any official workaround here?

@super-kamil
Copy link

+1

4 similar comments
@jmonsma
Copy link

jmonsma commented Sep 20, 2017

+1

@axax
Copy link

axax commented Sep 24, 2017

+1

@TrentBrown
Copy link

+1

@AbiSadhasivam
Copy link

+1

@renfeng
Copy link
Contributor

renfeng commented Jan 9, 2018

+1

@renfeng
Copy link
Contributor

renfeng commented Jan 10, 2018

For people looking for a working solution,
#1976 (comment)

@TimvdLippe
Copy link
Contributor

We have a proposal for a core solution:

Detect if a <template> is inside an element that is in a SVG namespace (if it has namespaceURI which is SVG), then swap its contents into an svg element, do the parsing and then swap it back. This should be in parse-template.

The way to handle the transformation, is to expose a function Polymer.svg which transforms a tagged string into the corresponding svg namespace and returns the corrected template.

This whole process ensures that the elements are parsed in the correct namespace, to make sure the actual nodes are created. Then once the parsing has completed, we can swap the correctly constructed nodes back into the template.

We will be working on this issue this week to hopefully finally fix svg compatibility with templates + custom elements.

@TimvdLippe
Copy link
Contributor

Above comment has been implemented in #5135. Would be great to get some feedback whether this is actually working for your use-cases 🎉

@kevinpschaaf
Copy link
Member

Note full fix is blocked on webcomponents/shadycss#166

@Neil65
Copy link

Neil65 commented Dec 17, 2018

Is there a way forward with this issue? It seems like there is a Polymer solution (#5135) but it has been held back because of the possibility of addressing the issue at the platform level; however from what I can sense by reading whatwg/html#3553 and whatwg/html#3563 it does not seem that a platform level solution is likely any time soon.

Update: It seems that this is solved in the new lit-html templating system (https://lit-html.polymer-project.org/guide), which is at release candidate stage (as of 17 December 2018).

@stale
Copy link

stale bot commented Mar 13, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Mar 13, 2020
@stale
Copy link

stale bot commented Apr 17, 2022

This issue has been automatically closed after being marked stale. If you're still facing this problem with the above solution, please comment and we'll reopen!

@stale stale bot closed this as completed Apr 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.