|
| 1 | +# DOM Parts Declarative API |
| 2 | + |
| 3 | +This proposal covers the declarative API for creating a DOM part within a |
| 4 | +`<template>` element and main document HTML. |
| 5 | + |
| 6 | +## Proposal |
| 7 | + |
| 8 | +Double curly braces `{{}}` provide markers for DOM parts. |
| 9 | + |
| 10 | +In the most basic level, this proposal can produce the three DOM parts: |
| 11 | +`NodePart`, `AttributePart`, `ChildNodePart`. |
| 12 | + |
| 13 | +### Basic Examples |
| 14 | + |
| 15 | +Suppose we had the following template in some HTML extension template languages |
| 16 | +where `{name}` and `{email}` indicated locations of dynamic data insertion: |
| 17 | + |
| 18 | +```html |
| 19 | +<section> |
| 20 | + <h1 id="name">{name}</h1> |
| 21 | + Email: <a id="link" href="mailto:{email}">{email}</a> |
| 22 | +</section> |
| 23 | +``` |
| 24 | + |
| 25 | +And the application has produced an HTML `<template>` with the following |
| 26 | +content: |
| 27 | + |
| 28 | +```html |
| 29 | +<template> |
| 30 | + <section> |
| 31 | + <h1 id="name">{{}}</h1> |
| 32 | + Email: <a id="link" href="{{}}">{{}}</a> |
| 33 | + </section> |
| 34 | +</template> |
| 35 | +``` |
| 36 | + |
| 37 | +This will create a `ChildNodePart` attached to `<h1>` with no content, an |
| 38 | +`AttributePart` connected to `href`, and a `ChildNodePart` connected to `<a>` |
| 39 | +with no content. |
| 40 | + |
| 41 | +A framework could fetch these parts using the `getPartRoot()` on the [`DocumentFragment`](./DOM-Parts-Imperative.md#retrieving-a-documentpartroot) and then calling [`getParts()`](./DOM-Parts-Imperative.md#getparts). |
| 42 | + |
| 43 | +## Enablement |
| 44 | + |
| 45 | +For any DOM node, including `<template>`, a new `parseparts` attribute is introduced that indicates |
| 46 | +to the parser it should parse DOM part tags as DOM parts. |
| 47 | + |
| 48 | +```html |
| 49 | +<div parseparts></div> |
| 50 | +``` |
| 51 | + |
| 52 | +Even for `innerHTML` use cases, only DOM nodes that are wrapped DOM with the |
| 53 | +`parseparts` attribute will use declarative parts. |
| 54 | + |
| 55 | +## Node parts |
| 56 | + |
| 57 | +For node parts, a `{{}}` tag could be provided as an attribute. |
| 58 | + |
| 59 | +```html |
| 60 | +<template> |
| 61 | + <section {{}}></section> |
| 62 | +</template> |
| 63 | +``` |
| 64 | + |
| 65 | +Would create a `NodePart` for `<section>`. |
| 66 | + |
| 67 | +## Partial attributes |
| 68 | + |
| 69 | +Allowing `{{}}` inside an attribute works the same as a |
| 70 | +[partial attribute update](./DOM-Parts-Imperative.md#partial-attribute-updates), |
| 71 | +in that it will create an `AttributePart` for the entire attribute, but it will |
| 72 | +have multi-valued `value` property. |
| 73 | + |
| 74 | +```html |
| 75 | +<template> |
| 76 | + <section> |
| 77 | + <h1 id="name">{{}}</h1> |
| 78 | + Email: <a id="link" href="mailto:{{}}">{{}}</a> |
| 79 | + </section> |
| 80 | +</template> |
| 81 | +``` |
| 82 | + |
| 83 | +The `AttributePart` for `href` would have `value` equal to `['mailto:', '']`. |
| 84 | +Empty string values are provided for any markers without default content. |
| 85 | + |
| 86 | +## Default Values |
| 87 | + |
| 88 | +To provide default values for any part, a part can be split into a start `{{#}}` |
| 89 | +and finish `{{/}}` indicators. |
| 90 | + |
| 91 | +```html |
| 92 | +<template> |
| 93 | + <section> |
| 94 | + <h1 id="name">{{#}}Ryosuke Niwa{{/}}</h1> |
| 95 | + Email: |
| 96 | + < a id= "link" href= "mailto:{{#}}[email protected]{{/}}"> |
| 97 | + |
| 98 | + </a> |
| 99 | + </section> |
| 100 | +</template> |
| 101 | +``` |
| 102 | + |
| 103 | +## Names and Metadata |
| 104 | + |
| 105 | +Templating systems may need to serialize data about the nodes they are marking |
| 106 | +into the processing instructions. Or at the very least parts could be named so |
| 107 | +that they are easier to fetch. |
| 108 | + |
| 109 | +```html |
| 110 | +<div>{{email data="foo"}}</div> |
| 111 | +``` |
| 112 | + |
| 113 | +This could be exposed on the imperative API to be consumed in JavaScript by |
| 114 | +application logic. |
| 115 | + |
| 116 | +For parts that are split between opening and closing, it's possible to have multiple metadata values |
| 117 | +which are included as two elements in the `metadata` field. |
| 118 | + |
| 119 | +``` |
| 120 | +{{# metadata1}}default value{{/ metadata2}} |
| 121 | +``` |
| 122 | + |
| 123 | +## Choice of marker |
| 124 | + |
| 125 | +The `{{}}` and `{{#}}{{/}}` are reasonable DOM part markers, but it could be |
| 126 | +something else, or it could even be something that is declared as the |
| 127 | +placeholder. |
| 128 | + |
| 129 | +## Compatability |
| 130 | + |
| 131 | +It may be challenging to implement `<template>` parsing of `{{}}` for |
| 132 | +compatability reasons, so there may need to be restrictions such as only |
| 133 | +allowing this template syntax in a new API like `createTemplateWithParts()`. |
0 commit comments