-
Notifications
You must be signed in to change notification settings - Fork 255
Use DOM for marker content (allows listeners to work) #294
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
base: master
Are you sure you want to change the base?
Use DOM for marker content (allows listeners to work) #294
Conversation
|
Any idea when this fix will be released? |
|
This fixed my issue :) |
| }); | ||
|
|
||
| var content = this.innerHTML.trim(); | ||
| var content = this.children[0]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is selecting the first light dom child. are you meaning to pull the <div> in this element's shadow dom? I think this will work b/c of shady dom but fail under native shadow dom.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I'm not the author of this pull request, just interested in getting the issue fixed)
I've tried this line (369) with all four combinations of shady dom, shadow dom, webcomponents and webcomponents-lite and it certainly seems to work. Why might it fail under shadow dom?
On the other hand, issues:
The next line, 370 if (content) { ... }, fails because content always contains the new div element now so content itself is always true. This leads to opening an empty infowindow. Maybe 370 if (content.innerHTML.trim()) { ... }
More serious, Polymer ink bearing elements crash the infowindow. For example, when a paper-button or paper-icon-button is clicked inside the infowindow, elements are added inside the button to show the ink effect. This triggers _contentChanged() in the middle of the ink actions, and the infowindow content winds up empty. Non ink elements don’t seem to have this problem, for example an iron-icon with an on-tap event works fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to figure out why the <div> was added to the element's shadow dom. Also, var content = this.children[0]; won't select marker content if it's just text content (<google-marker>text content</google-marker>).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mlisook can you file a separate issue on the ink elements not working? That'll need investigation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, right you are, this.children[0] will not pick up content that is just text in shadow dom.
Well I’m fairly certain the idea behind adding the div was to be able to get a single element that could be moved into the infowindow content in one step, minimizing content change events. The way the infowindow content is currently populated with this.innerHTML.trim() leaves event bindings behind, of course.
The ink issue applies only to this pull request, not to the released code base, so I don’t think a new issue is appropriate.
While it may be possible to loop through this.childNodes to set the infowindow content and control for the content change events during the assembly, I’m now doubtful that issue #288 can be resolved with infowindow markup as content of the marker. Rapid mutation, such as the ink example, is just one reason.. There are alternatives to using the infowindow to display information on top of a map.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No please, don't abandon it, it's working fine and we need actions from within the infowindow
I am using a all the changes (in lines 41, 369, 384, plus new line 399) and it works in both scenarios:
- with data binding and actions (code) within the infowindow element
- and also working fine with just text as you suggested (text content)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ebidel Sorry, I've been busy with other projects and haven't been able to get back to these until now.
@mlisook is correct that the div was added so that you could depend on this.children[0] containing all of the contents. I can look into whether there's a way to make it work with just a text node and fix the if (content) predicate.
@mlisook, Not sure I understand what your theory is on why the ink elements don't work in the InfoWindow. What's the fundamental problem you see with moving the DOM node?
Is there another possible way to preserve the events handlers attached to the contents of the marker besides this idea? Realistically, the google-maps-marker element is radically less useful without this ability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My original question of whether this will work under native shadow dom is still bothering me. this.children[0]will give you the marker's light dom, but you've added the <div> wrapper to the element's shadow dom. This will require users to use a single wrapper for their marker content, so I'm not sure what the internal wrapper does.
<google-map-marker>
<div>...</div>
</google-map-marker>
One thing you could do is use (this.$.contentwrapper), and the id: <template><content id="contentwrapper"></content></template>, and pull the distributed nodes: this.$.content.getDistributedNodes() to see what users have put inside the marker element. Then, wrap all that in a single <div>?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tst-dhudlow fundamentally, moving the DOM is absolutely the right thing to do. I also agree that preserving event handlers is vitally important.
I don't really understand what's happening during the ripple/ink effect, but it's not (as I had thought) that the infowindow content is destroyed - it's still there, but the display of the content in the browser is gone (see pics).
before clicking paper-icon-button +

after clicking paper-icon-button

