Re: [WICG/webcomponents] [DOM Parts] Add new declarative syntax and update iterative proposal (PR #1023)

@rictic commented on this pull request.



> +content:
+
+```html
+<template>
+  <section>
+    <h1 id="name">{{}}</h1>
+    Email: <a id="link" href="{{}}">{{}}</a>
+  </section>
+</template>
+```
+
+This will create a `ChildNodePart` attached to `<h1>` with no content, an
+`AttributePart` connected to `href`, and a `ChildNodePart` connected to `<a>`
+with no content.
+
+A framework could fetch these parts use either a

Looks like the wording here was caught up in an edit

> +
+Allowing `{{}}` inside an attribute works the same as a
+[partial attribute update](./DOM-Parts-Imperative.md#partial-attribute-updates),
+in that it will create an `AttributePart` for the entire attribute, but it will
+have multi-valued `value` property.
+
+```html
+<template>
+  <section>
+    <h1 id="name">{{}}</h1>
+    Email: <a id="link" href="mailto:{{}}">{{}}</a>
+  </section>
+</template>
+```
+
+The `AttributePart` for `href` would have `value` equal to `['mailto:', '']`.

But the `value` is the mutable field that the user writes. Seems like we want to have a readonly array for the static strings, and then use `AttributePart#value` for the dynamic values

> +
+Allowing `{{}}` inside an attribute works the same as a
+[partial attribute update](./DOM-Parts-Imperative.md#partial-attribute-updates),
+in that it will create an `AttributePart` for the entire attribute, but it will
+have multi-valued `value` property.
+
+```html
+<template>
+  <section>
+    <h1 id="name">{{}}</h1>
+    Email: <a id="link" href="mailto:{{}}">{{}}</a>
+  </section>
+</template>
+```
+
+The `AttributePart` for `href` would have `value` equal to `['mailto:', '']`.

But the `value` is the mutable field that the user writes to to update value, isn't it? Seems like we want to have a readonly array for the static strings, and then use `AttributePart#value` for the dynamic values

> +  </section>
+</template>
+```
+
+## Names and Metadata
+
+Templating systems may need to serialize data about the nodes they are marking
+into the processing instructions. Or at the very least parts could be named so
+that they are easier to fetch.
+
+```html
+<div>{{email data="foo"}}</div>
+```
+
+This could be exposed on the imperative API to be consumed in JavaScript by
+application logic.

Feel free to punt, but have we considered giving the metadata as a string rather than a string array? People may want to use a variety of metadata encodings, e.g. JSON, and it'd be easier to just pass along the raw contents and let them split by spaces if they'd like to do that.

Related, but we'll want to specify how to escape `}}` inside of part syntax, and how to escape `{{` inside `parsepart` html

> +```
+
+This could be exposed on the imperative API to be consumed in JavaScript by
+application logic.
+
+## Choice of marker
+
+The `{{}}` and `{{#}}{{/}}` are reasonable DOM part markers, but it could be
+something else, or it could even be something that is declared as the
+placeholder.
+
+## Compatability
+
+It may be challenging to implement `<template>` parsing of `{{}}` for
+compatability reasons, so there may need to be restrictions such as only
+allowing this template syntax in a new API like `createTemplateWithParts()`.

Why not use a `parseparts` attribute on the `<template>` for this?

>  };
 
 interface AttributePart : Part {
-    constructor(Element element, DOMString qualifiedName, DOMString? namespace);
-    readonly attribute DOMString prefix;
-    readonly attribute DOMString localName;
-    readonly attribute DOMString namespaceURI;
+  constructor(
+      PartRoot root,
+      Element element,
+      DOMString qualifiedName,
+      optional DOMString? namespace = null,
+      optional PartInit init = {});
+
+  readonly attribute DOMString prefix;
+  readonly attribute DOMString localName;
+  readonly attribute DOMString namespaceURI;

```suggestion
  readonly attribute DOMString namespaceURI;
  readonly attribute DOMString rawName;
```

Consider adding a field representing the attribute name as it was written in the original source, before it was lower cased.

>  };
 
 interface AttributePart : Part {
-    constructor(Element element, DOMString qualifiedName, DOMString? namespace);
-    readonly attribute DOMString prefix;
-    readonly attribute DOMString localName;
-    readonly attribute DOMString namespaceURI;
+  constructor(
+      PartRoot root,
+      Element element,
+      DOMString qualifiedName,
+      optional DOMString? namespace = null,
+      optional PartInit init = {});
+
+  readonly attribute DOMString prefix;

```suggestion
  readonly attribute DOMString prefix;
  readonly attribute FrozenArray<DOMString> strings;
```

Consider adding a field representing the static strings that the values are interpolated in between, with `['', '']` as the default value.

> +Instead of `AttributePart` having a single string `value`, it could optionally
+take an `Array` that contains values that should be concatenated together. This
+allows updating individually parts of the attribute without needing to serialize
+the entire string.

```suggestion
Instead of `AttributePart` having a single string `value`, it could instead
take an `Array` with values that will be interleaved with those from the `strings` array. 
```

If we go with the `strings` design, we might want to require that `values` be an array, to be interleaved with the `strings`. I suppose we could take a non-array value if there's only two strings, but in practice I expect template systems to just always pass through an array here.

> -  constructor() {
-    this.firstName = "";
-    this.lastName = "";
-  }
-
-  toString() {
-    return `${this.firstName} ${this.lastName}`;
-  }
-}
-
-const part = AttributePart(element, "title");
-part.value = new TitleAttributeValue();
-part.value.firstName = "Ryosuke";
-part.value.lastName = "Niwa";
+const part = AttributePart(element, "href", {
+  template: attribute`mailto: ${0}`,

I'm not sure if taking a template strings array here gives us any security benefits. The static and dynamic values will just be concatted together into a single string before they're set as an attribute.

Hm, on the other hand, if native elements got information about the static and dynamic values, that might give future content security policies the ability to set constraints that some parts of attribute strings must be constant. The `safevalues` library does something like that for high risk URL attributes like an iframe's `src`, where the origin must be statically determined, but the path can be dynamic.

Ok, in that case I think I see the value here.

-- 
Reply to this email directly or view it on GitHub:
https://github.com/WICG/webcomponents/pull/1023#pullrequestreview-1555659534
You are receiving this because you are subscribed to this thread.

Message ID: <WICG/webcomponents/pull/1023/review/1555659534@github.com>

Received on Monday, 31 July 2023 20:25:41 UTC