[dom-parts] Creation API
rniwa opened this issue · comments
We need to decide on the exact shape of API to create DOM parts.
Current proposal:
new ChildNodePart(node, previousSibling, nextSibling)
new AttributeNodePart(element, 'title')
For ChildNodePart
, the first argument would be a parent node? Would it require that previousSibling
and nextSibling
already be parented by that node, or would it permit them regardless of whether they are currently parented / parented by another node?
This signature is a little “forgettable” to me and I wonder if ChildNodePart
wouldn’t be better off with a dictionary argument.
dictionary ChildNodePartInit {
required Node parentNode;
Node? previousSibling = null;
Node? nextSibling = null;
};
(If the parent is required to be “in agreement” with the siblings at construction time, then parentNode
would not need to be required
unless both siblings were null, I suppose.)
Another possibility would be something like
dictionary ChildNodePartOpts {
Node? nextSibling = null;
Node? previousSibling = null;
};
interface ChildNodePart {
constructor(Node parentNode, optional ChildNodePartOpts opts = {});
// ...
};
...which seems fairly natural if both of the “opts” options are actually optional/nullable but the parent node isn’t.
I'm interesting in particular in what happens if the nodes the ChildNodePart
is referring to changes, either removed or otherwise. I'm interested in what book-keeping we expect the browser to do - is it holding onto ChildNodePart
in some construct or are they only in JS?
I'm interesting in particular in what happens if the nodes the
ChildNodePart
is referring to changes, either removed or otherwise.
Yeah this is something I've never understood with this API idea, it seems like it'd be simpler instead of the proposed ChildNodePart
to do a similar thing to attributes and just have a part that sets the full list of child nodes.
i.e. If we had a template like:
<div>
<b>Hello </b>{{name}}!
</div>
then some template parser would just generate this:
const namePart = new PartialNodeChildListPart();
const childListPart = new NodeChildListPart(divElement, [bElement, namePart, "!"]);
committing a change would effectively just be the same as setting the child list of the div. (Though internally committing would deal with the previousSibling
/nextSibling
stuff which it can derive from the list passed to ChildListPart
).