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

> in order for them to do it, they are having to replace interpolations with comment nodes before cloning the HTML template. Then, after cloning the template, they have to retrieve references for all those comment nodes, something like ...
> Lastly, they are having to replace each comment node with the actual element created within the web-component's constructor.

@Lonniebiz just to clarify, hyperHTML doesn't replace comments, it uses these as "_pin_" in the DOM and relate changes to these without ever replacing a thing.

The eventual update is handled by [domdiff](https://github.com/WebReflection/domdiff#signature) which takes care of adding, removing, or swapping only nodes that have changed since last update.

Since I've recently refactored out all the major parts of hyperHTML, what might interest you here is the [domtagger](https://github.com/WebReflection/domtagger#example), which is the hyperHTML engine in charge of using `<template>` once, parse its normalized HTML/SVG once and find out all the holes in it.

A hole can be a textContent, as example if inside a textarea or a text only node such a style one, an attribute, or "_any_" hole, meaning any sparse hole within a node.

The most basic example:
```js
var html = domtagger({
  type: 'html',
  attribute: (node, name) => value => {
    var type = typeof value;
    if (type === 'boolean' || type === 'function')
      node[name] = value;
    else if (value == null)
      node.removeAttribute(name);
    else
      node.setAttribute(name, value);
  },
  any: comment => html => {
    const {parentNode} = comment;
    parentNode.innerHTML = html;
    parentNode.appendChild(comment);
  },
  text: node => textContent => {
    node.textContent = textContent;
  }
});

// render example
function render(model) {
  return html`
    <div onclick=${model.onclick}>
      <div>${model.html}</div>
      <textarea>${model.text}</textarea>
    </div>
  `;
}

document.body.appendChild(
  render({
    onclick: function (e) {
      alert(e.currentTarget.outerHTML);
    },
    html: 'Hello <strong>domtagger</strong>!',
    text: "isn't this cool?"
  })
);
```

So, pretty much all the primitives I need are there, the only missing part to me is a **persistent fragment**, so that I can keep comparing, or appending, a fragment without it ever losing its childNodes.

Such fragment would be smart enough to move its childNodes over a new node only if the node it's appended into changes from the previous one.

That is honestly the only thing the platform doesn't provide, everything else can be done with relative ease on user-land, and performances are already better than pretty much every relevant competitor.



-- 
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-445385746

Received on Friday, 7 December 2018 22:30:55 UTC