Re: [w3c/webcomponents] Discussion: Templates that Don't Destroy Element References (#777)

> Template Literals, without the help of any type of HTML template element, already contain everything that needs to be known to generate DOM. Therefore, I think it would be ideal for Browsers to add 2 prototype method to all strings. One called toDOM() and the other called toTemplate(). Here's how this would work.

...

> Template Literals already know the context from which to determine the values of the `${interpolations/expressions}` they contain. They also already inherently know which portions of the string are "parts".

There is a difference between the template literal and the string it generates. "`~`" is a template literal but the [runtime semantics of a template literal](https://www.ecma-international.org/ecma-262/6.0/#sec-template-literals-runtime-semantics-evaluation) is to generate a regular string. So once the template literal is evaluated (which happens once), then the generated string is no different from any other string and doesn't retain any information about the context or where the substations occurred.

This is precisely why our proposal uses `{{~}}` as opposed to `${~}` so that we can retain these contexts beyond when the template is instantiated.

An alternative approach is to use tagged template literal like lit-html and hyperHTML. One big difference between a regular template literal and a tagged template literals is that the latter can return a non-string object.

> Well, then I'd expect `.toDOM()` to throw an error if `this.btn` is not accessible from within the scope where `.toDOM()` is called. I'm fine with that; I won't need that original template literal at all after I have the DOM.

That's going to be an extremely exotic behavior because this `.toDOM()` function would be looking up things in its caller's scope. Since literally nothing else in the platform behaves like this, I don't think we should do this.

> Template Literals, without the help of any type of HTML template element, already contain everything that needs to be known to generate DOM. Therefore, I think it would be ideal for Browsers to add 2 prototype method to all strings. One called toDOM() and the other called toTemplate(). Here's how this would work.

That would be a massive layering violation. Because ECMAScript is used in non-browser environments without DOM like node.js these days, adding any sort of DOM related API directly onto String would be a bad idea.

Having said that, I'm amendable to the idea that there probably is a valid use case for creating a template instance directly from a string. For example, I could imagine an alternative approach to instantiating a TemplateInstance is perhaps via constructor as in:

```html
<template id="boldTemplate"><b>{{text}}</b></template>
<script>
const content = {text: 'hello, world'};
const instance1 = new TemplateInstance('<b>{{text}}</b>', content);
const instance2 = new TemplateInstance(boldTemplate, content);
</script>
```
where `instance1` and `instance2` are semantically equivalent template instances.

Alternatively, using tagged template literal, we could introduce something like `htmlTemplate` tag built into the browser which creates a HTMLTemplateElement or some kind of a DocumentFragment variant which knows it's a template fragment  as in:

```html
<template id="template3"><b>{{text}}</b></template>
<script>
const content = {text: 'hello, world'};
const template4 = htmlTemplate`<b>{{text}}</b>`;
const instance3 = template3.createInstance(content);
const instance4 = template4.createInstance(content);
</script>
```

Again, `instance3` and `instance4` are semantically identical. Now, because `htmlTemplate` is a tagged template literal, you can then insert a random DOM node as in:

```js
const br = document.createElement('br');
const template5 = htmlTemplate`<b>{{text}}</b>${br}`;
const instance5 = template5.createInstance({text: "hello"});
</script>
```

Then `instance5` would have the HTML fragment of `<b>hello</b><br>` as desired. I think this is the closest thing I can come up with to what you're proposing without all the issues I listed above.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/webcomponents/issues/777#issuecomment-445352046

Received on Friday, 7 December 2018 20:14:02 UTC