localDom API and other libraries

140 views
Skip to first unread message

Eric Eslinger

unread,
May 18, 2015, 8:46:20 PM5/18/15
to polymer-dev
One of the really rad things about Polymer (0.5) and webcomponents is that everything is just DOM. You can pretty easily use core- and paper- components libraries inside of an (say) angular app to render out content. Doesn't matter if you're using jQuery raw or ember or what have you- DOM is DOM, and it mostly works (modulo some property / attribute bindings)

The new localDom API seems to indicate that this may no longer be the case- if I'm redistributing DOM content, I need to use the polymer dom interface, rather than just plain parent/child/append calls on document.

This seems to indicate that modern polymer isn't going to be compatible with angular, or with any other library that manipulates the DOM, or is it the case that this only matters when there's more complicated shady/light manipulations?

As an example, if I have content in the drawer part of a paper-drawer-panel, and then, using jquery or some other element selector, inject nodes inside of the already-projected menu div, will this break things? Or is it only the case that I need to use the local DOM api when if I'm changing the nodes that would be selected as content to project (and not their child nodes)?

Is there some way to shim the document-level query selectors in there or add a mutation observer that calls distributeContent as needed? I'm guessing it was this shimming and mutation observer that contributed to the slowness of 0.5 in non-chrome browsers.

I've got next week blocked out to actually work on getting angular 1.4 to play nice with polymer 0.9 (we use angular to build the page and manage data, and polymer for handy flexbox directives and material design ui bindings). So I guess I'll figure it out then.

e

Scott Miles

unread,
May 18, 2015, 9:16:21 PM5/18/15
to Eric Eslinger, polymer-dev
>> One of the really rad things about Polymer (0.5) and webcomponents is that everything is just DOM. You can pretty easily use core- and paper- components libraries inside of an (say) angular app to render out content. 

This is truly the great promise of Web Components, and will be completely true when Shadow DOM is native in all browsers. However, up to now, we've only had the Shadow DOM polyfill on non-supporting browsers. The Shadow DOM polyfill is a great piece of code, but it only approximates the interoperability we crave. There are numerous cases where the polyfill falls over: it has never been fire and forget.

More specifically, the Shadow DOM polyfill is extremely invasive: it wraps the majority of the DOM api in JavaScript. This is an imperfect task which leads to an interoperation mine-field, and dramatically degrades performance. Additionally, the Shadow DOM polyfill makes no attempt to simulate Shadow DOM CSS scoping, so styling fidelity vs native Shadow DOM is poor.

Ultimately, we decided that providing users with a Polymer experience that was sufficiently robust for production code required a different solution that the Shadow DOM polyfill, and Shady DOM was born. Shady DOM is compatible with native Shadow DOM, has a more robust CSS scoping facility, and is dramatically more performant. We feel good suggesting that developers can build and ship products using Shady DOM, a bar we never quite surmounted with the Shadow DOM polyfill.

As I mentioned at the outset, the true promise of Web Component will not be achieved until Shadow DOM is truly native across browsers. The great news is that all major browser vendors are actively working towards this goal. Go take a look at the recent discussions on public-webapps mailing list if you want to see the sausage being made.

Users interested in Web Components are encouraged to chime in and let the browser vendors know their feelings on the importance of Shadow DOM interoperation.

Scott


Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/CABsi40JyUq76PSwF%2Bxx_k9CXcJtJmnXEOVXstdQu6BVRoYRc6g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Justin Fagnani

unread,
May 18, 2015, 9:19:21 PM5/18/15
to Eric Eslinger, polymer-dev
On Mon, May 18, 2015 at 5:46 PM, Eric Eslinger <eric.e...@gmail.com> wrote:
One of the really rad things about Polymer (0.5) and webcomponents is that everything is just DOM. You can pretty easily use core- and paper- components libraries inside of an (say) angular app to render out content. Doesn't matter if you're using jQuery raw or ember or what have you- DOM is DOM, and it mostly works (modulo some property / attribute bindings)

The new localDom API seems to indicate that this may no longer be the case- if I'm redistributing DOM content, I need to use the polymer dom interface, rather than just plain parent/child/append calls on document.

This seems to indicate that modern polymer isn't going to be compatible with angular, or with any other library that manipulates the DOM, or is it the case that this only matters when there's more complicated shady/light manipulations?

The full answer is that there are a range of options with various trade-offs, and for Polymer.dom() there will be a set of workarounds for integration with various libraries.

The best option, if available, is native Shadow DOM. But that's not so interesting because everything just works :) So, without native, there are now two options: Shady DOM and Shadow DOM polyfill. It's important to note that you can still use the full polyfill.

The polyfill has the upside that it's _mostly_ compatible with existing code (there are some cases that aren't wrapped, like `document`). The downside is that it's slow, possibly unacceptably slow in mobile Safari, say.

