npm package: @matthewp/template-instantiation
Description: A prollyfill for HTML template instantiation
Author: The Polymer Authors
Latest version: 1.1.1

# 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](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Template-Instantiation.md).

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](https://github.com/polymerlabs/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](https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Template-Instantiation.md#2-use-cases).

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 to `replace` or `replaceHTML` on `NodeTemplatePart`.~

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 derived `TemplatePart` 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 for `TemplateAssembly` as a value type that may be assigned
   to a `TemplateNodePart`.~
 - ~Ability to customize `TemplatePart` creation via `TemplateProcessor`'s
   `partCalback` (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` and `AttributeTemplateRule`.
 - A list of these is parsed from an `HTMLTemplateElement` and held by a
   `TemplateDefinition`

### 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 related `DocumentFragment` and held by a
   `TemplateInstance`.

### 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`'s `TemplateResult`.
 - Has a `TemplateDefinition` instance.
 - Has some state that will eventually be set on a `TemplateInstance` generated
   from the `TemplateDefinition`.
 - Can be assigned as the value of a `NodeTemplatePart`, enabling
   `TemplateInstance` nesting.
 - Not sure how an author would actually create this yet.

### TemplateProcessor

 - Defines stateless-ish updates for template parts.
 - ~Implements `TemplatePart` creation via `partCallback` (working name
   borrowed from lit-html).~
 - Implements `TemplatePart` updating via `processCallback` (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 the
   `TemplateDefinition`'s `TemplateRules` against its own content and
   invoking the `TemplateProcessor`'s `partCallback` 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
   a `TemplateDefinition` for the `HTMLTemplateElement` if one does not exist,
   then invokes `TemplateDefinition#createInstance(processor, state?)` and
   returns that value.