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

Initialization might fail when surrounded by p-element #1180

Closed
ItsAsbreuk opened this issue Feb 11, 2015 · 20 comments
Closed

Initialization might fail when surrounded by p-element #1180

ItsAsbreuk opened this issue Feb 11, 2015 · 20 comments

Comments

@ItsAsbreuk
Copy link

There is a strange issue we've encountered during development of our own custom elements. Not polymer, but it also seems to hit Polymer elements.

Whenever a customelement is wrapped inside a p-element, initialization might fail.

While reading the innerHTML of a custom-element -on initialization-, the dom seems to do a miscalculation on some child-elements. That is: some childNodes might be missing. It depends on what type of child-element is within: not all fail... div does and fieldset fails. And when it encounters an unprocessable element, the rest of the content is disregarded. So, you could end up with a "partial" inner-content.

This jsbin shows when the dom fails to see some child-elements --> look at the console to find out that the 3th element seems to be empty. It inspects innerHTML, but inspecting the childNodes gives the same result. And all browsers seem to act the same.

For now, we changed the design-setup for our custom elements to accept only comment-nodes inside their definition. Something like this:

<p>
<my-element><!--
      <div>Front</div>
      <div>Back</div>
--> </my-element>
</p>

And use a html-parser to create true nodes from the read comment-node, which is processed further.

Even though i'm not using Polymer, it would be great if you guys know what's going on and find a solution.

Thx,

Marco Asbreuk

@ItsAsbreuk
Copy link
Author

If I'm right, this probably means the end of Polymer in its current form and needs re-design.
So, I'm surprised no one picks it up.

Can anyone confirm the issue?
And why this jsbin shows an empty third line in the console?

@pflannery
Copy link

I found that its because P does not allow block elements Stack overflow
Removing the DIV will make it work..

@pflannery
Copy link

it is possible to use

<span style="display: block;">

but not

<div style="display: inline;">

@ItsAsbreuk
Copy link
Author

Interesting. that is likely to be the reason for this behaviour.

It still means you cannot design custom-elements that have a block-element inside their definition. And there are many arround already. They will fail initializing when placed inside a p-element.

@pflannery
Copy link

You can have custom-elements that contain block elements sit inside a P element. I'm wondering if your seeing this issue because your using a shadow element? which would mean you need to access the innerHTML via {parentElement}.shadowRoot.innerHTML

shadow and no-shadow example in a P element

@ItsAsbreuk
Copy link
Author

I'm not using Polymer, but our own definition of custom-elements that don't use shadow-elements (because we build serverside-renderable elements)
However, the issue is the same.

I made a small setup that shows Polymer fails as well when using custom-elements inside p-elements:

http://jsbin.com/livinujije/1/

When the p-element gets removed, it will work.

@ItsAsbreuk
Copy link
Author

it also will work if you leave the p-element, yet remove the h2 and div

@miztroh-zz
Copy link

To me, this looks like the browser is simply moving the block level elements outside of the p tag. Per the HTML spec, p tags can only contain "phrasing content". See http://www.w3.org/TR/html-markup/p.html.

I've created a modified example. If you inspect the page, you'll see that the core-overlay works just fine and displays the span it contains, but all the block level elements have been moved out of the overlay and into the body of the page.

http://jsbin.com/wiyifazora/2/edit

@ItsAsbreuk
Copy link
Author

yeah, that's the issue. Just like pflannery mentioned here.

It basicly means you cannot use block-elements when designing custom-elements (or you must assume no one puts them inside a p-element).

Because neither is a workable sollution, we've changed the setup to only accept comment nodes inside

@miztroh-zz
Copy link

@ItsAsbreuk If page HTML violates the spec (especially when there's consistency among browser implementations of said spec), its authors should be prepared for the end result to differ from the desired output. You can only go so far to protect people from themselves ;)

@ItsAsbreuk
Copy link
Author

@miztroh haha, you're absolutely right. But I'm wondering where spec-violation concerning custom-elements or its childnodes is defined ;)