Shady DOM is fast, but brings up the compatibility issue.

But... we've done experiments with making other libraries use Shady DOM and it looks like it'll work well enough in a lot of situations.

One strategy is custom adapters. Angular2 for instance has a complete DOM abstraction so that it can use different APIs, like virtual DOM and Dart's dart:html. It's really trivial to implement a Shady DOM version, and it all works as expected. I'm guessing that virtual-dom-ish oriented frameworks like React and Ember will be amenable to this kind of adaptor, though they may not be as easily hookable as Angular2.

Another strategy is patching just enough of the DOM APIs to make a framework happy. We think we can do enough for React, since it uses a pretty small portion of the DOM APIs.
 

As an example, if I have content in the drawer part of a paper-drawer-panel, and then, using jquery or some other element selector, inject nodes inside of the already-projected menu div, will this break things? Or is it only the case that I need to use the local DOM api when if I'm changing the nodes that would be selected as content to project (and not their child nodes)?

Is there some way to shim the document-level query selectors in there or add a mutation observer that calls distributeContent as needed? I'm guessing it was this shimming and mutation observer that contributed to the slowness of 0.5 in non-chrome browsers.

Exactly, but again the full polyfill is still available.
 

I've got next week blocked out to actually work on getting angular 1.4 to play nice with polymer 0.9 (we use angular to build the page and manage data, and polymer for handy flexbox directives and material design ui bindings). So I guess I'll figure it out then.

I'm guessing that Angular1 will be a little harder to get working than Angular2, but since I know my way around Angular a _little_, I'd be very happy to help out.

Cheers,
  Justin

Eric Eslinger

unread,
May 18, 2015, 10:18:56 PM5/18/15
to Justin Fagnani, polymer-dev
Hmm, this all makes sense, and I totally understand the decision process here. It is definitely mobile safari that's driving me here (personally); our webapp is one of those vertical things - captive audience, internal users. So I don't feel terribad saying "please use chrome", where I could rely on the native shadow DOM implementation to make stuff mostly work. It's really mobile safari where I've got issues (it's harder to get people to use chrome on ios than on desktops).

Maybe the full shadow polyfill is what I stick with first, if that keeps everything else on the up-and-up. We'll see- maybe I can grab the appropriate hooks into angular 1. I *really* want to use the css variable-based theming stuff you're providing in polymer 0.9. It's super-rad. The speed hasn't been a horrendous problem, but I have noticed some other inconsistencies in third-party stuff with event retargeting and oddly, document.createTreeWalker, enough to make me want to see if I could get off of the full polyfill.

Of course, maybe I'm just being too ambitious. Stick with just angular for a bit, port my UI to ngMaterial, and come back in a year when the platform is more stable and there's (hopefully) better cross-browser native implementations of shadow DOM stuff. Hard to say which would be more difficult. Probably best if I try both and see what happens.

e

jim.j...@gmail.com

unread,
May 19, 2015, 9:09:18 AM5/19/15
to polym...@googlegroups.com
Was there a reason that the built-in versions of the Polymer.dom API couldn't be monkeypatched? In other words, why not make document.querySelector or element.querySelector behave like Polymer.dom's version? Wouldn't this increase interoperability with third party libraries?

Steve Orvell

unread,
May 19, 2015, 3:48:21 PM5/19/15
to jim.j...@gmail.com, polym...@googlegroups.com
We have experimented with patching dom traversal and mutation api's, and there's an experimental import in Polymer that does this. It can let some libraries interoperate more smoothly with Shady DOM powered elements that, for example, perform distribution. We're continuing to work on it and explore if it should be integrated out of the box or be available as an opt in layer.

On Tue, May 19, 2015 at 6:09 AM, <jim.j...@gmail.com> wrote:
Was there a reason that the built-in versions of the Polymer.dom API couldn't be monkeypatched?  In other words, why not make document.querySelector or element.querySelector behave like Polymer.dom's version?  Wouldn't this increase interoperability with third party libraries?
Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.

Eric Eslinger

unread,
May 20, 2015, 12:52:01 PM5/20/15
to Steve Orvell, jim.j...@gmail.com, polym...@googlegroups.com
Hmm, the good news is that just shutting my eyes, going "la la la" and pretending that Polymer.dom doesn't exist seems to work just fine. I built a test angular application that uses paper-drawer-panel, paper-header-panel, and paper-icon-button to add paper-icon-buttons to a list on a timeout using angular's $interval callback to append items to an array and angular's ng-repeat and ng-if directives to manipulate the DOM.

My hypothesis here is that I'm only ever really adding new child nodes in the already-distributed DOM elements.

I whipped up a simple bunch of test cases for most of my UI elements here:


in the event anyone cares to keep score at home. I'd love someone to point out areas where the Polymer shady DOM is going to bite me in the .. well any place would be a bad place to be bitten. If I can get this working for all of the polymer elements I currently use in production, I'll move forward on it.

e

Justin Fagnani

unread,
May 20, 2015, 1:19:24 PM5/20/15
to Eric Eslinger, Steve Orvell, jim.j...@gmail.com, polym...@googlegroups.com
On Wed, May 20, 2015 at 9:51 AM, Eric Eslinger <eric.e...@gmail.com> wrote:
Hmm, the good news is that just shutting my eyes, going "la la la" and pretending that Polymer.dom doesn't exist seems to work just fine. I built a test angular application that uses paper-drawer-panel, paper-header-panel, and paper-icon-button to add paper-icon-buttons to a list on a timeout using angular's $interval callback to append items to an array and angular's ng-repeat and ng-if directives to manipulate the DOM.

My hypothesis here is that I'm only ever really adding new child nodes in the already-distributed DOM elements.

Yes, you can probably get away with a lot as long as your only ever creating new Polymer elements, and not modifying their direct light children.

I whipped up a simple bunch of test cases for most of my UI elements here:


in the event anyone cares to keep score at home. I'd love someone to point out areas where the Polymer shady DOM is going to bite me in the .. well any place would be a bad place to be bitten. If I can get this working for all of the polymer elements I currently use in production, I'll move forward on it.

The time it'll bite you is when you want to use some awesome element that uses it's light-children as APIm like marked-element, or you use an ng-repeat in a Polymer element, etc. I do think there will be workarounds, such as forking ng-repeat to use Polymer.dom, but in Angular1 I suspect it'll be piecemeal patches, rather than a single fix as with Angular2.

Of course your other option is to just use Polymer for your whole app ;)
 

