@microsoft/webui-framework 0.0.24 → 0.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +209 -53
- package/dist/component-asset/asset.d.ts +4 -2
- package/dist/component-asset/asset.js +19 -3
- package/dist/component-asset/generated-manifest.d.ts +1 -0
- package/dist/component-asset/generated-manifest.js +32 -0
- package/dist/component-asset/loader.d.ts +2 -1
- package/dist/component-asset/loader.js +98 -22
- package/dist/component-asset/manifest.d.ts +2 -1
- package/dist/component-asset.d.ts +1 -1
- package/dist/component-asset.js +12 -2
- package/dist/element/link-styles.d.ts +20 -0
- package/dist/element/link-styles.js +1030 -0
- package/dist/element/markers.d.ts +4 -0
- package/dist/element/markers.js +60 -5
- package/dist/element/styles.d.ts +39 -1
- package/dist/element/styles.js +623 -13
- package/dist/element/types.d.ts +5 -3
- package/dist/element.js +9 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/interaction-hydration.d.ts +8 -0
- package/dist/interaction-hydration.js +167 -0
- package/dist/static-host.js +43 -1
- package/dist/streaming-activation.d.ts +2 -2
- package/dist/streaming-activation.js +4 -2
- package/dist/streaming-bootstrap.d.ts +2 -2
- package/dist/streaming-bootstrap.js +7 -1
- package/dist/streaming-cleanup.d.ts +1 -0
- package/dist/streaming-cleanup.js +66 -14
- package/dist/streaming-coordinator.d.ts +3 -2
- package/dist/streaming-coordinator.js +107 -47
- package/dist/streaming-deferred.d.ts +14 -4
- package/dist/streaming-deferred.js +200 -87
- package/dist/streaming-dom.d.ts +12 -3
- package/dist/streaming-dom.js +41 -27
- package/dist/streaming-mode.d.ts +5 -0
- package/dist/streaming-mode.js +4 -0
- package/dist/streaming-protocol.d.ts +19 -3
- package/dist/streaming-protocol.js +4 -3
- package/dist/streaming-spans.d.ts +9 -0
- package/dist/streaming-spans.js +200 -0
- package/dist/template-content.d.ts +17 -0
- package/dist/template-content.js +106 -0
- package/dist/template-element.d.ts +17 -2
- package/dist/template-element.js +493 -177
- package/dist/template-events.d.ts +7 -0
- package/dist/template-events.js +7 -1
- package/dist/template-types.d.ts +1 -2
- package/dist/template.d.ts +15 -8
- package/dist/template.js +79 -16
- package/package.json +9 -3
- package/dist/component-asset/resources.d.ts +0 -4
- package/dist/component-asset/resources.js +0 -83
package/dist/template-element.js
CHANGED
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
import { deferTemplateDefinition, getTemplate } from './template.js';
|
|
2
|
+
import { cloneTemplateContent, } from './template-content.js';
|
|
2
3
|
import { hydrationStart, hydrationEnd } from './lifecycle.js';
|
|
3
|
-
import { isStreamingHydrationMode, PENDING_ROOT_CONNECTED, STREAMED_HOST_ATTR, STREAMING_BOUNDARY_ACTIVATE, } from './streaming-mode.js';
|
|
4
|
+
import { ACTIVATION_ACTIVATED, ACTIVATION_ANCESTOR_BARRIER, ACTIVATION_MISSING_TEMPLATE, ACTIVATION_STATIC_HOST_OPT_OUT, isStreamingHydrationMode, PENDING_ROOT_CONNECTED, STREAMED_HOST_ATTR, STREAMING_BOUNDARY_ACTIVATE, } from './streaming-mode.js';
|
|
4
5
|
import { createRepeatKeyState, seedHydratedRepeatKeys, syncRepeat, dotWalk, } from './element/diff.js';
|
|
5
|
-
import { collectItemMarkers, nextElement, findByOrdinal, buildSSRIndex, collectTemplateElements, MARKER_COND_START, MARKER_COND_END, } from './element/markers.js';
|
|
6
|
-
import {
|
|
6
|
+
import { collectItemMarkers, nextElement, findByOrdinal, buildSSRIndex, collectTemplateElements, MARKER_COND_START, MARKER_COND_END, rawMarker, } from './element/markers.js';
|
|
7
|
+
import { claimSsrComponentStyles, installComponentStyles, isComponentStyleMarker, } from './element/styles.js';
|
|
8
|
+
import { cancelTemplateLinkStyleMount, installTemplateLinkStyles, prepareTemplateLinkStyles, templateMayContainLinkStyles, } from './element/link-styles.js';
|
|
7
9
|
import { ATTR_KIND_BOOLEAN, ATTR_KIND_COMPLEX, ATTR_KIND_TEMPLATE, hasNativeLiveProperty, } from './element/types.js';
|
|
8
10
|
import { templateHasRoot, templateRootForAttribute } from './template-roots.js';
|
|
9
11
|
const DEV = typeof __WEBUI_DEV__ === 'undefined' || __WEBUI_DEV__;
|
|
10
|
-
const templateCache = new WeakMap();
|
|
11
|
-
const templateDOMCache = new WeakMap();
|
|
12
12
|
const rootTagCache = new WeakMap();
|
|
13
|
+
const templateDOMCache = new WeakMap();
|
|
13
14
|
const tplOrdinalCache = new WeakMap();
|
|
15
|
+
const textMarkerBoundaryCache = new WeakMap();
|
|
16
|
+
const NO_TEXT_MARKER_BOUNDARIES = new Int32Array(0);
|
|
17
|
+
const RAW_MARKER_BOUNDARY_BASE = 0x40000000;
|
|
14
18
|
const tplElementCache = new WeakMap();
|
|
19
|
+
function comparePendingSlots(left, right) {
|
|
20
|
+
return left.order - right.order;
|
|
21
|
+
}
|
|
22
|
+
function insertPendingSlots(slots, count, needsOrdering) {
|
|
23
|
+
if (needsOrdering) {
|
|
24
|
+
slots.length = count;
|
|
25
|
+
slots.sort(comparePendingSlots);
|
|
26
|
+
}
|
|
27
|
+
for (let i = 0; i < count; i++) {
|
|
28
|
+
const slot = slots[i];
|
|
29
|
+
slot.parent.insertBefore(slot.node, slot.before);
|
|
30
|
+
if (slot.end)
|
|
31
|
+
slot.parent.insertBefore(slot.end, slot.before);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
15
34
|
function getTemplateElements(tplRoot) {
|
|
16
35
|
let cached = tplElementCache.get(tplRoot);
|
|
17
36
|
if (!cached) {
|
|
@@ -27,6 +46,7 @@ function getTplOrdinals(tplNode) {
|
|
|
27
46
|
map = new Map();
|
|
28
47
|
let elemOrd = 0;
|
|
29
48
|
let textOrd = 0;
|
|
49
|
+
let commentOrd = 0;
|
|
30
50
|
const children = tplNode.childNodes;
|
|
31
51
|
for (let k = 0; k < children.length; k++) {
|
|
32
52
|
const type = children[k].nodeType;
|
|
@@ -38,20 +58,61 @@ function getTplOrdinals(tplNode) {
|
|
|
38
58
|
map.set(k, [3, textOrd]);
|
|
39
59
|
textOrd++;
|
|
40
60
|
}
|
|
61
|
+
else if (type === 8) {
|
|
62
|
+
map.set(k, [8, commentOrd]);
|
|
63
|
+
commentOrd++;
|
|
64
|
+
}
|
|
41
65
|
}
|
|
42
66
|
tplOrdinalCache.set(tplNode, map);
|
|
43
67
|
return map;
|
|
44
68
|
}
|
|
69
|
+
function slotKey(slot, orderOffset = 0) {
|
|
70
|
+
return `${slot[0]},${slot[1]},${(slot[2] ?? 0) + orderOffset}`;
|
|
71
|
+
}
|
|
72
|
+
function getTextMarkerBoundaries(meta) {
|
|
73
|
+
const cached = textMarkerBoundaryCache.get(meta);
|
|
74
|
+
if (cached)
|
|
75
|
+
return cached;
|
|
76
|
+
const texts = meta.tx;
|
|
77
|
+
if (!texts) {
|
|
78
|
+
textMarkerBoundaryCache.set(meta, NO_TEXT_MARKER_BOUNDARIES);
|
|
79
|
+
return NO_TEXT_MARKER_BOUNDARIES;
|
|
80
|
+
}
|
|
81
|
+
const markers = new Map();
|
|
82
|
+
if (meta.c) {
|
|
83
|
+
for (let i = 0; i < meta.c.length; i++) {
|
|
84
|
+
markers.set(slotKey(meta.c[i][2]), i + 1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (meta.r) {
|
|
88
|
+
for (let i = 0; i < meta.r.length; i++) {
|
|
89
|
+
markers.set(slotKey(meta.r[i][3]), -(i + 1));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
let rawIndex = 0;
|
|
93
|
+
for (let i = 0; i < texts.length; i++) {
|
|
94
|
+
if (texts[i][2] !== 1)
|
|
95
|
+
continue;
|
|
96
|
+
markers.set(slotKey(texts[i][0]), RAW_MARKER_BOUNDARY_BASE + rawIndex + 1);
|
|
97
|
+
rawIndex++;
|
|
98
|
+
}
|
|
99
|
+
const boundaries = new Int32Array(texts.length);
|
|
100
|
+
for (let i = 0; i < texts.length; i++) {
|
|
101
|
+
boundaries[i] = markers.get(slotKey(texts[i][0], 1)) ?? 0;
|
|
102
|
+
}
|
|
103
|
+
textMarkerBoundaryCache.set(meta, boundaries);
|
|
104
|
+
return boundaries;
|
|
105
|
+
}
|
|
45
106
|
const EMPTY_ARR = [];
|
|
46
107
|
const EMPTY_SET = Object.freeze(new Set());
|
|
47
108
|
const WEBUI_SET_STATE_KEY = Symbol.for('microsoft.webui.setStateKey');
|
|
48
109
|
const STREAMING_BOUNDARY_ABANDON = Symbol.for('microsoft.webui.boundaryAbandon');
|
|
49
|
-
const ACTIVATION_ACTIVATED = 1;
|
|
50
|
-
const ACTIVATION_STATIC_HOST_OPT_OUT = 2;
|
|
51
|
-
const ACTIVATION_MISSING_TEMPLATE = 3;
|
|
52
110
|
const templateMetaByCtor = new WeakMap();
|
|
53
111
|
const pendingAncestorDescendants = new WeakMap();
|
|
54
112
|
const pendingParentStateByElement = new WeakMap();
|
|
113
|
+
function bindingArray(count) {
|
|
114
|
+
return count > 0 ? [] : EMPTY_ARR;
|
|
115
|
+
}
|
|
55
116
|
function queuePendingParentState(element, name, value, replayAfterHydration) {
|
|
56
117
|
let pending = pendingParentStateByElement.get(element);
|
|
57
118
|
if (!pending) {
|
|
@@ -65,6 +126,12 @@ function queuePendingParentState(element, name, value, replayAfterHydration) {
|
|
|
65
126
|
(pending.replay ??= new Set()).add(name);
|
|
66
127
|
}
|
|
67
128
|
}
|
|
129
|
+
export function consumePendingParentState(element) {
|
|
130
|
+
const pending = pendingParentStateByElement.get(element);
|
|
131
|
+
if (pending)
|
|
132
|
+
pendingParentStateByElement.delete(element);
|
|
133
|
+
return pending;
|
|
134
|
+
}
|
|
68
135
|
function isUnupgradedWebUITarget(element) {
|
|
69
136
|
const tagName = element.localName;
|
|
70
137
|
if (tagName.indexOf('-') === -1)
|
|
@@ -129,6 +196,11 @@ function installTemplateObservedAttributes(ctor, tagName, meta = getTemplate(tag
|
|
|
129
196
|
}
|
|
130
197
|
function defineTemplateConstructor(ctor, tagName, meta) {
|
|
131
198
|
installTemplateObservedAttributes(ctor, tagName, meta);
|
|
199
|
+
if (meta) {
|
|
200
|
+
const ready = prepareTemplateLinkStyles(meta);
|
|
201
|
+
if (ready)
|
|
202
|
+
void ready;
|
|
203
|
+
}
|
|
132
204
|
customElements.define(tagName, ctor);
|
|
133
205
|
}
|
|
134
206
|
function hasAuthoredMember(instance, key) {
|
|
@@ -148,6 +220,8 @@ export class TemplateElement extends HTMLElement {
|
|
|
148
220
|
this.$root = null;
|
|
149
221
|
this.$ready = false;
|
|
150
222
|
this.$hydrated = false;
|
|
223
|
+
this.$deferredClientMount = false;
|
|
224
|
+
this.$resetClientShadow = false;
|
|
151
225
|
this.$hasMounted = false;
|
|
152
226
|
this.$deferredSSR = false;
|
|
153
227
|
this.$activatingDeferredSSR = false;
|
|
@@ -156,7 +230,6 @@ export class TemplateElement extends HTMLElement {
|
|
|
156
230
|
this.$dirtyPaths = null;
|
|
157
231
|
this.$pendingFlush = false;
|
|
158
232
|
this.$preReadyWrites = null;
|
|
159
|
-
this.$resolver = (p, s) => this.$resolveValue(p, s);
|
|
160
233
|
}
|
|
161
234
|
static { this.$ancestorReleaseQueue = []; }
|
|
162
235
|
static { this.$ancestorReleaseIndex = 0; }
|
|
@@ -170,7 +243,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
170
243
|
this.$afterExternalStateWrite(owned);
|
|
171
244
|
return owned;
|
|
172
245
|
}
|
|
173
|
-
[STREAMING_BOUNDARY_ACTIVATE](state) {
|
|
246
|
+
[STREAMING_BOUNDARY_ACTIVATE](state, bypassAncestor) {
|
|
174
247
|
if (!this.$deferredSSR && this.hasAttribute(STREAMED_HOST_ATTR)) {
|
|
175
248
|
this.$deferredSSR = true;
|
|
176
249
|
this.$ready = true;
|
|
@@ -182,16 +255,20 @@ export class TemplateElement extends HTMLElement {
|
|
|
182
255
|
return ACTIVATION_MISSING_TEMPLATE;
|
|
183
256
|
}
|
|
184
257
|
this.$meta = meta;
|
|
185
|
-
if (!this.$shouldActivateOnBoundaryCommit())
|
|
258
|
+
if (!this.$shouldActivateOnBoundaryCommit()) {
|
|
259
|
+
this.$installStyles(meta);
|
|
186
260
|
return ACTIVATION_STATIC_HOST_OPT_OUT;
|
|
187
|
-
|
|
261
|
+
}
|
|
262
|
+
const ancestor = this.$nearestHydrationBarrier(bypassAncestor);
|
|
188
263
|
if (ancestor) {
|
|
189
264
|
this.$deferredByAncestor = true;
|
|
190
265
|
this.$ancestorBoundaryState = state;
|
|
191
266
|
this.$hasAncestorBoundaryState = true;
|
|
192
267
|
this.$registerWithHydrationBarrier(ancestor);
|
|
193
|
-
return
|
|
268
|
+
return ACTIVATION_ANCESTOR_BARRIER;
|
|
194
269
|
}
|
|
270
|
+
if (this.$deferredByAncestor)
|
|
271
|
+
this.$clearAncestorDeferral();
|
|
195
272
|
this.$activatingDeferredSSR = true;
|
|
196
273
|
try {
|
|
197
274
|
this.$activateDeferredSSR(state);
|
|
@@ -202,22 +279,32 @@ export class TemplateElement extends HTMLElement {
|
|
|
202
279
|
return ACTIVATION_ACTIVATED;
|
|
203
280
|
}
|
|
204
281
|
[STREAMING_BOUNDARY_ABANDON]() {
|
|
205
|
-
this.$
|
|
282
|
+
this.$clearAncestorDeferral();
|
|
206
283
|
this.$abandonDeferredDescendants();
|
|
207
284
|
this.$deferredSSR = false;
|
|
208
|
-
this.$deferredByAncestor = undefined;
|
|
209
|
-
this.$ancestorBoundaryState = undefined;
|
|
210
|
-
this.$hasAncestorBoundaryState = undefined;
|
|
211
285
|
this.$activatingDeferredSSR = false;
|
|
212
286
|
this.$ready = false;
|
|
213
287
|
this.$preReadyWrites = null;
|
|
214
288
|
if (this.$deferredWrites)
|
|
215
289
|
this.$deferredWrites = undefined;
|
|
216
290
|
}
|
|
291
|
+
$clearAncestorDeferral() {
|
|
292
|
+
this.$detachDeferredAncestor();
|
|
293
|
+
this.$deferredByAncestor = undefined;
|
|
294
|
+
this.$ancestorBoundaryState = undefined;
|
|
295
|
+
this.$hasAncestorBoundaryState = undefined;
|
|
296
|
+
}
|
|
297
|
+
$resumeRetainedRoot() {
|
|
298
|
+
const resume = this[PENDING_ROOT_CONNECTED];
|
|
299
|
+
if (typeof resume !== 'function')
|
|
300
|
+
return false;
|
|
301
|
+
resume.call(this);
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
217
304
|
static define(tagName) {
|
|
218
305
|
const ctor = this;
|
|
219
306
|
const meta = getTemplate(tagName);
|
|
220
|
-
if (!meta
|
|
307
|
+
if (!meta) {
|
|
221
308
|
deferTemplateDefinition(tagName, ctor, () => {
|
|
222
309
|
defineTemplateConstructor(ctor, tagName, getTemplate(tagName));
|
|
223
310
|
});
|
|
@@ -244,6 +331,8 @@ export class TemplateElement extends HTMLElement {
|
|
|
244
331
|
return;
|
|
245
332
|
}
|
|
246
333
|
if (this.$hydrated && this.$root) {
|
|
334
|
+
if (this.$deferredClientMount)
|
|
335
|
+
return;
|
|
247
336
|
hydrationStart();
|
|
248
337
|
try {
|
|
249
338
|
this.$ready = true;
|
|
@@ -259,9 +348,8 @@ export class TemplateElement extends HTMLElement {
|
|
|
259
348
|
this.hasAttribute(STREAMED_HOST_ATTR)) {
|
|
260
349
|
this.$deferredSSR = true;
|
|
261
350
|
this.$ready = true;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
resume.call(this);
|
|
351
|
+
if (this.$resumeRetainedRoot())
|
|
352
|
+
return;
|
|
265
353
|
this.$didDeferSSRHydration();
|
|
266
354
|
return;
|
|
267
355
|
}
|
|
@@ -287,6 +375,8 @@ export class TemplateElement extends HTMLElement {
|
|
|
287
375
|
return;
|
|
288
376
|
const hasShadow = !!this.shadowRoot;
|
|
289
377
|
const wantShadow = hasShadow || !!meta.sd;
|
|
378
|
+
const resetClientShadow = this.$resetClientShadow;
|
|
379
|
+
this.$resetClientShadow = false;
|
|
290
380
|
const remountStructuralTemplate = reconnecting &&
|
|
291
381
|
((meta.c?.length ?? 0) !== 0 || (meta.r?.length ?? 0) !== 0);
|
|
292
382
|
let root;
|
|
@@ -296,11 +386,18 @@ export class TemplateElement extends HTMLElement {
|
|
|
296
386
|
const renderRoot = wantShadow
|
|
297
387
|
? this.shadowRoot ?? this.attachShadow({ mode: 'open' })
|
|
298
388
|
: this;
|
|
299
|
-
|
|
389
|
+
const retainedStyles = [];
|
|
390
|
+
let child = renderRoot.firstElementChild;
|
|
391
|
+
while (child) {
|
|
392
|
+
if (isComponentStyleMarker(child))
|
|
393
|
+
retainedStyles.push(child);
|
|
394
|
+
child = child.nextElementSibling;
|
|
395
|
+
}
|
|
396
|
+
renderRoot.replaceChildren(...retainedStyles);
|
|
300
397
|
root = renderRoot;
|
|
301
398
|
isSSR = false;
|
|
302
399
|
}
|
|
303
|
-
else if (hasShadow) {
|
|
400
|
+
else if (hasShadow && !resetClientShadow) {
|
|
304
401
|
root = this.shadowRoot;
|
|
305
402
|
isSSR = true;
|
|
306
403
|
}
|
|
@@ -309,16 +406,18 @@ export class TemplateElement extends HTMLElement {
|
|
|
309
406
|
isSSR = true;
|
|
310
407
|
}
|
|
311
408
|
else if (wantShadow) {
|
|
312
|
-
|
|
409
|
+
const renderRoot = this.shadowRoot ?? this.attachShadow({ mode: 'open' });
|
|
410
|
+
if (resetClientShadow)
|
|
411
|
+
renderRoot.replaceChildren();
|
|
412
|
+
root = renderRoot;
|
|
313
413
|
isSSR = false;
|
|
314
414
|
}
|
|
315
415
|
else {
|
|
316
416
|
root = this;
|
|
317
417
|
isSSR = false;
|
|
318
418
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
!reconnecting) {
|
|
419
|
+
this.$installStyles(meta);
|
|
420
|
+
if (isSSR && !forceSSR && !reconnecting) {
|
|
322
421
|
const ancestor = this.$nearestHydrationBarrier();
|
|
323
422
|
if (ancestor) {
|
|
324
423
|
this.$meta = meta;
|
|
@@ -329,9 +428,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
329
428
|
this.$registerWithHydrationBarrier(ancestor);
|
|
330
429
|
return;
|
|
331
430
|
}
|
|
332
|
-
if (
|
|
333
|
-
}
|
|
334
|
-
else {
|
|
431
|
+
if (this.$shouldDeferSSRHydration(meta)) {
|
|
335
432
|
this.$meta = meta;
|
|
336
433
|
this.$deferredSSR = true;
|
|
337
434
|
this.$ready = true;
|
|
@@ -339,10 +436,9 @@ export class TemplateElement extends HTMLElement {
|
|
|
339
436
|
return;
|
|
340
437
|
}
|
|
341
438
|
}
|
|
439
|
+
let deferredHydrationFinish = false;
|
|
342
440
|
hydrationStart();
|
|
343
441
|
try {
|
|
344
|
-
if (meta.sa)
|
|
345
|
-
injectModuleStyle(meta.sa, this.shadowRoot);
|
|
346
442
|
if (!reconnecting) {
|
|
347
443
|
if (isSSR) {
|
|
348
444
|
if (this.$shouldApplySSRBootstrapState()) {
|
|
@@ -365,6 +461,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
365
461
|
if (isSSR && this.$deferredWrites)
|
|
366
462
|
this.$replayDeferredWrites();
|
|
367
463
|
if (isSSR && reconnecting) {
|
|
464
|
+
this.$invalidateRawValues(this.$root);
|
|
368
465
|
this.$updateBindings(this.$root.texts, this.$root.attrs, this.$root.conds, this.$root.repeats, true);
|
|
369
466
|
}
|
|
370
467
|
if (isSSR && DEV)
|
|
@@ -373,19 +470,72 @@ export class TemplateElement extends HTMLElement {
|
|
|
373
470
|
this.$preReadyWrites = null;
|
|
374
471
|
if (!isSSR && clientRoot) {
|
|
375
472
|
this.$updateInstance(this.$root);
|
|
376
|
-
|
|
473
|
+
const hasStructuralBindings = this.$root.repeats.length !== 0 || this.$root.conds.length !== 0;
|
|
474
|
+
if (hasStructuralBindings) {
|
|
377
475
|
this.$root.nodes = childNodesArray(clientRoot);
|
|
476
|
+
}
|
|
477
|
+
let deferredStyles = false;
|
|
478
|
+
if (templateMayContainLinkStyles(meta)) {
|
|
479
|
+
const stagingRoot = clientRoot;
|
|
480
|
+
const mountedInstance = this.$root;
|
|
481
|
+
deferredStyles = installTemplateLinkStyles(this, meta, this.shadowRoot, clientRoot, this.$root.attrs, {
|
|
482
|
+
hasAuthorHydrationLifecycle: this.hydratedCallback !==
|
|
483
|
+
TemplateElement.prototype.hydratedCallback,
|
|
484
|
+
beforeAppend: () => {
|
|
485
|
+
if (this.$root !== mountedInstance || !this.$hydrated)
|
|
486
|
+
return;
|
|
487
|
+
this.$updateInstance(mountedInstance);
|
|
488
|
+
if (hasStructuralBindings) {
|
|
489
|
+
mountedInstance.nodes = childNodesArray(stagingRoot);
|
|
490
|
+
}
|
|
491
|
+
},
|
|
492
|
+
afterAppend: () => {
|
|
493
|
+
if (this.$root !== mountedInstance || !this.$hydrated)
|
|
494
|
+
return;
|
|
495
|
+
this.$replaceInstanceContainer(mountedInstance, clientRoot, root);
|
|
496
|
+
mountedInstance.container = root;
|
|
497
|
+
this.$deferredClientMount = false;
|
|
498
|
+
this.$ready = true;
|
|
499
|
+
this.$finishHydration();
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
if (deferredStyles) {
|
|
504
|
+
this.$deferredClientMount = true;
|
|
505
|
+
this.$ready = false;
|
|
506
|
+
deferredHydrationFinish = true;
|
|
507
|
+
}
|
|
508
|
+
if (!deferredStyles && hasStructuralBindings) {
|
|
378
509
|
this.$replaceInstanceContainer(this.$root, clientRoot, root);
|
|
379
510
|
}
|
|
380
|
-
|
|
381
|
-
|
|
511
|
+
if (!deferredStyles)
|
|
512
|
+
this.$appendStagedChildren(root, clientRoot);
|
|
513
|
+
if (!deferredStyles)
|
|
514
|
+
this.$root.container = root;
|
|
382
515
|
}
|
|
383
|
-
|
|
516
|
+
if (!deferredHydrationFinish)
|
|
517
|
+
this.$finishHydration();
|
|
384
518
|
}
|
|
385
519
|
finally {
|
|
386
520
|
hydrationEnd();
|
|
387
521
|
}
|
|
388
522
|
}
|
|
523
|
+
$installStyles(meta) {
|
|
524
|
+
const wantShadow = !!this.shadowRoot || !!meta.sd;
|
|
525
|
+
const containingRoot = this.getRootNode();
|
|
526
|
+
const styleTarget = wantShadow
|
|
527
|
+
? this.shadowRoot
|
|
528
|
+
: containingRoot.nodeType === 11 && 'host' in containingRoot
|
|
529
|
+
? containingRoot
|
|
530
|
+
: this.ownerDocument;
|
|
531
|
+
claimSsrComponentStyles(this, styleTarget);
|
|
532
|
+
const installation = installComponentStyles(this.localName, styleTarget, this);
|
|
533
|
+
if (installation) {
|
|
534
|
+
void installation.catch((error) => {
|
|
535
|
+
console.error(error);
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
}
|
|
389
539
|
disconnectedCallback() {
|
|
390
540
|
this.$detachDeferredAncestor();
|
|
391
541
|
if (this.$root) {
|
|
@@ -396,13 +546,14 @@ export class TemplateElement extends HTMLElement {
|
|
|
396
546
|
}
|
|
397
547
|
}
|
|
398
548
|
$destroy() {
|
|
549
|
+
const shadowRoot = this.shadowRoot;
|
|
550
|
+
if (shadowRoot && cancelTemplateLinkStyleMount(shadowRoot)) {
|
|
551
|
+
this.$resetClientShadow = true;
|
|
552
|
+
}
|
|
399
553
|
if (!this.$root) {
|
|
400
|
-
this.$
|
|
554
|
+
this.$clearAncestorDeferral();
|
|
401
555
|
this.$abandonDeferredDescendants();
|
|
402
556
|
this.$deferredSSR = false;
|
|
403
|
-
this.$deferredByAncestor = undefined;
|
|
404
|
-
this.$ancestorBoundaryState = undefined;
|
|
405
|
-
this.$hasAncestorBoundaryState = undefined;
|
|
406
557
|
this.$ready = false;
|
|
407
558
|
this.$hasUnknownScopes = false;
|
|
408
559
|
if (this.$deferredWrites)
|
|
@@ -417,6 +568,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
417
568
|
this.$pendingFlush = false;
|
|
418
569
|
this.$preReadyWrites = null;
|
|
419
570
|
this.$hydrated = false;
|
|
571
|
+
this.$deferredClientMount = false;
|
|
420
572
|
this.$ready = false;
|
|
421
573
|
this.$hasUnknownScopes = false;
|
|
422
574
|
}
|
|
@@ -437,10 +589,14 @@ export class TemplateElement extends HTMLElement {
|
|
|
437
589
|
instance.parent = undefined;
|
|
438
590
|
instance.container = null;
|
|
439
591
|
instance.nodes.length = 0;
|
|
440
|
-
instance.texts.length
|
|
441
|
-
|
|
442
|
-
instance.
|
|
443
|
-
|
|
592
|
+
if (instance.texts.length > 0)
|
|
593
|
+
instance.texts.length = 0;
|
|
594
|
+
if (instance.attrs.length > 0)
|
|
595
|
+
instance.attrs.length = 0;
|
|
596
|
+
if (instance.conds.length > 0)
|
|
597
|
+
instance.conds.length = 0;
|
|
598
|
+
if (instance.repeats.length > 0)
|
|
599
|
+
instance.repeats.length = 0;
|
|
444
600
|
}
|
|
445
601
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
446
602
|
if (Object.is(oldValue, newValue))
|
|
@@ -489,7 +645,8 @@ export class TemplateElement extends HTMLElement {
|
|
|
489
645
|
$currentTemplateMetadata() {
|
|
490
646
|
return this.$meta ?? this.$templateMeta();
|
|
491
647
|
}
|
|
492
|
-
$nearestHydrationBarrier() {
|
|
648
|
+
$nearestHydrationBarrier(bypassAncestor) {
|
|
649
|
+
let bypass = bypassAncestor;
|
|
493
650
|
let current = this;
|
|
494
651
|
while (true) {
|
|
495
652
|
let parent = current.assignedSlot ?? current.parentElement;
|
|
@@ -505,6 +662,11 @@ export class TemplateElement extends HTMLElement {
|
|
|
505
662
|
}
|
|
506
663
|
if (!parent)
|
|
507
664
|
return undefined;
|
|
665
|
+
if (parent === bypass) {
|
|
666
|
+
bypass = undefined;
|
|
667
|
+
current = parent;
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
508
670
|
if (parent instanceof TemplateElement) {
|
|
509
671
|
const parentMeta = parent.$meta ?? parent.$templateMeta();
|
|
510
672
|
if (parentMeta?.th) {
|
|
@@ -633,6 +795,8 @@ export class TemplateElement extends HTMLElement {
|
|
|
633
795
|
const boundaryState = this.$ancestorBoundaryState;
|
|
634
796
|
this.$hasAncestorBoundaryState = undefined;
|
|
635
797
|
this.$ancestorBoundaryState = undefined;
|
|
798
|
+
if (this.$resumeRetainedRoot())
|
|
799
|
+
return;
|
|
636
800
|
const meta = this.$meta;
|
|
637
801
|
if (meta && this.$shouldDeferSSRHydration(meta)) {
|
|
638
802
|
if (hasBoundaryState) {
|
|
@@ -802,10 +966,9 @@ export class TemplateElement extends HTMLElement {
|
|
|
802
966
|
}
|
|
803
967
|
}
|
|
804
968
|
$applyPendingParentState(replayAfterHydration) {
|
|
805
|
-
const pending =
|
|
969
|
+
const pending = consumePendingParentState(this);
|
|
806
970
|
if (!pending)
|
|
807
971
|
return;
|
|
808
|
-
pendingParentStateByElement.delete(this);
|
|
809
972
|
const state = pending.values;
|
|
810
973
|
const observableNames = this.$observableNames();
|
|
811
974
|
const keys = Object.keys(state);
|
|
@@ -835,6 +998,8 @@ export class TemplateElement extends HTMLElement {
|
|
|
835
998
|
}
|
|
836
999
|
$update(path) {
|
|
837
1000
|
if (!this.$ready || !this.$root) {
|
|
1001
|
+
if (this.$deferredClientMount)
|
|
1002
|
+
return;
|
|
838
1003
|
if (path && this.$deferredSSR)
|
|
839
1004
|
this.$recordDeferredWrite(path);
|
|
840
1005
|
if (DEV && path && this.isConnected)
|
|
@@ -933,7 +1098,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
933
1098
|
if (!index)
|
|
934
1099
|
return;
|
|
935
1100
|
const ctx = {
|
|
936
|
-
resolver: this.$
|
|
1101
|
+
resolver: this.$conditionResolver(),
|
|
937
1102
|
resolveParts: (parts, scope) => this.$resolveParts(parts, scope),
|
|
938
1103
|
resolveValue: (path, scope) => this.$resolveValue(path, scope),
|
|
939
1104
|
};
|
|
@@ -941,13 +1106,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
941
1106
|
void import('./hydration-mismatch.js').then((m) => m.reportHydrationMismatch(tag, writes, index, ctx));
|
|
942
1107
|
}
|
|
943
1108
|
$parseTemplate(meta) {
|
|
944
|
-
|
|
945
|
-
if (cached)
|
|
946
|
-
return cached.cloneNode(true);
|
|
947
|
-
const tpl = document.createElement('template');
|
|
948
|
-
tpl.innerHTML = meta.h;
|
|
949
|
-
templateCache.set(meta, tpl.content);
|
|
950
|
-
return tpl.content.cloneNode(true);
|
|
1109
|
+
return cloneTemplateContent(meta);
|
|
951
1110
|
}
|
|
952
1111
|
$createStagingRoot(meta) {
|
|
953
1112
|
const wrapper = document.createElement('div');
|
|
@@ -998,102 +1157,113 @@ export class TemplateElement extends HTMLElement {
|
|
|
998
1157
|
$wire(root, meta, scope) {
|
|
999
1158
|
const instance = {
|
|
1000
1159
|
scope, container: root, nodes: childNodesArray(root),
|
|
1001
|
-
texts:
|
|
1160
|
+
texts: bindingArray(meta.tx?.length ?? 0),
|
|
1161
|
+
attrs: bindingArray(meta.a?.length ?? 0),
|
|
1162
|
+
conds: bindingArray(meta.c?.length ?? 0),
|
|
1163
|
+
repeats: bindingArray(meta.r?.length ?? 0),
|
|
1002
1164
|
};
|
|
1003
1165
|
const elements = collectTemplateElements(root);
|
|
1004
|
-
const
|
|
1005
|
-
let
|
|
1166
|
+
const pendingSlots = new Array((meta.tx?.length ?? 0) + (meta.c?.length ?? 0) + (meta.r?.length ?? 0));
|
|
1167
|
+
let pendingSlotCount = 0;
|
|
1168
|
+
let needsSlotOrdering = false;
|
|
1169
|
+
let rawIndex = 0;
|
|
1006
1170
|
if (meta.tx) {
|
|
1007
1171
|
for (let i = 0; i < meta.tx.length; i++) {
|
|
1008
1172
|
const entry = meta.tx[i];
|
|
1009
1173
|
const [slot, parts] = entry;
|
|
1010
1174
|
const raw = entry[2] === 1;
|
|
1011
|
-
const [parentIndex, beforeIndex] = slot;
|
|
1175
|
+
const [parentIndex, beforeIndex, order = 0] = slot;
|
|
1012
1176
|
const parent = elements[parentIndex];
|
|
1013
1177
|
if (!parent || (parent.nodeType !== 1 && parent.nodeType !== 11))
|
|
1014
1178
|
continue;
|
|
1015
|
-
|
|
1016
|
-
|
|
1179
|
+
let node;
|
|
1180
|
+
let end;
|
|
1181
|
+
if (raw) {
|
|
1182
|
+
const start = document.createComment(rawMarker(rawIndex));
|
|
1183
|
+
end = document.createComment(rawMarker(rawIndex, true));
|
|
1184
|
+
rawIndex++;
|
|
1185
|
+
instance.texts.push({
|
|
1186
|
+
node: start,
|
|
1187
|
+
parts,
|
|
1188
|
+
scope,
|
|
1189
|
+
raw: true,
|
|
1190
|
+
rawEnd: end,
|
|
1191
|
+
rawOwner: instance,
|
|
1192
|
+
});
|
|
1193
|
+
node = start;
|
|
1194
|
+
}
|
|
1195
|
+
else {
|
|
1196
|
+
const textNode = document.createTextNode('');
|
|
1197
|
+
instance.texts.push({ node: textNode, parts, scope });
|
|
1198
|
+
node = textNode;
|
|
1199
|
+
}
|
|
1200
|
+
pendingSlots[pendingSlotCount++] = {
|
|
1201
|
+
parent,
|
|
1202
|
+
before: parent.childNodes[beforeIndex] || null,
|
|
1203
|
+
order,
|
|
1204
|
+
node,
|
|
1205
|
+
end,
|
|
1206
|
+
};
|
|
1207
|
+
if (order > 0)
|
|
1208
|
+
needsSlotOrdering = true;
|
|
1017
1209
|
}
|
|
1018
1210
|
}
|
|
1019
|
-
const condRefs = new Array(meta.c?.length ?? 0);
|
|
1020
|
-
let condRefCount = 0;
|
|
1021
1211
|
if (meta.c) {
|
|
1022
1212
|
for (let i = 0; i < meta.c.length; i++) {
|
|
1023
1213
|
const [condition, blockIndex, slotMeta] = meta.c[i];
|
|
1024
|
-
const [parentIndex, beforeIndex] = slotMeta;
|
|
1214
|
+
const [parentIndex, beforeIndex, order = 0] = slotMeta;
|
|
1025
1215
|
const parent = elements[parentIndex];
|
|
1026
1216
|
if (!parent || (parent.nodeType !== 1 && parent.nodeType !== 11))
|
|
1027
1217
|
continue;
|
|
1028
|
-
|
|
1029
|
-
|
|
1218
|
+
const anchor = document.createComment('');
|
|
1219
|
+
instance.conds.push({
|
|
1220
|
+
condition: condition,
|
|
1221
|
+
blockIndex,
|
|
1222
|
+
anchor,
|
|
1223
|
+
scope,
|
|
1224
|
+
owner: instance,
|
|
1225
|
+
instance: null,
|
|
1226
|
+
});
|
|
1227
|
+
pendingSlots[pendingSlotCount++] = {
|
|
1228
|
+
parent,
|
|
1229
|
+
before: parent.childNodes[beforeIndex] || null,
|
|
1230
|
+
order,
|
|
1231
|
+
node: anchor,
|
|
1232
|
+
};
|
|
1233
|
+
if (order > 0)
|
|
1234
|
+
needsSlotOrdering = true;
|
|
1030
1235
|
}
|
|
1031
1236
|
}
|
|
1032
|
-
const repRefs = new Array(meta.r?.length ?? 0);
|
|
1033
|
-
let repRefCount = 0;
|
|
1034
1237
|
if (meta.r) {
|
|
1035
1238
|
for (let i = 0; i < meta.r.length; i++) {
|
|
1036
1239
|
const [collection, itemVar, blockIndex, slotMeta, keyPath] = meta.r[i];
|
|
1037
|
-
const [parentIndex, beforeIndex] = slotMeta;
|
|
1240
|
+
const [parentIndex, beforeIndex, order = 0] = slotMeta;
|
|
1038
1241
|
const parent = elements[parentIndex];
|
|
1039
1242
|
if (!parent || (parent.nodeType !== 1 && parent.nodeType !== 11))
|
|
1040
1243
|
continue;
|
|
1041
|
-
|
|
1244
|
+
const anchor = document.createComment('');
|
|
1245
|
+
const binding = {
|
|
1246
|
+
markerId: i, collection, itemVar, blockIndex,
|
|
1247
|
+
container: parent, start: anchor, end: null,
|
|
1248
|
+
scope, owner: instance, instances: [],
|
|
1249
|
+
};
|
|
1250
|
+
if (keyPath !== undefined) {
|
|
1251
|
+
binding.keyState = createRepeatKeyState(keyPath);
|
|
1252
|
+
}
|
|
1253
|
+
instance.repeats.push(binding);
|
|
1254
|
+
pendingSlots[pendingSlotCount++] = {
|
|
1042
1255
|
parent,
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
blockIndex,
|
|
1047
|
-
keyPath,
|
|
1256
|
+
before: parent.childNodes[beforeIndex] || null,
|
|
1257
|
+
order,
|
|
1258
|
+
node: anchor,
|
|
1048
1259
|
};
|
|
1049
|
-
|
|
1260
|
+
if (order > 0)
|
|
1261
|
+
needsSlotOrdering = true;
|
|
1050
1262
|
}
|
|
1051
1263
|
}
|
|
1052
1264
|
this.$wireAttrs(instance, meta, scope, (i) => elements[i] ?? null);
|
|
1053
1265
|
this.$finalize(instance, root, meta, (_r, i) => elements[i] ?? null, scope);
|
|
1054
|
-
|
|
1055
|
-
const t = textRefs[i];
|
|
1056
|
-
const anchor = document.createComment('');
|
|
1057
|
-
t.parent.insertBefore(anchor, t.ref);
|
|
1058
|
-
if (t.raw) {
|
|
1059
|
-
const container = document.createElement('span');
|
|
1060
|
-
t.parent.insertBefore(container, anchor);
|
|
1061
|
-
const textNode = document.createTextNode('');
|
|
1062
|
-
instance.texts.push({ node: textNode, parts: t.parts, scope, raw: true, rawParent: container });
|
|
1063
|
-
}
|
|
1064
|
-
else {
|
|
1065
|
-
const textNode = document.createTextNode('');
|
|
1066
|
-
t.parent.insertBefore(textNode, anchor);
|
|
1067
|
-
instance.texts.push({ node: textNode, parts: t.parts, scope });
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
for (let i = 0; i < condRefCount; i++) {
|
|
1071
|
-
const c = condRefs[i];
|
|
1072
|
-
const anchor = document.createComment('');
|
|
1073
|
-
c.parent.insertBefore(anchor, c.ref);
|
|
1074
|
-
instance.conds.push({
|
|
1075
|
-
condition: c.condition,
|
|
1076
|
-
blockIndex: c.blockIndex,
|
|
1077
|
-
anchor,
|
|
1078
|
-
scope,
|
|
1079
|
-
owner: instance,
|
|
1080
|
-
instance: null,
|
|
1081
|
-
});
|
|
1082
|
-
}
|
|
1083
|
-
for (let i = 0; i < repRefCount; i++) {
|
|
1084
|
-
const r = repRefs[i];
|
|
1085
|
-
const anchor = document.createComment('');
|
|
1086
|
-
r.parent.insertBefore(anchor, r.ref);
|
|
1087
|
-
const binding = {
|
|
1088
|
-
markerId: i, collection: r.collection, itemVar: r.itemVar, blockIndex: r.blockIndex,
|
|
1089
|
-
container: r.parent, start: anchor, end: null,
|
|
1090
|
-
scope, owner: instance, instances: [],
|
|
1091
|
-
};
|
|
1092
|
-
if (r.keyPath !== undefined) {
|
|
1093
|
-
binding.keyState = createRepeatKeyState(r.keyPath);
|
|
1094
|
-
}
|
|
1095
|
-
instance.repeats.push(binding);
|
|
1096
|
-
}
|
|
1266
|
+
insertPendingSlots(pendingSlots, pendingSlotCount, needsSlotOrdering);
|
|
1097
1267
|
for (let i = 0; i < instance.conds.length; i++)
|
|
1098
1268
|
this.$toggleCond(instance.conds[i]);
|
|
1099
1269
|
return instance;
|
|
@@ -1103,18 +1273,31 @@ export class TemplateElement extends HTMLElement {
|
|
|
1103
1273
|
scope,
|
|
1104
1274
|
container: (pathStart > 0 ? ssrRoot.parentNode : ssrRoot),
|
|
1105
1275
|
nodes: pathStart > 0 ? [ssrRoot] : childNodesArray(ssrRoot),
|
|
1106
|
-
texts:
|
|
1276
|
+
texts: bindingArray(meta.tx?.length ?? 0),
|
|
1277
|
+
attrs: bindingArray(meta.a?.length ?? 0),
|
|
1278
|
+
conds: bindingArray(meta.c?.length ?? 0),
|
|
1279
|
+
repeats: bindingArray(meta.r?.length ?? 0),
|
|
1107
1280
|
};
|
|
1108
1281
|
const staleMarkers = [];
|
|
1109
|
-
|
|
1282
|
+
let rawTextCount = 0;
|
|
1283
|
+
if (meta.tx) {
|
|
1284
|
+
for (let i = 0; i < meta.tx.length; i++) {
|
|
1285
|
+
if (meta.tx[i][2] === 1)
|
|
1286
|
+
rawTextCount++;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
const ssrIndex = buildSSRIndex(tplDom, ssrRoot, meta.c !== undefined || meta.r !== undefined || rawTextCount !== 0, pathStart > 0);
|
|
1110
1290
|
const ssrElements = ssrIndex.elements;
|
|
1111
1291
|
const tplElements = getTemplateElements(tplDom);
|
|
1292
|
+
const textMarkerBoundaries = getTextMarkerBoundaries(meta);
|
|
1112
1293
|
if (meta.tx) {
|
|
1294
|
+
const rawRanges = ssrIndex.raws.length === rawTextCount ? ssrIndex.raws : null;
|
|
1295
|
+
let rawIndex = 0;
|
|
1113
1296
|
for (let i = 0; i < meta.tx.length; i++) {
|
|
1114
1297
|
const entry = meta.tx[i];
|
|
1115
1298
|
const [slot, parts] = entry;
|
|
1116
1299
|
const raw = entry[2] === 1;
|
|
1117
|
-
const [parentIndex
|
|
1300
|
+
const [parentIndex] = slot;
|
|
1118
1301
|
const ssrParent = ssrElements[parentIndex];
|
|
1119
1302
|
if (!ssrParent)
|
|
1120
1303
|
continue;
|
|
@@ -1122,19 +1305,37 @@ export class TemplateElement extends HTMLElement {
|
|
|
1122
1305
|
if (!tplParent)
|
|
1123
1306
|
continue;
|
|
1124
1307
|
if (raw) {
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1127
|
-
|
|
1308
|
+
const rawRange = rawRanges?.[rawIndex++];
|
|
1309
|
+
if (!rawRange)
|
|
1310
|
+
continue;
|
|
1311
|
+
const binding = {
|
|
1312
|
+
node: rawRange[0],
|
|
1313
|
+
parts,
|
|
1314
|
+
scope,
|
|
1315
|
+
raw: true,
|
|
1316
|
+
rawEnd: rawRange[1],
|
|
1317
|
+
rawOwner: instance,
|
|
1318
|
+
};
|
|
1319
|
+
if ((!scope || this.$scopeIsKnown(scope))
|
|
1320
|
+
&& this.$textStateIsKnown(binding)) {
|
|
1321
|
+
binding.rawValue = this.$resolveParts(parts, scope);
|
|
1322
|
+
}
|
|
1323
|
+
instance.texts.push(binding);
|
|
1128
1324
|
}
|
|
1129
1325
|
else {
|
|
1130
|
-
|
|
1131
|
-
|
|
1326
|
+
const insertRef = this.$findSSRSlotRef(ssrParent, tplParent, meta, ssrIndex, slot, textMarkerBoundaries[i] ?? 0);
|
|
1327
|
+
let previous = insertRef ? insertRef.previousSibling : ssrParent.lastChild;
|
|
1328
|
+
if (previous?.nodeType === 8
|
|
1329
|
+
&& previous.data === ''
|
|
1330
|
+
&& previous.previousSibling?.nodeType === 3) {
|
|
1331
|
+
previous = previous.previousSibling;
|
|
1332
|
+
}
|
|
1333
|
+
let textNode = previous?.nodeType === 3 ? previous : null;
|
|
1334
|
+
if (textNode === null) {
|
|
1132
1335
|
textNode = document.createTextNode('');
|
|
1133
|
-
const insertRef = this.$findSSRSlotRef(ssrParent, tplParent, beforeIndex);
|
|
1134
1336
|
ssrParent.insertBefore(textNode, insertRef);
|
|
1135
1337
|
}
|
|
1136
|
-
|
|
1137
|
-
instance.texts.push({ node: textNode, parts, scope });
|
|
1338
|
+
instance.texts.push({ node: textNode, parts, scope });
|
|
1138
1339
|
}
|
|
1139
1340
|
}
|
|
1140
1341
|
}
|
|
@@ -1161,7 +1362,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
1161
1362
|
if (marker && blockMeta) {
|
|
1162
1363
|
condInstance = this.$hydrateCondContent(condAnchor, blockMeta, scope);
|
|
1163
1364
|
if (condInstance)
|
|
1164
|
-
condInstance
|
|
1365
|
+
this.$setInstanceParent(condInstance, instance);
|
|
1165
1366
|
}
|
|
1166
1367
|
if (marker) {
|
|
1167
1368
|
const lastNode = condInstance ? condInstance.nodes[condInstance.nodes.length - 1] : condAnchor;
|
|
@@ -1170,9 +1371,14 @@ export class TemplateElement extends HTMLElement {
|
|
|
1170
1371
|
staleMarkers.push(endMarker);
|
|
1171
1372
|
}
|
|
1172
1373
|
}
|
|
1374
|
+
let liveAnchor = condAnchor;
|
|
1375
|
+
if (condInstance && condInstance.nodes.length > 0) {
|
|
1376
|
+
staleMarkers.push(condAnchor);
|
|
1377
|
+
liveAnchor = null;
|
|
1378
|
+
}
|
|
1173
1379
|
instance.conds.push({
|
|
1174
1380
|
condition: condition, blockIndex,
|
|
1175
|
-
anchor:
|
|
1381
|
+
anchor: liveAnchor,
|
|
1176
1382
|
scope, owner: instance, instance: condInstance,
|
|
1177
1383
|
});
|
|
1178
1384
|
}
|
|
@@ -1186,7 +1392,10 @@ export class TemplateElement extends HTMLElement {
|
|
|
1186
1392
|
const ssrParent = (marker ? marker.parentNode : ssrElements[parentIndex]) ?? ssrRoot;
|
|
1187
1393
|
const blockMeta = this.$block(blockIndex);
|
|
1188
1394
|
const blockTplDom = blockMeta ? getTemplateDom(blockMeta) : null;
|
|
1189
|
-
const rootTag = blockMeta
|
|
1395
|
+
const rootTag = blockMeta
|
|
1396
|
+
&& blockTplDom?.childNodes.length === 1
|
|
1397
|
+
&& blockTplDom.children.length === 1
|
|
1398
|
+
&& !this.$hasRootStructuralSlot(blockMeta)
|
|
1190
1399
|
? this.$rootTag(blockMeta)
|
|
1191
1400
|
: null;
|
|
1192
1401
|
let anchor;
|
|
@@ -1229,7 +1438,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
1229
1438
|
const itemEl = nextElement(itemMarkers[j]);
|
|
1230
1439
|
if (itemEl) {
|
|
1231
1440
|
const childInstance = this.$hydrate(itemEl, blockMeta, blockTplDom, itemScope, 1);
|
|
1232
|
-
childInstance
|
|
1441
|
+
this.$setInstanceParent(childInstance, instance);
|
|
1233
1442
|
repeatInsts.push(childInstance);
|
|
1234
1443
|
}
|
|
1235
1444
|
}
|
|
@@ -1244,7 +1453,6 @@ export class TemplateElement extends HTMLElement {
|
|
|
1244
1453
|
cursor = next;
|
|
1245
1454
|
}
|
|
1246
1455
|
const inst = this.$hydrate(wrapper, blockMeta, blockTplDom, itemScope);
|
|
1247
|
-
inst.parent = instance;
|
|
1248
1456
|
inst.nodes = childNodesArray(wrapper);
|
|
1249
1457
|
let afterNode = itemMarkers[j];
|
|
1250
1458
|
for (let nodeIndex = 0; nodeIndex < inst.nodes.length; nodeIndex++) {
|
|
@@ -1255,6 +1463,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
1255
1463
|
if (itemParent) {
|
|
1256
1464
|
this.$replaceInstanceContainer(inst, wrapper, itemParent);
|
|
1257
1465
|
}
|
|
1466
|
+
this.$setInstanceParent(inst, instance);
|
|
1258
1467
|
repeatInsts.push(inst);
|
|
1259
1468
|
}
|
|
1260
1469
|
}
|
|
@@ -1321,6 +1530,12 @@ export class TemplateElement extends HTMLElement {
|
|
|
1321
1530
|
return true;
|
|
1322
1531
|
}
|
|
1323
1532
|
}
|
|
1533
|
+
if (meta.tx) {
|
|
1534
|
+
for (let i = 0; i < meta.tx.length; i++) {
|
|
1535
|
+
if (meta.tx[i][2] === 1 && meta.tx[i][0][0] === 0)
|
|
1536
|
+
return true;
|
|
1537
|
+
}
|
|
1538
|
+
}
|
|
1324
1539
|
return false;
|
|
1325
1540
|
}
|
|
1326
1541
|
$hydrateCondContent(condAnchor, blockMeta, scope) {
|
|
@@ -1351,27 +1566,25 @@ export class TemplateElement extends HTMLElement {
|
|
|
1351
1566
|
this.$replaceInstanceContainer(inst, wrapper, container);
|
|
1352
1567
|
return inst;
|
|
1353
1568
|
}
|
|
1354
|
-
$
|
|
1355
|
-
const
|
|
1356
|
-
let
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
}
|
|
1374
|
-
$findSSRSlotRef(ssrParent, tplParent, beforeIndex) {
|
|
1569
|
+
$findSSRSlotRef(ssrParent, tplParent, meta, ssrIndex, slot, markerBoundary) {
|
|
1570
|
+
const [, beforeIndex] = slot;
|
|
1571
|
+
let marker = null;
|
|
1572
|
+
if (markerBoundary >= RAW_MARKER_BOUNDARY_BASE) {
|
|
1573
|
+
marker =
|
|
1574
|
+
ssrIndex.raws[markerBoundary - RAW_MARKER_BOUNDARY_BASE - 1]?.[0] ?? null;
|
|
1575
|
+
}
|
|
1576
|
+
else if (markerBoundary > 0
|
|
1577
|
+
&& meta.c
|
|
1578
|
+
&& ssrIndex.conds.length === meta.c.length) {
|
|
1579
|
+
marker = ssrIndex.conds[markerBoundary - 1];
|
|
1580
|
+
}
|
|
1581
|
+
else if (markerBoundary < 0
|
|
1582
|
+
&& meta.r
|
|
1583
|
+
&& ssrIndex.repeats.length === meta.r.length) {
|
|
1584
|
+
marker = ssrIndex.repeats[-markerBoundary - 1];
|
|
1585
|
+
}
|
|
1586
|
+
if (marker?.parentNode === ssrParent)
|
|
1587
|
+
return marker;
|
|
1375
1588
|
const ordinals = getTplOrdinals(tplParent);
|
|
1376
1589
|
const children = tplParent.childNodes;
|
|
1377
1590
|
for (let i = beforeIndex; i < children.length; i++) {
|
|
@@ -1582,6 +1795,29 @@ export class TemplateElement extends HTMLElement {
|
|
|
1582
1795
|
return this.$partsAreKnown(binding.parts, binding.scope);
|
|
1583
1796
|
return !binding.path || this.$hasStateRoot(binding.path, binding.scope);
|
|
1584
1797
|
}
|
|
1798
|
+
$invalidateRawValues(root) {
|
|
1799
|
+
const stack = [root];
|
|
1800
|
+
while (stack.length > 0) {
|
|
1801
|
+
const instance = stack.pop();
|
|
1802
|
+
if (!instance)
|
|
1803
|
+
continue;
|
|
1804
|
+
for (let i = 0; i < instance.texts.length; i++) {
|
|
1805
|
+
const binding = instance.texts[i];
|
|
1806
|
+
if (binding.raw)
|
|
1807
|
+
binding.rawValue = undefined;
|
|
1808
|
+
}
|
|
1809
|
+
for (let i = 0; i < instance.conds.length; i++) {
|
|
1810
|
+
const child = instance.conds[i].instance;
|
|
1811
|
+
if (child)
|
|
1812
|
+
stack.push(child);
|
|
1813
|
+
}
|
|
1814
|
+
for (let i = 0; i < instance.repeats.length; i++) {
|
|
1815
|
+
const children = instance.repeats[i].instances;
|
|
1816
|
+
for (let j = 0; j < children.length; j++)
|
|
1817
|
+
stack.push(children[j]);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
}
|
|
1585
1821
|
$attrStateIsKnown(binding) {
|
|
1586
1822
|
if (binding.path && !this.$hasStateRoot(binding.path, binding.scope))
|
|
1587
1823
|
return false;
|
|
@@ -1629,9 +1865,39 @@ export class TemplateElement extends HTMLElement {
|
|
|
1629
1865
|
else {
|
|
1630
1866
|
return;
|
|
1631
1867
|
}
|
|
1632
|
-
if (b.raw && b.
|
|
1633
|
-
if (b.
|
|
1634
|
-
|
|
1868
|
+
if (b.raw && b.rawEnd) {
|
|
1869
|
+
if (b.rawValue === val)
|
|
1870
|
+
return;
|
|
1871
|
+
const range = document.createRange();
|
|
1872
|
+
range.setStartAfter(b.node);
|
|
1873
|
+
range.setEndBefore(b.rawEnd);
|
|
1874
|
+
range.deleteContents();
|
|
1875
|
+
let rawNodes;
|
|
1876
|
+
const rawOwner = b.rawOwner;
|
|
1877
|
+
if (val !== '') {
|
|
1878
|
+
const fragment = range.createContextualFragment(val);
|
|
1879
|
+
if (rawOwner && b.node.parentNode === rawOwner.container) {
|
|
1880
|
+
rawNodes = childNodesArray(fragment);
|
|
1881
|
+
}
|
|
1882
|
+
range.insertNode(fragment);
|
|
1883
|
+
}
|
|
1884
|
+
else if (rawOwner && b.node.parentNode === rawOwner.container) {
|
|
1885
|
+
rawNodes = [];
|
|
1886
|
+
}
|
|
1887
|
+
if (rawNodes && rawOwner) {
|
|
1888
|
+
const container = b.node.parentNode;
|
|
1889
|
+
let owner = rawOwner;
|
|
1890
|
+
while (owner && owner.container === container) {
|
|
1891
|
+
const ownerNodes = owner.nodes;
|
|
1892
|
+
const startIndex = ownerNodes.indexOf(b.node);
|
|
1893
|
+
const endIndex = ownerNodes.indexOf(b.rawEnd, startIndex + 1);
|
|
1894
|
+
if (startIndex >= 0 && endIndex > startIndex) {
|
|
1895
|
+
ownerNodes.splice(startIndex + 1, endIndex - startIndex - 1, ...rawNodes);
|
|
1896
|
+
}
|
|
1897
|
+
owner = owner.parent;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
b.rawValue = val;
|
|
1635
1901
|
}
|
|
1636
1902
|
else {
|
|
1637
1903
|
if (b.node.data !== val)
|
|
@@ -1647,7 +1913,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
1647
1913
|
break;
|
|
1648
1914
|
}
|
|
1649
1915
|
case ATTR_KIND_BOOLEAN: {
|
|
1650
|
-
const show = b.condition[0](this.$
|
|
1916
|
+
const show = b.condition[0](this.$conditionResolver(), b.scope);
|
|
1651
1917
|
if (show)
|
|
1652
1918
|
el.setAttribute(b.name, '');
|
|
1653
1919
|
else
|
|
@@ -1684,28 +1950,68 @@ export class TemplateElement extends HTMLElement {
|
|
|
1684
1950
|
}
|
|
1685
1951
|
}
|
|
1686
1952
|
}
|
|
1953
|
+
$swapOwnedRange(owner, current, replacement) {
|
|
1954
|
+
const currentIsRange = Array.isArray(current);
|
|
1955
|
+
const first = currentIsRange ? current[0] : current;
|
|
1956
|
+
if (!first)
|
|
1957
|
+
return;
|
|
1958
|
+
const count = currentIsRange ? current.length : 1;
|
|
1959
|
+
const last = currentIsRange ? current[count - 1] : first;
|
|
1960
|
+
const container = first.parentNode;
|
|
1961
|
+
let instance = owner;
|
|
1962
|
+
while (container && instance && instance.container === container) {
|
|
1963
|
+
const nodes = instance.nodes;
|
|
1964
|
+
const index = nodes.indexOf(first);
|
|
1965
|
+
if (index >= 0 && nodes[index + count - 1] === last) {
|
|
1966
|
+
if (Array.isArray(replacement)) {
|
|
1967
|
+
nodes.splice(index, count, ...replacement);
|
|
1968
|
+
}
|
|
1969
|
+
else {
|
|
1970
|
+
nodes.splice(index, count, replacement);
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
instance = instance.parent;
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1687
1976
|
$toggleCond(c) {
|
|
1688
|
-
const show = c.condition[0](this.$
|
|
1977
|
+
const show = c.condition[0](this.$conditionResolver(), c.scope);
|
|
1689
1978
|
if (show) {
|
|
1690
|
-
|
|
1691
|
-
const container = c.anchor.parentNode;
|
|
1692
|
-
if (!c.instance) {
|
|
1693
|
-
c.instance = this.$createBlockInstance(c.blockIndex, c.scope, c.owner, container ?? undefined);
|
|
1694
|
-
created = c.instance !== null;
|
|
1695
|
-
}
|
|
1696
|
-
else {
|
|
1979
|
+
if (c.instance) {
|
|
1697
1980
|
this.$updateInstance(c.instance);
|
|
1981
|
+
return;
|
|
1698
1982
|
}
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1983
|
+
const anchor = c.anchor;
|
|
1984
|
+
const container = anchor?.parentNode;
|
|
1985
|
+
if (!anchor || !container)
|
|
1986
|
+
return;
|
|
1987
|
+
const instance = this.$createBlockInstance(c.blockIndex, c.scope, c.owner, container);
|
|
1988
|
+
if (!instance)
|
|
1989
|
+
return;
|
|
1990
|
+
c.instance = instance;
|
|
1991
|
+
const nodes = instance.nodes;
|
|
1992
|
+
this.$insertInstanceAfter(anchor, container, instance);
|
|
1993
|
+
if (nodes.length > 0) {
|
|
1994
|
+
this.$swapOwnedRange(c.owner, anchor, nodes);
|
|
1995
|
+
anchor.remove();
|
|
1996
|
+
c.anchor = null;
|
|
1703
1997
|
}
|
|
1998
|
+
this.$changeStructure();
|
|
1704
1999
|
}
|
|
1705
2000
|
else if (c.instance) {
|
|
1706
|
-
|
|
2001
|
+
const instance = c.instance;
|
|
2002
|
+
const block = this.$block(c.blockIndex);
|
|
2003
|
+
const compactOwners = !!block && this.$hasRootStructuralSlot(block);
|
|
2004
|
+
const first = instance.nodes[0] ?? null;
|
|
2005
|
+
const container = first?.parentNode;
|
|
2006
|
+
if (first && container) {
|
|
2007
|
+
const anchor = document.createComment('');
|
|
2008
|
+
container.insertBefore(anchor, first);
|
|
2009
|
+
this.$swapOwnedRange(c.owner, instance.nodes, anchor);
|
|
2010
|
+
c.anchor = anchor;
|
|
2011
|
+
}
|
|
2012
|
+
this.$removeInstance(instance);
|
|
1707
2013
|
c.instance = null;
|
|
1708
|
-
this.$changeStructure(c.owner);
|
|
2014
|
+
this.$changeStructure(compactOwners ? c.owner : undefined);
|
|
1709
2015
|
}
|
|
1710
2016
|
}
|
|
1711
2017
|
$resolveValue(path, scope) {
|
|
@@ -1723,6 +2029,9 @@ export class TemplateElement extends HTMLElement {
|
|
|
1723
2029
|
return this.$resolveComponentRoot(path);
|
|
1724
2030
|
return dotWalk(this.$resolveComponentRoot(path.substring(0, dot)), path, dot + 1);
|
|
1725
2031
|
}
|
|
2032
|
+
$conditionResolver() {
|
|
2033
|
+
return this.$resolver ??= (path, scope) => this.$resolveValue(path, scope);
|
|
2034
|
+
}
|
|
1726
2035
|
$hasStateRoot(path, scope) {
|
|
1727
2036
|
let frame = scope;
|
|
1728
2037
|
while (frame) {
|
|
@@ -1762,6 +2071,9 @@ export class TemplateElement extends HTMLElement {
|
|
|
1762
2071
|
}
|
|
1763
2072
|
return result;
|
|
1764
2073
|
}
|
|
2074
|
+
$setInstanceParent(instance, parent) {
|
|
2075
|
+
instance.parent = parent;
|
|
2076
|
+
}
|
|
1765
2077
|
$block(blockIndex) {
|
|
1766
2078
|
return this.$meta?.b?.[blockIndex];
|
|
1767
2079
|
}
|
|
@@ -1771,7 +2083,6 @@ export class TemplateElement extends HTMLElement {
|
|
|
1771
2083
|
return null;
|
|
1772
2084
|
const wrapper = this.$createStagingRoot(bm);
|
|
1773
2085
|
const inst = this.$wire(wrapper, bm, scope);
|
|
1774
|
-
inst.parent = parent;
|
|
1775
2086
|
inst.nodes = childNodesArray(wrapper);
|
|
1776
2087
|
this.$updateInstance(inst);
|
|
1777
2088
|
if (inst.repeats.length !== 0 || inst.conds.length !== 0) {
|
|
@@ -1781,6 +2092,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
1781
2092
|
else if (container) {
|
|
1782
2093
|
inst.container = container;
|
|
1783
2094
|
}
|
|
2095
|
+
this.$setInstanceParent(inst, parent);
|
|
1784
2096
|
return inst;
|
|
1785
2097
|
}
|
|
1786
2098
|
$removeInstance(instance) {
|
|
@@ -1799,8 +2111,7 @@ export class TemplateElement extends HTMLElement {
|
|
|
1799
2111
|
cleanups.length = 0;
|
|
1800
2112
|
}
|
|
1801
2113
|
if (removeNodes) {
|
|
1802
|
-
|
|
1803
|
-
node.parentNode?.removeChild(node);
|
|
2114
|
+
this.$removeInstanceNodes(instance);
|
|
1804
2115
|
}
|
|
1805
2116
|
for (const binding of instance.conds) {
|
|
1806
2117
|
if (binding.instance)
|
|
@@ -1815,6 +2126,11 @@ export class TemplateElement extends HTMLElement {
|
|
|
1815
2126
|
this.$clearInstance(instance);
|
|
1816
2127
|
}
|
|
1817
2128
|
}
|
|
2129
|
+
$removeInstanceNodes(instance) {
|
|
2130
|
+
const nodes = instance.nodes;
|
|
2131
|
+
for (let i = 0; i < nodes.length; i++)
|
|
2132
|
+
nodes[i].parentNode?.removeChild(nodes[i]);
|
|
2133
|
+
}
|
|
1818
2134
|
$compactNodeArray(instance) {
|
|
1819
2135
|
const container = instance.container;
|
|
1820
2136
|
if (!container)
|