@farm.js/react 0.1.0-beta.3 → 0.1.0-beta.4
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 +120 -37
- package/dist/compiler-runtime.cjs +1925 -156
- package/dist/compiler-runtime.cjs.map +1 -1
- package/dist/compiler-runtime.d.mts +76 -1
- package/dist/compiler-runtime.d.ts +76 -1
- package/dist/compiler-runtime.mjs +1925 -156
- package/dist/compiler-runtime.mjs.map +1 -1
- package/dist/index.cjs +5 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.mjs +5 -1
- package/dist/index.mjs.map +1 -1
- package/dist/list.cjs +18 -1
- package/dist/list.cjs.map +1 -1
- package/dist/list.mjs +18 -1
- package/dist/list.mjs.map +1 -1
- package/dist/vite.cjs +1168 -85
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.mjs +1168 -85
- package/dist/vite.mjs.map +1 -1
- package/package.json +4 -3
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { flushSync } from 'react-dom';
|
|
3
3
|
|
|
4
|
+
// src/compiler-runtime.tsx
|
|
5
|
+
|
|
6
|
+
// src/iterable.ts
|
|
7
|
+
var oneShotSnapshots = /* @__PURE__ */ new WeakMap();
|
|
8
|
+
function materializeIterable(source) {
|
|
9
|
+
if (source == null) return [];
|
|
10
|
+
const iterator = source[Symbol.iterator]();
|
|
11
|
+
const oneShot = iterator === source && (typeof source === "object" || typeof source === "function");
|
|
12
|
+
if (oneShot) {
|
|
13
|
+
const cached = oneShotSnapshots.get(source);
|
|
14
|
+
if (cached) return cached;
|
|
15
|
+
}
|
|
16
|
+
const items = Array.from({ [Symbol.iterator]: () => iterator });
|
|
17
|
+
if (oneShot) oneShotSnapshots.set(source, items);
|
|
18
|
+
return items;
|
|
19
|
+
}
|
|
20
|
+
|
|
4
21
|
// src/compiler-runtime.tsx
|
|
5
22
|
var COMPILER_HMR_REGISTRY = /* @__PURE__ */ Symbol.for("@farm.js/react/compiler-hmr-registry");
|
|
6
23
|
function getCompilerHmrRegistry() {
|
|
@@ -16,6 +33,11 @@ function renderTextValue(value) {
|
|
|
16
33
|
if (value === null || value === void 0 || typeof value === "boolean") return "";
|
|
17
34
|
return String(value);
|
|
18
35
|
}
|
|
36
|
+
function isCompilerPrimitive(value) {
|
|
37
|
+
if (value === null) return true;
|
|
38
|
+
const kind = typeof value;
|
|
39
|
+
return kind === "string" || kind === "number" || kind === "boolean" || kind === "bigint" || kind === "undefined";
|
|
40
|
+
}
|
|
19
41
|
function findBindingTarget(root, path, blockRoots) {
|
|
20
42
|
let current = root;
|
|
21
43
|
for (const index of path) {
|
|
@@ -254,14 +276,19 @@ function createCompilerHostElement(document, descriptor) {
|
|
|
254
276
|
updateAttribute(element, attribute.name, attribute.value);
|
|
255
277
|
}
|
|
256
278
|
for (const style of descriptor.styles) updateStyle(element, style.name, style.value);
|
|
257
|
-
|
|
279
|
+
const appendChild = (child) => {
|
|
280
|
+
if (Array.isArray(child)) {
|
|
281
|
+
for (const nested of child) appendChild(nested);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
258
284
|
if (isCompilerHostElement(child)) {
|
|
259
285
|
element.append(createCompilerHostElement(document, child));
|
|
260
|
-
|
|
286
|
+
return;
|
|
261
287
|
}
|
|
262
288
|
const text = renderTextValue(child);
|
|
263
289
|
if (text) element.append(document.createTextNode(text));
|
|
264
|
-
}
|
|
290
|
+
};
|
|
291
|
+
for (const child of materializeCompilerHostChildren(descriptor)) appendChild(child);
|
|
265
292
|
for (const attribute of descriptor.attributes) {
|
|
266
293
|
if (attribute.name === "value" && (isSelectElement(element) || isTextAreaElement(element))) {
|
|
267
294
|
updateAttribute(element, attribute.name, attribute.value);
|
|
@@ -271,18 +298,110 @@ function createCompilerHostElement(document, descriptor) {
|
|
|
271
298
|
}
|
|
272
299
|
function matchesCompilerHostElement(element, descriptor, opaquePaths = /* @__PURE__ */ new Set(), path = []) {
|
|
273
300
|
if (element.tagName.toLowerCase() !== descriptor.tag.toLowerCase()) return false;
|
|
274
|
-
if (opaquePaths.has(path.join("."))) return true;
|
|
275
|
-
const expectedChildren = descriptor.children
|
|
301
|
+
if (opaquePaths.has(path.join(".")) || descriptor.block) return true;
|
|
302
|
+
const expectedChildren = flattenCompilerHostElements(descriptor.children);
|
|
276
303
|
if (element.children.length !== expectedChildren.length) return false;
|
|
277
304
|
return expectedChildren.every(
|
|
278
305
|
(child, index) => matchesCompilerHostElement(element.children[index], child, opaquePaths, [...path, index])
|
|
279
306
|
);
|
|
280
307
|
}
|
|
308
|
+
function flattenCompilerHostElements(children) {
|
|
309
|
+
const elements = [];
|
|
310
|
+
const visit = (child) => {
|
|
311
|
+
if (Array.isArray(child)) {
|
|
312
|
+
for (const nested of child) visit(nested);
|
|
313
|
+
} else if (isCompilerHostElement(child)) {
|
|
314
|
+
elements.push(child);
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
for (const child of children) visit(child);
|
|
318
|
+
return elements;
|
|
319
|
+
}
|
|
320
|
+
function materializeCompilerHostChildren(descriptor) {
|
|
321
|
+
const block = descriptor.block;
|
|
322
|
+
if (block?.kind !== "keyed-ranges" || !block.staticChildrenOnly) {
|
|
323
|
+
return descriptor.children;
|
|
324
|
+
}
|
|
325
|
+
const staticChildren = flattenCompilerHostElements(descriptor.children);
|
|
326
|
+
const children = [];
|
|
327
|
+
let cursor = 0;
|
|
328
|
+
for (const range of block.ranges) {
|
|
329
|
+
children.push(...staticChildren.slice(cursor, cursor + range.before));
|
|
330
|
+
cursor += range.before;
|
|
331
|
+
const items = materializeIterable(range.items());
|
|
332
|
+
children.push(...items.map((item, index) => range.create(item, index)));
|
|
333
|
+
}
|
|
334
|
+
children.push(...staticChildren.slice(cursor, cursor + block.trailing));
|
|
335
|
+
return children;
|
|
336
|
+
}
|
|
337
|
+
function collectCompilerHostBlockIds(descriptor, ids) {
|
|
338
|
+
for (const child of flattenCompilerHostElements(descriptor.children)) {
|
|
339
|
+
collectCompilerHostBlockIds(child, ids);
|
|
340
|
+
}
|
|
341
|
+
const block = descriptor.block;
|
|
342
|
+
if (!block || ids.has(block.id)) return;
|
|
343
|
+
ids.add(block.id);
|
|
344
|
+
if (block.kind === "conditional-ranges") {
|
|
345
|
+
for (const range of block.ranges) {
|
|
346
|
+
if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
|
|
347
|
+
if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
|
|
348
|
+
}
|
|
349
|
+
} else if (block.kind === "keyed-ranges") {
|
|
350
|
+
for (const range of block.ranges) {
|
|
351
|
+
const first = materializeIterable(range.items())[0];
|
|
352
|
+
if (first !== void 0) collectCompilerHostBlockIds(range.create(first, 0), ids);
|
|
353
|
+
}
|
|
354
|
+
} else {
|
|
355
|
+
for (const range of block.ranges) {
|
|
356
|
+
if (range.kind === "conditional") {
|
|
357
|
+
if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
|
|
358
|
+
if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
|
|
359
|
+
} else {
|
|
360
|
+
const first = materializeIterable(range.items())[0];
|
|
361
|
+
if (first !== void 0) collectCompilerHostBlockIds(range.create(first, 0), ids);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
281
366
|
function findCompilerHostTarget(root, path) {
|
|
282
367
|
let current = root;
|
|
283
368
|
for (const index of path) current = current?.children[index] || null;
|
|
284
369
|
return current;
|
|
285
370
|
}
|
|
371
|
+
var UNSET_STATIC_RANGE_BINDING = /* @__PURE__ */ Symbol("unset static range binding");
|
|
372
|
+
function normalizedStaticRangeBindingValue(binding, value) {
|
|
373
|
+
return binding.kind === "text" ? renderTextValue(value) : value;
|
|
374
|
+
}
|
|
375
|
+
function applyStaticRangeBindings(bindings, segments, values) {
|
|
376
|
+
const activeBindings = bindings || [];
|
|
377
|
+
if (values.length === 0 && activeBindings.length > 0) {
|
|
378
|
+
values.push(...activeBindings.map(() => UNSET_STATIC_RANGE_BINDING));
|
|
379
|
+
}
|
|
380
|
+
if (values.length !== activeBindings.length) return false;
|
|
381
|
+
for (let index = 0; index < activeBindings.length; index += 1) {
|
|
382
|
+
const binding = activeBindings[index];
|
|
383
|
+
if (!Number.isSafeInteger(binding.segment) || binding.segment < 0 || !Number.isSafeInteger(binding.sibling) || binding.sibling < 0) {
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
const sibling = segments[binding.segment]?.[binding.sibling];
|
|
387
|
+
const target = sibling && findCompilerHostTarget(sibling, binding.path);
|
|
388
|
+
if (!target) return false;
|
|
389
|
+
const rawValue = binding.read();
|
|
390
|
+
const value = normalizedStaticRangeBindingValue(binding, rawValue);
|
|
391
|
+
if (Object.is(values[index], value)) continue;
|
|
392
|
+
values[index] = value;
|
|
393
|
+
if (binding.kind === "text") {
|
|
394
|
+
target.textContent = value;
|
|
395
|
+
} else if (binding.kind === "style" && binding.name) {
|
|
396
|
+
updateStyle(target, binding.name, rawValue);
|
|
397
|
+
} else if (binding.kind === "attribute" && binding.name) {
|
|
398
|
+
updateAttribute(target, binding.name, rawValue);
|
|
399
|
+
} else {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return true;
|
|
404
|
+
}
|
|
286
405
|
var UNSET_KEYED_ROW_BINDING = /* @__PURE__ */ Symbol("unset interactive keyed-row binding");
|
|
287
406
|
function keyedRowIdentity(key) {
|
|
288
407
|
return String(key);
|
|
@@ -297,20 +416,23 @@ function readKeyedRowBindingValues(props, item, index) {
|
|
|
297
416
|
}
|
|
298
417
|
function applyKeyedRowBindings(props, instance, item, index) {
|
|
299
418
|
for (let bindingIndex = 0; bindingIndex < props.bindings.length; bindingIndex += 1) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
419
|
+
applyKeyedRowBinding(props, instance, item, index, bindingIndex);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
function applyKeyedRowBinding(props, instance, item, index, bindingIndex) {
|
|
423
|
+
const binding = props.bindings[bindingIndex];
|
|
424
|
+
const rawValue = binding.read(item, index);
|
|
425
|
+
const value = normalizedKeyedRowBindingValue(binding, rawValue);
|
|
426
|
+
if (Object.is(instance.values[bindingIndex], value)) return;
|
|
427
|
+
instance.values[bindingIndex] = value;
|
|
428
|
+
const target = findCompilerHostTarget(instance.element, binding.path);
|
|
429
|
+
if (!target) return;
|
|
430
|
+
if (binding.kind === "text") {
|
|
431
|
+
target.textContent = value;
|
|
432
|
+
} else if (binding.kind === "style" && binding.name) {
|
|
433
|
+
updateStyle(target, binding.name, rawValue);
|
|
434
|
+
} else if (binding.kind === "attribute" && binding.name) {
|
|
435
|
+
updateAttribute(target, binding.name, rawValue);
|
|
314
436
|
}
|
|
315
437
|
}
|
|
316
438
|
function keyedRowConditionalSnapshot(conditional, item, index) {
|
|
@@ -329,13 +451,15 @@ function keyedRowConditionalSnapshot(conditional, item, index) {
|
|
|
329
451
|
];
|
|
330
452
|
}
|
|
331
453
|
function readKeyedRowConditionalValues(props, item, index) {
|
|
454
|
+
if (!props.conditionals?.length) return EMPTY_KEYED_ROW_CONDITIONAL_VALUES;
|
|
332
455
|
return new Map(
|
|
333
|
-
|
|
456
|
+
props.conditionals.map((conditional) => [
|
|
334
457
|
conditional.id,
|
|
335
458
|
keyedRowConditionalSnapshot(conditional, item, index)
|
|
336
459
|
])
|
|
337
460
|
);
|
|
338
461
|
}
|
|
462
|
+
var EMPTY_KEYED_ROW_CONDITIONAL_VALUES = /* @__PURE__ */ new Map();
|
|
339
463
|
function keyedRowConditionalChanged(previous, next) {
|
|
340
464
|
return !previous || previous.length !== next.length || next.some((value, index) => !Object.is(value, previous[index]));
|
|
341
465
|
}
|
|
@@ -352,11 +476,6 @@ function hostConditionalSelection(props) {
|
|
|
352
476
|
function normalizedHostConditionalBindingValue(binding, value) {
|
|
353
477
|
return binding.kind === "text" ? renderTextValue(value) : value;
|
|
354
478
|
}
|
|
355
|
-
function readHostConditionalBindingValues(branch) {
|
|
356
|
-
return branch.bindings.map(
|
|
357
|
-
(binding) => normalizedHostConditionalBindingValue(binding, binding.read())
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
479
|
function applyHostConditionalBindings(branch, instance) {
|
|
361
480
|
for (let bindingIndex = 0; bindingIndex < branch.bindings.length; bindingIndex += 1) {
|
|
362
481
|
const binding = branch.bindings[bindingIndex];
|
|
@@ -375,6 +494,903 @@ function applyHostConditionalBindings(branch, instance) {
|
|
|
375
494
|
}
|
|
376
495
|
}
|
|
377
496
|
}
|
|
497
|
+
var UNSET_HOST_CONDITIONAL_BINDING = /* @__PURE__ */ Symbol("unset host conditional binding");
|
|
498
|
+
function mountCompilerHostTree(owner, element, descriptor, onFallback) {
|
|
499
|
+
if (!matchesCompilerHostElement(element, descriptor)) return null;
|
|
500
|
+
if (descriptor.block?.kind === "conditional-ranges") {
|
|
501
|
+
const controller = new CompilerNestedConditionalRanges(
|
|
502
|
+
owner,
|
|
503
|
+
element,
|
|
504
|
+
descriptor,
|
|
505
|
+
descriptor.block,
|
|
506
|
+
onFallback
|
|
507
|
+
);
|
|
508
|
+
try {
|
|
509
|
+
if (controller.adopt()) return controller;
|
|
510
|
+
controller.cleanup();
|
|
511
|
+
return null;
|
|
512
|
+
} catch (error) {
|
|
513
|
+
controller.cleanup();
|
|
514
|
+
throw error;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
if (descriptor.block?.kind === "keyed-ranges") {
|
|
518
|
+
const controller = new CompilerNestedKeyedRanges(
|
|
519
|
+
owner,
|
|
520
|
+
element,
|
|
521
|
+
descriptor,
|
|
522
|
+
descriptor.block,
|
|
523
|
+
onFallback
|
|
524
|
+
);
|
|
525
|
+
try {
|
|
526
|
+
if (controller.adopt()) return controller;
|
|
527
|
+
controller.cleanup();
|
|
528
|
+
return null;
|
|
529
|
+
} catch (error) {
|
|
530
|
+
controller.cleanup();
|
|
531
|
+
throw error;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if (descriptor.block?.kind === "mixed-ranges") {
|
|
535
|
+
const controller = new CompilerNestedMixedRanges(
|
|
536
|
+
owner,
|
|
537
|
+
element,
|
|
538
|
+
descriptor,
|
|
539
|
+
descriptor.block,
|
|
540
|
+
onFallback
|
|
541
|
+
);
|
|
542
|
+
try {
|
|
543
|
+
if (controller.adopt()) return controller;
|
|
544
|
+
controller.cleanup();
|
|
545
|
+
return null;
|
|
546
|
+
} catch (error) {
|
|
547
|
+
controller.cleanup();
|
|
548
|
+
throw error;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
const descriptors = flattenCompilerHostElements(descriptor.children);
|
|
552
|
+
if (descriptors.length !== element.children.length) return null;
|
|
553
|
+
const scopes = [];
|
|
554
|
+
for (let index = 0; index < descriptors.length; index += 1) {
|
|
555
|
+
const scope = mountCompilerHostTree(
|
|
556
|
+
owner,
|
|
557
|
+
element.children[index],
|
|
558
|
+
descriptors[index],
|
|
559
|
+
onFallback
|
|
560
|
+
);
|
|
561
|
+
if (!scope) {
|
|
562
|
+
for (const mounted of scopes) mounted.cleanup();
|
|
563
|
+
return null;
|
|
564
|
+
}
|
|
565
|
+
scopes.push(scope);
|
|
566
|
+
}
|
|
567
|
+
let active = true;
|
|
568
|
+
return {
|
|
569
|
+
update(nextDescriptor) {
|
|
570
|
+
if (!active || nextDescriptor.block || !matchesCompilerHostElement(element, nextDescriptor)) {
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
const nextChildren = flattenCompilerHostElements(nextDescriptor.children);
|
|
574
|
+
if (nextChildren.length !== scopes.length) return false;
|
|
575
|
+
return scopes.every((scope, index) => scope.update(nextChildren[index]));
|
|
576
|
+
},
|
|
577
|
+
cleanup() {
|
|
578
|
+
if (!active) return;
|
|
579
|
+
active = false;
|
|
580
|
+
for (const scope of scopes) scope.cleanup();
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
function mountCompilerHostInstance(owner, element, descriptor, branch, onFallback) {
|
|
585
|
+
const scope = mountCompilerHostTree(owner, element, descriptor, onFallback);
|
|
586
|
+
if (!scope) return null;
|
|
587
|
+
const instance = {
|
|
588
|
+
element,
|
|
589
|
+
scope,
|
|
590
|
+
values: branch.bindings.map(() => UNSET_HOST_CONDITIONAL_BINDING)
|
|
591
|
+
};
|
|
592
|
+
try {
|
|
593
|
+
applyHostConditionalBindings(branch, instance);
|
|
594
|
+
} catch (error) {
|
|
595
|
+
scope.cleanup();
|
|
596
|
+
throw error;
|
|
597
|
+
}
|
|
598
|
+
return instance;
|
|
599
|
+
}
|
|
600
|
+
var CompilerNestedConditionalRanges = class {
|
|
601
|
+
constructor(owner, root, host, block, onFallback) {
|
|
602
|
+
this.owner = owner;
|
|
603
|
+
this.root = root;
|
|
604
|
+
this.host = host;
|
|
605
|
+
this.block = block;
|
|
606
|
+
this.onFallback = onFallback;
|
|
607
|
+
this.instances = [];
|
|
608
|
+
this.staticSegments = [];
|
|
609
|
+
this.staticScopes = [];
|
|
610
|
+
this.staticValues = [];
|
|
611
|
+
this.active = true;
|
|
612
|
+
this.refresh = (afterCommit) => {
|
|
613
|
+
if (!this.active) {
|
|
614
|
+
afterCommit?.();
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
const selections = this.readSelections();
|
|
618
|
+
if (!selections || selections.length !== this.instances.length) {
|
|
619
|
+
this.onFallback();
|
|
620
|
+
afterCommit?.();
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
624
|
+
this.onFallback();
|
|
625
|
+
afterCommit?.();
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
for (let index = this.instances.length - 1; index >= 0; index -= 1) {
|
|
629
|
+
if (!this.reconcileRange(index, selections[index])) {
|
|
630
|
+
this.onFallback();
|
|
631
|
+
afterCommit?.();
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
afterCommit?.();
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
readSelections() {
|
|
639
|
+
const selections = [];
|
|
640
|
+
for (const range of this.block.ranges) {
|
|
641
|
+
const selection = hostConditionalSelection(range);
|
|
642
|
+
if (selection.kind === "fallback") return null;
|
|
643
|
+
selections.push(selection);
|
|
644
|
+
}
|
|
645
|
+
return selections;
|
|
646
|
+
}
|
|
647
|
+
mountStatic(elements, descriptors) {
|
|
648
|
+
if (elements.length !== descriptors.length) return false;
|
|
649
|
+
for (let index = 0; index < elements.length; index += 1) {
|
|
650
|
+
const scope = mountCompilerHostTree(
|
|
651
|
+
this.owner,
|
|
652
|
+
elements[index],
|
|
653
|
+
descriptors[index],
|
|
654
|
+
this.onFallback
|
|
655
|
+
);
|
|
656
|
+
if (!scope) return false;
|
|
657
|
+
this.staticScopes.push(scope);
|
|
658
|
+
}
|
|
659
|
+
return true;
|
|
660
|
+
}
|
|
661
|
+
adopt() {
|
|
662
|
+
if (!Number.isSafeInteger(this.block.trailing) || this.block.trailing < 0) return false;
|
|
663
|
+
const selections = this.readSelections();
|
|
664
|
+
if (!selections) return false;
|
|
665
|
+
const elements = [...this.root.children];
|
|
666
|
+
const descriptors = flattenCompilerHostElements(this.host.children);
|
|
667
|
+
if (elements.length !== descriptors.length) return false;
|
|
668
|
+
let cursor = 0;
|
|
669
|
+
for (let index = 0; index < this.block.ranges.length; index += 1) {
|
|
670
|
+
const range = this.block.ranges[index];
|
|
671
|
+
if (!Number.isSafeInteger(range.before) || range.before < 0) {
|
|
672
|
+
this.cleanup();
|
|
673
|
+
return false;
|
|
674
|
+
}
|
|
675
|
+
const staticEnd = cursor + range.before;
|
|
676
|
+
if (staticEnd > elements.length || !this.mountStatic(elements.slice(cursor, staticEnd), descriptors.slice(cursor, staticEnd))) {
|
|
677
|
+
this.cleanup();
|
|
678
|
+
return false;
|
|
679
|
+
}
|
|
680
|
+
this.staticSegments.push(elements.slice(cursor, staticEnd));
|
|
681
|
+
cursor = staticEnd;
|
|
682
|
+
const selection = selections[index];
|
|
683
|
+
if (selection.kind === "empty") {
|
|
684
|
+
this.instances.push(null);
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
const element = elements[cursor];
|
|
688
|
+
if (!element) {
|
|
689
|
+
this.cleanup();
|
|
690
|
+
return false;
|
|
691
|
+
}
|
|
692
|
+
const descriptor = selection.branch.create();
|
|
693
|
+
const host = mountCompilerHostInstance(
|
|
694
|
+
this.owner,
|
|
695
|
+
element,
|
|
696
|
+
descriptor,
|
|
697
|
+
selection.branch,
|
|
698
|
+
this.onFallback
|
|
699
|
+
);
|
|
700
|
+
if (!host) {
|
|
701
|
+
this.cleanup();
|
|
702
|
+
return false;
|
|
703
|
+
}
|
|
704
|
+
this.instances.push({ key: selection.key, host });
|
|
705
|
+
cursor += 1;
|
|
706
|
+
}
|
|
707
|
+
const trailingEnd = cursor + this.block.trailing;
|
|
708
|
+
if (trailingEnd !== elements.length || !this.mountStatic(elements.slice(cursor), descriptors.slice(cursor))) {
|
|
709
|
+
this.cleanup();
|
|
710
|
+
return false;
|
|
711
|
+
}
|
|
712
|
+
this.staticSegments.push(elements.slice(cursor));
|
|
713
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
714
|
+
this.cleanup();
|
|
715
|
+
return false;
|
|
716
|
+
}
|
|
717
|
+
this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
|
|
718
|
+
return true;
|
|
719
|
+
}
|
|
720
|
+
anchorAfter(rangeIndex) {
|
|
721
|
+
for (let next = rangeIndex + 1; next < this.instances.length; next += 1) {
|
|
722
|
+
const staticAnchor = this.staticSegments[next]?.[0];
|
|
723
|
+
if (staticAnchor) return staticAnchor;
|
|
724
|
+
const rangeAnchor = this.instances[next]?.host.element;
|
|
725
|
+
if (rangeAnchor) return rangeAnchor;
|
|
726
|
+
}
|
|
727
|
+
return this.staticSegments[this.instances.length]?.[0] || null;
|
|
728
|
+
}
|
|
729
|
+
reconcileRange(rangeIndex, selection) {
|
|
730
|
+
const previous = this.instances[rangeIndex];
|
|
731
|
+
if (selection.kind === "empty") {
|
|
732
|
+
previous?.host.scope?.cleanup();
|
|
733
|
+
previous?.host.element.remove();
|
|
734
|
+
this.instances[rangeIndex] = null;
|
|
735
|
+
return true;
|
|
736
|
+
}
|
|
737
|
+
if (previous?.key === selection.key) {
|
|
738
|
+
const descriptor2 = selection.branch.create();
|
|
739
|
+
if (!previous.host.scope?.update(descriptor2)) return false;
|
|
740
|
+
applyHostConditionalBindings(selection.branch, previous.host);
|
|
741
|
+
return true;
|
|
742
|
+
}
|
|
743
|
+
const descriptor = selection.branch.create();
|
|
744
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
745
|
+
const host = mountCompilerHostInstance(
|
|
746
|
+
this.owner,
|
|
747
|
+
element,
|
|
748
|
+
descriptor,
|
|
749
|
+
selection.branch,
|
|
750
|
+
this.onFallback
|
|
751
|
+
);
|
|
752
|
+
if (!host) return false;
|
|
753
|
+
previous?.host.scope?.cleanup();
|
|
754
|
+
if (previous) previous.host.element.replaceWith(element);
|
|
755
|
+
else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
|
|
756
|
+
this.instances[rangeIndex] = { key: selection.key, host };
|
|
757
|
+
return true;
|
|
758
|
+
}
|
|
759
|
+
updateStaticScopes(descriptor, selections) {
|
|
760
|
+
const descriptors = flattenCompilerHostElements(descriptor.children);
|
|
761
|
+
let descriptorIndex = 0;
|
|
762
|
+
let scopeIndex = 0;
|
|
763
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
764
|
+
const range = this.block.ranges[rangeIndex];
|
|
765
|
+
for (let index = 0; index < range.before; index += 1) {
|
|
766
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
767
|
+
const child = descriptors[descriptorIndex++];
|
|
768
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
769
|
+
}
|
|
770
|
+
if (selections[rangeIndex].kind === "branch") descriptorIndex += 1;
|
|
771
|
+
}
|
|
772
|
+
for (let index = 0; index < this.block.trailing; index += 1) {
|
|
773
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
774
|
+
const child = descriptors[descriptorIndex++];
|
|
775
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
776
|
+
}
|
|
777
|
+
return scopeIndex === this.staticScopes.length && descriptorIndex === descriptors.length;
|
|
778
|
+
}
|
|
779
|
+
update(descriptor) {
|
|
780
|
+
const block = descriptor.block;
|
|
781
|
+
if (!this.active || block?.kind !== "conditional-ranges" || block.id !== this.block.id || block.ranges.length !== this.block.ranges.length || block.trailing !== this.block.trailing || block.ranges.some((range, index) => range.before !== this.block.ranges[index].before)) {
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
784
|
+
this.host = descriptor;
|
|
785
|
+
this.block = block;
|
|
786
|
+
const selections = this.readSelections();
|
|
787
|
+
if (!selections || !this.updateStaticScopes(descriptor, selections) || !applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
788
|
+
return false;
|
|
789
|
+
}
|
|
790
|
+
for (let index = this.instances.length - 1; index >= 0; index -= 1) {
|
|
791
|
+
if (!this.reconcileRange(index, selections[index])) return false;
|
|
792
|
+
}
|
|
793
|
+
return true;
|
|
794
|
+
}
|
|
795
|
+
cleanup() {
|
|
796
|
+
if (!this.active) return;
|
|
797
|
+
this.active = false;
|
|
798
|
+
this.unsubscribe?.();
|
|
799
|
+
for (const instance of this.instances) instance?.host.scope?.cleanup();
|
|
800
|
+
for (const scope of this.staticScopes) scope.cleanup();
|
|
801
|
+
this.instances.length = 0;
|
|
802
|
+
this.staticSegments.length = 0;
|
|
803
|
+
this.staticScopes.length = 0;
|
|
804
|
+
this.staticValues.length = 0;
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
var CompilerNestedKeyedRanges = class {
|
|
808
|
+
constructor(owner, root, host, block, onFallback) {
|
|
809
|
+
this.owner = owner;
|
|
810
|
+
this.root = root;
|
|
811
|
+
this.host = host;
|
|
812
|
+
this.block = block;
|
|
813
|
+
this.onFallback = onFallback;
|
|
814
|
+
this.instances = [];
|
|
815
|
+
this.staticSegments = [];
|
|
816
|
+
this.staticScopes = [];
|
|
817
|
+
this.staticValues = [];
|
|
818
|
+
this.active = true;
|
|
819
|
+
this.refresh = (afterCommit) => {
|
|
820
|
+
if (!this.active) {
|
|
821
|
+
afterCommit?.();
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
const rowsByRange = this.readRanges();
|
|
825
|
+
if (!rowsByRange || rowsByRange.length !== this.instances.length) {
|
|
826
|
+
this.onFallback();
|
|
827
|
+
afterCommit?.();
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
831
|
+
this.onFallback();
|
|
832
|
+
afterCommit?.();
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
const activeElement = this.root.ownerDocument.activeElement;
|
|
836
|
+
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
837
|
+
for (let index = rowsByRange.length - 1; index >= 0; index -= 1) {
|
|
838
|
+
if (!this.reconcileRange(index, rowsByRange[index])) {
|
|
839
|
+
this.onFallback();
|
|
840
|
+
afterCommit?.();
|
|
841
|
+
return;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
|
|
845
|
+
activeElement.focus({ preventScroll: true });
|
|
846
|
+
}
|
|
847
|
+
afterCommit?.();
|
|
848
|
+
};
|
|
849
|
+
}
|
|
850
|
+
readRange(range) {
|
|
851
|
+
const items = materializeIterable(range.items());
|
|
852
|
+
const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
|
|
853
|
+
return new Set(keys).size === keys.length ? { items, keys } : null;
|
|
854
|
+
}
|
|
855
|
+
readRanges() {
|
|
856
|
+
const ranges = [];
|
|
857
|
+
for (const range of this.block.ranges) {
|
|
858
|
+
const rows = this.readRange(range);
|
|
859
|
+
if (!rows) return null;
|
|
860
|
+
ranges.push(rows);
|
|
861
|
+
}
|
|
862
|
+
return ranges;
|
|
863
|
+
}
|
|
864
|
+
mountStatic(elements, descriptors) {
|
|
865
|
+
if (elements.length !== descriptors.length) return false;
|
|
866
|
+
for (let index = 0; index < elements.length; index += 1) {
|
|
867
|
+
const scope = mountCompilerHostTree(
|
|
868
|
+
this.owner,
|
|
869
|
+
elements[index],
|
|
870
|
+
descriptors[index],
|
|
871
|
+
this.onFallback
|
|
872
|
+
);
|
|
873
|
+
if (!scope) return false;
|
|
874
|
+
this.staticScopes.push(scope);
|
|
875
|
+
}
|
|
876
|
+
return true;
|
|
877
|
+
}
|
|
878
|
+
adopt() {
|
|
879
|
+
if (!Number.isSafeInteger(this.block.trailing) || this.block.trailing < 0) return false;
|
|
880
|
+
const rowsByRange = this.readRanges();
|
|
881
|
+
if (!rowsByRange) return false;
|
|
882
|
+
const elements = [...this.root.children];
|
|
883
|
+
const descriptors = flattenCompilerHostElements(materializeCompilerHostChildren(this.host));
|
|
884
|
+
if (elements.length !== descriptors.length) return false;
|
|
885
|
+
let cursor = 0;
|
|
886
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
887
|
+
const range = this.block.ranges[rangeIndex];
|
|
888
|
+
const rows = rowsByRange[rangeIndex];
|
|
889
|
+
if (!Number.isSafeInteger(range.before) || range.before < 0) {
|
|
890
|
+
this.cleanup();
|
|
891
|
+
return false;
|
|
892
|
+
}
|
|
893
|
+
const staticEnd = cursor + range.before;
|
|
894
|
+
if (staticEnd > elements.length || !this.mountStatic(elements.slice(cursor, staticEnd), descriptors.slice(cursor, staticEnd))) {
|
|
895
|
+
this.cleanup();
|
|
896
|
+
return false;
|
|
897
|
+
}
|
|
898
|
+
this.staticSegments.push(elements.slice(cursor, staticEnd));
|
|
899
|
+
cursor = staticEnd;
|
|
900
|
+
const instances = /* @__PURE__ */ new Map();
|
|
901
|
+
for (let index = 0; index < rows.items.length; index += 1) {
|
|
902
|
+
const element = elements[cursor + index];
|
|
903
|
+
if (!element) {
|
|
904
|
+
this.cleanup();
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
const descriptor = range.create(rows.items[index], index);
|
|
908
|
+
const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
|
|
909
|
+
if (!scope) {
|
|
910
|
+
this.cleanup();
|
|
911
|
+
return false;
|
|
912
|
+
}
|
|
913
|
+
instances.set(rows.keys[index], {
|
|
914
|
+
key: rows.keys[index],
|
|
915
|
+
element,
|
|
916
|
+
scope,
|
|
917
|
+
values: range.bindings.map(() => UNSET_KEYED_ROW_BINDING),
|
|
918
|
+
item: rows.items[index],
|
|
919
|
+
index,
|
|
920
|
+
conditionalValues: /* @__PURE__ */ new Map()
|
|
921
|
+
});
|
|
922
|
+
applyKeyedRowBindings(range, instances.get(rows.keys[index]), rows.items[index], index);
|
|
923
|
+
}
|
|
924
|
+
this.instances.push(instances);
|
|
925
|
+
cursor += rows.items.length;
|
|
926
|
+
}
|
|
927
|
+
const trailingEnd = cursor + this.block.trailing;
|
|
928
|
+
if (trailingEnd !== elements.length || !this.mountStatic(elements.slice(cursor), descriptors.slice(cursor))) {
|
|
929
|
+
this.cleanup();
|
|
930
|
+
return false;
|
|
931
|
+
}
|
|
932
|
+
this.staticSegments.push(elements.slice(cursor));
|
|
933
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
934
|
+
this.cleanup();
|
|
935
|
+
return false;
|
|
936
|
+
}
|
|
937
|
+
this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
|
|
938
|
+
return true;
|
|
939
|
+
}
|
|
940
|
+
anchorAfter(rangeIndex) {
|
|
941
|
+
for (let next = rangeIndex + 1; next < this.instances.length; next += 1) {
|
|
942
|
+
const staticAnchor = this.staticSegments[next]?.[0];
|
|
943
|
+
if (staticAnchor) return staticAnchor;
|
|
944
|
+
const rowAnchor = this.instances[next].values().next().value?.element;
|
|
945
|
+
if (rowAnchor) return rowAnchor;
|
|
946
|
+
}
|
|
947
|
+
return this.staticSegments[this.instances.length]?.[0] || null;
|
|
948
|
+
}
|
|
949
|
+
reconcileRange(rangeIndex, rows) {
|
|
950
|
+
const range = this.block.ranges[rangeIndex];
|
|
951
|
+
const previous = this.instances[rangeIndex];
|
|
952
|
+
const oldIndices = /* @__PURE__ */ new Map();
|
|
953
|
+
[...previous.keys()].forEach((key, index) => oldIndices.set(key, index));
|
|
954
|
+
const nextKeys = new Set(rows.keys);
|
|
955
|
+
for (const [key, instance] of previous) {
|
|
956
|
+
if (nextKeys.has(key)) continue;
|
|
957
|
+
instance.scope?.cleanup();
|
|
958
|
+
instance.element.remove();
|
|
959
|
+
}
|
|
960
|
+
const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
|
|
961
|
+
const stablePositions = longestIncreasingSubsequencePositions(sequence);
|
|
962
|
+
const nextInstances = [];
|
|
963
|
+
for (let index = 0; index < rows.items.length; index += 1) {
|
|
964
|
+
const key = rows.keys[index];
|
|
965
|
+
const existing = previous.get(key);
|
|
966
|
+
if (existing) {
|
|
967
|
+
const descriptor2 = range.create(rows.items[index], index);
|
|
968
|
+
if (!existing.scope?.update(descriptor2)) return false;
|
|
969
|
+
applyKeyedRowBindings(range, existing, rows.items[index], index);
|
|
970
|
+
existing.item = rows.items[index];
|
|
971
|
+
existing.index = index;
|
|
972
|
+
nextInstances.push(existing);
|
|
973
|
+
continue;
|
|
974
|
+
}
|
|
975
|
+
const descriptor = range.create(rows.items[index], index);
|
|
976
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
977
|
+
const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
|
|
978
|
+
if (!scope) return false;
|
|
979
|
+
nextInstances.push({
|
|
980
|
+
key,
|
|
981
|
+
element,
|
|
982
|
+
scope,
|
|
983
|
+
values: readKeyedRowBindingValues(range, rows.items[index], index),
|
|
984
|
+
item: rows.items[index],
|
|
985
|
+
index,
|
|
986
|
+
conditionalValues: /* @__PURE__ */ new Map()
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
let anchor = this.anchorAfter(rangeIndex);
|
|
990
|
+
for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
|
|
991
|
+
const instance = nextInstances[index];
|
|
992
|
+
if (sequence[index] < 0 || !stablePositions.has(index) && instance.element.nextSibling !== anchor) {
|
|
993
|
+
this.root.insertBefore(instance.element, anchor);
|
|
994
|
+
}
|
|
995
|
+
anchor = instance.element;
|
|
996
|
+
}
|
|
997
|
+
this.instances[rangeIndex] = new Map(nextInstances.map((instance) => [instance.key, instance]));
|
|
998
|
+
return true;
|
|
999
|
+
}
|
|
1000
|
+
updateStaticScopes(descriptor, rowsByRange) {
|
|
1001
|
+
const descriptors = flattenCompilerHostElements(materializeCompilerHostChildren(descriptor));
|
|
1002
|
+
let descriptorIndex = 0;
|
|
1003
|
+
let scopeIndex = 0;
|
|
1004
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
1005
|
+
const range = this.block.ranges[rangeIndex];
|
|
1006
|
+
for (let index = 0; index < range.before; index += 1) {
|
|
1007
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
1008
|
+
const child = descriptors[descriptorIndex++];
|
|
1009
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
1010
|
+
}
|
|
1011
|
+
descriptorIndex += rowsByRange[rangeIndex].items.length;
|
|
1012
|
+
}
|
|
1013
|
+
for (let index = 0; index < this.block.trailing; index += 1) {
|
|
1014
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
1015
|
+
const child = descriptors[descriptorIndex++];
|
|
1016
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
1017
|
+
}
|
|
1018
|
+
return scopeIndex === this.staticScopes.length && descriptorIndex === descriptors.length;
|
|
1019
|
+
}
|
|
1020
|
+
update(descriptor) {
|
|
1021
|
+
const block = descriptor.block;
|
|
1022
|
+
if (!this.active || block?.kind !== "keyed-ranges" || block.id !== this.block.id || block.ranges.length !== this.block.ranges.length || block.trailing !== this.block.trailing || block.ranges.some((range, index) => range.before !== this.block.ranges[index].before)) {
|
|
1023
|
+
return false;
|
|
1024
|
+
}
|
|
1025
|
+
this.host = descriptor;
|
|
1026
|
+
this.block = block;
|
|
1027
|
+
const rowsByRange = this.readRanges();
|
|
1028
|
+
if (!rowsByRange || rowsByRange.length !== this.instances.length || !this.updateStaticScopes(descriptor, rowsByRange) || !applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
1029
|
+
return false;
|
|
1030
|
+
}
|
|
1031
|
+
for (let index = rowsByRange.length - 1; index >= 0; index -= 1) {
|
|
1032
|
+
if (!this.reconcileRange(index, rowsByRange[index])) return false;
|
|
1033
|
+
}
|
|
1034
|
+
return true;
|
|
1035
|
+
}
|
|
1036
|
+
cleanup() {
|
|
1037
|
+
if (!this.active) return;
|
|
1038
|
+
this.active = false;
|
|
1039
|
+
this.unsubscribe?.();
|
|
1040
|
+
for (const instances of this.instances) {
|
|
1041
|
+
for (const instance of instances.values()) instance.scope?.cleanup();
|
|
1042
|
+
}
|
|
1043
|
+
for (const scope of this.staticScopes) scope.cleanup();
|
|
1044
|
+
this.instances.length = 0;
|
|
1045
|
+
this.staticSegments.length = 0;
|
|
1046
|
+
this.staticScopes.length = 0;
|
|
1047
|
+
this.staticValues.length = 0;
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
var CompilerNestedMixedRanges = class {
|
|
1051
|
+
constructor(owner, root, host, block, onFallback) {
|
|
1052
|
+
this.owner = owner;
|
|
1053
|
+
this.root = root;
|
|
1054
|
+
this.host = host;
|
|
1055
|
+
this.block = block;
|
|
1056
|
+
this.onFallback = onFallback;
|
|
1057
|
+
this.instances = [];
|
|
1058
|
+
this.staticSegments = [];
|
|
1059
|
+
this.staticScopes = [];
|
|
1060
|
+
this.staticValues = [];
|
|
1061
|
+
this.active = true;
|
|
1062
|
+
this.refresh = (afterCommit) => {
|
|
1063
|
+
if (!this.active) {
|
|
1064
|
+
afterCommit?.();
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
const snapshots = this.readSnapshots();
|
|
1068
|
+
if (!snapshots || snapshots.length !== this.instances.length) {
|
|
1069
|
+
this.onFallback();
|
|
1070
|
+
afterCommit?.();
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
1074
|
+
this.onFallback();
|
|
1075
|
+
afterCommit?.();
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
const activeElement = this.root.ownerDocument.activeElement;
|
|
1079
|
+
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
1080
|
+
for (let index = snapshots.length - 1; index >= 0; index -= 1) {
|
|
1081
|
+
if (!this.reconcileRange(index, snapshots[index])) {
|
|
1082
|
+
this.onFallback();
|
|
1083
|
+
afterCommit?.();
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
|
|
1088
|
+
activeElement.focus({ preventScroll: true });
|
|
1089
|
+
}
|
|
1090
|
+
afterCommit?.();
|
|
1091
|
+
};
|
|
1092
|
+
}
|
|
1093
|
+
readSnapshots() {
|
|
1094
|
+
const snapshots = [];
|
|
1095
|
+
for (const range of this.block.ranges) {
|
|
1096
|
+
if (range.kind === "conditional") {
|
|
1097
|
+
const selection = hostConditionalSelection(range);
|
|
1098
|
+
if (selection.kind === "fallback") return null;
|
|
1099
|
+
snapshots.push({ kind: "conditional", selection });
|
|
1100
|
+
continue;
|
|
1101
|
+
}
|
|
1102
|
+
const items = materializeIterable(range.items());
|
|
1103
|
+
const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
|
|
1104
|
+
if (new Set(keys).size !== keys.length) return null;
|
|
1105
|
+
snapshots.push({ kind: "keyed", rows: { items, keys } });
|
|
1106
|
+
}
|
|
1107
|
+
return snapshots;
|
|
1108
|
+
}
|
|
1109
|
+
mountStatic(elements, descriptors) {
|
|
1110
|
+
if (elements.length !== descriptors.length) return false;
|
|
1111
|
+
for (let index = 0; index < elements.length; index += 1) {
|
|
1112
|
+
const scope = mountCompilerHostTree(
|
|
1113
|
+
this.owner,
|
|
1114
|
+
elements[index],
|
|
1115
|
+
descriptors[index],
|
|
1116
|
+
this.onFallback
|
|
1117
|
+
);
|
|
1118
|
+
if (!scope) return false;
|
|
1119
|
+
this.staticScopes.push(scope);
|
|
1120
|
+
}
|
|
1121
|
+
return true;
|
|
1122
|
+
}
|
|
1123
|
+
adopt() {
|
|
1124
|
+
if (!Number.isSafeInteger(this.block.trailing) || this.block.trailing < 0) return false;
|
|
1125
|
+
const snapshots = this.readSnapshots();
|
|
1126
|
+
if (!snapshots) return false;
|
|
1127
|
+
const elements = [...this.root.children];
|
|
1128
|
+
const descriptors = flattenCompilerHostElements(this.host.children);
|
|
1129
|
+
if (elements.length !== descriptors.length) return false;
|
|
1130
|
+
let cursor = 0;
|
|
1131
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
1132
|
+
const range = this.block.ranges[rangeIndex];
|
|
1133
|
+
const snapshot = snapshots[rangeIndex];
|
|
1134
|
+
if (!Number.isSafeInteger(range.before) || range.before < 0 || range.kind !== snapshot.kind) {
|
|
1135
|
+
this.cleanup();
|
|
1136
|
+
return false;
|
|
1137
|
+
}
|
|
1138
|
+
const staticEnd = cursor + range.before;
|
|
1139
|
+
if (staticEnd > elements.length || !this.mountStatic(elements.slice(cursor, staticEnd), descriptors.slice(cursor, staticEnd))) {
|
|
1140
|
+
this.cleanup();
|
|
1141
|
+
return false;
|
|
1142
|
+
}
|
|
1143
|
+
this.staticSegments.push(elements.slice(cursor, staticEnd));
|
|
1144
|
+
cursor = staticEnd;
|
|
1145
|
+
if (range.kind === "conditional" && snapshot.kind === "conditional") {
|
|
1146
|
+
if (snapshot.selection.kind === "empty") {
|
|
1147
|
+
this.instances.push({ kind: "conditional", value: null });
|
|
1148
|
+
continue;
|
|
1149
|
+
}
|
|
1150
|
+
const element = elements[cursor];
|
|
1151
|
+
if (!element) {
|
|
1152
|
+
this.cleanup();
|
|
1153
|
+
return false;
|
|
1154
|
+
}
|
|
1155
|
+
const descriptor = snapshot.selection.branch.create();
|
|
1156
|
+
const host = mountCompilerHostInstance(
|
|
1157
|
+
this.owner,
|
|
1158
|
+
element,
|
|
1159
|
+
descriptor,
|
|
1160
|
+
snapshot.selection.branch,
|
|
1161
|
+
this.onFallback
|
|
1162
|
+
);
|
|
1163
|
+
if (!host) {
|
|
1164
|
+
this.cleanup();
|
|
1165
|
+
return false;
|
|
1166
|
+
}
|
|
1167
|
+
this.instances.push({
|
|
1168
|
+
kind: "conditional",
|
|
1169
|
+
value: { key: snapshot.selection.key, host }
|
|
1170
|
+
});
|
|
1171
|
+
cursor += 1;
|
|
1172
|
+
continue;
|
|
1173
|
+
}
|
|
1174
|
+
if (range.kind !== "keyed" || snapshot.kind !== "keyed") {
|
|
1175
|
+
this.cleanup();
|
|
1176
|
+
return false;
|
|
1177
|
+
}
|
|
1178
|
+
const keyedInstances = /* @__PURE__ */ new Map();
|
|
1179
|
+
for (let index = 0; index < snapshot.rows.items.length; index += 1) {
|
|
1180
|
+
const element = elements[cursor + index];
|
|
1181
|
+
if (!element) {
|
|
1182
|
+
this.cleanup();
|
|
1183
|
+
return false;
|
|
1184
|
+
}
|
|
1185
|
+
const descriptor = range.create(snapshot.rows.items[index], index);
|
|
1186
|
+
const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
|
|
1187
|
+
if (!scope) {
|
|
1188
|
+
this.cleanup();
|
|
1189
|
+
return false;
|
|
1190
|
+
}
|
|
1191
|
+
const instance = {
|
|
1192
|
+
key: snapshot.rows.keys[index],
|
|
1193
|
+
element,
|
|
1194
|
+
scope,
|
|
1195
|
+
values: range.bindings.map(() => UNSET_KEYED_ROW_BINDING),
|
|
1196
|
+
item: snapshot.rows.items[index],
|
|
1197
|
+
index,
|
|
1198
|
+
conditionalValues: /* @__PURE__ */ new Map()
|
|
1199
|
+
};
|
|
1200
|
+
try {
|
|
1201
|
+
applyKeyedRowBindings(range, instance, snapshot.rows.items[index], index);
|
|
1202
|
+
} catch (error) {
|
|
1203
|
+
scope.cleanup();
|
|
1204
|
+
throw error;
|
|
1205
|
+
}
|
|
1206
|
+
keyedInstances.set(snapshot.rows.keys[index], instance);
|
|
1207
|
+
}
|
|
1208
|
+
this.instances.push({ kind: "keyed", value: keyedInstances });
|
|
1209
|
+
cursor += snapshot.rows.items.length;
|
|
1210
|
+
}
|
|
1211
|
+
const trailingEnd = cursor + this.block.trailing;
|
|
1212
|
+
if (trailingEnd !== elements.length || !this.mountStatic(elements.slice(cursor), descriptors.slice(cursor))) {
|
|
1213
|
+
this.cleanup();
|
|
1214
|
+
return false;
|
|
1215
|
+
}
|
|
1216
|
+
this.staticSegments.push(elements.slice(cursor));
|
|
1217
|
+
if (!applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
1218
|
+
this.cleanup();
|
|
1219
|
+
return false;
|
|
1220
|
+
}
|
|
1221
|
+
this.unsubscribe = this.owner.subscribe(this.block.id, this.refresh);
|
|
1222
|
+
return true;
|
|
1223
|
+
}
|
|
1224
|
+
firstInstanceElement(instance) {
|
|
1225
|
+
if (instance.kind === "conditional") return instance.value?.host.element || null;
|
|
1226
|
+
return instance.value.values().next().value?.element || null;
|
|
1227
|
+
}
|
|
1228
|
+
anchorAfter(rangeIndex) {
|
|
1229
|
+
for (let next = rangeIndex + 1; next < this.instances.length; next += 1) {
|
|
1230
|
+
const staticAnchor = this.staticSegments[next]?.[0];
|
|
1231
|
+
if (staticAnchor) return staticAnchor;
|
|
1232
|
+
const rangeAnchor = this.firstInstanceElement(this.instances[next]);
|
|
1233
|
+
if (rangeAnchor) return rangeAnchor;
|
|
1234
|
+
}
|
|
1235
|
+
return this.staticSegments[this.instances.length]?.[0] || null;
|
|
1236
|
+
}
|
|
1237
|
+
reconcileConditional(rangeIndex, range, selection) {
|
|
1238
|
+
const instance = this.instances[rangeIndex];
|
|
1239
|
+
if (instance.kind !== "conditional") return false;
|
|
1240
|
+
const previous = instance.value;
|
|
1241
|
+
if (selection.kind === "empty") {
|
|
1242
|
+
previous?.host.scope?.cleanup();
|
|
1243
|
+
previous?.host.element.remove();
|
|
1244
|
+
instance.value = null;
|
|
1245
|
+
return true;
|
|
1246
|
+
}
|
|
1247
|
+
if (previous?.key === selection.key) {
|
|
1248
|
+
const descriptor2 = selection.branch.create();
|
|
1249
|
+
if (!previous.host.scope?.update(descriptor2)) return false;
|
|
1250
|
+
applyHostConditionalBindings(selection.branch, previous.host);
|
|
1251
|
+
return true;
|
|
1252
|
+
}
|
|
1253
|
+
const descriptor = selection.branch.create();
|
|
1254
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
1255
|
+
const host = mountCompilerHostInstance(
|
|
1256
|
+
this.owner,
|
|
1257
|
+
element,
|
|
1258
|
+
descriptor,
|
|
1259
|
+
selection.branch,
|
|
1260
|
+
this.onFallback
|
|
1261
|
+
);
|
|
1262
|
+
if (!host) return false;
|
|
1263
|
+
previous?.host.scope?.cleanup();
|
|
1264
|
+
if (previous) previous.host.element.replaceWith(element);
|
|
1265
|
+
else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
|
|
1266
|
+
instance.value = { key: selection.key, host };
|
|
1267
|
+
return true;
|
|
1268
|
+
}
|
|
1269
|
+
reconcileKeyed(rangeIndex, range, rows) {
|
|
1270
|
+
const instance = this.instances[rangeIndex];
|
|
1271
|
+
if (instance.kind !== "keyed") return false;
|
|
1272
|
+
const previous = instance.value;
|
|
1273
|
+
const oldIndices = /* @__PURE__ */ new Map();
|
|
1274
|
+
[...previous.keys()].forEach((key, index) => oldIndices.set(key, index));
|
|
1275
|
+
const nextKeys = new Set(rows.keys);
|
|
1276
|
+
for (const [key, row] of previous) {
|
|
1277
|
+
if (nextKeys.has(key)) continue;
|
|
1278
|
+
row.scope?.cleanup();
|
|
1279
|
+
row.element.remove();
|
|
1280
|
+
}
|
|
1281
|
+
const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
|
|
1282
|
+
const stablePositions = longestIncreasingSubsequencePositions(sequence);
|
|
1283
|
+
const nextInstances = [];
|
|
1284
|
+
for (let index = 0; index < rows.items.length; index += 1) {
|
|
1285
|
+
const key = rows.keys[index];
|
|
1286
|
+
const existing = previous.get(key);
|
|
1287
|
+
if (existing) {
|
|
1288
|
+
const descriptor2 = range.create(rows.items[index], index);
|
|
1289
|
+
if (!existing.scope?.update(descriptor2)) return false;
|
|
1290
|
+
applyKeyedRowBindings(range, existing, rows.items[index], index);
|
|
1291
|
+
existing.item = rows.items[index];
|
|
1292
|
+
existing.index = index;
|
|
1293
|
+
nextInstances.push(existing);
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
const descriptor = range.create(rows.items[index], index);
|
|
1297
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
1298
|
+
const scope = mountCompilerHostTree(this.owner, element, descriptor, this.onFallback);
|
|
1299
|
+
if (!scope) return false;
|
|
1300
|
+
let values;
|
|
1301
|
+
try {
|
|
1302
|
+
values = readKeyedRowBindingValues(range, rows.items[index], index);
|
|
1303
|
+
} catch (error) {
|
|
1304
|
+
scope.cleanup();
|
|
1305
|
+
throw error;
|
|
1306
|
+
}
|
|
1307
|
+
nextInstances.push({
|
|
1308
|
+
key,
|
|
1309
|
+
element,
|
|
1310
|
+
scope,
|
|
1311
|
+
values,
|
|
1312
|
+
item: rows.items[index],
|
|
1313
|
+
index,
|
|
1314
|
+
conditionalValues: /* @__PURE__ */ new Map()
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1317
|
+
let anchor = this.anchorAfter(rangeIndex);
|
|
1318
|
+
for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
|
|
1319
|
+
const row = nextInstances[index];
|
|
1320
|
+
if (sequence[index] < 0 || !stablePositions.has(index) && row.element.nextSibling !== anchor) {
|
|
1321
|
+
this.root.insertBefore(row.element, anchor);
|
|
1322
|
+
}
|
|
1323
|
+
anchor = row.element;
|
|
1324
|
+
}
|
|
1325
|
+
instance.value = new Map(nextInstances.map((row) => [row.key, row]));
|
|
1326
|
+
return true;
|
|
1327
|
+
}
|
|
1328
|
+
reconcileRange(rangeIndex, snapshot) {
|
|
1329
|
+
const range = this.block.ranges[rangeIndex];
|
|
1330
|
+
if (range.kind !== snapshot.kind) return false;
|
|
1331
|
+
return range.kind === "conditional" && snapshot.kind === "conditional" ? this.reconcileConditional(rangeIndex, range, snapshot.selection) : range.kind === "keyed" && snapshot.kind === "keyed" ? this.reconcileKeyed(rangeIndex, range, snapshot.rows) : false;
|
|
1332
|
+
}
|
|
1333
|
+
updateStaticScopes(descriptor, snapshots) {
|
|
1334
|
+
const descriptors = flattenCompilerHostElements(descriptor.children);
|
|
1335
|
+
let descriptorIndex = 0;
|
|
1336
|
+
let scopeIndex = 0;
|
|
1337
|
+
for (let rangeIndex = 0; rangeIndex < this.block.ranges.length; rangeIndex += 1) {
|
|
1338
|
+
const range = this.block.ranges[rangeIndex];
|
|
1339
|
+
for (let index = 0; index < range.before; index += 1) {
|
|
1340
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
1341
|
+
const child = descriptors[descriptorIndex++];
|
|
1342
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
1343
|
+
}
|
|
1344
|
+
const snapshot = snapshots[rangeIndex];
|
|
1345
|
+
if (snapshot.kind === "conditional") {
|
|
1346
|
+
if (snapshot.selection.kind === "branch") descriptorIndex += 1;
|
|
1347
|
+
} else {
|
|
1348
|
+
descriptorIndex += snapshot.rows.items.length;
|
|
1349
|
+
}
|
|
1350
|
+
}
|
|
1351
|
+
for (let index = 0; index < this.block.trailing; index += 1) {
|
|
1352
|
+
const scope = this.staticScopes[scopeIndex++];
|
|
1353
|
+
const child = descriptors[descriptorIndex++];
|
|
1354
|
+
if (!scope || !child || !scope.update(child)) return false;
|
|
1355
|
+
}
|
|
1356
|
+
return scopeIndex === this.staticScopes.length && descriptorIndex === descriptors.length;
|
|
1357
|
+
}
|
|
1358
|
+
update(descriptor) {
|
|
1359
|
+
const block = descriptor.block;
|
|
1360
|
+
if (!this.active || block?.kind !== "mixed-ranges" || block.id !== this.block.id || block.ranges.length !== this.block.ranges.length || block.trailing !== this.block.trailing || block.ranges.some(
|
|
1361
|
+
(range, index) => range.kind !== this.block.ranges[index].kind || range.before !== this.block.ranges[index].before
|
|
1362
|
+
)) {
|
|
1363
|
+
return false;
|
|
1364
|
+
}
|
|
1365
|
+
this.host = descriptor;
|
|
1366
|
+
this.block = block;
|
|
1367
|
+
const snapshots = this.readSnapshots();
|
|
1368
|
+
if (!snapshots || snapshots.length !== this.instances.length || !this.updateStaticScopes(descriptor, snapshots) || !applyStaticRangeBindings(this.block.bindings, this.staticSegments, this.staticValues)) {
|
|
1369
|
+
return false;
|
|
1370
|
+
}
|
|
1371
|
+
for (let index = snapshots.length - 1; index >= 0; index -= 1) {
|
|
1372
|
+
if (!this.reconcileRange(index, snapshots[index])) return false;
|
|
1373
|
+
}
|
|
1374
|
+
return true;
|
|
1375
|
+
}
|
|
1376
|
+
cleanup() {
|
|
1377
|
+
if (!this.active) return;
|
|
1378
|
+
this.active = false;
|
|
1379
|
+
this.unsubscribe?.();
|
|
1380
|
+
for (const instance of this.instances) {
|
|
1381
|
+
if (instance.kind === "conditional") {
|
|
1382
|
+
instance.value?.host.scope?.cleanup();
|
|
1383
|
+
} else {
|
|
1384
|
+
for (const row of instance.value.values()) row.scope?.cleanup();
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
for (const scope of this.staticScopes) scope.cleanup();
|
|
1388
|
+
this.instances.length = 0;
|
|
1389
|
+
this.staticSegments.length = 0;
|
|
1390
|
+
this.staticScopes.length = 0;
|
|
1391
|
+
this.staticValues.length = 0;
|
|
1392
|
+
}
|
|
1393
|
+
};
|
|
378
1394
|
function createHostConditionalBlockComponent(owner) {
|
|
379
1395
|
class FarmHostConditionalBlock extends React.Component {
|
|
380
1396
|
constructor() {
|
|
@@ -386,8 +1402,13 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
386
1402
|
this.fallbackVersion = 0;
|
|
387
1403
|
this.propSyncQueued = false;
|
|
388
1404
|
this.currentProps = this.props;
|
|
1405
|
+
this.fallbackUnsubscribers = [];
|
|
389
1406
|
this.activeBranch = null;
|
|
390
1407
|
this.instance = null;
|
|
1408
|
+
this.requestNestedFallback = () => {
|
|
1409
|
+
this.instance?.scope?.cleanup();
|
|
1410
|
+
this.activateFallback();
|
|
1411
|
+
};
|
|
391
1412
|
this.captureRoot = (root) => {
|
|
392
1413
|
this.root = root;
|
|
393
1414
|
};
|
|
@@ -395,6 +1416,26 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
395
1416
|
this.reconcile(afterCommit);
|
|
396
1417
|
};
|
|
397
1418
|
}
|
|
1419
|
+
subscribeFallbackDescendants() {
|
|
1420
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1421
|
+
this.fallbackUnsubscribers = [];
|
|
1422
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1423
|
+
if (this.currentProps.truthy) {
|
|
1424
|
+
collectCompilerHostBlockIds(this.currentProps.truthy.create(), ids);
|
|
1425
|
+
}
|
|
1426
|
+
if (this.currentProps.falsy) {
|
|
1427
|
+
collectCompilerHostBlockIds(this.currentProps.falsy.create(), ids);
|
|
1428
|
+
}
|
|
1429
|
+
ids.delete(this.currentProps.id);
|
|
1430
|
+
for (const id of ids) {
|
|
1431
|
+
this.fallbackUnsubscribers.push(
|
|
1432
|
+
owner.subscribe(id, (afterCommit) => {
|
|
1433
|
+
this.fallbackVersion += 1;
|
|
1434
|
+
this.forceUpdate(afterCommit);
|
|
1435
|
+
})
|
|
1436
|
+
);
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
398
1439
|
adopt() {
|
|
399
1440
|
if (!this.root) return false;
|
|
400
1441
|
const selection = hostConditionalSelection(this.currentProps);
|
|
@@ -411,11 +1452,16 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
411
1452
|
const descriptor = selection.branch.create();
|
|
412
1453
|
const element = this.root.firstElementChild;
|
|
413
1454
|
if (!matchesCompilerHostElement(element, descriptor)) return false;
|
|
414
|
-
|
|
415
|
-
|
|
1455
|
+
const instance = mountCompilerHostInstance(
|
|
1456
|
+
owner,
|
|
416
1457
|
element,
|
|
417
|
-
|
|
418
|
-
|
|
1458
|
+
descriptor,
|
|
1459
|
+
selection.branch,
|
|
1460
|
+
this.requestNestedFallback
|
|
1461
|
+
);
|
|
1462
|
+
if (!instance) return false;
|
|
1463
|
+
this.activeBranch = selection.key;
|
|
1464
|
+
this.instance = instance;
|
|
419
1465
|
return true;
|
|
420
1466
|
}
|
|
421
1467
|
activateFallback(afterCommit) {
|
|
@@ -424,6 +1470,10 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
424
1470
|
return;
|
|
425
1471
|
}
|
|
426
1472
|
this.fallbackRequested = true;
|
|
1473
|
+
this.instance?.scope?.cleanup();
|
|
1474
|
+
this.instance = null;
|
|
1475
|
+
this.activeBranch = null;
|
|
1476
|
+
this.subscribeFallbackDescendants();
|
|
427
1477
|
this.fallbackVersion += 1;
|
|
428
1478
|
this.setState({ fallback: true }, afterCommit);
|
|
429
1479
|
}
|
|
@@ -442,6 +1492,7 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
442
1492
|
return;
|
|
443
1493
|
}
|
|
444
1494
|
if (selection.kind === "empty") {
|
|
1495
|
+
this.instance?.scope?.cleanup();
|
|
445
1496
|
if (this.instance) this.instance.element.remove();
|
|
446
1497
|
this.activeBranch = null;
|
|
447
1498
|
this.instance = null;
|
|
@@ -449,17 +1500,40 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
449
1500
|
return;
|
|
450
1501
|
}
|
|
451
1502
|
if (this.activeBranch === selection.key && this.instance) {
|
|
1503
|
+
const descriptor2 = selection.branch.create();
|
|
1504
|
+
const scope = mountCompilerHostTree(
|
|
1505
|
+
owner,
|
|
1506
|
+
this.instance.element,
|
|
1507
|
+
descriptor2,
|
|
1508
|
+
this.requestNestedFallback
|
|
1509
|
+
);
|
|
1510
|
+
if (!scope) {
|
|
1511
|
+
this.activateFallback(afterCommit);
|
|
1512
|
+
return;
|
|
1513
|
+
}
|
|
1514
|
+
this.instance.scope?.cleanup();
|
|
1515
|
+
this.instance.scope = scope;
|
|
452
1516
|
applyHostConditionalBindings(selection.branch, this.instance);
|
|
453
1517
|
afterCommit?.();
|
|
454
1518
|
return;
|
|
455
1519
|
}
|
|
456
|
-
const
|
|
1520
|
+
const descriptor = selection.branch.create();
|
|
1521
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
1522
|
+
const instance = mountCompilerHostInstance(
|
|
1523
|
+
owner,
|
|
1524
|
+
element,
|
|
1525
|
+
descriptor,
|
|
1526
|
+
selection.branch,
|
|
1527
|
+
this.requestNestedFallback
|
|
1528
|
+
);
|
|
1529
|
+
if (!instance) {
|
|
1530
|
+
this.activateFallback(afterCommit);
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
this.instance?.scope?.cleanup();
|
|
457
1534
|
this.root.replaceChildren(element);
|
|
458
1535
|
this.activeBranch = selection.key;
|
|
459
|
-
this.instance =
|
|
460
|
-
element,
|
|
461
|
-
values: readHostConditionalBindingValues(selection.branch)
|
|
462
|
-
};
|
|
1536
|
+
this.instance = instance;
|
|
463
1537
|
afterCommit?.();
|
|
464
1538
|
}
|
|
465
1539
|
schedulePropSync() {
|
|
@@ -484,6 +1558,9 @@ function createHostConditionalBlockComponent(owner) {
|
|
|
484
1558
|
componentWillUnmount() {
|
|
485
1559
|
this.mounted = false;
|
|
486
1560
|
this.unsubscribe?.();
|
|
1561
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1562
|
+
this.fallbackUnsubscribers = [];
|
|
1563
|
+
this.instance?.scope?.cleanup();
|
|
487
1564
|
this.root = null;
|
|
488
1565
|
this.activeBranch = null;
|
|
489
1566
|
this.instance = null;
|
|
@@ -515,8 +1592,14 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
515
1592
|
this.fallbackVersion = 0;
|
|
516
1593
|
this.propFallbackQueued = false;
|
|
517
1594
|
this.currentProps = this.props;
|
|
1595
|
+
this.fallbackUnsubscribers = [];
|
|
518
1596
|
this.rangeInstances = [];
|
|
519
1597
|
this.staticSegments = [];
|
|
1598
|
+
this.staticValues = [];
|
|
1599
|
+
this.requestNestedFallback = () => {
|
|
1600
|
+
for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
|
|
1601
|
+
this.activateFallback();
|
|
1602
|
+
};
|
|
520
1603
|
this.captureRoot = (root) => {
|
|
521
1604
|
this.root = root;
|
|
522
1605
|
this.currentProps.rootRef?.(root);
|
|
@@ -525,6 +1608,24 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
525
1608
|
this.reconcile(afterCommit);
|
|
526
1609
|
};
|
|
527
1610
|
}
|
|
1611
|
+
subscribeFallbackDescendants() {
|
|
1612
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1613
|
+
this.fallbackUnsubscribers = [];
|
|
1614
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1615
|
+
for (const range of this.currentProps.ranges) {
|
|
1616
|
+
if (range.truthy) collectCompilerHostBlockIds(range.truthy.create(), ids);
|
|
1617
|
+
if (range.falsy) collectCompilerHostBlockIds(range.falsy.create(), ids);
|
|
1618
|
+
}
|
|
1619
|
+
ids.delete(this.currentProps.id);
|
|
1620
|
+
for (const id of ids) {
|
|
1621
|
+
this.fallbackUnsubscribers.push(
|
|
1622
|
+
owner.subscribe(id, (afterCommit) => {
|
|
1623
|
+
this.fallbackVersion += 1;
|
|
1624
|
+
this.forceUpdate(afterCommit);
|
|
1625
|
+
})
|
|
1626
|
+
);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
528
1629
|
readSelections(props) {
|
|
529
1630
|
const selections = [];
|
|
530
1631
|
for (const range of props.ranges) {
|
|
@@ -541,12 +1642,21 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
541
1642
|
const elements = [...this.root.children];
|
|
542
1643
|
const staticSegments = [];
|
|
543
1644
|
const instances = [];
|
|
1645
|
+
const cleanupInstances = () => {
|
|
1646
|
+
for (const instance of instances) instance?.host.scope?.cleanup();
|
|
1647
|
+
};
|
|
544
1648
|
let cursor = 0;
|
|
545
1649
|
for (let rangeIndex = 0; rangeIndex < props.ranges.length; rangeIndex += 1) {
|
|
546
1650
|
const range = props.ranges[rangeIndex];
|
|
547
|
-
if (!Number.isSafeInteger(range.before) || range.before < 0)
|
|
1651
|
+
if (!Number.isSafeInteger(range.before) || range.before < 0) {
|
|
1652
|
+
cleanupInstances();
|
|
1653
|
+
return false;
|
|
1654
|
+
}
|
|
548
1655
|
const staticEnd = cursor + range.before;
|
|
549
|
-
if (staticEnd > elements.length)
|
|
1656
|
+
if (staticEnd > elements.length) {
|
|
1657
|
+
cleanupInstances();
|
|
1658
|
+
return false;
|
|
1659
|
+
}
|
|
550
1660
|
staticSegments.push(elements.slice(cursor, staticEnd));
|
|
551
1661
|
cursor = staticEnd;
|
|
552
1662
|
const selection = selections[rangeIndex];
|
|
@@ -555,22 +1665,45 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
555
1665
|
continue;
|
|
556
1666
|
}
|
|
557
1667
|
const element = elements[cursor];
|
|
558
|
-
if (!element)
|
|
1668
|
+
if (!element) {
|
|
1669
|
+
cleanupInstances();
|
|
1670
|
+
return false;
|
|
1671
|
+
}
|
|
559
1672
|
const descriptor = selection.branch.create();
|
|
560
|
-
if (!matchesCompilerHostElement(element, descriptor))
|
|
1673
|
+
if (!matchesCompilerHostElement(element, descriptor)) {
|
|
1674
|
+
cleanupInstances();
|
|
1675
|
+
return false;
|
|
1676
|
+
}
|
|
1677
|
+
const host = mountCompilerHostInstance(
|
|
1678
|
+
owner,
|
|
1679
|
+
element,
|
|
1680
|
+
descriptor,
|
|
1681
|
+
selection.branch,
|
|
1682
|
+
this.requestNestedFallback
|
|
1683
|
+
);
|
|
1684
|
+
if (!host) {
|
|
1685
|
+
cleanupInstances();
|
|
1686
|
+
return false;
|
|
1687
|
+
}
|
|
561
1688
|
instances.push({
|
|
562
1689
|
key: selection.key,
|
|
563
|
-
host
|
|
564
|
-
element,
|
|
565
|
-
values: readHostConditionalBindingValues(selection.branch)
|
|
566
|
-
}
|
|
1690
|
+
host
|
|
567
1691
|
});
|
|
568
1692
|
cursor += 1;
|
|
569
1693
|
}
|
|
570
|
-
if (cursor + props.trailing !== elements.length)
|
|
1694
|
+
if (cursor + props.trailing !== elements.length) {
|
|
1695
|
+
cleanupInstances();
|
|
1696
|
+
return false;
|
|
1697
|
+
}
|
|
571
1698
|
staticSegments.push(elements.slice(cursor));
|
|
572
1699
|
this.staticSegments = staticSegments;
|
|
573
1700
|
this.rangeInstances = instances;
|
|
1701
|
+
if (!applyStaticRangeBindings(props.bindings, this.staticSegments, this.staticValues)) {
|
|
1702
|
+
cleanupInstances();
|
|
1703
|
+
this.rangeInstances = [];
|
|
1704
|
+
this.staticSegments = [];
|
|
1705
|
+
return false;
|
|
1706
|
+
}
|
|
574
1707
|
return true;
|
|
575
1708
|
}
|
|
576
1709
|
anchorAfter(rangeIndex) {
|
|
@@ -583,27 +1716,52 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
583
1716
|
return this.staticSegments[this.rangeInstances.length]?.[0] || null;
|
|
584
1717
|
}
|
|
585
1718
|
reconcileRange(rangeIndex, selection) {
|
|
586
|
-
if (!this.root) return;
|
|
1719
|
+
if (!this.root) return false;
|
|
587
1720
|
const previous = this.rangeInstances[rangeIndex];
|
|
588
1721
|
if (selection.kind === "empty") {
|
|
1722
|
+
previous?.host.scope?.cleanup();
|
|
589
1723
|
previous?.host.element.remove();
|
|
590
1724
|
this.rangeInstances[rangeIndex] = null;
|
|
591
|
-
return;
|
|
1725
|
+
return true;
|
|
592
1726
|
}
|
|
593
1727
|
if (previous?.key === selection.key) {
|
|
1728
|
+
const descriptor2 = selection.branch.create();
|
|
1729
|
+
const scope = mountCompilerHostTree(
|
|
1730
|
+
owner,
|
|
1731
|
+
previous.host.element,
|
|
1732
|
+
descriptor2,
|
|
1733
|
+
this.requestNestedFallback
|
|
1734
|
+
);
|
|
1735
|
+
if (!scope) {
|
|
1736
|
+
this.requestNestedFallback();
|
|
1737
|
+
return false;
|
|
1738
|
+
}
|
|
1739
|
+
previous.host.scope?.cleanup();
|
|
1740
|
+
previous.host.scope = scope;
|
|
594
1741
|
applyHostConditionalBindings(selection.branch, previous.host);
|
|
595
|
-
return;
|
|
1742
|
+
return true;
|
|
596
1743
|
}
|
|
597
|
-
const
|
|
1744
|
+
const descriptor = selection.branch.create();
|
|
1745
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
1746
|
+
const host = mountCompilerHostInstance(
|
|
1747
|
+
owner,
|
|
1748
|
+
element,
|
|
1749
|
+
descriptor,
|
|
1750
|
+
selection.branch,
|
|
1751
|
+
this.requestNestedFallback
|
|
1752
|
+
);
|
|
1753
|
+
if (!host) {
|
|
1754
|
+
this.requestNestedFallback();
|
|
1755
|
+
return false;
|
|
1756
|
+
}
|
|
1757
|
+
previous?.host.scope?.cleanup();
|
|
598
1758
|
if (previous) previous.host.element.replaceWith(element);
|
|
599
1759
|
else this.root.insertBefore(element, this.anchorAfter(rangeIndex));
|
|
600
1760
|
this.rangeInstances[rangeIndex] = {
|
|
601
1761
|
key: selection.key,
|
|
602
|
-
host
|
|
603
|
-
element,
|
|
604
|
-
values: readHostConditionalBindingValues(selection.branch)
|
|
605
|
-
}
|
|
1762
|
+
host
|
|
606
1763
|
};
|
|
1764
|
+
return true;
|
|
607
1765
|
}
|
|
608
1766
|
reconcile(afterCommit) {
|
|
609
1767
|
if (!this.mounted || !this.root) {
|
|
@@ -624,8 +1782,19 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
624
1782
|
this.activateFallback(afterCommit);
|
|
625
1783
|
return;
|
|
626
1784
|
}
|
|
1785
|
+
if (!applyStaticRangeBindings(
|
|
1786
|
+
this.currentProps.bindings,
|
|
1787
|
+
this.staticSegments,
|
|
1788
|
+
this.staticValues
|
|
1789
|
+
)) {
|
|
1790
|
+
this.activateFallback(afterCommit);
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
627
1793
|
for (let rangeIndex = this.rangeInstances.length - 1; rangeIndex >= 0; rangeIndex -= 1) {
|
|
628
|
-
this.reconcileRange(rangeIndex, selections[rangeIndex])
|
|
1794
|
+
if (!this.reconcileRange(rangeIndex, selections[rangeIndex])) {
|
|
1795
|
+
afterCommit?.();
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
629
1798
|
}
|
|
630
1799
|
afterCommit?.();
|
|
631
1800
|
}
|
|
@@ -635,6 +1804,8 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
635
1804
|
return;
|
|
636
1805
|
}
|
|
637
1806
|
this.fallbackRequested = true;
|
|
1807
|
+
for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
|
|
1808
|
+
this.subscribeFallbackDescendants();
|
|
638
1809
|
this.setState({ fallback: true }, afterCommit);
|
|
639
1810
|
}
|
|
640
1811
|
schedulePropFallback() {
|
|
@@ -659,9 +1830,13 @@ function createConditionalRangesBlockComponent(owner) {
|
|
|
659
1830
|
componentWillUnmount() {
|
|
660
1831
|
this.mounted = false;
|
|
661
1832
|
this.unsubscribe?.();
|
|
1833
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
1834
|
+
this.fallbackUnsubscribers = [];
|
|
1835
|
+
for (const instance of this.rangeInstances) instance?.host.scope?.cleanup();
|
|
662
1836
|
this.root = null;
|
|
663
1837
|
this.rangeInstances = [];
|
|
664
1838
|
this.staticSegments = [];
|
|
1839
|
+
this.staticValues.length = 0;
|
|
665
1840
|
}
|
|
666
1841
|
render() {
|
|
667
1842
|
const container = this.currentProps.render();
|
|
@@ -703,6 +1878,10 @@ function longestIncreasingSubsequencePositions(sequence) {
|
|
|
703
1878
|
return positions;
|
|
704
1879
|
}
|
|
705
1880
|
function createKeyedRowsBlockComponent(owner) {
|
|
1881
|
+
const rowHostScopeOwner = {
|
|
1882
|
+
subscribe: () => () => {
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
706
1885
|
class FarmKeyedRowConditional extends React.Component {
|
|
707
1886
|
constructor() {
|
|
708
1887
|
super(...arguments);
|
|
@@ -759,16 +1938,23 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
759
1938
|
this.renderVersion = 0;
|
|
760
1939
|
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
761
1940
|
this.conditionalListeners = /* @__PURE__ */ new Map();
|
|
1941
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
762
1942
|
this.conditionalOwner = {
|
|
763
1943
|
subscribe: (key, id, refresh) => this.subscribeToRowConditional(key, id, refresh)
|
|
764
1944
|
};
|
|
765
1945
|
this.captureRoot = (root) => {
|
|
766
1946
|
this.root = root;
|
|
767
1947
|
};
|
|
1948
|
+
this.requestHostScopeFallback = () => {
|
|
1949
|
+
this.activateFallback();
|
|
1950
|
+
};
|
|
768
1951
|
this.rowEvent = (item, index, eventId) => {
|
|
769
1952
|
if (this.state.fallback) {
|
|
770
1953
|
return (event) => this.currentProps.events?.[eventId]?.invoke(item, index, event);
|
|
771
1954
|
}
|
|
1955
|
+
if (this.usesDelegatedEvents()) {
|
|
1956
|
+
return void 0;
|
|
1957
|
+
}
|
|
772
1958
|
const key = keyedRowIdentity(this.currentProps.rowKey(item, index));
|
|
773
1959
|
let handlers = this.eventHandlers.get(key);
|
|
774
1960
|
if (!handlers) {
|
|
@@ -786,6 +1972,26 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
786
1972
|
handlers.set(eventId, handler);
|
|
787
1973
|
return handler;
|
|
788
1974
|
};
|
|
1975
|
+
this.dispatchDelegatedEvent = (name, event) => {
|
|
1976
|
+
const instance = this.eventRowInstance(event);
|
|
1977
|
+
const eventTarget = event.target;
|
|
1978
|
+
if (!instance || !eventTarget) return;
|
|
1979
|
+
const capture = name.endsWith("Capture");
|
|
1980
|
+
const matches = (this.currentProps.events || []).filter((descriptor) => descriptor.name === name && descriptor.path !== void 0).map((descriptor) => ({
|
|
1981
|
+
descriptor,
|
|
1982
|
+
target: findCompilerHostTarget(instance.element, descriptor.path || [])
|
|
1983
|
+
})).filter(
|
|
1984
|
+
(match) => Boolean(
|
|
1985
|
+
match.target && (match.target === eventTarget || match.target.contains(eventTarget))
|
|
1986
|
+
)
|
|
1987
|
+
).sort(
|
|
1988
|
+
(left, right) => capture ? (left.descriptor.path?.length || 0) - (right.descriptor.path?.length || 0) : (right.descriptor.path?.length || 0) - (left.descriptor.path?.length || 0)
|
|
1989
|
+
);
|
|
1990
|
+
for (const match of matches) {
|
|
1991
|
+
this.invokeDelegatedEvent(match.descriptor, instance, event, match.target);
|
|
1992
|
+
if (event.isPropagationStopped()) break;
|
|
1993
|
+
}
|
|
1994
|
+
};
|
|
789
1995
|
this.rowConditional = (item, index, conditionalId, render) => {
|
|
790
1996
|
if (this.state.fallback) return render(item, index);
|
|
791
1997
|
const key = keyedRowIdentity(this.currentProps.rowKey(item, index));
|
|
@@ -800,17 +2006,65 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
800
2006
|
render
|
|
801
2007
|
});
|
|
802
2008
|
};
|
|
803
|
-
this.refresh = (afterCommit) => {
|
|
2009
|
+
this.refresh = (afterCommit, dirtyState) => {
|
|
2010
|
+
if (dirtyState && this.refreshDirtyBindings(dirtyState, afterCommit)) return;
|
|
804
2011
|
this.reconcile(afterCommit);
|
|
805
2012
|
};
|
|
806
2013
|
}
|
|
807
2014
|
readRows(props) {
|
|
808
|
-
const
|
|
809
|
-
const items = source ? Array.from(source) : [];
|
|
2015
|
+
const items = materializeIterable(props.items());
|
|
810
2016
|
const keys = items.map((item, index) => keyedRowIdentity(props.rowKey(item, index)));
|
|
811
2017
|
if (new Set(keys).size !== keys.length) return null;
|
|
812
2018
|
return { items, keys };
|
|
813
2019
|
}
|
|
2020
|
+
usesDelegatedEvents(props = this.currentProps) {
|
|
2021
|
+
return Boolean(
|
|
2022
|
+
props.delegateEvents && props.events?.length && props.events.every((event) => event.path !== void 0)
|
|
2023
|
+
);
|
|
2024
|
+
}
|
|
2025
|
+
rebuildElementIndex(instances) {
|
|
2026
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
2027
|
+
for (const instance of instances.values()) {
|
|
2028
|
+
this.instancesByElement.set(instance.element, instance);
|
|
2029
|
+
}
|
|
2030
|
+
}
|
|
2031
|
+
eventRowInstance(event) {
|
|
2032
|
+
if (!this.root) return void 0;
|
|
2033
|
+
const target = event.target;
|
|
2034
|
+
if (!target) return void 0;
|
|
2035
|
+
let element = target.nodeType === 1 ? target : target.parentElement;
|
|
2036
|
+
while (element && element.parentElement !== this.root) element = element.parentElement;
|
|
2037
|
+
return element?.parentElement === this.root ? this.instancesByElement.get(element) : void 0;
|
|
2038
|
+
}
|
|
2039
|
+
invokeDelegatedEvent(descriptor, instance, event, currentTarget) {
|
|
2040
|
+
const ownCurrentTarget = Object.getOwnPropertyDescriptor(event, "currentTarget");
|
|
2041
|
+
try {
|
|
2042
|
+
Object.defineProperty(event, "currentTarget", {
|
|
2043
|
+
configurable: true,
|
|
2044
|
+
value: currentTarget
|
|
2045
|
+
});
|
|
2046
|
+
descriptor.invoke(instance.item, instance.index, event);
|
|
2047
|
+
} finally {
|
|
2048
|
+
if (ownCurrentTarget) Object.defineProperty(event, "currentTarget", ownCurrentTarget);
|
|
2049
|
+
else Reflect.deleteProperty(event, "currentTarget");
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
delegatedContainerProps(container) {
|
|
2053
|
+
if (this.state.fallback || !this.usesDelegatedEvents()) return {};
|
|
2054
|
+
const props = container.props;
|
|
2055
|
+
return Object.fromEntries(
|
|
2056
|
+
[...new Set((this.currentProps.events || []).map((event) => event.name))].map((name) => {
|
|
2057
|
+
const existing = props[name];
|
|
2058
|
+
const capture = name.endsWith("Capture");
|
|
2059
|
+
const handler = (event) => {
|
|
2060
|
+
if (capture) existing?.(event);
|
|
2061
|
+
if (!event.isPropagationStopped()) this.dispatchDelegatedEvent(name, event);
|
|
2062
|
+
if (!capture && !event.isPropagationStopped()) existing?.(event);
|
|
2063
|
+
};
|
|
2064
|
+
return [name, handler];
|
|
2065
|
+
})
|
|
2066
|
+
);
|
|
2067
|
+
}
|
|
814
2068
|
subscribeToRowConditional(key, id, refresh) {
|
|
815
2069
|
let listeners = this.conditionalListeners.get(key);
|
|
816
2070
|
if (!listeners) {
|
|
@@ -826,7 +2080,21 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
826
2080
|
};
|
|
827
2081
|
}
|
|
828
2082
|
hasReactOwnedRows(props = this.currentProps) {
|
|
829
|
-
return Boolean(
|
|
2083
|
+
return Boolean(
|
|
2084
|
+
props.conditionals?.length || props.events?.length && !this.usesDelegatedEvents(props)
|
|
2085
|
+
);
|
|
2086
|
+
}
|
|
2087
|
+
cleanupHostScopes(instances = this.instances) {
|
|
2088
|
+
for (const instance of instances.values()) instance.scope?.cleanup();
|
|
2089
|
+
}
|
|
2090
|
+
mountRowHostScope(element, descriptor, props = this.currentProps) {
|
|
2091
|
+
if (!props.hostBlocks) return void 0;
|
|
2092
|
+
return mountCompilerHostTree(
|
|
2093
|
+
rowHostScopeOwner,
|
|
2094
|
+
element,
|
|
2095
|
+
descriptor,
|
|
2096
|
+
this.requestHostScopeFallback
|
|
2097
|
+
);
|
|
830
2098
|
}
|
|
831
2099
|
pruneEventHandlers(keys) {
|
|
832
2100
|
const active = new Set(keys);
|
|
@@ -850,16 +2118,20 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
850
2118
|
);
|
|
851
2119
|
const instances = /* @__PURE__ */ new Map();
|
|
852
2120
|
for (let index = 0; index < rows.items.length; index += 1) {
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
this.
|
|
856
|
-
|
|
857
|
-
|
|
2121
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2122
|
+
if (this.hasReactOwnedRows() && !matchesCompilerHostElement(elements[index], descriptor, opaqueConditionalPaths)) {
|
|
2123
|
+
this.cleanupHostScopes(instances);
|
|
2124
|
+
return false;
|
|
2125
|
+
}
|
|
2126
|
+
const scope = this.mountRowHostScope(elements[index], descriptor);
|
|
2127
|
+
if (this.currentProps.hostBlocks && !scope) {
|
|
2128
|
+
this.cleanupHostScopes(instances);
|
|
858
2129
|
return false;
|
|
859
2130
|
}
|
|
860
2131
|
const instance = {
|
|
861
2132
|
key: rows.keys[index],
|
|
862
2133
|
element: elements[index],
|
|
2134
|
+
scope: scope || void 0,
|
|
863
2135
|
values: this.hasReactOwnedRows() ? this.currentProps.bindings.map(() => UNSET_KEYED_ROW_BINDING) : readKeyedRowBindingValues(this.currentProps, rows.items[index], index),
|
|
864
2136
|
item: rows.items[index],
|
|
865
2137
|
index,
|
|
@@ -874,7 +2146,9 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
874
2146
|
}
|
|
875
2147
|
instances.set(rows.keys[index], instance);
|
|
876
2148
|
}
|
|
2149
|
+
this.cleanupHostScopes();
|
|
877
2150
|
this.instances = instances;
|
|
2151
|
+
this.rebuildElementIndex(instances);
|
|
878
2152
|
this.pruneEventHandlers(rows.keys);
|
|
879
2153
|
this.pruneConditionalListeners(rows.keys);
|
|
880
2154
|
return true;
|
|
@@ -893,6 +2167,7 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
893
2167
|
}
|
|
894
2168
|
this.fallbackRequested = true;
|
|
895
2169
|
this.fallbackKeysWereUnsafe = this.hasUnsafeFallbackKeys();
|
|
2170
|
+
this.cleanupHostScopes();
|
|
896
2171
|
this.fallbackVersion += 1;
|
|
897
2172
|
this.setState({ fallback: true }, afterCommit);
|
|
898
2173
|
}
|
|
@@ -927,6 +2202,116 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
927
2202
|
}
|
|
928
2203
|
});
|
|
929
2204
|
}
|
|
2205
|
+
refreshDirtyBindings(dirtyState, afterCommit) {
|
|
2206
|
+
if (!this.mounted || !this.root || this.state.fallback || this.hasReactOwnedRows() || this.currentProps.hostBlocks || !this.currentProps.structureDependencies || this.currentProps.structureDependencies.some((dependency) => dirtyState.has(dependency)) || this.currentProps.bindings.some((binding) => binding.dependencies === void 0)) {
|
|
2207
|
+
return false;
|
|
2208
|
+
}
|
|
2209
|
+
const affectedBindingIndices = [];
|
|
2210
|
+
for (let bindingIndex = 0; bindingIndex < this.currentProps.bindings.length; bindingIndex += 1) {
|
|
2211
|
+
const dependencies = this.currentProps.bindings[bindingIndex].dependencies || [];
|
|
2212
|
+
if (dependencies.some((dependency) => dirtyState.has(dependency))) {
|
|
2213
|
+
affectedBindingIndices.push(bindingIndex);
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
for (const instance of this.instances.values()) {
|
|
2217
|
+
for (const bindingIndex of affectedBindingIndices) {
|
|
2218
|
+
applyKeyedRowBinding(
|
|
2219
|
+
this.currentProps,
|
|
2220
|
+
instance,
|
|
2221
|
+
instance.item,
|
|
2222
|
+
instance.index,
|
|
2223
|
+
bindingIndex
|
|
2224
|
+
);
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
afterCommit?.();
|
|
2228
|
+
return true;
|
|
2229
|
+
}
|
|
2230
|
+
reconcileStableRows(rows, afterCommit) {
|
|
2231
|
+
if (rows.keys.length !== this.instances.size) return false;
|
|
2232
|
+
let index = 0;
|
|
2233
|
+
for (const key of this.instances.keys()) {
|
|
2234
|
+
if (rows.keys[index] !== key) return false;
|
|
2235
|
+
index += 1;
|
|
2236
|
+
}
|
|
2237
|
+
const conditionalChanges = [];
|
|
2238
|
+
for (index = 0; index < rows.items.length; index += 1) {
|
|
2239
|
+
const key = rows.keys[index];
|
|
2240
|
+
const existing = this.instances.get(key);
|
|
2241
|
+
if (!existing) return false;
|
|
2242
|
+
if (this.currentProps.hostBlocks) {
|
|
2243
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2244
|
+
if (!existing.scope?.update(descriptor)) {
|
|
2245
|
+
this.activateFallback(afterCommit);
|
|
2246
|
+
return true;
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
|
|
2250
|
+
const conditionalValues = readKeyedRowConditionalValues(
|
|
2251
|
+
this.currentProps,
|
|
2252
|
+
rows.items[index],
|
|
2253
|
+
index
|
|
2254
|
+
);
|
|
2255
|
+
for (const [id, values] of conditionalValues) {
|
|
2256
|
+
if (keyedRowConditionalChanged(existing.conditionalValues.get(id), values)) {
|
|
2257
|
+
conditionalChanges.push({ key, id, item: rows.items[index], index });
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
existing.conditionalValues = conditionalValues;
|
|
2261
|
+
existing.item = rows.items[index];
|
|
2262
|
+
existing.index = index;
|
|
2263
|
+
}
|
|
2264
|
+
this.notifyConditionalChanges(conditionalChanges, afterCommit);
|
|
2265
|
+
return true;
|
|
2266
|
+
}
|
|
2267
|
+
reconcileSingleRemoval(rows, afterCommit) {
|
|
2268
|
+
if (this.hasReactOwnedRows() || rows.keys.length + 1 !== this.instances.size) return false;
|
|
2269
|
+
const previousKeys = [...this.instances.keys()];
|
|
2270
|
+
let removedIndex = 0;
|
|
2271
|
+
while (removedIndex < rows.keys.length && previousKeys[removedIndex] === rows.keys[removedIndex]) {
|
|
2272
|
+
removedIndex += 1;
|
|
2273
|
+
}
|
|
2274
|
+
for (let index = removedIndex; index < rows.keys.length; index += 1) {
|
|
2275
|
+
if (previousKeys[index + 1] !== rows.keys[index]) return false;
|
|
2276
|
+
}
|
|
2277
|
+
const removedKey = previousKeys[removedIndex];
|
|
2278
|
+
const removed = this.instances.get(removedKey);
|
|
2279
|
+
if (!removed) return false;
|
|
2280
|
+
const conditionalChanges = [];
|
|
2281
|
+
for (let index = 0; index < rows.items.length; index += 1) {
|
|
2282
|
+
const key = rows.keys[index];
|
|
2283
|
+
const existing = this.instances.get(key);
|
|
2284
|
+
if (!existing) return false;
|
|
2285
|
+
if (this.currentProps.hostBlocks) {
|
|
2286
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2287
|
+
if (!existing.scope?.update(descriptor)) {
|
|
2288
|
+
this.activateFallback(afterCommit);
|
|
2289
|
+
return true;
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
|
|
2293
|
+
const conditionalValues = readKeyedRowConditionalValues(
|
|
2294
|
+
this.currentProps,
|
|
2295
|
+
rows.items[index],
|
|
2296
|
+
index
|
|
2297
|
+
);
|
|
2298
|
+
for (const [id, values] of conditionalValues) {
|
|
2299
|
+
if (keyedRowConditionalChanged(existing.conditionalValues.get(id), values)) {
|
|
2300
|
+
conditionalChanges.push({ key, id, item: rows.items[index], index });
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
existing.conditionalValues = conditionalValues;
|
|
2304
|
+
existing.item = rows.items[index];
|
|
2305
|
+
existing.index = index;
|
|
2306
|
+
}
|
|
2307
|
+
removed.scope?.cleanup();
|
|
2308
|
+
removed.element.remove();
|
|
2309
|
+
this.instances.delete(removedKey);
|
|
2310
|
+
this.eventHandlers.delete(removedKey);
|
|
2311
|
+
this.conditionalListeners.delete(removedKey);
|
|
2312
|
+
this.notifyConditionalChanges(conditionalChanges, afterCommit);
|
|
2313
|
+
return true;
|
|
2314
|
+
}
|
|
930
2315
|
reconcile(afterCommit) {
|
|
931
2316
|
if (!this.mounted || !this.root) {
|
|
932
2317
|
afterCommit?.();
|
|
@@ -946,27 +2331,54 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
946
2331
|
this.activateFallback(afterCommit);
|
|
947
2332
|
return;
|
|
948
2333
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
2334
|
+
if (this.hasReactOwnedRows()) {
|
|
2335
|
+
const previousKeys = [...this.instances.keys()];
|
|
2336
|
+
if (rows.keys.length !== previousKeys.length || rows.keys.some((key, index) => key !== previousKeys[index])) {
|
|
2337
|
+
this.synchronizeReactOwnedRows(afterCommit);
|
|
2338
|
+
return;
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
if (rows.items.length === 0) {
|
|
2342
|
+
this.cleanupHostScopes();
|
|
2343
|
+
this.root.replaceChildren();
|
|
2344
|
+
this.instances = /* @__PURE__ */ new Map();
|
|
2345
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
2346
|
+
this.eventHandlers.clear();
|
|
2347
|
+
this.conditionalListeners.clear();
|
|
2348
|
+
afterCommit?.();
|
|
952
2349
|
return;
|
|
953
2350
|
}
|
|
954
|
-
|
|
2351
|
+
if (this.reconcileStableRows(rows, afterCommit)) return;
|
|
2352
|
+
if (this.reconcileSingleRemoval(rows, afterCommit)) return;
|
|
955
2353
|
const activeElement = this.root.ownerDocument.activeElement;
|
|
956
2354
|
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
957
|
-
[...this.instances].forEach(([key], index) => oldIndices.set(key, index));
|
|
958
2355
|
const nextKeys = new Set(rows.keys);
|
|
2356
|
+
const hasSurvivingRows = rows.keys.some((key) => this.instances.has(key));
|
|
2357
|
+
const oldIndices = /* @__PURE__ */ new Map();
|
|
2358
|
+
if (hasSurvivingRows) {
|
|
2359
|
+
[...this.instances].forEach(([key], index) => oldIndices.set(key, index));
|
|
2360
|
+
}
|
|
959
2361
|
for (const [key, instance] of this.instances) {
|
|
960
|
-
if (!nextKeys.has(key))
|
|
2362
|
+
if (!nextKeys.has(key)) {
|
|
2363
|
+
instance.scope?.cleanup();
|
|
2364
|
+
if (hasSurvivingRows) instance.element.remove();
|
|
2365
|
+
}
|
|
961
2366
|
}
|
|
962
|
-
const sequence = rows.keys.map((key) => oldIndices.get(key) ?? -1);
|
|
963
|
-
const stablePositions = longestIncreasingSubsequencePositions(sequence);
|
|
2367
|
+
const sequence = hasSurvivingRows ? rows.keys.map((key) => oldIndices.get(key) ?? -1) : rows.keys.map(() => -1);
|
|
2368
|
+
const stablePositions = hasSurvivingRows ? longestIncreasingSubsequencePositions(sequence) : /* @__PURE__ */ new Set();
|
|
964
2369
|
const nextInstances = [];
|
|
965
2370
|
const conditionalChanges = [];
|
|
966
2371
|
for (let index = 0; index < rows.items.length; index += 1) {
|
|
967
2372
|
const key = rows.keys[index];
|
|
968
2373
|
const existing = this.instances.get(key);
|
|
969
2374
|
if (existing) {
|
|
2375
|
+
if (this.currentProps.hostBlocks) {
|
|
2376
|
+
const descriptor2 = this.currentProps.create(rows.items[index], index);
|
|
2377
|
+
if (!existing.scope?.update(descriptor2)) {
|
|
2378
|
+
this.activateFallback(afterCommit);
|
|
2379
|
+
return;
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
970
2382
|
applyKeyedRowBindings(this.currentProps, existing, rows.items[index], index);
|
|
971
2383
|
const conditionalValues = readKeyedRowConditionalValues(
|
|
972
2384
|
this.currentProps,
|
|
@@ -984,13 +2396,20 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
984
2396
|
nextInstances.push(existing);
|
|
985
2397
|
continue;
|
|
986
2398
|
}
|
|
987
|
-
const
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
)
|
|
2399
|
+
const descriptor = this.currentProps.create(rows.items[index], index);
|
|
2400
|
+
const element = createCompilerHostElement(this.root.ownerDocument, descriptor);
|
|
2401
|
+
const scope = this.mountRowHostScope(element, descriptor);
|
|
2402
|
+
if (this.currentProps.hostBlocks && !scope) {
|
|
2403
|
+
for (const instance of nextInstances) {
|
|
2404
|
+
if (!this.instances.has(instance.key)) instance.scope?.cleanup();
|
|
2405
|
+
}
|
|
2406
|
+
this.activateFallback(afterCommit);
|
|
2407
|
+
return;
|
|
2408
|
+
}
|
|
991
2409
|
nextInstances.push({
|
|
992
2410
|
key,
|
|
993
2411
|
element,
|
|
2412
|
+
scope: scope || void 0,
|
|
994
2413
|
values: readKeyedRowBindingValues(this.currentProps, rows.items[index], index),
|
|
995
2414
|
item: rows.items[index],
|
|
996
2415
|
index,
|
|
@@ -1001,17 +2420,34 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
1001
2420
|
)
|
|
1002
2421
|
});
|
|
1003
2422
|
}
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
const instance
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
2423
|
+
if (!hasSurvivingRows) {
|
|
2424
|
+
const fragment = this.root.ownerDocument.createDocumentFragment();
|
|
2425
|
+
for (const instance of nextInstances) fragment.append(instance.element);
|
|
2426
|
+
this.root.replaceChildren(fragment);
|
|
2427
|
+
} else {
|
|
2428
|
+
let anchor = null;
|
|
2429
|
+
for (let index = nextInstances.length - 1; index >= 0; index -= 1) {
|
|
2430
|
+
const instance = nextInstances[index];
|
|
2431
|
+
if (sequence[index] < 0) {
|
|
2432
|
+
let start = index;
|
|
2433
|
+
while (start > 0 && sequence[start - 1] < 0) start -= 1;
|
|
2434
|
+
const fragment = this.root.ownerDocument.createDocumentFragment();
|
|
2435
|
+
for (let itemIndex = start; itemIndex <= index; itemIndex += 1) {
|
|
2436
|
+
fragment.append(nextInstances[itemIndex].element);
|
|
2437
|
+
}
|
|
2438
|
+
this.root.insertBefore(fragment, anchor);
|
|
2439
|
+
anchor = nextInstances[start].element;
|
|
2440
|
+
index = start;
|
|
2441
|
+
} else {
|
|
2442
|
+
if (!stablePositions.has(index) && instance.element.nextSibling !== anchor) {
|
|
2443
|
+
this.root.insertBefore(instance.element, anchor);
|
|
2444
|
+
}
|
|
2445
|
+
anchor = instance.element;
|
|
2446
|
+
}
|
|
1011
2447
|
}
|
|
1012
|
-
anchor = instance.element;
|
|
1013
2448
|
}
|
|
1014
2449
|
this.instances = new Map(nextInstances.map((instance) => [instance.key, instance]));
|
|
2450
|
+
this.rebuildElementIndex(this.instances);
|
|
1015
2451
|
this.pruneEventHandlers(rows.keys);
|
|
1016
2452
|
this.pruneConditionalListeners(rows.keys);
|
|
1017
2453
|
if (restoreFocus && activeElement?.isConnected && activeElement.ownerDocument.activeElement !== activeElement && "focus" in activeElement) {
|
|
@@ -1054,7 +2490,9 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
1054
2490
|
this.mounted = false;
|
|
1055
2491
|
this.unsubscribe?.();
|
|
1056
2492
|
this.root = null;
|
|
2493
|
+
this.cleanupHostScopes();
|
|
1057
2494
|
this.instances.clear();
|
|
2495
|
+
this.instancesByElement = /* @__PURE__ */ new WeakMap();
|
|
1058
2496
|
this.eventHandlers.clear();
|
|
1059
2497
|
this.conditionalListeners.clear();
|
|
1060
2498
|
}
|
|
@@ -1067,6 +2505,7 @@ function createKeyedRowsBlockComponent(owner) {
|
|
|
1067
2505
|
);
|
|
1068
2506
|
}
|
|
1069
2507
|
return React.cloneElement(container, {
|
|
2508
|
+
...this.delegatedContainerProps(container),
|
|
1070
2509
|
key: this.state.fallback ? `react-${this.fallbackVersion}` : "compiled",
|
|
1071
2510
|
ref: this.captureRoot
|
|
1072
2511
|
});
|
|
@@ -1088,6 +2527,7 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1088
2527
|
this.currentProps = this.props;
|
|
1089
2528
|
this.rangeInstances = [];
|
|
1090
2529
|
this.staticSegments = [];
|
|
2530
|
+
this.staticValues = [];
|
|
1091
2531
|
this.captureRoot = (root) => {
|
|
1092
2532
|
this.root = root;
|
|
1093
2533
|
this.currentProps.rootRef?.(root);
|
|
@@ -1097,8 +2537,7 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1097
2537
|
};
|
|
1098
2538
|
}
|
|
1099
2539
|
readRange(range) {
|
|
1100
|
-
const
|
|
1101
|
-
const items = source ? Array.from(source) : [];
|
|
2540
|
+
const items = materializeIterable(range.items());
|
|
1102
2541
|
const keys = items.map((item, index) => keyedRowIdentity(range.rowKey(item, index)));
|
|
1103
2542
|
if (new Set(keys).size !== keys.length) return null;
|
|
1104
2543
|
return { items, keys };
|
|
@@ -1152,6 +2591,11 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1152
2591
|
staticSegments.push(elements.slice(cursor));
|
|
1153
2592
|
this.staticSegments = staticSegments;
|
|
1154
2593
|
this.rangeInstances = instancesByRange;
|
|
2594
|
+
if (!applyStaticRangeBindings(props.bindings, this.staticSegments, this.staticValues)) {
|
|
2595
|
+
this.rangeInstances = [];
|
|
2596
|
+
this.staticSegments = [];
|
|
2597
|
+
return false;
|
|
2598
|
+
}
|
|
1155
2599
|
return true;
|
|
1156
2600
|
}
|
|
1157
2601
|
anchorAfter(rangeIndex) {
|
|
@@ -1228,6 +2672,14 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1228
2672
|
this.activateFallback(afterCommit);
|
|
1229
2673
|
return;
|
|
1230
2674
|
}
|
|
2675
|
+
if (!applyStaticRangeBindings(
|
|
2676
|
+
this.currentProps.bindings,
|
|
2677
|
+
this.staticSegments,
|
|
2678
|
+
this.staticValues
|
|
2679
|
+
)) {
|
|
2680
|
+
this.activateFallback(afterCommit);
|
|
2681
|
+
return;
|
|
2682
|
+
}
|
|
1231
2683
|
const activeElement = this.root.ownerDocument.activeElement;
|
|
1232
2684
|
const restoreFocus = Boolean(activeElement && this.root.contains(activeElement));
|
|
1233
2685
|
for (let rangeIndex = rowsByRange.length - 1; rangeIndex >= 0; rangeIndex -= 1) {
|
|
@@ -1271,6 +2723,7 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1271
2723
|
this.root = null;
|
|
1272
2724
|
this.rangeInstances = [];
|
|
1273
2725
|
this.staticSegments = [];
|
|
2726
|
+
this.staticValues.length = 0;
|
|
1274
2727
|
}
|
|
1275
2728
|
render() {
|
|
1276
2729
|
const container = this.currentProps.render();
|
|
@@ -1288,6 +2741,128 @@ function createKeyedRangesBlockComponent(owner) {
|
|
|
1288
2741
|
FarmKeyedRangesBlock.displayName = "FarmCompiledKeyedRanges";
|
|
1289
2742
|
return FarmKeyedRangesBlock;
|
|
1290
2743
|
}
|
|
2744
|
+
function createMixedRangesBlockComponent(owner) {
|
|
2745
|
+
class FarmMixedRangesBlock extends React.Component {
|
|
2746
|
+
constructor() {
|
|
2747
|
+
super(...arguments);
|
|
2748
|
+
this.state = { fallback: false };
|
|
2749
|
+
this.root = null;
|
|
2750
|
+
this.mounted = false;
|
|
2751
|
+
this.fallbackRequested = false;
|
|
2752
|
+
this.fallbackVersion = 0;
|
|
2753
|
+
this.propFallbackQueued = false;
|
|
2754
|
+
this.currentProps = this.props;
|
|
2755
|
+
this.controller = null;
|
|
2756
|
+
this.fallbackUnsubscribers = [];
|
|
2757
|
+
this.captureRoot = (root) => {
|
|
2758
|
+
this.root = root;
|
|
2759
|
+
this.currentProps.rootRef?.(root);
|
|
2760
|
+
};
|
|
2761
|
+
this.activateFallback = (afterCommit) => {
|
|
2762
|
+
if (!this.mounted || this.state.fallback || this.fallbackRequested) {
|
|
2763
|
+
afterCommit?.();
|
|
2764
|
+
return;
|
|
2765
|
+
}
|
|
2766
|
+
this.fallbackRequested = true;
|
|
2767
|
+
this.controller?.cleanup();
|
|
2768
|
+
this.controller = null;
|
|
2769
|
+
this.fallbackVersion += 1;
|
|
2770
|
+
this.setState({ fallback: true }, () => {
|
|
2771
|
+
this.subscribeFallbackBlocks();
|
|
2772
|
+
afterCommit?.();
|
|
2773
|
+
});
|
|
2774
|
+
};
|
|
2775
|
+
}
|
|
2776
|
+
clearFallbackSubscriptions() {
|
|
2777
|
+
for (const unsubscribe of this.fallbackUnsubscribers) unsubscribe();
|
|
2778
|
+
this.fallbackUnsubscribers = [];
|
|
2779
|
+
}
|
|
2780
|
+
subscribeFallbackBlocks() {
|
|
2781
|
+
this.clearFallbackSubscriptions();
|
|
2782
|
+
const descriptor = this.currentProps.create();
|
|
2783
|
+
const ids = /* @__PURE__ */ new Set();
|
|
2784
|
+
collectCompilerHostBlockIds(descriptor, ids);
|
|
2785
|
+
for (const id of ids) {
|
|
2786
|
+
this.fallbackUnsubscribers.push(
|
|
2787
|
+
owner.subscribe(id, (afterCommit) => {
|
|
2788
|
+
if (!this.mounted || !this.state.fallback) {
|
|
2789
|
+
afterCommit?.();
|
|
2790
|
+
return;
|
|
2791
|
+
}
|
|
2792
|
+
this.fallbackVersion += 1;
|
|
2793
|
+
this.forceUpdate(afterCommit);
|
|
2794
|
+
})
|
|
2795
|
+
);
|
|
2796
|
+
}
|
|
2797
|
+
}
|
|
2798
|
+
adopt() {
|
|
2799
|
+
if (!this.root) return false;
|
|
2800
|
+
const descriptor = this.currentProps.create();
|
|
2801
|
+
const block = descriptor.block;
|
|
2802
|
+
if (block?.kind !== "mixed-ranges" || block.id !== this.currentProps.id) return false;
|
|
2803
|
+
const controller = new CompilerNestedMixedRanges(
|
|
2804
|
+
owner,
|
|
2805
|
+
this.root,
|
|
2806
|
+
descriptor,
|
|
2807
|
+
block,
|
|
2808
|
+
this.activateFallback
|
|
2809
|
+
);
|
|
2810
|
+
try {
|
|
2811
|
+
if (!controller.adopt()) {
|
|
2812
|
+
controller.cleanup();
|
|
2813
|
+
return false;
|
|
2814
|
+
}
|
|
2815
|
+
} catch (error) {
|
|
2816
|
+
controller.cleanup();
|
|
2817
|
+
throw error;
|
|
2818
|
+
}
|
|
2819
|
+
this.controller = controller;
|
|
2820
|
+
return true;
|
|
2821
|
+
}
|
|
2822
|
+
schedulePropFallback() {
|
|
2823
|
+
if (this.propFallbackQueued) return;
|
|
2824
|
+
this.propFallbackQueued = true;
|
|
2825
|
+
queueMicrotask(() => {
|
|
2826
|
+
this.propFallbackQueued = false;
|
|
2827
|
+
if (this.mounted && !this.state.fallback) this.activateFallback();
|
|
2828
|
+
});
|
|
2829
|
+
}
|
|
2830
|
+
shouldComponentUpdate(nextProps, nextState) {
|
|
2831
|
+
this.currentProps = nextProps;
|
|
2832
|
+
if (nextState.fallback || this.state.fallback) return true;
|
|
2833
|
+
this.schedulePropFallback();
|
|
2834
|
+
return false;
|
|
2835
|
+
}
|
|
2836
|
+
componentDidMount() {
|
|
2837
|
+
this.mounted = true;
|
|
2838
|
+
if (!this.adopt()) this.activateFallback();
|
|
2839
|
+
}
|
|
2840
|
+
componentDidUpdate() {
|
|
2841
|
+
if (this.state.fallback) this.subscribeFallbackBlocks();
|
|
2842
|
+
}
|
|
2843
|
+
componentWillUnmount() {
|
|
2844
|
+
this.mounted = false;
|
|
2845
|
+
this.controller?.cleanup();
|
|
2846
|
+
this.controller = null;
|
|
2847
|
+
this.clearFallbackSubscriptions();
|
|
2848
|
+
this.root = null;
|
|
2849
|
+
}
|
|
2850
|
+
render() {
|
|
2851
|
+
const container = this.currentProps.render();
|
|
2852
|
+
if (!React.isValidElement(container) || typeof container.type !== "string") {
|
|
2853
|
+
throw new TypeError(
|
|
2854
|
+
`Compiled mixed ranges ${this.currentProps.id} must own one host container.`
|
|
2855
|
+
);
|
|
2856
|
+
}
|
|
2857
|
+
return React.cloneElement(container, {
|
|
2858
|
+
key: this.state.fallback ? `react-${this.fallbackVersion}` : "compiled",
|
|
2859
|
+
ref: this.captureRoot
|
|
2860
|
+
});
|
|
2861
|
+
}
|
|
2862
|
+
}
|
|
2863
|
+
FarmMixedRangesBlock.displayName = "FarmCompiledMixedRanges";
|
|
2864
|
+
return FarmMixedRangesBlock;
|
|
2865
|
+
}
|
|
1291
2866
|
function createComponentBlockComponent(owner) {
|
|
1292
2867
|
class FarmComponentBlock extends React.Component {
|
|
1293
2868
|
constructor() {
|
|
@@ -1340,6 +2915,17 @@ function createCompiledComponent(definition) {
|
|
|
1340
2915
|
this.hasBindingError = false;
|
|
1341
2916
|
this.inputSelection = null;
|
|
1342
2917
|
this.dirtyState = /* @__PURE__ */ new Set();
|
|
2918
|
+
this.indexedDefinition = null;
|
|
2919
|
+
this.staticBindingsByDependency = [];
|
|
2920
|
+
this.blockBindingsByDependency = [];
|
|
2921
|
+
this.blockBindings = /* @__PURE__ */ new Map();
|
|
2922
|
+
this.trackedBindingsByDependency = [];
|
|
2923
|
+
this.trackedDependenciesByBinding = /* @__PURE__ */ new Map();
|
|
2924
|
+
this.bindingValues = /* @__PURE__ */ new Map();
|
|
2925
|
+
this.activeBinding = null;
|
|
2926
|
+
this.activeDependencies = null;
|
|
2927
|
+
this.renderedDefinition = null;
|
|
2928
|
+
this.renderedElement = null;
|
|
1343
2929
|
this.blockRefreshListeners = /* @__PURE__ */ new Map();
|
|
1344
2930
|
this.blockRoots = /* @__PURE__ */ new Map();
|
|
1345
2931
|
this.blockRootElements = /* @__PURE__ */ new Set();
|
|
@@ -1351,20 +2937,35 @@ function createCompiledComponent(definition) {
|
|
|
1351
2937
|
this.refreshDefinition = () => {
|
|
1352
2938
|
if (this.mounted) this.forceUpdate();
|
|
1353
2939
|
};
|
|
1354
|
-
|
|
2940
|
+
const initialState = definitionReference.current.initialize(props);
|
|
2941
|
+
const initialProps = definitionReference.current.readProps?.(props) || [];
|
|
2942
|
+
this.propCellOffset = initialState.length;
|
|
2943
|
+
this.cells = [...initialState, ...initialProps].map((initialValue, index) => {
|
|
1355
2944
|
let value = initialValue;
|
|
1356
2945
|
const pending = [];
|
|
1357
2946
|
return {
|
|
1358
|
-
get: () =>
|
|
2947
|
+
get: () => {
|
|
2948
|
+
if (this.activeBinding && this.activeDependencies) {
|
|
2949
|
+
this.activeDependencies.add(index);
|
|
2950
|
+
}
|
|
2951
|
+
return value;
|
|
2952
|
+
},
|
|
1359
2953
|
set: (next) => {
|
|
1360
|
-
pending.push(next);
|
|
2954
|
+
pending.push({ kind: "state", update: next });
|
|
1361
2955
|
this.scheduleBindingFlush(index);
|
|
1362
2956
|
},
|
|
2957
|
+
replace: (next) => {
|
|
2958
|
+
pending.push({ kind: "value", value: next });
|
|
2959
|
+
},
|
|
1363
2960
|
flush: () => {
|
|
1364
2961
|
if (pending.length === 0) return false;
|
|
1365
2962
|
const previous = value;
|
|
1366
2963
|
for (const next of pending.splice(0)) {
|
|
1367
|
-
|
|
2964
|
+
if (next.kind === "value") {
|
|
2965
|
+
value = next.value;
|
|
2966
|
+
} else {
|
|
2967
|
+
value = typeof next.update === "function" ? next.update(value) : next.update;
|
|
2968
|
+
}
|
|
1368
2969
|
}
|
|
1369
2970
|
return !Object.is(previous, value);
|
|
1370
2971
|
}
|
|
@@ -1390,12 +2991,113 @@ function createCompiledComponent(definition) {
|
|
|
1390
2991
|
KeyedRanges: createKeyedRangesBlockComponent({
|
|
1391
2992
|
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1392
2993
|
}),
|
|
2994
|
+
MixedRanges: createMixedRangesBlockComponent({
|
|
2995
|
+
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
2996
|
+
}),
|
|
1393
2997
|
Component: createComponentBlockComponent({
|
|
1394
2998
|
subscribe: (id, refresh) => this.subscribeToBlock(id, refresh)
|
|
1395
2999
|
}),
|
|
1396
3000
|
target: (id) => this.bindingTarget(id)
|
|
1397
3001
|
};
|
|
1398
3002
|
}
|
|
3003
|
+
usesHybridReactivity() {
|
|
3004
|
+
return definitionReference.current.reactivity === "hybrid";
|
|
3005
|
+
}
|
|
3006
|
+
canReuseRenderedElement(currentDefinition, propValues) {
|
|
3007
|
+
return Boolean(
|
|
3008
|
+
this.mounted && propValues && propValues.every(isCompilerPrimitive) && this.renderedDefinition === currentDefinition && this.renderedElement
|
|
3009
|
+
);
|
|
3010
|
+
}
|
|
3011
|
+
renderCellsForProps(propValues) {
|
|
3012
|
+
if (!propValues) return { cells: this.cells, commit: () => void 0 };
|
|
3013
|
+
let committed = false;
|
|
3014
|
+
const cells = this.cells.slice(0, this.propCellOffset);
|
|
3015
|
+
for (let propIndex = 0; propIndex < propValues.length; propIndex += 1) {
|
|
3016
|
+
const cell = this.cells[this.propCellOffset + propIndex];
|
|
3017
|
+
if (!cell) continue;
|
|
3018
|
+
cells.push({
|
|
3019
|
+
get: () => committed ? cell.get() : propValues[propIndex],
|
|
3020
|
+
set: (next) => cell.set(next)
|
|
3021
|
+
});
|
|
3022
|
+
}
|
|
3023
|
+
return {
|
|
3024
|
+
cells,
|
|
3025
|
+
commit: () => {
|
|
3026
|
+
committed = true;
|
|
3027
|
+
}
|
|
3028
|
+
};
|
|
3029
|
+
}
|
|
3030
|
+
tracksBinding(binding) {
|
|
3031
|
+
return this.usesHybridReactivity() && binding.tracking === "dynamic";
|
|
3032
|
+
}
|
|
3033
|
+
ensureBindingIndex() {
|
|
3034
|
+
const currentDefinition = definitionReference.current;
|
|
3035
|
+
if (this.indexedDefinition === currentDefinition) return;
|
|
3036
|
+
this.indexedDefinition = currentDefinition;
|
|
3037
|
+
this.staticBindingsByDependency = Array.from({ length: this.cells.length }, () => []);
|
|
3038
|
+
this.blockBindingsByDependency = Array.from({ length: this.cells.length }, () => []);
|
|
3039
|
+
this.trackedBindingsByDependency = Array.from(
|
|
3040
|
+
{ length: this.cells.length },
|
|
3041
|
+
() => /* @__PURE__ */ new Set()
|
|
3042
|
+
);
|
|
3043
|
+
this.blockBindings.clear();
|
|
3044
|
+
this.trackedDependenciesByBinding.clear();
|
|
3045
|
+
this.bindingValues.clear();
|
|
3046
|
+
for (const binding of currentDefinition.bindings) {
|
|
3047
|
+
if (binding.kind === "block") this.blockBindings.set(binding.id, binding);
|
|
3048
|
+
for (const dependency of binding.dependencies) {
|
|
3049
|
+
if (dependency < 0 || dependency >= this.cells.length) continue;
|
|
3050
|
+
if (binding.kind === "block") {
|
|
3051
|
+
this.blockBindingsByDependency[dependency].push(binding);
|
|
3052
|
+
} else if (!this.tracksBinding(binding)) {
|
|
3053
|
+
this.staticBindingsByDependency[dependency].push(binding);
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
3058
|
+
updateTrackedDependencies(binding, nextDependencies) {
|
|
3059
|
+
const previousDependencies = this.trackedDependenciesByBinding.get(binding);
|
|
3060
|
+
if (previousDependencies) {
|
|
3061
|
+
for (const dependency of previousDependencies) {
|
|
3062
|
+
if (!nextDependencies.has(dependency)) {
|
|
3063
|
+
this.trackedBindingsByDependency[dependency]?.delete(binding);
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
for (const dependency of nextDependencies) {
|
|
3068
|
+
if (!previousDependencies?.has(dependency)) {
|
|
3069
|
+
this.trackedBindingsByDependency[dependency]?.add(binding);
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
this.trackedDependenciesByBinding.set(binding, nextDependencies);
|
|
3073
|
+
}
|
|
3074
|
+
readBinding(binding) {
|
|
3075
|
+
if (!this.tracksBinding(binding)) return binding.read(this.props, this.cells);
|
|
3076
|
+
const previousBinding = this.activeBinding;
|
|
3077
|
+
const previousDependencies = this.activeDependencies;
|
|
3078
|
+
const nextDependencies = /* @__PURE__ */ new Set();
|
|
3079
|
+
this.activeBinding = binding;
|
|
3080
|
+
this.activeDependencies = nextDependencies;
|
|
3081
|
+
try {
|
|
3082
|
+
return binding.read(this.props, this.cells);
|
|
3083
|
+
} finally {
|
|
3084
|
+
this.activeBinding = previousBinding;
|
|
3085
|
+
this.activeDependencies = previousDependencies;
|
|
3086
|
+
this.updateTrackedDependencies(binding, nextDependencies);
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
bindingValue(binding, value) {
|
|
3090
|
+
return binding.kind === "text" ? renderTextValue(value) : value;
|
|
3091
|
+
}
|
|
3092
|
+
primeHybridBindings() {
|
|
3093
|
+
if (!this.usesHybridReactivity()) return;
|
|
3094
|
+
for (const binding of definitionReference.current.bindings) {
|
|
3095
|
+
if (binding.kind === "block") continue;
|
|
3096
|
+
if (!this.tracksBinding(binding)) continue;
|
|
3097
|
+
const value = this.readBinding(binding);
|
|
3098
|
+
this.bindingValues.set(binding, this.bindingValue(binding, value));
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
1399
3101
|
bindingTarget(id) {
|
|
1400
3102
|
const existing = this.bindingTargetRefs.get(id);
|
|
1401
3103
|
if (existing) return existing;
|
|
@@ -1452,83 +3154,118 @@ function createCompiledComponent(definition) {
|
|
|
1452
3154
|
this.flushQueued = true;
|
|
1453
3155
|
queueMicrotask(() => {
|
|
1454
3156
|
this.flushQueued = false;
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
3157
|
+
this.flushBindingUpdates();
|
|
3158
|
+
});
|
|
3159
|
+
}
|
|
3160
|
+
flushBindingUpdates() {
|
|
3161
|
+
const inputSelection = this.inputSelection;
|
|
3162
|
+
this.inputSelection = null;
|
|
3163
|
+
if (!this.mounted) return;
|
|
3164
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
3165
|
+
for (const index of this.dirtyState) {
|
|
3166
|
+
if (this.cells[index]?.flush()) dirty.add(index);
|
|
3167
|
+
}
|
|
3168
|
+
this.dirtyState.clear();
|
|
3169
|
+
if (dirty.size === 0) return;
|
|
3170
|
+
try {
|
|
3171
|
+
this.ensureBindingIndex();
|
|
3172
|
+
const affectedBlockIds = /* @__PURE__ */ new Set();
|
|
3173
|
+
const affectedBindings = /* @__PURE__ */ new Set();
|
|
3174
|
+
for (const dependency of dirty) {
|
|
3175
|
+
for (const binding of this.blockBindingsByDependency[dependency] || []) {
|
|
3176
|
+
affectedBlockIds.add(binding.id);
|
|
1474
3177
|
}
|
|
1475
|
-
const
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
parent = blockBindings.get(parent)?.parent;
|
|
1482
|
-
}
|
|
1483
|
-
return false;
|
|
1484
|
-
};
|
|
1485
|
-
const blockRefreshes = [...affectedBlockIds].map((id) => {
|
|
1486
|
-
const binding = blockBindings.get(id);
|
|
1487
|
-
const refresh = this.blockRefreshListeners.get(id);
|
|
1488
|
-
return binding && refresh && !hasAffectedMountedAncestor(binding) ? refresh : void 0;
|
|
1489
|
-
}).filter(
|
|
1490
|
-
(refresh) => refresh !== void 0
|
|
1491
|
-
);
|
|
1492
|
-
for (const binding of bindings) {
|
|
1493
|
-
if (binding.kind !== "block" && binding.dependencies.some((dependency) => dirty.has(dependency))) {
|
|
1494
|
-
this.applyBinding(binding);
|
|
3178
|
+
for (const binding of this.staticBindingsByDependency[dependency] || []) {
|
|
3179
|
+
affectedBindings.add(binding);
|
|
3180
|
+
}
|
|
3181
|
+
if (this.usesHybridReactivity()) {
|
|
3182
|
+
for (const binding of this.trackedBindingsByDependency[dependency] || []) {
|
|
3183
|
+
affectedBindings.add(binding);
|
|
1495
3184
|
}
|
|
1496
3185
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
3186
|
+
}
|
|
3187
|
+
const hasAffectedMountedAncestor = (binding) => {
|
|
3188
|
+
let parent = binding.parent;
|
|
3189
|
+
while (parent !== void 0) {
|
|
3190
|
+
if (affectedBlockIds.has(parent) && this.blockRefreshListeners.has(parent)) {
|
|
3191
|
+
return true;
|
|
3192
|
+
}
|
|
3193
|
+
parent = this.blockBindings.get(parent)?.parent;
|
|
1503
3194
|
}
|
|
1504
|
-
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
this.
|
|
3195
|
+
return false;
|
|
3196
|
+
};
|
|
3197
|
+
const blockRefreshes = [...affectedBlockIds].map((id) => {
|
|
3198
|
+
const binding = this.blockBindings.get(id);
|
|
3199
|
+
const refresh = this.blockRefreshListeners.get(id);
|
|
3200
|
+
return binding && refresh && !hasAffectedMountedAncestor(binding) ? refresh : void 0;
|
|
3201
|
+
}).filter((refresh) => refresh !== void 0);
|
|
3202
|
+
for (const binding of affectedBindings) {
|
|
3203
|
+
if (binding.kind !== "block") this.applyBinding(binding);
|
|
1509
3204
|
}
|
|
1510
|
-
|
|
3205
|
+
let pendingBlockCommits = blockRefreshes.length;
|
|
3206
|
+
for (const refresh of blockRefreshes) {
|
|
3207
|
+
refresh(() => {
|
|
3208
|
+
pendingBlockCommits -= 1;
|
|
3209
|
+
if (pendingBlockCommits === 0) this.restoreInputSelection(inputSelection);
|
|
3210
|
+
}, dirty);
|
|
3211
|
+
}
|
|
3212
|
+
if (blockRefreshes.length === 0) this.restoreInputSelection(inputSelection);
|
|
3213
|
+
} catch (error) {
|
|
3214
|
+
this.bindingError = error;
|
|
3215
|
+
this.hasBindingError = true;
|
|
3216
|
+
this.forceUpdate();
|
|
3217
|
+
}
|
|
1511
3218
|
}
|
|
1512
|
-
applyBinding(binding) {
|
|
3219
|
+
applyBinding(binding, force = false) {
|
|
1513
3220
|
if (!this.root || binding.kind === "block") return;
|
|
1514
3221
|
const target = binding.target === void 0 ? findBindingTarget(this.root, binding.path, this.blockRootElements) : binding.path.length === 0 ? this.root : this.bindingTargets.get(binding.target) || null;
|
|
1515
3222
|
if (!target) return;
|
|
1516
|
-
const value =
|
|
3223
|
+
const value = this.readBinding(binding);
|
|
3224
|
+
const comparableValue = this.bindingValue(binding, value);
|
|
3225
|
+
if (!force && this.bindingValues.has(binding)) {
|
|
3226
|
+
if (Object.is(this.bindingValues.get(binding), comparableValue)) return;
|
|
3227
|
+
}
|
|
1517
3228
|
if (binding.kind === "text") {
|
|
1518
|
-
target.textContent =
|
|
3229
|
+
target.textContent = comparableValue;
|
|
1519
3230
|
} else if (binding.kind === "style") {
|
|
1520
3231
|
updateStyle(target, binding.name, value);
|
|
1521
3232
|
} else {
|
|
1522
3233
|
updateAttribute(target, binding.name, value);
|
|
1523
3234
|
}
|
|
3235
|
+
this.bindingValues.set(binding, comparableValue);
|
|
1524
3236
|
}
|
|
1525
3237
|
componentDidMount() {
|
|
1526
3238
|
this.mounted = true;
|
|
1527
3239
|
refreshListeners.add(this.refreshDefinition);
|
|
3240
|
+
this.ensureBindingIndex();
|
|
3241
|
+
this.primeHybridBindings();
|
|
1528
3242
|
}
|
|
1529
|
-
|
|
3243
|
+
getSnapshotBeforeUpdate() {
|
|
3244
|
+
const currentDefinition = definitionReference.current;
|
|
3245
|
+
const propValues = currentDefinition.readProps?.(this.props) || null;
|
|
3246
|
+
return this.canReuseRenderedElement(currentDefinition, propValues);
|
|
3247
|
+
}
|
|
3248
|
+
componentDidUpdate(_previousProps, _previousState, reusedRenderedElement = false) {
|
|
3249
|
+
const propValues = definitionReference.current.readProps?.(this.props) || null;
|
|
3250
|
+
if (propValues) {
|
|
3251
|
+
if (reusedRenderedElement) this.captureInputSelection();
|
|
3252
|
+
for (let propIndex = 0; propIndex < propValues.length; propIndex += 1) {
|
|
3253
|
+
const cellIndex = this.propCellOffset + propIndex;
|
|
3254
|
+
const cell = this.cells[cellIndex];
|
|
3255
|
+
if (!cell) continue;
|
|
3256
|
+
cell.replace(propValues[propIndex]);
|
|
3257
|
+
if (reusedRenderedElement) {
|
|
3258
|
+
this.dirtyState.add(cellIndex);
|
|
3259
|
+
} else {
|
|
3260
|
+
cell.flush();
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
this.flushBindingUpdates();
|
|
3264
|
+
return;
|
|
3265
|
+
}
|
|
3266
|
+
this.ensureBindingIndex();
|
|
1530
3267
|
for (const binding of definitionReference.current.bindings) {
|
|
1531
|
-
if (binding.kind !== "block") this.applyBinding(binding);
|
|
3268
|
+
if (binding.kind !== "block") this.applyBinding(binding, true);
|
|
1532
3269
|
}
|
|
1533
3270
|
}
|
|
1534
3271
|
componentWillUnmount() {
|
|
@@ -1541,36 +3278,68 @@ function createCompiledComponent(definition) {
|
|
|
1541
3278
|
this.blockRootElements.clear();
|
|
1542
3279
|
this.bindingTargets.clear();
|
|
1543
3280
|
this.bindingTargetRefs.clear();
|
|
3281
|
+
this.indexedDefinition = null;
|
|
3282
|
+
this.staticBindingsByDependency = [];
|
|
3283
|
+
this.blockBindingsByDependency = [];
|
|
3284
|
+
this.blockBindings.clear();
|
|
3285
|
+
this.trackedBindingsByDependency = [];
|
|
3286
|
+
this.trackedDependenciesByBinding.clear();
|
|
3287
|
+
this.bindingValues.clear();
|
|
3288
|
+
this.activeBinding = null;
|
|
3289
|
+
this.activeDependencies = null;
|
|
1544
3290
|
refreshListeners.delete(this.refreshDefinition);
|
|
1545
3291
|
}
|
|
1546
3292
|
render() {
|
|
1547
3293
|
if (this.hasBindingError) throw this.bindingError;
|
|
1548
3294
|
const currentDefinition = definitionReference.current;
|
|
1549
|
-
const
|
|
3295
|
+
const propValues = currentDefinition.readProps?.(this.props) || null;
|
|
3296
|
+
if (this.canReuseRenderedElement(currentDefinition, propValues)) {
|
|
3297
|
+
return this.renderedElement;
|
|
3298
|
+
}
|
|
3299
|
+
const renderCells = this.renderCellsForProps(propValues);
|
|
3300
|
+
const element = currentDefinition.render(this.props, renderCells.cells, this.blockRuntime);
|
|
1550
3301
|
if (!React.isValidElement(element)) {
|
|
1551
3302
|
throw new TypeError(
|
|
1552
3303
|
`Compiled component ${currentDefinition.displayName} must return one host element.`
|
|
1553
3304
|
);
|
|
1554
3305
|
}
|
|
3306
|
+
let renderedElement;
|
|
3307
|
+
const captureCommittedRoot = (root) => {
|
|
3308
|
+
this.captureRoot(root);
|
|
3309
|
+
if (!root) return;
|
|
3310
|
+
renderCells.commit();
|
|
3311
|
+
this.renderedDefinition = currentDefinition;
|
|
3312
|
+
this.renderedElement = renderedElement;
|
|
3313
|
+
};
|
|
1555
3314
|
if (element.type === this.blockRuntime.KeyedRanges) {
|
|
1556
|
-
|
|
1557
|
-
rootRef: this.captureRoot
|
|
1558
|
-
});
|
|
1559
|
-
}
|
|
1560
|
-
if (element.type === this.blockRuntime.ConditionalRanges) {
|
|
1561
|
-
return React.cloneElement(
|
|
3315
|
+
renderedElement = React.cloneElement(
|
|
1562
3316
|
element,
|
|
1563
|
-
{
|
|
3317
|
+
{
|
|
3318
|
+
rootRef: captureCommittedRoot
|
|
3319
|
+
}
|
|
1564
3320
|
);
|
|
1565
|
-
}
|
|
1566
|
-
|
|
3321
|
+
} else if (element.type === this.blockRuntime.ConditionalRanges) {
|
|
3322
|
+
renderedElement = React.cloneElement(
|
|
3323
|
+
element,
|
|
3324
|
+
{ rootRef: captureCommittedRoot }
|
|
3325
|
+
);
|
|
3326
|
+
} else if (element.type === this.blockRuntime.MixedRanges) {
|
|
3327
|
+
renderedElement = React.cloneElement(
|
|
3328
|
+
element,
|
|
3329
|
+
{
|
|
3330
|
+
rootRef: captureCommittedRoot
|
|
3331
|
+
}
|
|
3332
|
+
);
|
|
3333
|
+
} else if (typeof element.type !== "string") {
|
|
1567
3334
|
throw new TypeError(
|
|
1568
3335
|
`Compiled component ${currentDefinition.displayName} must return one host element.`
|
|
1569
3336
|
);
|
|
3337
|
+
} else {
|
|
3338
|
+
renderedElement = React.cloneElement(element, {
|
|
3339
|
+
ref: captureCommittedRoot
|
|
3340
|
+
});
|
|
1570
3341
|
}
|
|
1571
|
-
return
|
|
1572
|
-
ref: this.captureRoot
|
|
1573
|
-
});
|
|
3342
|
+
return renderedElement;
|
|
1574
3343
|
}
|
|
1575
3344
|
}
|
|
1576
3345
|
FarmCompiledComponent.displayName = `FarmCompiled(${definition.displayName})`;
|