e

On Tue, May 19, 2015 at 12:48 PM 'Steve Orvell' via Polymer <polym...@googlegroups.com> wrote:
We have experimented with patching dom traversal and mutation api's, and there's an experimental import in Polymer that does this. It can let some libraries interoperate more smoothly with Shady DOM powered elements that, for example, perform distribution. We're continuing to work on it and explore if it should be integrated out of the box or be available as an opt in layer.

On Tue, May 19, 2015 at 6:09 AM, <jim.j...@gmail.com> wrote:
Was there a reason that the built-in versions of the Polymer.dom API couldn't be monkeypatched?  In other words, why not make document.querySelector or element.querySelector behave like Polymer.dom's version?  Wouldn't this increase interoperability with third party libraries?

Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/2ed4c38f-8544-4a29-b79d-aad0ee0c40aa%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/polymer-dev/CA%2BrMWZhJJtkY_jKm8mSaLavGj3tRSk8Gonka%3DVfgEdD%2BoUaBeQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Follow Polymer on Google+: plus.google.com/107187849809354688692
---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.

jim.j...@gmail.com

unread,
May 20, 2015, 1:36:19 PM5/20/15
to polym...@googlegroups.com
Is the experimental import for avoiding Polymer.dom documented anywhere?  I'd be interested in trying it out.

Justin Fagnani

unread,
May 20, 2015, 1:41:47 PM5/20/15
to jim.j...@gmail.com, polymer-dev
On Wed, May 20, 2015 at 10:36 AM, <jim.j...@gmail.com> wrote:
Is the experimental import for avoiding Polymer.dom documented anywhere?  I'd be interested in trying it out.

It's not experimental, it's the same Shadow DOM polyfill that we've had for a a long time: https://github.com/webcomponents/webcomponentsjs

webcomponents.js includes the full polyfill, webcomponents-lite.js doesn't.

 

Follow Polymer on Google+: plus.google.com/107187849809354688692

---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.

jim.j...@gmail.com

unread,
May 20, 2015, 1:48:40 PM5/20/15
to polym...@googlegroups.com, jim.j...@gmail.com
"We have experimented with patching dom traversal and mutation api's, and there's an experimental import in Polymer that does this. It can let some libraries interoperate more smoothly with Shady DOM powered elements that, for example, perform distribution. We're continuing to work on it and explore if it should be integrated out of the box or be available as an opt in layer."

See the above quote.  I just want to make sure I was clear about what I was asking about, as Steve Orvell seemed to be hinting at something that would work with Shady DOM and not require falling back to Shadow DOM.

raz...@gmail.com

unread,
May 20, 2015, 3:40:31 PM5/20/15
to polym...@googlegroups.com
Just wanna make sure...
If I build a web-app that targets the Chrome browser, or any browser that will have native Shadow DOM support, can I refrain from using the Polymer.dom APIs, and use native DOM APIs?

Justin Fagnani

