Webcomponents: [templates] implement a polyfill of template-instantiation before even considering to add the API natively to the platform

Created on 10 Nov 2017  ·  4Comments  ·  Source: WICG/webcomponents

It isn't clear what all features are needed for template instantiation, and looks like at least https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Template-Instantiation.md proposal should be rather polyfillable, so it would be good to have a library to play with before deciding to add such a complicated API to the platform.
(We've managed to done rather bad job with web components before, so need to be careful to not repeat the mistakes, like shipping "v0" and then "v1")

templates

Most helpful comment

@rniwa I'm very interested in helping with a polyfill

All 4 comments

@rniwa I'm very interested in helping with a polyfill

I decided to spend a couple days writing a polyfill for the spec as it stands and here it is (attached as zip), it supports all the API surface I could derive from the spec except currently InnerTemplatePart . (I couldn't work out what declareCallback is supposed to do so that is also ommitted).

Some notes from implementing it:


The parentNode, previousSibling, nextSibling thing isn't well specified when it comes to what happens if parentNode is the template instance or previousSibling and nextSibling are null. I had to replace Step 6.i of apply node template part list with something simpler just so things would work.

In particular I also allowed parentNode to be null if it's a direct descendant of the TemplateInstance rather than caring what it is. However this operation was still by far the most difficult to implement as there's a lot of edge cases not mentioned.

To simplify some code I also made it so that adjust single node case only checks if there's no previousSibling rather than no sibling at all.

I had no problems implementing the attribute part list.

The declaration of how processCallback is associated with a given TemplateInstance wasn't specified so I just passed it into the TemplateInstance constructor which will then get called each time .update() is called.


A couple questions I have from implementing a polyfill:

1:

What is the purpose of apply node template part list Step 6.i?

It seems complex to try to handle if just one of the siblings has changed parent whereas it would be simpler to simply drop the parentNode and previousReplacementNodes concepts when a template part has siblings.

2:

Further to the previous question why track the siblings at all rather than just having an anchor node (could be a TextNode, Comment or otherwise)?

We could simply replace the {{part}} with an anchor node and keep track of it's replacementNodes that immediately follow the anchor.

Alternatively we could have a new node type that is essentially a node that represents display: contents; and just change it's children.

In either case we could do away with the concept of _node template part list_ and instead of needing to concatenate every time we'd just update around the anchor.


To build the polyfill: npm run build. Also it's not actually quite a polyfill, it just exposes a function createInstance(htmlTemplateElement, initialState) but otherwise it should behave the same as if it were a method.

polyfill.zip

I published a polyfill, which takes advice from @Jamesernator 's work on a number of questions

https://npm.im/template-instantiation-polyfill

BTW there is an incomplete polyfill based on the older proposal available here: https://github.com/platosha/hti

Was this page helpful?
0 / 5 - 0 ratings