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

Unpredictable availability of template's content #4566

Open
tomalec opened this issue Apr 25, 2019 · 6 comments
Open

Unpredictable availability of template's content #4566

tomalec opened this issue Apr 25, 2019 · 6 comments

Comments

@tomalec
Copy link

tomalec commented Apr 25, 2019

As already discussed at web-platform-tests/wpt#15487 (comment) authors have no mean to observe whether the .content of a <template> was already parsed and the template is ready to be used.

That makes it impossible to create a custom element, autonomous <my-element><template>foo</template></my-element> or customized built-in <template is="my-template">foo</template>, which uses its template content when connected.

@rniwa:
This behavior is implementation dependent. The browser engines are free to pause the HTML immediately after it had processed the start of a template element but before "foo" has been encountered.

Imagine the case where the network packet was immediately terminated between <template is="my-template"> and foo. The HTML parser would parse the template element and happily insert it into the document and invoke the connected callback before the text node for "foo" is created.

If the template's content is streamed, then on my-element's connectedCallback it's empty. As an author, I can attach MutationObserver to .content, but I never know which mutation is the last one, for a given connect. I understand that custom elements should not assume their children presence. However, I thought that's what makes <template> element special. It does not have children, it has content to be used/stamped. And it does not feel intuitive to stamp something that's not finished yet.

I found that the only way to use template is to be assured by other means that my code is executed after the template's content was parsed, like:

<dom-module>
   <template>foo</template>
   <script>/* this is the moment that actually uses the template above */</script>
</dom-module>

So if I want <my-element> to use a template I should rather use sibling relation <template>foo</template><my-element></my-element>, not the sol or parent-children relation. I believe that is contrary to the intent behind custom elements.

The concrete use-case behind my problems is implementing custom element for declarative Shadow DOM (whatwg/dom#510) that works in run-time. To make use of the fact that the needed, problematic end tag macro is already implemented for <template>.

@domenic
Copy link
Member

domenic commented Apr 25, 2019

I believe that is contrary to the intent behind custom elements.

No, I don't think so. The intention is you need to react to any children changes, including any changes to the contents of your template child.

As an author, I can attach MutationObserver to .content, but I never know which mutation is the last one,

Correct. You need to never assume that there is a last mutation; you need to react to all mutations.

@annevk
Copy link
Member

annevk commented Apr 29, 2019

In the meeting a point was brought up that you could not necessarily rely on a marker inserted after </template> due to dynamic content insertion, but it seems that'd equally apply to the contents of a template, unless that is somehow magic. So I think @domenic is correct and there shouldn't be any special casing here. (I do think we should have declarative shadow trees, but probably not this way.)

@rniwa
Copy link
Collaborator

rniwa commented Apr 29, 2019

it seems that'd equally apply to the contents of a template, unless that is somehow magic

I'd argue that such a change is rather rare. A lot of scripts mutate the document tree in order to load resources, add iframe, etc... but not template's content tree.

@annevk
Copy link
Member

annevk commented Apr 30, 2019

Yeah, it is rare (or close to non-existent, perhaps), but is that a sound enough principle to add new primitives for?

It also creates rather different semantics for the top-most template versus any nested templates.

It gives a decent workaround, but not something I'd necessarily want to commit to for the next two decades.

@rniwa
Copy link
Collaborator

rniwa commented Apr 30, 2019

Yeah, it is rare (or close to non-existent, perhaps), but is that a sound enough principle to add new primitives for?

We have DOMContentLoaded for document. In principle, the document could be kept being modified by JS so we could have made the same argument that scripts should simply listen to DOM mutations happening in the document but we didn't.

I think scripts can currently workaround this by waiting for DOMContentLoaded as well but having to delay any processing of a template until DOMContentLoaded is fired on the document would be very unfortunate.

@annevk
Copy link
Member

annevk commented May 1, 2019

Well, but again, for any nested template elements it'll be effectively that, with this design (having to wait for DOMContentLoaded). And if the primary motivation is shadow roots, that does not necessarily seem great for incremental rendering.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

5 participants
@tomalec @rniwa @domenic @annevk and others