@miztroh-zz
Copy link

@ItsAsbreuk Custom element children (light DOM) follow the same rules. You could create a custom element that contains a core-overlay and its children in its shadow DOM. That would protect them from the block level element issue.

@ItsAsbreuk
Copy link
Author

@pflannery @miztroh thx for your comments.
I'll close the issue for I know what causes the behaviour. I''l leave it to Polymer whether they find it acceptable or not.

@Ajedi32
Copy link

Ajedi32 commented Jun 16, 2015

But I'm wondering where spec-violation concerning custom-elements or its childnodes is defined

Yeah, I'm really curious about that too.

@ItsAsbreuk
Copy link
Author

@miztroh, @Ajedi32: it says:

A start tag whose tag name is one of: "address", "article", "aside", "blockquote", "center", "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", "section", "summary", "ul"

Correctly spoken, what happens seems to be right.

On the other hand, the tag that the user want to insert is a custom tag, not itself one of those specifed above. What we see is that the p-element is closing, because one of the descendants of the custom-element has one of the tags mentioned above. But those descendents were meant to initialize the custom element and may probably not even end up in the dom after rendering.

So, it is pretty confusing for end-users who want a custom element inside a p-element to run into this issue. As far as it concerns Polymer, creators of custom elements need to avoid using the specified elements, or mention it strongly in the documentation that it should not be used inside a p-element

@miztroh-zz
Copy link

@ItsAsbreuk, @Ajedi32: Take a look at this link. It gives the spec for the p tag, listing its "content model" as "phrasing content". You can then click on "phrasing content" for a list of tags that are viable as children of elements whose content model is phrasing content.

http://www.w3.org/html/wg/drafts/html/master/single-page.html#the-p-element

So, the spec is quite clear on this. Custom elements aren't on the whitelist for allowed paragraph children. This issue has nothing to do with custom elements specifically. For example, the following would not give you what you might expect.

<p><div>test1</div>test2</p>

Instead, it produces the following:

<p></p><div>test1</div>test2<p></p>

I don't think it should be the Polymer team's responsibility to document all the caveats involved in constructing spec-compliant HTML.

@ItsAsbreuk
Copy link
Author

@miztroh (@Ajedi32 ), I didn't see that part, so again what you say is true (though quite understandable for the fact that custom-elements are only recently implemented at their full strength).

I personal disagree with the responsibility part. Imo, because CE only recently found their way, and to protect end-users from running into edge cases, it is Polymer team's responsibility to define the playground where the CE should be used.

@Ajedi32
Copy link

Ajedi32 commented Jun 16, 2015

That spec doesn't mention custom elements at all though. So what content category does a custom element have? Going exclusively by those specs, aren't custom elements invalid no matter where you place them? The custom elements spec doesn't seem to specify a content category for custom elements either.

I think this behavior has more to do with the section on tag omission.

A p element's end tag can be omitted if the p element is immediately followed by an address, article, aside, blockquote, details, div, dl, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, main, menu, nav, ol, p, pre, section, table, or ul, element, or if there is no more content in the parent element and the parent element is an HTML element that is not an a, audio, del, ins, map, noscript, or video element.

As soon as the parser sees one of the other tags on the "blacklist" (if you want to call it that), it closes the p tag. Does that sound right to you?

@adalinesimonian
Copy link

Polymer is not Web Components. Polymer is only there to make creating Web Components easier, provide useful utilities, and provide its own library of custom elements for use. Thus, I disagree that it is the "Polymer team's responsibility to define the playground where ... [custom elements] should be used" because that's not within the bounds of the Polymer project in the first place.

Instead, the heart of the problem described here seems to rest not within the Polymer library, but within the semantics of the HTML <p> tag. Therefore, I think that feedback like this should be going towards the HTML standard and/or the Web Components standard instead of towards Polymer.


That all being said, here's something interesting to take a look at: http://jsbin.com/zetiziceza/edit?html,output

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

5 participants