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

Cannot dynamically import templates under safari with webcomponents-lite.js #2157

Closed
plequang opened this issue Jul 27, 2015 · 3 comments
Closed
Assignees

Comments

@plequang
Copy link

Hi,

We have developed a routing element, based on app-router, that allows to load views dynamically. These views are dom-bind templates defined in external html files.

Views are imported using link rel="import"tags. Once the file is loaded, its content is imported into the document using document.importNode and then appended to the document.

I've created this jsbin that tries reproduces how this is implemented:
http://jsbin.com/dedenaviho/1/edit?html,output

The imported template looks like the following (hosted here for the jsbin purpose: https://gist.github.com/plequang/37cb1f3ad0ecc18a3e74) :

<template>
    <template is="dom-bind">

    This is the template content

    <x-test>
        <button>My test button</button>
    </x-test>
    </template>
</template>

All this process is working correctly under Chrome and Firefox, but not Safari (8.0.6).

Safari behaves like if importNode isn't importing templates content.

Hoewever, if I use full webcomponents.js polyfill (not the lite version), then it works on safari as well.

I've seen this issue #1888, and tried to use Polymer.dom.importNode instead of document.importNode, but with no success (it does not work in Chrome either if I use this dom API function).

I've also found in the shadow DOM polyfill there is a redefinition of importNode (https://github.com/webcomponents/webcomponentsjs/blob/master/src/ShadowDOM/wrappers/Node.js#L257), that specifically clones the content of templates, so maybe what I'm trying is possible only with ShadowDOM.

What I've not managed to understand is how polymer with shady dom can load custom elements templates content correctly, but not my template files.

Actually, I'm not sure if this is a polymer issue or a webcomponents polyfill issue.

@kevinpschaaf
Copy link
Member

This is due to a Safari bug with their native template implementation (you can read a description from a similar bug posted here). We confirmed that it is fixed in WebKit nightly, but it's not yet in a stable version of Safari yet.

In the meantime, I've fixed the cloneNode implementation you copied from the full wcjs polyfill to properly clone template content as "inert" so that it does not upgrade, which solves the problem you were having with it. Using that implementation should be a good workaround for you in the short-term.
http://jsbin.com/qixeve/edit?html,output

I've also opened a bug on the wcjs tracker to consider polyfilling importNode for templates, since the same use case would fail on IE (which has no native template support) in a similar way, and applying that polyfill implementation on Safari as well would avoid the problem you had.
webcomponents/webcomponentsjs#362

@plequang
Copy link
Author

Thanks a lot.

Your workaround for cloneNode works perfectly on safari.

@nomego
Copy link

nomego commented Aug 10, 2015

Actually, this didn't work out for more complex templates.
For example, adding a <template is="dom-repeat"> in the dom-bind template causes the error Polymer::Attributes: couldnt decode Array as JSONbecause it's being sent theitems` statement instead of the bound data.

Example gist: https://gist.githubusercontent.com/nomego/515a3681142c8d0d14f1/raw/36b1322b6e9e8b10166e76093160f0b8bad96952/template.html

JSBin: http://jsbin.com/demisaqupo/edit?html,console,output

The template still works though!

But, even more complex examples (which I haven't been able to reproduce on jsbin), causes inst._nodes to contain undefined items, which causes deserialize in Polymer standard to find undefined nodes and fail on addEventListener.

The way both issues above can be solved on Safari is to change the cloneNode function to simply:

    function cloneNode(node) {
      var clone = document.importNode(node, false);
      clone.innerHTML = node.innerHTML;
      return clone;
    }

nomego pushed a commit to Neovici/cosmoz-router that referenced this issue Aug 10, 2015
- Fixes `Polymer::Attributes: couldn't decode Array as JSON`
- Fixes `addEventListener` on undefined nodes in Polymer `deserialize`

Fixes #4
Replaces workaround from Polymer/polymer#2157
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants