@barefootjs/client 0.26.4 → 0.28.0
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/dist/reactive.d.ts.map +1 -1
- package/dist/runtime/claim-slots.d.ts +222 -0
- package/dist/runtime/claim-slots.d.ts.map +1 -0
- package/dist/runtime/component.d.ts +40 -18
- package/dist/runtime/component.d.ts.map +1 -1
- package/dist/runtime/dynamic-text.d.ts +24 -1
- package/dist/runtime/dynamic-text.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +4 -5
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +467 -259
- package/dist/runtime/loop-markers.d.ts +26 -0
- package/dist/runtime/loop-markers.d.ts.map +1 -0
- package/dist/runtime/map-array-lazy.d.ts +164 -0
- package/dist/runtime/map-array-lazy.d.ts.map +1 -0
- package/dist/runtime/map-array.d.ts +35 -0
- package/dist/runtime/map-array.d.ts.map +1 -1
- package/dist/runtime/qsa-item.d.ts +7 -0
- package/dist/runtime/qsa-item.d.ts.map +1 -1
- package/dist/runtime/registry.d.ts.map +1 -1
- package/dist/runtime/standalone.js +455 -248
- package/package.json +2 -2
- package/src/reactive.ts +2 -1
- package/src/runtime/claim-slots.ts +647 -0
- package/src/runtime/component.ts +153 -70
- package/src/runtime/dynamic-text.ts +24 -1
- package/src/runtime/index.ts +20 -7
- package/src/runtime/insert.ts +1 -1
- package/src/runtime/loop-markers.ts +100 -0
- package/src/runtime/map-array-lazy.ts +470 -0
- package/src/runtime/map-array.ts +68 -11
- package/src/runtime/qsa-item.ts +9 -3
- package/src/runtime/registry.ts +5 -3
- package/dist/runtime/client-marker.d.ts +0 -21
- package/dist/runtime/client-marker.d.ts.map +0 -1
- package/dist/runtime/list.d.ts +0 -21
- package/dist/runtime/list.d.ts.map +0 -1
- package/dist/runtime/patch-slot-range.d.ts +0 -47
- package/dist/runtime/patch-slot-range.d.ts.map +0 -1
- package/dist/runtime/reconcile-elements.d.ts +0 -44
- package/dist/runtime/reconcile-elements.d.ts.map +0 -1
- package/src/runtime/client-marker.ts +0 -46
- package/src/runtime/list.ts +0 -47
- package/src/runtime/patch-slot-range.ts +0 -105
- package/src/runtime/reconcile-elements.ts +0 -391
package/dist/runtime/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// src/runtime/index.ts
|
|
2
2
|
import {
|
|
3
|
-
createSignal as
|
|
4
|
-
createEffect as
|
|
3
|
+
createSignal as createSignal3,
|
|
4
|
+
createEffect as createEffect5,
|
|
5
5
|
createDisposableEffect,
|
|
6
6
|
createMemo,
|
|
7
7
|
createSelector,
|
|
8
8
|
createRoot as createRoot3,
|
|
9
9
|
onCleanup,
|
|
10
10
|
onMount,
|
|
11
|
-
untrack as
|
|
11
|
+
untrack as untrack4,
|
|
12
12
|
batch,
|
|
13
13
|
setProfilerSink,
|
|
14
14
|
beginTurn,
|
|
@@ -1142,9 +1142,7 @@ function upsertChild(parent, name, slotId, props, key, anchorScope) {
|
|
|
1142
1142
|
const ph = parent.getAttribute(BF_PLACEHOLDER) === phId ? parent : parent.querySelector(`[${BF_PLACEHOLDER}="${phId}"]`);
|
|
1143
1143
|
if (ph) {
|
|
1144
1144
|
const slot = slotId ? buildSlotInfo(parent, slotId, anchorScope) : undefined;
|
|
1145
|
-
|
|
1146
|
-
ph.replaceWith(comp);
|
|
1147
|
-
return comp;
|
|
1145
|
+
return createComponent(name, props, key, slot, ph);
|
|
1148
1146
|
}
|
|
1149
1147
|
return null;
|
|
1150
1148
|
}
|
|
@@ -1352,13 +1350,30 @@ var _parentScopeId = null;
|
|
|
1352
1350
|
function setParentScopeId(id) {
|
|
1353
1351
|
_parentScopeId = id;
|
|
1354
1352
|
}
|
|
1355
|
-
var
|
|
1356
|
-
|
|
1357
|
-
|
|
1353
|
+
var _rowMountPoint = null;
|
|
1354
|
+
function setRowMountPoint(p) {
|
|
1355
|
+
const prev = _rowMountPoint;
|
|
1356
|
+
_rowMountPoint = p;
|
|
1357
|
+
return prev;
|
|
1358
|
+
}
|
|
1359
|
+
function takeRowMountPoint() {
|
|
1360
|
+
const p = _rowMountPoint;
|
|
1361
|
+
_rowMountPoint = null;
|
|
1362
|
+
return p;
|
|
1363
|
+
}
|
|
1364
|
+
function createComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
1365
|
+
const element = materializeComponent(nameOrDef, props, key, slot, mountAt);
|
|
1366
|
+
if (mountAt && mountAt.parentNode && element !== mountAt) {
|
|
1367
|
+
mountAt.replaceWith(element);
|
|
1368
|
+
}
|
|
1369
|
+
return element;
|
|
1370
|
+
}
|
|
1371
|
+
function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
1358
1372
|
if (props == null)
|
|
1359
1373
|
props = {};
|
|
1374
|
+
const rowMount = mountAt ? null : takeRowMountPoint();
|
|
1360
1375
|
if (typeof nameOrDef !== "string") {
|
|
1361
|
-
return createComponentFromDef(nameOrDef, props, key);
|
|
1376
|
+
return createComponentFromDef(nameOrDef, props, key, mountAt, rowMount);
|
|
1362
1377
|
}
|
|
1363
1378
|
const name = nameOrDef;
|
|
1364
1379
|
const templateFn = getTemplate(name);
|
|
@@ -1418,8 +1433,13 @@ function createComponent(nameOrDef, props = {}, key, slot) {
|
|
|
1418
1433
|
if (key !== undefined) {
|
|
1419
1434
|
element.setAttribute(BF_KEY, String(key));
|
|
1420
1435
|
}
|
|
1421
|
-
const prevScope = setCurrentScope(element);
|
|
1422
1436
|
const rootIsDeferredPlaceholder = element.hasAttribute(BF_PLACEHOLDER);
|
|
1437
|
+
if (mountAt && !rootIsDeferredPlaceholder) {
|
|
1438
|
+
mountAt.replaceWith(element);
|
|
1439
|
+
} else if (rowMount && !rootIsDeferredPlaceholder) {
|
|
1440
|
+
rowMount.container.insertBefore(element, rowMount.anchor);
|
|
1441
|
+
}
|
|
1442
|
+
const prevScope = setCurrentScope(element);
|
|
1423
1443
|
let placeholderWrapper = null;
|
|
1424
1444
|
if (rootIsDeferredPlaceholder) {
|
|
1425
1445
|
placeholderWrapper = parseHTML("<div></div>").firstChild;
|
|
@@ -1445,24 +1465,8 @@ function createComponent(nameOrDef, props = {}, key, slot) {
|
|
|
1445
1465
|
}
|
|
1446
1466
|
setCurrentScope(prevScope);
|
|
1447
1467
|
hydratedScopes.add(element);
|
|
1448
|
-
propsMap.set(element, props);
|
|
1449
|
-
registerPropsUpdate(element, name, props);
|
|
1450
1468
|
return element;
|
|
1451
1469
|
}
|
|
1452
|
-
function getComponentProps(element) {
|
|
1453
|
-
return propsMap.get(element);
|
|
1454
|
-
}
|
|
1455
|
-
function registerPropsUpdate(element, name, _initialProps) {
|
|
1456
|
-
propsUpdateMap.set(element, (newProps) => {
|
|
1457
|
-
const init = getComponentInit(name);
|
|
1458
|
-
if (init) {
|
|
1459
|
-
init(element, newProps);
|
|
1460
|
-
}
|
|
1461
|
-
});
|
|
1462
|
-
}
|
|
1463
|
-
function getPropsUpdateFn(element) {
|
|
1464
|
-
return propsUpdateMap.get(element);
|
|
1465
|
-
}
|
|
1466
1470
|
function renderChild(name, props, key, slotSuffix) {
|
|
1467
1471
|
const templateFn = getTemplate(name);
|
|
1468
1472
|
const suffix = slotSuffix ? `_${slotSuffix}` : "";
|
|
@@ -1528,6 +1532,11 @@ function escapeText(value) {
|
|
|
1528
1532
|
return "";
|
|
1529
1533
|
return escapeAttr(value);
|
|
1530
1534
|
}
|
|
1535
|
+
function escapeTextOrNode(value) {
|
|
1536
|
+
if (typeof Node !== "undefined" && value instanceof Node)
|
|
1537
|
+
return value;
|
|
1538
|
+
return escapeText(value);
|
|
1539
|
+
}
|
|
1531
1540
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1532
1541
|
function parseHTML(html, parent) {
|
|
1533
1542
|
const tpl = document.createElement("template");
|
|
@@ -1571,7 +1580,7 @@ function insertGetterChildren(element, children) {
|
|
|
1571
1580
|
element.appendChild(document.createTextNode(String(children)));
|
|
1572
1581
|
}
|
|
1573
1582
|
}
|
|
1574
|
-
function createComponentFromDef(def, props, key) {
|
|
1583
|
+
function createComponentFromDef(def, props, key, mountAt, rowMount) {
|
|
1575
1584
|
if (!def.template) {
|
|
1576
1585
|
throw new Error("[BarefootJS] createComponent with ComponentDef requires a template function");
|
|
1577
1586
|
}
|
|
@@ -1590,9 +1599,13 @@ function createComponentFromDef(def, props, key) {
|
|
|
1590
1599
|
if (key !== undefined) {
|
|
1591
1600
|
element.setAttribute(BF_KEY, String(key));
|
|
1592
1601
|
}
|
|
1602
|
+
if (mountAt) {
|
|
1603
|
+
mountAt.replaceWith(element);
|
|
1604
|
+
} else if (rowMount) {
|
|
1605
|
+
rowMount.container.insertBefore(element, rowMount.anchor);
|
|
1606
|
+
}
|
|
1593
1607
|
def.init(element, props);
|
|
1594
1608
|
hydratedScopes.add(element);
|
|
1595
|
-
propsMap.set(element, props);
|
|
1596
1609
|
return element;
|
|
1597
1610
|
}
|
|
1598
1611
|
|
|
@@ -1650,7 +1663,7 @@ function createPortal(children, container = document.body, options) {
|
|
|
1650
1663
|
}
|
|
1651
1664
|
};
|
|
1652
1665
|
}
|
|
1653
|
-
// src/runtime/
|
|
1666
|
+
// src/runtime/loop-markers.ts
|
|
1654
1667
|
function findLoopMarkers(container, markerId) {
|
|
1655
1668
|
let startMarker = null;
|
|
1656
1669
|
let endMarker = null;
|
|
@@ -1695,14 +1708,6 @@ function getElementsBetweenMarkers(start, end) {
|
|
|
1695
1708
|
}
|
|
1696
1709
|
return elements;
|
|
1697
1710
|
}
|
|
1698
|
-
function removeElementsBetweenMarkers(start, end) {
|
|
1699
|
-
let node = start.nextSibling;
|
|
1700
|
-
while (node && node !== end) {
|
|
1701
|
-
const next = node.nextSibling;
|
|
1702
|
-
node.parentNode?.removeChild(node);
|
|
1703
|
-
node = next;
|
|
1704
|
-
}
|
|
1705
|
-
}
|
|
1706
1711
|
function getLoopChildren(container, markerId) {
|
|
1707
1712
|
const { startMarker, endMarker } = findLoopMarkers(container, markerId);
|
|
1708
1713
|
if (startMarker && endMarker) {
|
|
@@ -1723,159 +1728,6 @@ function getLoopNodes(container, markerId) {
|
|
|
1723
1728
|
}
|
|
1724
1729
|
return Array.from(container.childNodes);
|
|
1725
1730
|
}
|
|
1726
|
-
function reconcileElements(container, items, getKey, renderItem, firstElement, markerId) {
|
|
1727
|
-
if (!container || !items)
|
|
1728
|
-
return;
|
|
1729
|
-
const { startMarker, endMarker } = findLoopMarkers(container, markerId);
|
|
1730
|
-
const existingByKey = new Map;
|
|
1731
|
-
let hasKeyedChildren = false;
|
|
1732
|
-
const loopChildren = startMarker ? getElementsBetweenMarkers(startMarker, endMarker) : Array.from(container.children);
|
|
1733
|
-
for (const child of loopChildren) {
|
|
1734
|
-
const el = child;
|
|
1735
|
-
const key = el.dataset?.key;
|
|
1736
|
-
if (key !== undefined) {
|
|
1737
|
-
existingByKey.set(key, el);
|
|
1738
|
-
hasKeyedChildren = true;
|
|
1739
|
-
}
|
|
1740
|
-
}
|
|
1741
|
-
if (!hasKeyedChildren) {
|
|
1742
|
-
if (items.length === 0) {
|
|
1743
|
-
if (startMarker) {
|
|
1744
|
-
removeElementsBetweenMarkers(startMarker, endMarker);
|
|
1745
|
-
} else {
|
|
1746
|
-
container.innerHTML = "";
|
|
1747
|
-
}
|
|
1748
|
-
return;
|
|
1749
|
-
}
|
|
1750
|
-
const fragment = document.createDocumentFragment();
|
|
1751
|
-
for (let i = 0;i < items.length; i++) {
|
|
1752
|
-
const el = i === 0 && firstElement ? firstElement : renderItem(items[i], i);
|
|
1753
|
-
const key = getKey ? getKey(items[i], i) : String(i);
|
|
1754
|
-
if (!el.dataset.key)
|
|
1755
|
-
el.setAttribute(BF_KEY, key);
|
|
1756
|
-
fragment.appendChild(el);
|
|
1757
|
-
}
|
|
1758
|
-
if (startMarker) {
|
|
1759
|
-
removeElementsBetweenMarkers(startMarker, endMarker);
|
|
1760
|
-
endMarker.parentNode.insertBefore(fragment, endMarker);
|
|
1761
|
-
} else {
|
|
1762
|
-
container.innerHTML = "";
|
|
1763
|
-
container.appendChild(fragment);
|
|
1764
|
-
}
|
|
1765
|
-
return;
|
|
1766
|
-
}
|
|
1767
|
-
let insertAnchor = endMarker ?? null;
|
|
1768
|
-
if (!startMarker) {
|
|
1769
|
-
let foundKeyed = false;
|
|
1770
|
-
for (const child of Array.from(container.childNodes)) {
|
|
1771
|
-
if (child.nodeType === Node.ELEMENT_NODE && child.dataset.key !== undefined) {
|
|
1772
|
-
foundKeyed = true;
|
|
1773
|
-
} else if (foundKeyed) {
|
|
1774
|
-
insertAnchor = child;
|
|
1775
|
-
break;
|
|
1776
|
-
}
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
let focusedKey = null;
|
|
1780
|
-
const activeEl = document.activeElement;
|
|
1781
|
-
if (activeEl && activeEl !== document.body) {
|
|
1782
|
-
const tag = activeEl.tagName;
|
|
1783
|
-
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || activeEl.isContentEditable) {
|
|
1784
|
-
for (const [key, el] of existingByKey) {
|
|
1785
|
-
if (el.contains(activeEl)) {
|
|
1786
|
-
focusedKey = key;
|
|
1787
|
-
break;
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
}
|
|
1792
|
-
const desiredElements = [];
|
|
1793
|
-
const toRemove = [];
|
|
1794
|
-
let focusTarget = null;
|
|
1795
|
-
for (let i = 0;i < items.length; i++) {
|
|
1796
|
-
const item = items[i];
|
|
1797
|
-
const key = getKey ? getKey(item, i) : String(i);
|
|
1798
|
-
const createEl = () => i === 0 && firstElement ? firstElement : renderItem(item, i);
|
|
1799
|
-
const existing = existingByKey.get(key);
|
|
1800
|
-
if (existing) {
|
|
1801
|
-
existingByKey.delete(key);
|
|
1802
|
-
if (existing.getAttribute(BF_SCOPE) && !hydratedScopes.has(existing)) {
|
|
1803
|
-
const newEl = createEl();
|
|
1804
|
-
if (!newEl.dataset.key)
|
|
1805
|
-
newEl.setAttribute(BF_KEY, key);
|
|
1806
|
-
desiredElements.push(newEl);
|
|
1807
|
-
toRemove.push(existing);
|
|
1808
|
-
} else if (focusedKey === key) {
|
|
1809
|
-
const newEl = createEl();
|
|
1810
|
-
if (!newEl.dataset.key)
|
|
1811
|
-
newEl.setAttribute(BF_KEY, key);
|
|
1812
|
-
focusTarget = prepareInputTransfer(existing, newEl);
|
|
1813
|
-
desiredElements.push(newEl);
|
|
1814
|
-
toRemove.push(existing);
|
|
1815
|
-
} else {
|
|
1816
|
-
const newEl = createEl();
|
|
1817
|
-
if (!newEl.dataset.key)
|
|
1818
|
-
newEl.setAttribute(BF_KEY, key);
|
|
1819
|
-
desiredElements.push(newEl);
|
|
1820
|
-
toRemove.push(existing);
|
|
1821
|
-
}
|
|
1822
|
-
} else {
|
|
1823
|
-
const el = createEl();
|
|
1824
|
-
if (!el.dataset.key)
|
|
1825
|
-
el.setAttribute(BF_KEY, key);
|
|
1826
|
-
desiredElements.push(el);
|
|
1827
|
-
}
|
|
1828
|
-
}
|
|
1829
|
-
for (const el of existingByKey.values()) {
|
|
1830
|
-
toRemove.push(el);
|
|
1831
|
-
}
|
|
1832
|
-
for (const el of toRemove) {
|
|
1833
|
-
if (el.parentNode)
|
|
1834
|
-
el.remove();
|
|
1835
|
-
}
|
|
1836
|
-
for (const el of desiredElements) {
|
|
1837
|
-
container.insertBefore(el, insertAnchor);
|
|
1838
|
-
}
|
|
1839
|
-
if (focusTarget) {
|
|
1840
|
-
focusTarget.target.focus();
|
|
1841
|
-
if (typeof focusTarget.selectionStart === "number") {
|
|
1842
|
-
focusTarget.target.selectionStart = focusTarget.selectionStart;
|
|
1843
|
-
focusTarget.target.selectionEnd = focusTarget.selectionEnd;
|
|
1844
|
-
}
|
|
1845
|
-
}
|
|
1846
|
-
}
|
|
1847
|
-
function prepareInputTransfer(oldEl, newEl) {
|
|
1848
|
-
const focused = oldEl.contains(document.activeElement) ? document.activeElement : null;
|
|
1849
|
-
if (!focused)
|
|
1850
|
-
return null;
|
|
1851
|
-
const tag = focused.tagName;
|
|
1852
|
-
const oldInputs = Array.from(oldEl.querySelectorAll(tag));
|
|
1853
|
-
const idx = oldInputs.indexOf(focused);
|
|
1854
|
-
if (idx < 0)
|
|
1855
|
-
return null;
|
|
1856
|
-
const newInputs = Array.from(newEl.querySelectorAll(tag));
|
|
1857
|
-
const target = newInputs[idx];
|
|
1858
|
-
if (!target)
|
|
1859
|
-
return null;
|
|
1860
|
-
target.value = focused.value;
|
|
1861
|
-
return {
|
|
1862
|
-
target,
|
|
1863
|
-
selectionStart: focused.selectionStart,
|
|
1864
|
-
selectionEnd: focused.selectionEnd
|
|
1865
|
-
};
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
// src/runtime/list.ts
|
|
1869
|
-
function reconcileList(container, items, getKey, renderItem) {
|
|
1870
|
-
if (!container || !items)
|
|
1871
|
-
return;
|
|
1872
|
-
if (items.length === 0) {
|
|
1873
|
-
container.innerHTML = "";
|
|
1874
|
-
return;
|
|
1875
|
-
}
|
|
1876
|
-
const firstElement = renderItem(items[0], 0);
|
|
1877
|
-
reconcileElements(container, items, getKey, renderItem, firstElement);
|
|
1878
|
-
}
|
|
1879
1731
|
// src/runtime/qsa-item.ts
|
|
1880
1732
|
function* itemRootElements(primaryEl) {
|
|
1881
1733
|
yield primaryEl;
|
|
@@ -1932,9 +1784,7 @@ function upsertChildItem(primaryEl, name, slotId, props, key, anchorScope) {
|
|
|
1932
1784
|
const ph = qsaItem(primaryEl, `[data-bf-ph="${phId}"]`);
|
|
1933
1785
|
if (ph) {
|
|
1934
1786
|
const slot = slotId ? buildSlotInfo(primaryEl, slotId, anchorScope) : undefined;
|
|
1935
|
-
|
|
1936
|
-
ph.replaceWith(comp);
|
|
1937
|
-
return comp;
|
|
1787
|
+
return createComponent(name, props, key, slot, ph);
|
|
1938
1788
|
}
|
|
1939
1789
|
return null;
|
|
1940
1790
|
}
|
|
@@ -2047,7 +1897,7 @@ function removeScope(scope) {
|
|
|
2047
1897
|
ex.remove();
|
|
2048
1898
|
}
|
|
2049
1899
|
}
|
|
2050
|
-
function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart) {
|
|
1900
|
+
function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart, rowMount) {
|
|
2051
1901
|
let primaryEl;
|
|
2052
1902
|
let dispose;
|
|
2053
1903
|
let setItem;
|
|
@@ -2057,7 +1907,14 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
2057
1907
|
dispose = d;
|
|
2058
1908
|
const [itemAccessor, itemSetter] = createSignal(item);
|
|
2059
1909
|
setItem = itemSetter;
|
|
2060
|
-
|
|
1910
|
+
const ownsRowMount = !existingPrimary && !!rowMount;
|
|
1911
|
+
const prevRowMount = ownsRowMount ? setRowMountPoint(rowMount) : null;
|
|
1912
|
+
try {
|
|
1913
|
+
primaryEl = renderItem(itemAccessor, index, existingPrimary);
|
|
1914
|
+
} finally {
|
|
1915
|
+
if (ownsRowMount)
|
|
1916
|
+
setRowMountPoint(prevRowMount);
|
|
1917
|
+
}
|
|
2061
1918
|
if (existingPrimary) {
|
|
2062
1919
|
extras = existingExtras ?? [];
|
|
2063
1920
|
startMarker = existingStart ?? null;
|
|
@@ -2071,6 +1928,9 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
2071
1928
|
}
|
|
2072
1929
|
return;
|
|
2073
1930
|
});
|
|
1931
|
+
if (rowMount && !existingPrimary && extras.length > 0 && primaryEl.parentNode) {
|
|
1932
|
+
primaryEl.remove();
|
|
1933
|
+
}
|
|
2074
1934
|
return { startMarker, primaryEl, extras, dispose, setItem };
|
|
2075
1935
|
}
|
|
2076
1936
|
function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
@@ -2112,7 +1972,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2112
1972
|
for (let i2 = existingRanges.length;i2 < items.length; i2++) {
|
|
2113
1973
|
const item = items[i2];
|
|
2114
1974
|
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2115
|
-
const scope = createItemScope(item, i2, renderItem);
|
|
1975
|
+
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
|
|
2116
1976
|
if (!scope.primaryEl.dataset.key)
|
|
2117
1977
|
scope.primaryEl.setAttribute(BF_KEY, key);
|
|
2118
1978
|
scopes.set(key, scope);
|
|
@@ -2191,7 +2051,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2191
2051
|
existing.setItem(item);
|
|
2192
2052
|
desiredOrder.push(existing);
|
|
2193
2053
|
} else {
|
|
2194
|
-
const scope = createItemScope(item, i2, renderItem);
|
|
2054
|
+
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
|
|
2195
2055
|
if (!scope.primaryEl.dataset.key)
|
|
2196
2056
|
scope.primaryEl.setAttribute(BF_KEY, key);
|
|
2197
2057
|
scopes.set(key, scope);
|
|
@@ -2387,6 +2247,198 @@ function mapArrayAnchored(accessor, container, getKey, renderItem, markerId, bfI
|
|
|
2387
2247
|
}
|
|
2388
2248
|
}, bfId);
|
|
2389
2249
|
}
|
|
2250
|
+
// src/runtime/map-array-lazy.ts
|
|
2251
|
+
import { createEffect as createEffect2, createSignal as createSignal2, untrack as untrack2 } from "@barefootjs/client/reactive";
|
|
2252
|
+
function mapArrayLazy(accessor, container, getKey, plan, markerId, bfId) {
|
|
2253
|
+
if (!container)
|
|
2254
|
+
return;
|
|
2255
|
+
const entries = new Map;
|
|
2256
|
+
let entryList = [];
|
|
2257
|
+
let hydrated = false;
|
|
2258
|
+
const needsResubscribe = plan.applyOuter !== undefined;
|
|
2259
|
+
const [generation, bumpGeneration] = needsResubscribe ? createSignal2(0) : [null, null];
|
|
2260
|
+
let stranded = false;
|
|
2261
|
+
const markStranded = () => {
|
|
2262
|
+
if (needsResubscribe)
|
|
2263
|
+
stranded = true;
|
|
2264
|
+
};
|
|
2265
|
+
const flushStranded = () => {
|
|
2266
|
+
if (stranded && bumpGeneration) {
|
|
2267
|
+
stranded = false;
|
|
2268
|
+
bumpGeneration((n) => n + 1);
|
|
2269
|
+
}
|
|
2270
|
+
};
|
|
2271
|
+
let cachedStart = null;
|
|
2272
|
+
let cachedEnd = null;
|
|
2273
|
+
const resolveMarkers = () => {
|
|
2274
|
+
if (cachedStart && cachedEnd && cachedStart.isConnected && cachedEnd.isConnected) {
|
|
2275
|
+
return { start: cachedStart, end: cachedEnd };
|
|
2276
|
+
}
|
|
2277
|
+
const found = findLoopMarkers2(container, markerId);
|
|
2278
|
+
cachedStart = found.start;
|
|
2279
|
+
cachedEnd = found.end;
|
|
2280
|
+
return found;
|
|
2281
|
+
};
|
|
2282
|
+
const createEntry = (item, index, key) => {
|
|
2283
|
+
const entry = {
|
|
2284
|
+
key,
|
|
2285
|
+
primaryEl: undefined,
|
|
2286
|
+
item,
|
|
2287
|
+
refs: null,
|
|
2288
|
+
last: null
|
|
2289
|
+
};
|
|
2290
|
+
entry.primaryEl = untrack2(() => plan.createRow(entry, index));
|
|
2291
|
+
if (!entry.primaryEl.dataset.key)
|
|
2292
|
+
entry.primaryEl.setAttribute(BF_KEY, key);
|
|
2293
|
+
markStranded();
|
|
2294
|
+
return entry;
|
|
2295
|
+
};
|
|
2296
|
+
createEffect2(() => {
|
|
2297
|
+
const items = accessor();
|
|
2298
|
+
if (!items)
|
|
2299
|
+
return;
|
|
2300
|
+
const { start: startMarker, end: endMarker } = resolveMarkers();
|
|
2301
|
+
const anchor = endMarker ?? null;
|
|
2302
|
+
if (!hydrated) {
|
|
2303
|
+
hydrated = true;
|
|
2304
|
+
const doms = [];
|
|
2305
|
+
for (let node = startMarker ? startMarker.nextSibling : container.firstChild;node && node !== anchor; node = node.nextSibling) {
|
|
2306
|
+
if (node.nodeType === Node.ELEMENT_NODE)
|
|
2307
|
+
doms.push(node);
|
|
2308
|
+
}
|
|
2309
|
+
if (doms.length > 0 && entries.size === 0) {
|
|
2310
|
+
const list = [];
|
|
2311
|
+
const shared = Math.min(doms.length, items.length);
|
|
2312
|
+
for (let i2 = 0;i2 < shared; i2++) {
|
|
2313
|
+
const el = doms[i2];
|
|
2314
|
+
const ssrKey = el.getAttribute(BF_KEY);
|
|
2315
|
+
const key = ssrKey !== null ? ssrKey : getKey ? getKey(items[i2], i2) : String(i2);
|
|
2316
|
+
const entry = { key, primaryEl: el, item: items[i2], refs: null, last: null };
|
|
2317
|
+
entries.set(key, entry);
|
|
2318
|
+
list.push(entry);
|
|
2319
|
+
}
|
|
2320
|
+
for (let i2 = doms.length;i2 < items.length; i2++) {
|
|
2321
|
+
const item = items[i2];
|
|
2322
|
+
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2323
|
+
const entry = createEntry(item, i2, key);
|
|
2324
|
+
entries.set(key, entry);
|
|
2325
|
+
list.push(entry);
|
|
2326
|
+
container.insertBefore(entry.primaryEl, anchor);
|
|
2327
|
+
}
|
|
2328
|
+
for (let i2 = items.length;i2 < doms.length; i2++)
|
|
2329
|
+
doms[i2].remove();
|
|
2330
|
+
entryList = list;
|
|
2331
|
+
flushStranded();
|
|
2332
|
+
return;
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
if (items.length === 0) {
|
|
2336
|
+
if (entries.size > 0) {
|
|
2337
|
+
if (startMarker && endMarker) {
|
|
2338
|
+
const range = document.createRange();
|
|
2339
|
+
range.setStartAfter(startMarker);
|
|
2340
|
+
range.setEndBefore(endMarker);
|
|
2341
|
+
range.deleteContents();
|
|
2342
|
+
} else {
|
|
2343
|
+
let actualNodeCount = 0;
|
|
2344
|
+
for (let node = container.firstChild;node; node = node.nextSibling)
|
|
2345
|
+
actualNodeCount++;
|
|
2346
|
+
if (actualNodeCount === entries.size) {
|
|
2347
|
+
container.textContent = "";
|
|
2348
|
+
} else {
|
|
2349
|
+
for (const entry of entries.values())
|
|
2350
|
+
entry.primaryEl.remove();
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
entries.clear();
|
|
2354
|
+
entryList = [];
|
|
2355
|
+
}
|
|
2356
|
+
return;
|
|
2357
|
+
}
|
|
2358
|
+
const newKeys = new Set;
|
|
2359
|
+
const warnedKeys = new Set;
|
|
2360
|
+
const desiredOrder = [];
|
|
2361
|
+
for (let i2 = 0;i2 < items.length; i2++) {
|
|
2362
|
+
const item = items[i2];
|
|
2363
|
+
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2364
|
+
if (newKeys.has(key) && !warnedKeys.has(key)) {
|
|
2365
|
+
warnedKeys.add(key);
|
|
2366
|
+
console.warn(`[BarefootJS] mapArrayLazy: duplicate key "${key}" — items with this key collapse to a single DOM row, ` + `so only the last one renders. Use a per-item identifier (e.g. \`key={item.id}\`) for correct reconciliation.`);
|
|
2367
|
+
}
|
|
2368
|
+
newKeys.add(key);
|
|
2369
|
+
const existing = entries.get(key);
|
|
2370
|
+
if (existing) {
|
|
2371
|
+
if (!Object.is(existing.item, item)) {
|
|
2372
|
+
const prevItem = existing.item;
|
|
2373
|
+
existing.item = item;
|
|
2374
|
+
untrack2(() => plan.applyItem(existing, prevItem));
|
|
2375
|
+
markStranded();
|
|
2376
|
+
}
|
|
2377
|
+
desiredOrder.push(existing);
|
|
2378
|
+
} else {
|
|
2379
|
+
const entry = createEntry(item, i2, key);
|
|
2380
|
+
entries.set(key, entry);
|
|
2381
|
+
desiredOrder.push(entry);
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
for (const [key, entry] of entries) {
|
|
2385
|
+
if (!newKeys.has(key)) {
|
|
2386
|
+
if (entry.primaryEl.parentNode)
|
|
2387
|
+
entry.primaryEl.remove();
|
|
2388
|
+
entries.delete(key);
|
|
2389
|
+
}
|
|
2390
|
+
}
|
|
2391
|
+
const primaryElToDesiredIndex = new Map;
|
|
2392
|
+
for (let i2 = 0;i2 < desiredOrder.length; i2++) {
|
|
2393
|
+
primaryElToDesiredIndex.set(desiredOrder[i2].primaryEl, i2);
|
|
2394
|
+
}
|
|
2395
|
+
const domOrderIndices = [];
|
|
2396
|
+
for (let node = startMarker ? startMarker.nextSibling : container.firstChild;node && node !== anchor; node = node.nextSibling) {
|
|
2397
|
+
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
2398
|
+
continue;
|
|
2399
|
+
const idx = primaryElToDesiredIndex.get(node);
|
|
2400
|
+
if (idx !== undefined)
|
|
2401
|
+
domOrderIndices.push(idx);
|
|
2402
|
+
}
|
|
2403
|
+
const stationary = new Array(desiredOrder.length).fill(false);
|
|
2404
|
+
for (const pos of longestIncreasingSubsequenceIndices(domOrderIndices)) {
|
|
2405
|
+
stationary[domOrderIndices[pos]] = true;
|
|
2406
|
+
}
|
|
2407
|
+
let i = 0;
|
|
2408
|
+
while (i < desiredOrder.length) {
|
|
2409
|
+
if (stationary[i]) {
|
|
2410
|
+
i++;
|
|
2411
|
+
continue;
|
|
2412
|
+
}
|
|
2413
|
+
let j = i;
|
|
2414
|
+
while (j < desiredOrder.length && !stationary[j])
|
|
2415
|
+
j++;
|
|
2416
|
+
const before = j < desiredOrder.length ? desiredOrder[j].primaryEl : anchor;
|
|
2417
|
+
if (j - i === 1) {
|
|
2418
|
+
container.insertBefore(desiredOrder[i].primaryEl, before);
|
|
2419
|
+
} else {
|
|
2420
|
+
const runFragment = document.createDocumentFragment();
|
|
2421
|
+
for (let k = i;k < j; k++)
|
|
2422
|
+
runFragment.appendChild(desiredOrder[k].primaryEl);
|
|
2423
|
+
container.insertBefore(runFragment, before);
|
|
2424
|
+
}
|
|
2425
|
+
i = j;
|
|
2426
|
+
}
|
|
2427
|
+
entryList = desiredOrder;
|
|
2428
|
+
flushStranded();
|
|
2429
|
+
}, bfId);
|
|
2430
|
+
if (plan.applyOuter) {
|
|
2431
|
+
const applyOuter = plan.applyOuter.bind(plan);
|
|
2432
|
+
let seed = true;
|
|
2433
|
+
createEffect2(() => {
|
|
2434
|
+
if (generation)
|
|
2435
|
+
generation();
|
|
2436
|
+
const isSeed = seed;
|
|
2437
|
+
seed = false;
|
|
2438
|
+
applyOuter(entryList, isSeed);
|
|
2439
|
+
});
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2390
2442
|
// src/runtime/patch-leaf.ts
|
|
2391
2443
|
function patchLeaf(el, html) {
|
|
2392
2444
|
const tpl = document.createElement("template");
|
|
@@ -2412,35 +2464,44 @@ function patchLeaf(el, html) {
|
|
|
2412
2464
|
}
|
|
2413
2465
|
el.replaceChildren(...Array.from(next.childNodes));
|
|
2414
2466
|
}
|
|
2415
|
-
// src/runtime/
|
|
2416
|
-
function
|
|
2467
|
+
// src/runtime/claim-slots.ts
|
|
2468
|
+
function resolvePath(root, path) {
|
|
2469
|
+
let node = root;
|
|
2470
|
+
for (const index of path) {
|
|
2471
|
+
const child = node.childNodes[index];
|
|
2472
|
+
if (!child)
|
|
2473
|
+
return null;
|
|
2474
|
+
node = child;
|
|
2475
|
+
}
|
|
2476
|
+
return node;
|
|
2477
|
+
}
|
|
2478
|
+
function isSlotComment(node, id) {
|
|
2479
|
+
return node != null && node.nodeType === Node.COMMENT_NODE && node.nodeValue === `bf:${id}`;
|
|
2480
|
+
}
|
|
2481
|
+
function findOwnedMarker(root, id) {
|
|
2417
2482
|
const marker = `bf:${id}`;
|
|
2418
|
-
|
|
2419
|
-
const
|
|
2420
|
-
|
|
2421
|
-
|
|
2483
|
+
const parentOwned = id.startsWith(BF_PARENT_OWNED_PREFIX);
|
|
2484
|
+
const registryInfo = commentScopeRegistry.get(root);
|
|
2485
|
+
const boundary = registryInfo ? registryInfo.commentNode.parentElement : root;
|
|
2486
|
+
for (const comment of commentsInScope(root)) {
|
|
2422
2487
|
if (comment.nodeValue !== marker)
|
|
2423
2488
|
continue;
|
|
2489
|
+
if (parentOwned)
|
|
2490
|
+
return comment;
|
|
2424
2491
|
let owned = true;
|
|
2425
|
-
for (let el = comment.parentElement;el && el !==
|
|
2492
|
+
for (let el = comment.parentElement;el && el !== boundary; el = el.parentElement) {
|
|
2426
2493
|
if (el.hasAttribute(BF_SCOPE)) {
|
|
2427
2494
|
owned = false;
|
|
2428
2495
|
break;
|
|
2429
2496
|
}
|
|
2430
2497
|
}
|
|
2431
|
-
if (owned)
|
|
2432
|
-
|
|
2433
|
-
break;
|
|
2434
|
-
}
|
|
2435
|
-
}
|
|
2436
|
-
const parent = start?.parentNode;
|
|
2437
|
-
if (!start || !parent) {
|
|
2438
|
-
console.warn(`[barefootjs] preamble region marker bf:${id} not found in row; skipping patch`);
|
|
2439
|
-
return;
|
|
2498
|
+
if (owned)
|
|
2499
|
+
return comment;
|
|
2440
2500
|
}
|
|
2501
|
+
return null;
|
|
2502
|
+
}
|
|
2503
|
+
function findMarkupEnd(start) {
|
|
2441
2504
|
let depth = 0;
|
|
2442
|
-
let end = null;
|
|
2443
|
-
const toRemove = [];
|
|
2444
2505
|
let node = start.nextSibling;
|
|
2445
2506
|
while (node) {
|
|
2446
2507
|
if (node.nodeType === Node.COMMENT_NODE) {
|
|
@@ -2448,28 +2509,195 @@ function patchSlotRange(scope, id, html) {
|
|
|
2448
2509
|
if (value.startsWith("bf:")) {
|
|
2449
2510
|
depth++;
|
|
2450
2511
|
} else if (value === "/") {
|
|
2451
|
-
if (depth === 0)
|
|
2452
|
-
|
|
2453
|
-
break;
|
|
2454
|
-
}
|
|
2512
|
+
if (depth === 0)
|
|
2513
|
+
return node;
|
|
2455
2514
|
depth--;
|
|
2456
2515
|
}
|
|
2457
2516
|
}
|
|
2458
|
-
toRemove.push(node);
|
|
2459
2517
|
node = node.nextSibling;
|
|
2460
2518
|
}
|
|
2519
|
+
return null;
|
|
2520
|
+
}
|
|
2521
|
+
function resolveAnchor(root, spec) {
|
|
2522
|
+
if (spec.path.length > 0) {
|
|
2523
|
+
const resolved = resolvePath(root, spec.path);
|
|
2524
|
+
if (isSlotComment(resolved, spec.id))
|
|
2525
|
+
return resolved;
|
|
2526
|
+
console.warn(`[barefootjs] claim path for slot ${spec.id} did not resolve to its bf:${spec.id} marker; falling back to a scan`);
|
|
2527
|
+
}
|
|
2528
|
+
const found = findOwnedMarker(root, spec.id);
|
|
2529
|
+
if (!found) {
|
|
2530
|
+
console.warn(`[barefootjs] slot ${spec.id} marker not found; skipping`);
|
|
2531
|
+
}
|
|
2532
|
+
return found;
|
|
2533
|
+
}
|
|
2534
|
+
function claimMarkerlessText(root, spec) {
|
|
2535
|
+
if (spec.path.length === 0) {
|
|
2536
|
+
console.warn(`[barefootjs] markerless slot ${spec.id} has an empty path; skipping`);
|
|
2537
|
+
return null;
|
|
2538
|
+
}
|
|
2539
|
+
const parentPath = spec.path.slice(0, -1);
|
|
2540
|
+
const idx = spec.path[spec.path.length - 1];
|
|
2541
|
+
const parent = resolvePath(root, parentPath);
|
|
2542
|
+
if (!parent) {
|
|
2543
|
+
console.warn(`[barefootjs] markerless claim path for slot ${spec.id} did not resolve to a parent node; skipping`);
|
|
2544
|
+
return null;
|
|
2545
|
+
}
|
|
2546
|
+
const existing = parent.childNodes[idx];
|
|
2547
|
+
if (existing && existing.nodeType === Node.TEXT_NODE) {
|
|
2548
|
+
return { kind: "text", ref: existing };
|
|
2549
|
+
}
|
|
2550
|
+
const node = document.createTextNode("");
|
|
2551
|
+
parent.insertBefore(node, existing ?? null);
|
|
2552
|
+
return { kind: "text", ref: node };
|
|
2553
|
+
}
|
|
2554
|
+
function claimOne(root, spec) {
|
|
2555
|
+
if (spec.kind === "text" && spec.markerless) {
|
|
2556
|
+
return claimMarkerlessText(root, spec);
|
|
2557
|
+
}
|
|
2558
|
+
const anchor = resolveAnchor(root, spec);
|
|
2559
|
+
if (!anchor)
|
|
2560
|
+
return null;
|
|
2561
|
+
if (spec.kind === "text") {
|
|
2562
|
+
const next = anchor.nextSibling;
|
|
2563
|
+
return { kind: "text", ref: next?.nodeType === Node.TEXT_NODE ? next : anchor };
|
|
2564
|
+
}
|
|
2565
|
+
const end = findMarkupEnd(anchor);
|
|
2566
|
+
if (!end) {
|
|
2567
|
+
console.warn(`[barefootjs] slot ${spec.id} has no end marker; skipping`);
|
|
2568
|
+
return null;
|
|
2569
|
+
}
|
|
2570
|
+
return { kind: "markup", start: anchor, end, last: undefined };
|
|
2571
|
+
}
|
|
2572
|
+
function materializeText(slot) {
|
|
2573
|
+
const anchor = slot.ref;
|
|
2574
|
+
const parent = anchor.parentNode;
|
|
2575
|
+
if (!parent)
|
|
2576
|
+
return null;
|
|
2577
|
+
const node = document.createTextNode("");
|
|
2578
|
+
parent.insertBefore(node, anchor.nextSibling);
|
|
2579
|
+
slot.ref = node;
|
|
2580
|
+
return node;
|
|
2581
|
+
}
|
|
2582
|
+
function readText(slot) {
|
|
2583
|
+
return slot.ref.nodeType === Node.TEXT_NODE ? slot.ref.nodeValue ?? "" : "";
|
|
2584
|
+
}
|
|
2585
|
+
function writeText(slot, value) {
|
|
2586
|
+
const node = slot.ref.nodeType === Node.TEXT_NODE ? slot.ref : materializeText(slot);
|
|
2587
|
+
if (!node)
|
|
2588
|
+
return;
|
|
2589
|
+
node.nodeValue = String(value ?? "");
|
|
2590
|
+
}
|
|
2591
|
+
function textOrNode(value) {
|
|
2592
|
+
if (typeof Node !== "undefined" && value instanceof Node)
|
|
2593
|
+
return value;
|
|
2594
|
+
return String(value);
|
|
2595
|
+
}
|
|
2596
|
+
function promoteTextToMarkup(slot, id) {
|
|
2597
|
+
const anchor = slot.ref.nodeType === Node.COMMENT_NODE ? slot.ref : isSlotComment(slot.ref.previousSibling, id) ? slot.ref.previousSibling : null;
|
|
2598
|
+
if (!anchor) {
|
|
2599
|
+
console.warn(`[barefootjs] slot ${id} was claimed as text and received a Node, but has no anchor marker to promote from; write ignored`);
|
|
2600
|
+
return null;
|
|
2601
|
+
}
|
|
2602
|
+
const end = findMarkupEnd(anchor);
|
|
2461
2603
|
if (!end) {
|
|
2462
|
-
console.warn(`[barefootjs]
|
|
2604
|
+
console.warn(`[barefootjs] slot ${id} was claimed as text and received a Node, but has no end marker; write ignored`);
|
|
2605
|
+
return null;
|
|
2606
|
+
}
|
|
2607
|
+
return { kind: "markup", start: anchor, end, last: undefined };
|
|
2608
|
+
}
|
|
2609
|
+
function clearMarkupRange(start, end) {
|
|
2610
|
+
const parent = end.parentNode;
|
|
2611
|
+
if (!parent)
|
|
2463
2612
|
return;
|
|
2613
|
+
let node = start.nextSibling;
|
|
2614
|
+
while (node && node !== end) {
|
|
2615
|
+
const next = node.nextSibling;
|
|
2616
|
+
parent.removeChild(node);
|
|
2617
|
+
node = next;
|
|
2464
2618
|
}
|
|
2465
|
-
|
|
2466
|
-
|
|
2619
|
+
}
|
|
2620
|
+
function writeMarkup(ref, value) {
|
|
2621
|
+
const { start, end } = ref;
|
|
2622
|
+
const parent = end.parentNode;
|
|
2623
|
+
if (!parent)
|
|
2624
|
+
return;
|
|
2625
|
+
if (value != null && value.__isSlot)
|
|
2626
|
+
return;
|
|
2627
|
+
if (typeof Node !== "undefined" && value instanceof Node) {
|
|
2628
|
+
if (value === ref.last)
|
|
2629
|
+
return;
|
|
2630
|
+
clearMarkupRange(start, end);
|
|
2631
|
+
parent.insertBefore(value, end);
|
|
2632
|
+
ref.last = value;
|
|
2633
|
+
return;
|
|
2634
|
+
}
|
|
2635
|
+
const text = String(value ?? "");
|
|
2636
|
+
if (text === ref.last)
|
|
2637
|
+
return;
|
|
2638
|
+
clearMarkupRange(start, end);
|
|
2467
2639
|
const tpl = document.createElement("template");
|
|
2468
|
-
tpl.innerHTML =
|
|
2640
|
+
tpl.innerHTML = text;
|
|
2469
2641
|
parent.insertBefore(tpl.content, end);
|
|
2642
|
+
ref.last = text;
|
|
2643
|
+
}
|
|
2644
|
+
function writeSlot(refs, id, value) {
|
|
2645
|
+
const ref = refs.get(id);
|
|
2646
|
+
if (!ref) {
|
|
2647
|
+
console.warn(`[barefootjs] no claimed slot for id ${id}; write ignored`);
|
|
2648
|
+
return;
|
|
2649
|
+
}
|
|
2650
|
+
if (ref.kind === "text") {
|
|
2651
|
+
if (typeof Node !== "undefined" && value instanceof Node) {
|
|
2652
|
+
const promoted = promoteTextToMarkup(ref, id);
|
|
2653
|
+
if (!promoted)
|
|
2654
|
+
return;
|
|
2655
|
+
refs.set(id, promoted);
|
|
2656
|
+
writeMarkup(promoted, value);
|
|
2657
|
+
return;
|
|
2658
|
+
}
|
|
2659
|
+
writeText(ref, value);
|
|
2660
|
+
} else {
|
|
2661
|
+
writeMarkup(ref, value);
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
function readSlot(refs, id) {
|
|
2665
|
+
const ref = refs.get(id);
|
|
2666
|
+
if (!ref || ref.kind !== "text")
|
|
2667
|
+
return null;
|
|
2668
|
+
return readText(ref);
|
|
2669
|
+
}
|
|
2670
|
+
function claimSlots(root, plan) {
|
|
2671
|
+
const refs = claimRefs(root, plan);
|
|
2672
|
+
return { write: (id, value) => writeSlot(refs, id, value) };
|
|
2673
|
+
}
|
|
2674
|
+
function claimRefs(root, plan) {
|
|
2675
|
+
const refs = new Map;
|
|
2676
|
+
for (const spec of plan) {
|
|
2677
|
+
const ref = claimOne(root, spec);
|
|
2678
|
+
if (ref)
|
|
2679
|
+
refs.set(spec.id, ref);
|
|
2680
|
+
}
|
|
2681
|
+
return refs;
|
|
2682
|
+
}
|
|
2683
|
+
function lazySlots(root, plan) {
|
|
2684
|
+
let claimed = null;
|
|
2685
|
+
return (id, value) => {
|
|
2686
|
+
if (!claimed)
|
|
2687
|
+
claimed = claimSlots(root, plan);
|
|
2688
|
+
claimed.write(id, value);
|
|
2689
|
+
};
|
|
2690
|
+
}
|
|
2691
|
+
function lazyClaimSlots(root, plan) {
|
|
2692
|
+
let refs = null;
|
|
2693
|
+
const ensure = () => refs ??= claimRefs(root, plan);
|
|
2694
|
+
return {
|
|
2695
|
+
write: (id, value) => writeSlot(ensure(), id, value),
|
|
2696
|
+
read: (id) => readSlot(ensure(), id)
|
|
2697
|
+
};
|
|
2470
2698
|
}
|
|
2471
2699
|
// src/runtime/apply-rest-attrs.ts
|
|
2472
|
-
import { createEffect as
|
|
2700
|
+
import { createEffect as createEffect3 } from "@barefootjs/client/reactive";
|
|
2473
2701
|
|
|
2474
2702
|
// src/runtime/style.ts
|
|
2475
2703
|
function styleToCss(value) {
|
|
@@ -2514,7 +2742,7 @@ function applyRestAttrs(el, source, excludeKeys) {
|
|
|
2514
2742
|
}
|
|
2515
2743
|
}
|
|
2516
2744
|
const attrEntries = classified.filter(({ c }) => c.kind !== "ref" && c.kind !== "event" && c.kind !== "skip");
|
|
2517
|
-
|
|
2745
|
+
createEffect3(() => {
|
|
2518
2746
|
for (const { key, c } of attrEntries) {
|
|
2519
2747
|
const value = source[key];
|
|
2520
2748
|
if (c.kind === "innerHTML") {
|
|
@@ -2590,7 +2818,7 @@ function date(recv, op) {
|
|
|
2590
2818
|
return d[op]();
|
|
2591
2819
|
}
|
|
2592
2820
|
// src/runtime/insert.ts
|
|
2593
|
-
import { createEffect as
|
|
2821
|
+
import { createEffect as createEffect4, untrack as untrack3 } from "@barefootjs/client/reactive";
|
|
2594
2822
|
function makeRegion(scope) {
|
|
2595
2823
|
if (scope.nodeType === Node.COMMENT_NODE) {
|
|
2596
2824
|
const anchor = scope;
|
|
@@ -2645,7 +2873,7 @@ function normalizeTemplate(value) {
|
|
|
2645
2873
|
return typeof value === "string" ? { html: value, slots: EMPTY_SLOTS } : value;
|
|
2646
2874
|
}
|
|
2647
2875
|
function evalBranchTemplate(branch) {
|
|
2648
|
-
return
|
|
2876
|
+
return untrack3(() => normalizeTemplate(branch.template()));
|
|
2649
2877
|
}
|
|
2650
2878
|
function insert(scope, id, conditionFn, whenTrue, whenFalse, bfId) {
|
|
2651
2879
|
if (!scope)
|
|
@@ -2671,7 +2899,7 @@ function insert(scope, id, conditionFn, whenTrue, whenFalse, bfId) {
|
|
|
2671
2899
|
}
|
|
2672
2900
|
let prevCond;
|
|
2673
2901
|
let branchCleanup = null;
|
|
2674
|
-
|
|
2902
|
+
createEffect4(() => {
|
|
2675
2903
|
let currCond;
|
|
2676
2904
|
try {
|
|
2677
2905
|
currCond = Boolean(conditionFn());
|
|
@@ -2914,26 +3142,6 @@ function __bfText(current, value) {
|
|
|
2914
3142
|
}
|
|
2915
3143
|
return textNode;
|
|
2916
3144
|
}
|
|
2917
|
-
// src/runtime/client-marker.ts
|
|
2918
|
-
function updateClientMarker(scope, id, value) {
|
|
2919
|
-
if (!scope)
|
|
2920
|
-
return;
|
|
2921
|
-
const marker = `bf-client:${id}`;
|
|
2922
|
-
const walker = document.createTreeWalker(scope, NodeFilter.SHOW_COMMENT);
|
|
2923
|
-
while (walker.nextNode()) {
|
|
2924
|
-
if (walker.currentNode.nodeValue === marker) {
|
|
2925
|
-
const comment = walker.currentNode;
|
|
2926
|
-
let textNode = comment.nextSibling;
|
|
2927
|
-
if (textNode?.nodeType !== Node.TEXT_NODE || !textNode.nodeValue?.startsWith("")) {
|
|
2928
|
-
textNode = document.createTextNode("" + String(value ?? ""));
|
|
2929
|
-
comment.parentNode?.insertBefore(textNode, comment.nextSibling);
|
|
2930
|
-
} else {
|
|
2931
|
-
textNode.nodeValue = "" + String(value ?? "");
|
|
2932
|
-
}
|
|
2933
|
-
return;
|
|
2934
|
-
}
|
|
2935
|
-
}
|
|
2936
|
-
}
|
|
2937
3145
|
// src/runtime/render.ts
|
|
2938
3146
|
function render(container, nameOrDef, props = {}) {
|
|
2939
3147
|
let name;
|
|
@@ -3014,9 +3222,9 @@ export {
|
|
|
3014
3222
|
useContext,
|
|
3015
3223
|
upsertChildItem,
|
|
3016
3224
|
upsertChild,
|
|
3017
|
-
updateClientMarker,
|
|
3018
3225
|
unwrap,
|
|
3019
|
-
|
|
3226
|
+
untrack4 as untrack,
|
|
3227
|
+
textOrNode,
|
|
3020
3228
|
textNodeAfterComment as tAfter,
|
|
3021
3229
|
styleToCss,
|
|
3022
3230
|
spreadAttrs,
|
|
@@ -3030,21 +3238,21 @@ export {
|
|
|
3030
3238
|
rehydrateAll,
|
|
3031
3239
|
registerTemplate,
|
|
3032
3240
|
registerComponent,
|
|
3033
|
-
reconcileList,
|
|
3034
|
-
reconcileElements,
|
|
3035
3241
|
queryHref,
|
|
3036
3242
|
qsaItem,
|
|
3037
3243
|
qsaChildScopes,
|
|
3038
3244
|
qsaChildScope,
|
|
3039
3245
|
qsa,
|
|
3040
3246
|
provideContext,
|
|
3041
|
-
patchSlotRange,
|
|
3042
3247
|
patchLeaf,
|
|
3043
3248
|
parseHTML,
|
|
3044
3249
|
onMount,
|
|
3045
3250
|
onCleanup,
|
|
3251
|
+
mapArrayLazy,
|
|
3046
3252
|
mapArrayAnchored,
|
|
3047
3253
|
mapArray,
|
|
3254
|
+
lazySlots,
|
|
3255
|
+
lazyClaimSlots,
|
|
3048
3256
|
isSSRPortal,
|
|
3049
3257
|
insert,
|
|
3050
3258
|
initChild,
|
|
@@ -3053,10 +3261,8 @@ export {
|
|
|
3053
3261
|
hasTemplate,
|
|
3054
3262
|
getTemplate,
|
|
3055
3263
|
getRegisteredDef,
|
|
3056
|
-
getPropsUpdateFn,
|
|
3057
3264
|
getLoopNodes,
|
|
3058
3265
|
getLoopChildren,
|
|
3059
|
-
getComponentProps,
|
|
3060
3266
|
getComponentInit,
|
|
3061
3267
|
forwardProps,
|
|
3062
3268
|
formatDate,
|
|
@@ -3064,24 +3270,26 @@ export {
|
|
|
3064
3270
|
findSiblingSlot,
|
|
3065
3271
|
findScope,
|
|
3066
3272
|
find,
|
|
3273
|
+
escapeTextOrNode,
|
|
3067
3274
|
escapeText,
|
|
3068
3275
|
escapeAttr,
|
|
3069
3276
|
endTurn,
|
|
3070
3277
|
disposeScope,
|
|
3071
3278
|
date,
|
|
3072
3279
|
cssEscape,
|
|
3073
|
-
|
|
3280
|
+
createSignal3 as createSignal,
|
|
3074
3281
|
createSelector,
|
|
3075
3282
|
createSearchParams,
|
|
3076
3283
|
createRoot3 as createRoot,
|
|
3077
3284
|
createRecordingSink,
|
|
3078
3285
|
createPortal,
|
|
3079
3286
|
createMemo,
|
|
3080
|
-
|
|
3287
|
+
createEffect5 as createEffect,
|
|
3081
3288
|
createDisposableEffect,
|
|
3082
3289
|
createContext,
|
|
3083
3290
|
createComponent,
|
|
3084
3291
|
cleanupPortalPlaceholder,
|
|
3292
|
+
claimSlots,
|
|
3085
3293
|
beginTurn,
|
|
3086
3294
|
batch,
|
|
3087
3295
|
applyRestAttrs,
|