You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: patching-explainer.md
+33-23Lines changed: 33 additions & 23 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,8 +28,8 @@ A `marker` attribute on the parent element is used to "expose" those markers for
28
28
Example where a placeholder is replaced with actual content:
29
29
30
30
```html
31
-
<sectionmarker="gallery">
32
-
<!marker start>Loading...<!marker end>
31
+
<sectionrange="gallery">
32
+
<!start gallery>Loading...<!end gallery>
33
33
</section>
34
34
35
35
<templatefor="gallery">
@@ -40,17 +40,17 @@ Example where a placeholder is replaced with actual content:
40
40
The marker nodes and everything between them is replaced, so the resulting DOM is:
41
41
42
42
```html
43
-
<sectionmarker="gallery">
43
+
<sectionrange="gallery">
44
44
Actual gallery content
45
45
</section>
46
46
```
47
47
48
48
To insert at a single point, a single `<!marker>` is used:
49
49
50
50
```html
51
-
<ulmarker="list">
51
+
<ulrange="list">
52
52
<li>first item</li>
53
-
<!marker>
53
+
<!marker list>
54
54
<li>last item</li>
55
55
</ul>
56
56
@@ -62,14 +62,14 @@ To insert at a single point, a single `<!marker>` is used:
62
62
To support multiple ranges, marker nodes can be named. The names must match one of the tokens in the `marker` attribute, and any number of ranges can be exposed:
63
63
64
64
```html
65
-
<divmarker="part-one part-two">
66
-
<!marker start name="part-one">
65
+
<divrange="part-one part-two">
66
+
<!start part-one>
67
67
Placeholder content
68
-
<!marker end name="part-one">
68
+
<!end part-one>
69
69
<hr>
70
-
<!marker start name="part-two">
70
+
<!start part-two>
71
71
Placeholder content
72
-
<!marker end name="part-two">
72
+
<!end part-two>
73
73
</div>
74
74
75
75
<templatefor="part-one">
@@ -87,15 +87,15 @@ A few details about patching:
87
87
- If the patching element is not a direct child of `<body>`, the target element has to have a common ancestor with the patching element's parent.
88
88
- The patch template has to be in the same tree (shadow) scope as the target element.
89
89
90
-
Note on compat risk: Current HTML parsers interpret `<!marker>` as a bogus comment, so it's important that `<!marker>` does not appear in existing web content for this to be viable. Another name could be chosen if necessary for web compat.
90
+
Note on compat risk: Current HTML parsers interpret `<!...>` as a bogus comment, so it's important that `<!marker>`, `<!start>`, and `<!end>` does not appear in existing web content for this to be viable. Another name could be chosen if necessary for web compat.
91
91
92
92
### Interleaved patching
93
93
94
94
An element can be patched multiple times and patches for different elements can be interleaved. This allows for updates to different parts of the document to be interleaved. For example:
In this example, the search results populate in three steps while the product carousel populates in one step in between:
@@ -104,7 +104,7 @@ In this example, the search results populate in three steps while the product ca
104
104
<templatefor="search-results">
105
105
<p>first result</p>
106
106
<!-- a new marker is added at the end for the following patch -->
107
-
<!marker>
107
+
<!marker search-results>
108
108
</template>
109
109
110
110
<templatefor="product-carousel">
@@ -114,7 +114,7 @@ In this example, the search results populate in three steps while the product ca
114
114
<templatefor="search-results">
115
115
<p>second result</p>
116
116
<!-- a new marker is added at the end for the following patch -->
117
-
<!marker>
117
+
<!marker search-results>
118
118
</template>
119
119
120
120
<templatefor="search-results">
@@ -125,12 +125,12 @@ In this example, the search results populate in three steps while the product ca
125
125
126
126
## Marker APIs
127
127
128
-
The new `<!marker>` node would be represented with a new `Marker` interface inheriting from `Node`, with these attributes:
128
+
The new `<!marker>`, `<!start>`, and `<!end>` nodes would be represented with a new `Marker` interface inheriting from `Node`, with these read-only attributes:
129
129
130
-
-`type`, an enum with values "start", "end", and the empty string
130
+
-`type`, an enum with values "marker", "start", "end"
131
131
-`name`, a string
132
132
133
-
Scripts can create marker nodes using `new Marker()`.
133
+
Scripts can create marker nodes using `new Marker({ type, name })`.
134
134
135
135
To allow scripts to use markers in the same way a declarative patching would, an `element.markerRange("list")` method is introduced, returning a `Range` object spanning the same nodes that would be replaced.
136
136
@@ -140,12 +140,22 @@ To allow scripts to use markers in the same way a declarative patching would, an
140
140
141
141
## Potential enhancement
142
142
143
+
### Custom highlights integration
144
+
145
+
Named ranges created by marker nodes are similar to the named highlights created by the [custom highlights API](https://drafts.csswg.org/css-highlight-api-1/). For declarative highlights, a possible direction is named `<!start>` and `<!end>` nodes together with a CSS rule to specify the highlight priority and type.
146
+
147
+
See https://github.com/w3c/csswg-drafts/issues/13381 for discussion.
148
+
149
+
## DOM Parts integration
150
+
151
+
[DOM Parts](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/DOM-Parts.md) could make use of marker nodes to annotate ranges created by the "{{}}" syntax, so that the ranges are represented in the DOM and not just in the `<template>` and JS APIs.
152
+
143
153
### Implicit markers
144
154
145
-
To simplify the common case of replacing all children of an element without requiring a `<!marker start>` node, the `marker` attribute could have a microsyntax to target ranges. Example:
155
+
To simplify the common case of replacing all children of an element without requiring a `<!start>` node, the `marker` attribute could have a microsyntax to target ranges. Example:
146
156
147
157
```html
148
-
<sectionmarker="gallery:all">
158
+
<sectionrange="gallery:all">
149
159
Loading...
150
160
</section>
151
161
@@ -157,7 +167,7 @@ To simplify the common case of replacing all children of an element without requ
157
167
Appending could also be supported with another keyword:
158
168
159
169
```html
160
-
<ulmarker="gallery:last">
170
+
<ulrange="gallery:last">
161
171
<li>first item</li>
162
172
</ul>
163
173
@@ -182,9 +192,9 @@ Enabling remote fetching of patch content would act as a script in terms of CSP,
182
192
183
193
### Marker pointers on `Element`
184
194
185
-
The main proposal treats `<!marker start>` and `<!marker end>` as two nodes, which can appear in any number and order. Error handling is done when trying to apply a `<template>` patch.
195
+
The main proposal treats `<!start>` and `<!end>` as two nodes, which can appear in any number and order. Error handling is done when trying to apply a `<template>` patch.
186
196
187
-
An alternative is that the parser doesn't create `Marker` nodes, but instead sets pointers `element.beforeFirstMarker` and `element.afterLastMarker`. Serializing would insert `<!marker>` at the appropriate places.
197
+
An alternative is that the parser doesn't create `Marker` nodes, but instead sets pointers `element.beforeFirstMarker` and `element.afterLastMarker`. Serializing would insert `<!start>` and `<!end>` at the appropriate places.
188
198
189
199
The chief downside of this approach is that it requires bookkeeping similar to live `Range` objects.
0 commit comments