[Explanation inside]How to use Polymer with shady DOM


#1

Hi, I’ve managed to understand how to use Polymer with Meteor after a long struggle. I thought I would cross-post this from an answer I gave up in another meteor thread, since I can imagine some people are really curious about this.

You can see it in action working here (though I have no idea about bugs + I haven’t actually checked if the polyfill is broken right now … sometimes somehow I manage to make it break in FF/IE/Safari)

www.pigments.io/landing

You can see it here ( the markers are data from a mongo collection and you can filter them. Disable “silk screen” under “processes” to see it work). This is done with shady DOM, not the old shadow DOM polyfill.

Meteor and Polymer don’t work that well together out of the box. Why? When you use a custom-element such as

<paper-dropdown></paper-dropdown> 

Polymer generates DOM like this

<paper-dropdown>
    <div>
         <div>this is a random visualization to visualize div soup</div>
    </div>
</paper-dropdown>

Now, if you have something like this:

<paper-dropdown>
    {{#each bla}}
        <paper-item>blubb</paper-item>
    {{/each}}
</paper-dropdown>

Meteor get’s all confused because of the DIV soup and it’s like "What, I don’t get it, where am I supposed to put the paper-items in the #each helper? With shadow DOM this does not happen, because custom-elements with native shadow DOM are essentially normal HTML elements that you have built yourself. The old shadow DOM polyfill therefore works with Meteor - but is freaking slow.

As of today, only Chrome and Opera support shadow DOM. Safari has recently implemented shadow DOM but it is not yet shipped. Edge and Firefox are most likely working on the integration right now as well (just about 1-2 months ago all browser vendors agreed on a final v1 of shadow DOM).

Since the shadow DOM polyfill is slow, Google/smart people at https://github.com/webcomponents/webcomponentsjs came up with shady DOM, which roughly emulates shadow DOM, but not as strict as the old polyfill. It works a lot faster but: DIV soup that makes meteor and other frameworks sad.

Now, how do we solve this? Simple! We don’t generate new HTML elements with meteor. Instead, we only pass data (objects, arrays) to a custom Polymer element. This custom element contains all the frontend stuff we need. So in case of a {{#each}} helper what we do is this:

<map-view map-data='{{map-data-meteor'}}></map-view>

map-data is a property defined in the custom element “map-view”, whereas map-data-meteor is data that is pushed to the element via a meteor helper. Now in our template, we are able to just generate the elements similarly to how the each would work:

<template is='dom-repeat' items='{{mapData}}'>
   <paper-item>{{item.somedata}}</paper-item>
</template>

Bam, magic! This is the gist of it. I’m really, really trying to reach out to people to help meteor get a better integration with Polymer. Either by creating custom DOM insertion that uses Polymer’s DOM api or by creating a router that handles stuff better. Ideally, we would get rid of blaze and jquery because we don’t need them. All we need is a way to include our custom-element and pass data to it, that’s it.


#2

@sashko Is there a place where this could be pinned so people can find this solution again? Compatibility Meteor/Polymer is usually the first question that you see here all the time when people ask about Polymer and it seems nobody has been able to figure this one out before.

It certainly requires some experience with Polymer to come up with this solution, but users can’t explorePolymer if it doesn’t work with Meteor so that’s kind of a vicious cycle and won’t resolve itself anytime soon.


#3

Great work @AndreasGalster and to make sure you reach also the other half of the world (the Polymer users that should also look how nice both can play together given your solution) I’d suggest to post this also on Medium.com which usually not only gets good hits on Google but also has lots of “Geeks” posting their code there.

Another place where a link to this forum post might make a lot of sense is in the Yeoman generator for Meteor&Polymer and other places where people usually start with a Meteor & Polymer project.

Thanks a lot for this solution, will try it in my own project with some simpler paper elements but it’s beautiful to see how little code is needed to display these pin’s on a Google map (with the full user controls that Google Maps offers already coming in for free)!


#4

@a4xrbj1 You’re welcome :). I’ll be working on a framework agnostic medium article soon and post it there. Don’t forget to share by then. Pigments is going to need some views so we can start making revenue :smiley:


#5

i think mwc:compiler package may be solve these