unread,
May 20, 2015, 3:43:22 PM5/20/15
to raz...@gmail.com, polymer-dev
On Wed, May 20, 2015 at 12:40 PM, <raz...@gmail.com> wrote:
Just wanna make sure...
If I build a web-app that targets the Chrome browser, or any browser that will have native Shadow DOM support, can I refrain from using the Polymer.dom APIs, and use native DOM APIs?

I would not do this. If you're writing code, use Polymer.dom and everything will just work, whether in a browser with native Shadow DOM or not, or using the full polyfill or not. The question here is what to do about other libraries that you don't control that don't use Polymer.dom. That's where adapters, patching or falling back to the polyfill come into play.




On Tuesday, May 19, 2015 at 3:46:20 AM UTC+3, Eric Eslinger wrote:
One of the really rad things about Polymer (0.5) and webcomponents is that everything is just DOM. You can pretty easily use core- and paper- components libraries inside of an (say) angular app to render out content. Doesn't matter if you're using jQuery raw or ember or what have you- DOM is DOM, and it mostly works (modulo some property / attribute bindings)

The new localDom API seems to indicate that this may no longer be the case- if I'm redistributing DOM content, I need to use the polymer dom interface, rather than just plain parent/child/append calls on document.

This seems to indicate that modern polymer isn't going to be compatible with angular, or with any other library that manipulates the DOM, or is it the case that this only matters when there's more complicated shady/light manipulations?

As an example, if I have content in the drawer part of a paper-drawer-panel, and then, using jquery or some other element selector, inject nodes inside of the already-projected menu div, will this break things? Or is it only the case that I need to use the local DOM api when if I'm changing the nodes that would be selected as content to project (and not their child nodes)?

Is there some way to shim the document-level query selectors in there or add a mutation observer that calls distributeContent as needed? I'm guessing it was this shimming and mutation observer that contributed to the slowness of 0.5 in non-chrome browsers.

I've got next week blocked out to actually work on getting angular 1.4 to play nice with polymer 0.9 (we use angular to build the page and manage data, and polymer for handy flexbox directives and material design ui bindings). So I guess I'll figure it out then.

e

Follow Polymer on Google+: plus.google.com/107187849809354688692

---
You received this message because you are subscribed to the Google Groups "Polymer" group.
To unsubscribe from this group and stop receiving emails from it, send an email to polymer-dev...@googlegroups.com.

Arthur Evans

unread,
May 20, 2015, 4:01:04 PM5/20/15
to Eric Eslinger, Steve Orvell, jim.j...@gmail.com, polym...@googlegroups.com
Hi Eric,

One thing that is going to bite you is styling. If you don't use the Polymer.dom APIs, the children added imperatively won't have the correct style-scope class added, so you may see styling anomalies. (For example, those children will behave as if they aren't in shadow DOM, and be styled by document-level CSS.)

There is an scopeSubtree method that may help you here. It's designed for situations where you have a plugin or third-party library that just wants to squirt some DOM nodes into a container. You'd do something like this:

   this.scopeSubtree(myContainerNode, observe);

If observe is true, it creates a mutation observer and scopes descendants as they're added and removed from the container. If observe is false, only the current descendants are scoped.

This is certainly not a cure-all, but it may help in certain cases.
 
OK
Arthur


On Wed, May 20, 2015 at 9:51 AM, Eric Eslinger <eric.e...@gmail.com> wrote:

Eric Eslinger

unread,
May 20, 2015, 5:20:27 PM5/20/15
to Arthur Evans, Steve Orvell, jim.j...@gmail.com, polym...@googlegroups.com
Hmm, styling is a big deal- I'll keep a close eye on it. Thanks for the heads up. It's actually this x-platform style selector thing that caused us a lot of woes in 0.5.5 (we, like many other small-scale web teams, developed mostly on chrome and then were kind of nonplussed by the look and feel when we started testing on browserstack). So maybe unscoped styling isn't even the end of the world at this point, given the amount of /deep/ stuff we were doing earlier (just try and theme a paper-dialog where layered="true").

That mutation observer thing would help a *lot* - there's only a few containers that I really change at run-time, and I could just flag them with an angular element so <div watch-subtree></div> would set up and tear down the mutation observers. Given the push away from two-way binding anyway, this feels like a reasonable thing to do - flag the dom subtrees that are mutable via model events and only watch there.

e

Kevin Schaaf

unread,
May 20, 2015, 5:23:39 PM5/20/15
to jim.j...@gmail.com, polymer-dev
Jim,

You can find the experimental patching import here:

It has not been tested extensibly and there are a number of caveats (e.g. there is some performance impact, document.querySelector will traverse shady roots, etc.) so your mileage may vary.

Kevin

Reply all
Reply to author
Forward
0 new messages