Template Instantiation Strawman Prollyfill
Template Instantiation is a new web platform feature with ongoing, developing proposals coming out of a few corners of the ecosystem.
The most developed proposal so far comes from Ryosuke Niwa at Apple and can be found here.
This change proposes a Template Instantiation prollyfill implementation based on Ryosuke Niwa's proposal, and adapted with idioms and features found in the Polymer Team's own lit-html.
Concepts and Domain
Template Instantiation is meant to offer a standard API for enabling some level of dynamism in otherwise static HTML templates. There are several relevant use cases outlined in the Apple proposal.
Conceptually, this implementation consists of many of the same constructs. However, there are a few notable differences.
Compared to the Apple proposal, the implementation here is lacking:
- Special support for "inner" templates via an
InnerTemplatePart
. Ability toreplace
orreplaceHTML
onNodeTemplatePart
.
Areas where this implementation diverges from Apple's proposal include:
- No template processor registry. The desired processor is passed by the user when creating an instance.
TemplatePart
is updated by value, which has special meaning depending on the implementation of the derivedTemplatePart
derivative in question (a la lit-html).
Features included in this implementation that are not covered by Apple's proposal:
- An incremental construct pairing a parsed template and a future set of
values to fill that template (
TemplateAssembly
) Explicit support forTemplateAssembly
as a value type that may be assigned to aTemplateNodePart
.Ability to customizeTemplatePart
creation viaTemplateProcessor
'spartCalback
(a la lit-html)- No default implementation for
TemplateProcessor
, with the expectation that in v0 an author will be expected to provide their own.
Template string parsing
- Handled by a naive handlebars parser implementation.
- Parser takes a templatized string, and returns a set of static strings and a set of expressions, very similarly to how JavaScript template literal tag function arguments work (although in this case the expressions are string literals and not values meant to be inserted directly).
TemplateRule
- Represents a spot/range in the otherwise static template that is deemed to be dynamic
- Has a node index that is a walker-specific index of the node it cares about
- Knows the rule(s) for the dynamic spot, the inner raw string text of the template part
- Two specializations:
NodeTemplateRule
andAttributeTemplateRule
. - A list of these is parsed from an
HTMLTemplateElement
and held by aTemplateDefinition
TemplatePart
- A value setter for a dynamic spot in a
TemplateInstance
. - Has a reference to a related
TemplateRule
, where it can access the related rule. - Has a reference to a node, which might refer to an attribute or a
positionally relevant
Text
node somewhere. - Has a reference to its originating
TemplateInstance
(not sure why yet) - A list of these is generated by cross-referencing a set of
TemplateRule
instances with a relatedDocumentFragment
and held by aTemplateInstance
.
TemplateDefinition
- Prollyfill-specific construct, not yet obviously useful for authors
- Unique per
HTMLTemplateElement
(for cacheability, cache can be overridden if desired). - Has a reference to HTMLTemplateElement
- Has a parsed list of dynamic
TemplateRule
spots - Internally holds a reference to a "parsed" version of the static template
for faster cloning into a
TemplateInstance
.
TemplateAssembly
- Maps closely to
lit-html
'sTemplateResult
. - Has a
TemplateDefinition
instance. - Has some state that will eventually be set on a
TemplateInstance
generated from theTemplateDefinition
. - Can be assigned as the value of a
NodeTemplatePart
, enablingTemplateInstance
nesting. - Not sure how an author would actually create this yet.
TemplateProcessor
- Defines stateless-ish updates for template parts.
ImplementsTemplatePart
creation viapartCallback
(working name borrowed from lit-html).- Implements
TemplatePart
updating viaprocessCallback
(working name borrowed from Apple's proposal). - Trivial example processor provided in this project
TemplateInstance
- Created using
TemplateDefinition#createInstance(processor, state?)
(not to be invoked directly by author at this time). - Has a reference to its
TemplateProcessor
- Has a list of
TemplatePart
instances, generated by cross-referencing theTemplateDefinition
'sTemplateRules
against its own content and invoking theTemplateProcessor
'spartCallback
method. - Has a reference to the previously set state (maybe useful in
TemplateProcessor
, which is otherwise stateless) - Can be updated by calling
TemplateInstance#update(newState)
- Can handle a
TemplateAssembly
as a state value
HTMLTemplateElement
- Invoking
HTMLTemplateElement#createInstance(processor, state?)
creates aTemplateDefinition
for theHTMLTemplateElement
if one does not exist, then invokesTemplateDefinition#createInstance(processor, state?)
and returns that value.