Demo Code
ink-demo-pull-294.zip
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ebidel In my use case, I'm using <google-map-marker><h2>...</h2><custom-element>...</custom-element>...</google-map-marker> not using a single wrapper. Using just text works as well for me.
I'm afraid I'm a bit fuzzy on the shadow dom / light dom distinction or what use cases the method I'm using breaks.
|
@tst-dhudlow can you take a look at my comments? Interested in getting this merged. |
|
I have been using the modified code and it's working fine for my purpose of having binding and interaction within the info-window
This is the code I am using, in case you want to reproduce these issues. |
|
@tst-dhudlow I'm sorry, but the concept of the wrapping I'll admit that when I first saw this I thought it was clever, brilliant even. Now, however, I know more than I ever thought I wanted to about shadow. See this JS Bin with the chrome browser to illustrate. The With chrome's support for shadow dom pretty robust, the Polymer team is recommending to run with shadow as the default (e.g. see what's generated by the polymer cli) and just fall back to shady if the browser doesn't support shadow. We're just not going to be able to have a fix that doesn't work in shadow. |
|
I think my comments in #294 (comment) still need to be addressed. |
|
@ebidel The method in your comment from last week will work to allow the content of a child, like the google-map-marker, to be moved into a parent's shadow dom (google-map). I set up a JS Bin with an ultra simplified demo (ultra, like not even a google-map). It is analogous though. Infowindow creates a div inside the map div for its styled contents, then translates that into place within the map div. The JS Bin works on both shadow and shady. What I don't know, however, is the inner workings of Infowindow. Based on the last comment by @Fausto-theXS and my comment 11 days ago about ink bearing / ripple elements, it seems like the Infowindow has its own content / mutation observer. It may not be compatible with the types of action that happen in material design elements. In the sample I attached last week, it can be seen that the content of the infowindow has its height and width set to 0 when the ripple fires. I have no idea why, but the elements inside do go to 0 x 0 on ripple. Its also unclear what effect styling of the content would have on moving the elements from light dom to shadow/shady. Especially in shadow, the classes from outside wouldn't apply after moving, right? This will be extremely difficult to test. |
|
I modified that last JS Bin to include a style on one of the elements moving. The style is quashed under shadow dom, but shows under shady, as I suspected. |
|
@mlisook I can try your method to move the content and test it in shadow to see if it works, but if you know what it should look like already, feel free to PR into my branch and I'll merge it so it goes into this PR. |
|
@tst-dhudlow I can do that (PR into your branch), but I'm in an area with only sketchy internet access until after the holiday. With that it should be possible to support everything but styles. As far as I can tell there's no way the Infowindow will support style classes under shadow dom. To have full support we'd have to go big - not using infowindow at all. That would involve making google-map-marker a visual component that floats its content over the map on demand (like the paper-map-info, (or see demo), I did to get my current project working), but styling as close as possible to infowindow and probably duck typing the infowindow public interface. Not sure if management would entertain that, @ebidel your thoughts? |
|
I'm hesitate to support custom info windows. It's not a common case. Could On Thu, Jun 30, 2016, 8:06 AM Murray Lisook notifications@github.com
|
|
@ebidel Is there a "Polymeric" way of doing that? I'd rather do that than having thousands of infowindows in the DOM, when the user would click on just a few of them -- a huge performance improvement |
|
@Fausto-theXS the reusable window that is invoked on-google-map-marker-click is how the paper-map-info (demo) works. |
|
@ebidel I understand and agree completely. I don't think the styles thing is as important as events either, although it is outside developer's expectations, since something as straightforward as: Will never work to style the text under shadow dom with the native infowindow (but does under shady). |
|
|
||
| var content = this.innerHTML.trim(); | ||
| if (content) { | ||
| // Use this element's content DOM node for the info window content. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
element's content DOM -> element's light dom.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd still like Line 41: <template><div><content></content></div></template> changed.
The idea is that users write:
<google-map-marker>
<div>...</div> <!-- wrapper -->
</google-map-marker>
But you already have a wrapper inside shadow dom. Can we remove the one in shadow dom and update the docs to explain to users that they need to use a single wrapper in their light dom. We'll also need to rev a minor version b/c this is a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought @mlisook had a solution that didn't require the user to wrap in a single element via getContentChildNodes ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, it was traversing the existing DOM children.
|
Hi guys, |
See #288
May not be exactly the right solution, but it does seem to work.