@barefootjs/client 0.26.3 → 0.27.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 +157 -0
- package/dist/runtime/claim-slots.d.ts.map +1 -0
- package/dist/runtime/component.d.ts +29 -17
- 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 -4
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +206 -206
- package/dist/runtime/loop-markers.d.ts +26 -0
- package/dist/runtime/loop-markers.d.ts.map +1 -0
- package/dist/runtime/patch-leaf.d.ts +17 -0
- package/dist/runtime/patch-leaf.d.ts.map +1 -0
- package/dist/runtime/standalone.js +206 -206
- package/package.json +2 -2
- package/src/reactive.ts +2 -1
- package/src/runtime/claim-slots.ts +449 -0
- package/src/runtime/component.ts +39 -69
- package/src/runtime/dynamic-text.ts +24 -1
- package/src/runtime/index.ts +17 -6
- package/src/runtime/insert.ts +1 -1
- package/src/runtime/loop-markers.ts +100 -0
- package/src/runtime/patch-leaf.ts +41 -0
- 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/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/reconcile-elements.ts +0 -391
package/dist/runtime/index.js
CHANGED
|
@@ -1352,8 +1352,6 @@ var _parentScopeId = null;
|
|
|
1352
1352
|
function setParentScopeId(id) {
|
|
1353
1353
|
_parentScopeId = id;
|
|
1354
1354
|
}
|
|
1355
|
-
var propsUpdateMap = new WeakMap;
|
|
1356
|
-
var propsMap = new WeakMap;
|
|
1357
1355
|
function createComponent(nameOrDef, props = {}, key, slot) {
|
|
1358
1356
|
if (props == null)
|
|
1359
1357
|
props = {};
|
|
@@ -1445,24 +1443,8 @@ function createComponent(nameOrDef, props = {}, key, slot) {
|
|
|
1445
1443
|
}
|
|
1446
1444
|
setCurrentScope(prevScope);
|
|
1447
1445
|
hydratedScopes.add(element);
|
|
1448
|
-
propsMap.set(element, props);
|
|
1449
|
-
registerPropsUpdate(element, name, props);
|
|
1450
1446
|
return element;
|
|
1451
1447
|
}
|
|
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
1448
|
function renderChild(name, props, key, slotSuffix) {
|
|
1467
1449
|
const templateFn = getTemplate(name);
|
|
1468
1450
|
const suffix = slotSuffix ? `_${slotSuffix}` : "";
|
|
@@ -1528,6 +1510,11 @@ function escapeText(value) {
|
|
|
1528
1510
|
return "";
|
|
1529
1511
|
return escapeAttr(value);
|
|
1530
1512
|
}
|
|
1513
|
+
function escapeTextOrNode(value) {
|
|
1514
|
+
if (typeof Node !== "undefined" && value instanceof Node)
|
|
1515
|
+
return value;
|
|
1516
|
+
return escapeText(value);
|
|
1517
|
+
}
|
|
1531
1518
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1532
1519
|
function parseHTML(html, parent) {
|
|
1533
1520
|
const tpl = document.createElement("template");
|
|
@@ -1592,7 +1579,6 @@ function createComponentFromDef(def, props, key) {
|
|
|
1592
1579
|
}
|
|
1593
1580
|
def.init(element, props);
|
|
1594
1581
|
hydratedScopes.add(element);
|
|
1595
|
-
propsMap.set(element, props);
|
|
1596
1582
|
return element;
|
|
1597
1583
|
}
|
|
1598
1584
|
|
|
@@ -1650,7 +1636,7 @@ function createPortal(children, container = document.body, options) {
|
|
|
1650
1636
|
}
|
|
1651
1637
|
};
|
|
1652
1638
|
}
|
|
1653
|
-
// src/runtime/
|
|
1639
|
+
// src/runtime/loop-markers.ts
|
|
1654
1640
|
function findLoopMarkers(container, markerId) {
|
|
1655
1641
|
let startMarker = null;
|
|
1656
1642
|
let endMarker = null;
|
|
@@ -1695,14 +1681,6 @@ function getElementsBetweenMarkers(start, end) {
|
|
|
1695
1681
|
}
|
|
1696
1682
|
return elements;
|
|
1697
1683
|
}
|
|
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
1684
|
function getLoopChildren(container, markerId) {
|
|
1707
1685
|
const { startMarker, endMarker } = findLoopMarkers(container, markerId);
|
|
1708
1686
|
if (startMarker && endMarker) {
|
|
@@ -1723,159 +1701,6 @@ function getLoopNodes(container, markerId) {
|
|
|
1723
1701
|
}
|
|
1724
1702
|
return Array.from(container.childNodes);
|
|
1725
1703
|
}
|
|
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
1704
|
// src/runtime/qsa-item.ts
|
|
1880
1705
|
function* itemRootElements(primaryEl) {
|
|
1881
1706
|
yield primaryEl;
|
|
@@ -2387,6 +2212,202 @@ function mapArrayAnchored(accessor, container, getKey, renderItem, markerId, bfI
|
|
|
2387
2212
|
}
|
|
2388
2213
|
}, bfId);
|
|
2389
2214
|
}
|
|
2215
|
+
// src/runtime/patch-leaf.ts
|
|
2216
|
+
function patchLeaf(el, html) {
|
|
2217
|
+
const tpl = document.createElement("template");
|
|
2218
|
+
tpl.innerHTML = html;
|
|
2219
|
+
const next = tpl.content.firstElementChild;
|
|
2220
|
+
if (!next)
|
|
2221
|
+
return;
|
|
2222
|
+
if (next.tagName !== el.tagName) {
|
|
2223
|
+
console.warn("[barefootjs] flatMap leaf root tag changed under a stable key " + `(<${el.tagName.toLowerCase()}> -> <${next.tagName.toLowerCase()}>); ` + "give each branch its own key so the node is replaced instead of patched.");
|
|
2224
|
+
}
|
|
2225
|
+
for (const name of el.getAttributeNames()) {
|
|
2226
|
+
if (name === "data-key")
|
|
2227
|
+
continue;
|
|
2228
|
+
if (!next.hasAttribute(name))
|
|
2229
|
+
el.removeAttribute(name);
|
|
2230
|
+
}
|
|
2231
|
+
for (const name of next.getAttributeNames()) {
|
|
2232
|
+
if (name === "data-key")
|
|
2233
|
+
continue;
|
|
2234
|
+
const value = next.getAttribute(name);
|
|
2235
|
+
if (value !== null && el.getAttribute(name) !== value)
|
|
2236
|
+
el.setAttribute(name, value);
|
|
2237
|
+
}
|
|
2238
|
+
el.replaceChildren(...Array.from(next.childNodes));
|
|
2239
|
+
}
|
|
2240
|
+
// src/runtime/claim-slots.ts
|
|
2241
|
+
function resolvePath(root, path) {
|
|
2242
|
+
let node = root;
|
|
2243
|
+
for (const index of path) {
|
|
2244
|
+
const child = node.childNodes[index];
|
|
2245
|
+
if (!child)
|
|
2246
|
+
return null;
|
|
2247
|
+
node = child;
|
|
2248
|
+
}
|
|
2249
|
+
return node;
|
|
2250
|
+
}
|
|
2251
|
+
function isSlotComment(node, id) {
|
|
2252
|
+
return node != null && node.nodeType === Node.COMMENT_NODE && node.nodeValue === `bf:${id}`;
|
|
2253
|
+
}
|
|
2254
|
+
function findOwnedMarker(root, id) {
|
|
2255
|
+
const marker = `bf:${id}`;
|
|
2256
|
+
const parentOwned = id.startsWith(BF_PARENT_OWNED_PREFIX);
|
|
2257
|
+
const registryInfo = commentScopeRegistry.get(root);
|
|
2258
|
+
const boundary = registryInfo ? registryInfo.commentNode.parentElement : root;
|
|
2259
|
+
for (const comment of commentsInScope(root)) {
|
|
2260
|
+
if (comment.nodeValue !== marker)
|
|
2261
|
+
continue;
|
|
2262
|
+
if (parentOwned)
|
|
2263
|
+
return comment;
|
|
2264
|
+
let owned = true;
|
|
2265
|
+
for (let el = comment.parentElement;el && el !== boundary; el = el.parentElement) {
|
|
2266
|
+
if (el.hasAttribute(BF_SCOPE)) {
|
|
2267
|
+
owned = false;
|
|
2268
|
+
break;
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
if (owned)
|
|
2272
|
+
return comment;
|
|
2273
|
+
}
|
|
2274
|
+
return null;
|
|
2275
|
+
}
|
|
2276
|
+
function findMarkupEnd(start) {
|
|
2277
|
+
let depth = 0;
|
|
2278
|
+
let node = start.nextSibling;
|
|
2279
|
+
while (node) {
|
|
2280
|
+
if (node.nodeType === Node.COMMENT_NODE) {
|
|
2281
|
+
const value = node.nodeValue ?? "";
|
|
2282
|
+
if (value.startsWith("bf:")) {
|
|
2283
|
+
depth++;
|
|
2284
|
+
} else if (value === "/") {
|
|
2285
|
+
if (depth === 0)
|
|
2286
|
+
return node;
|
|
2287
|
+
depth--;
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
node = node.nextSibling;
|
|
2291
|
+
}
|
|
2292
|
+
return null;
|
|
2293
|
+
}
|
|
2294
|
+
function resolveAnchor(root, spec) {
|
|
2295
|
+
if (spec.path.length > 0) {
|
|
2296
|
+
const resolved = resolvePath(root, spec.path);
|
|
2297
|
+
if (isSlotComment(resolved, spec.id))
|
|
2298
|
+
return resolved;
|
|
2299
|
+
console.warn(`[barefootjs] claim path for slot ${spec.id} did not resolve to its bf:${spec.id} marker; falling back to a scan`);
|
|
2300
|
+
}
|
|
2301
|
+
const found = findOwnedMarker(root, spec.id);
|
|
2302
|
+
if (!found) {
|
|
2303
|
+
console.warn(`[barefootjs] slot ${spec.id} marker not found; skipping`);
|
|
2304
|
+
}
|
|
2305
|
+
return found;
|
|
2306
|
+
}
|
|
2307
|
+
function claimMarkerlessText(root, spec) {
|
|
2308
|
+
if (spec.path.length === 0) {
|
|
2309
|
+
console.warn(`[barefootjs] markerless slot ${spec.id} has an empty path; skipping`);
|
|
2310
|
+
return null;
|
|
2311
|
+
}
|
|
2312
|
+
const parentPath = spec.path.slice(0, -1);
|
|
2313
|
+
const idx = spec.path[spec.path.length - 1];
|
|
2314
|
+
const parent = resolvePath(root, parentPath);
|
|
2315
|
+
if (!parent) {
|
|
2316
|
+
console.warn(`[barefootjs] markerless claim path for slot ${spec.id} did not resolve to a parent node; skipping`);
|
|
2317
|
+
return null;
|
|
2318
|
+
}
|
|
2319
|
+
const existing = parent.childNodes[idx];
|
|
2320
|
+
if (existing && existing.nodeType === Node.TEXT_NODE) {
|
|
2321
|
+
return { kind: "text", node: existing };
|
|
2322
|
+
}
|
|
2323
|
+
const node = document.createTextNode("");
|
|
2324
|
+
parent.insertBefore(node, existing ?? null);
|
|
2325
|
+
return { kind: "text", node };
|
|
2326
|
+
}
|
|
2327
|
+
function claimOne(root, spec) {
|
|
2328
|
+
if (spec.kind === "text" && spec.markerless) {
|
|
2329
|
+
return claimMarkerlessText(root, spec);
|
|
2330
|
+
}
|
|
2331
|
+
const anchor = resolveAnchor(root, spec);
|
|
2332
|
+
if (!anchor)
|
|
2333
|
+
return null;
|
|
2334
|
+
if (spec.kind === "text") {
|
|
2335
|
+
return { kind: "text", node: textNodeAfterComment(anchor) };
|
|
2336
|
+
}
|
|
2337
|
+
const end = findMarkupEnd(anchor);
|
|
2338
|
+
if (!end) {
|
|
2339
|
+
console.warn(`[barefootjs] slot ${spec.id} has no end marker; skipping`);
|
|
2340
|
+
return null;
|
|
2341
|
+
}
|
|
2342
|
+
return { kind: "markup", start: anchor, end, last: undefined };
|
|
2343
|
+
}
|
|
2344
|
+
function writeText(ref, value) {
|
|
2345
|
+
ref.node.nodeValue = String(value ?? "");
|
|
2346
|
+
}
|
|
2347
|
+
function clearMarkupRange(start, end) {
|
|
2348
|
+
const parent = end.parentNode;
|
|
2349
|
+
if (!parent)
|
|
2350
|
+
return;
|
|
2351
|
+
let node = start.nextSibling;
|
|
2352
|
+
while (node && node !== end) {
|
|
2353
|
+
const next = node.nextSibling;
|
|
2354
|
+
parent.removeChild(node);
|
|
2355
|
+
node = next;
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
function writeMarkup(ref, value) {
|
|
2359
|
+
const { start, end } = ref;
|
|
2360
|
+
const parent = end.parentNode;
|
|
2361
|
+
if (!parent)
|
|
2362
|
+
return;
|
|
2363
|
+
if (value != null && value.__isSlot)
|
|
2364
|
+
return;
|
|
2365
|
+
if (typeof Node !== "undefined" && value instanceof Node) {
|
|
2366
|
+
if (value === ref.last)
|
|
2367
|
+
return;
|
|
2368
|
+
clearMarkupRange(start, end);
|
|
2369
|
+
parent.insertBefore(value, end);
|
|
2370
|
+
ref.last = value;
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
const text = String(value ?? "");
|
|
2374
|
+
if (text === ref.last)
|
|
2375
|
+
return;
|
|
2376
|
+
clearMarkupRange(start, end);
|
|
2377
|
+
const tpl = document.createElement("template");
|
|
2378
|
+
tpl.innerHTML = text;
|
|
2379
|
+
parent.insertBefore(tpl.content, end);
|
|
2380
|
+
ref.last = text;
|
|
2381
|
+
}
|
|
2382
|
+
function writeSlot(refs, id, value) {
|
|
2383
|
+
const ref = refs.get(id);
|
|
2384
|
+
if (!ref) {
|
|
2385
|
+
console.warn(`[barefootjs] no claimed slot for id ${id}; write ignored`);
|
|
2386
|
+
return;
|
|
2387
|
+
}
|
|
2388
|
+
if (ref.kind === "text") {
|
|
2389
|
+
writeText(ref, value);
|
|
2390
|
+
} else {
|
|
2391
|
+
writeMarkup(ref, value);
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
function claimSlots(root, plan) {
|
|
2395
|
+
const refs = new Map;
|
|
2396
|
+
for (const spec of plan) {
|
|
2397
|
+
const ref = claimOne(root, spec);
|
|
2398
|
+
if (ref)
|
|
2399
|
+
refs.set(spec.id, ref);
|
|
2400
|
+
}
|
|
2401
|
+
return { write: (id, value) => writeSlot(refs, id, value) };
|
|
2402
|
+
}
|
|
2403
|
+
function lazySlots(root, plan) {
|
|
2404
|
+
let claimed = null;
|
|
2405
|
+
return (id, value) => {
|
|
2406
|
+
if (!claimed)
|
|
2407
|
+
claimed = claimSlots(root, plan);
|
|
2408
|
+
claimed.write(id, value);
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2390
2411
|
// src/runtime/apply-rest-attrs.ts
|
|
2391
2412
|
import { createEffect as createEffect2 } from "@barefootjs/client/reactive";
|
|
2392
2413
|
|
|
@@ -2833,26 +2854,6 @@ function __bfText(current, value) {
|
|
|
2833
2854
|
}
|
|
2834
2855
|
return textNode;
|
|
2835
2856
|
}
|
|
2836
|
-
// src/runtime/client-marker.ts
|
|
2837
|
-
function updateClientMarker(scope, id, value) {
|
|
2838
|
-
if (!scope)
|
|
2839
|
-
return;
|
|
2840
|
-
const marker = `bf-client:${id}`;
|
|
2841
|
-
const walker = document.createTreeWalker(scope, NodeFilter.SHOW_COMMENT);
|
|
2842
|
-
while (walker.nextNode()) {
|
|
2843
|
-
if (walker.currentNode.nodeValue === marker) {
|
|
2844
|
-
const comment = walker.currentNode;
|
|
2845
|
-
let textNode = comment.nextSibling;
|
|
2846
|
-
if (textNode?.nodeType !== Node.TEXT_NODE || !textNode.nodeValue?.startsWith("")) {
|
|
2847
|
-
textNode = document.createTextNode("" + String(value ?? ""));
|
|
2848
|
-
comment.parentNode?.insertBefore(textNode, comment.nextSibling);
|
|
2849
|
-
} else {
|
|
2850
|
-
textNode.nodeValue = "" + String(value ?? "");
|
|
2851
|
-
}
|
|
2852
|
-
return;
|
|
2853
|
-
}
|
|
2854
|
-
}
|
|
2855
|
-
}
|
|
2856
2857
|
// src/runtime/render.ts
|
|
2857
2858
|
function render(container, nameOrDef, props = {}) {
|
|
2858
2859
|
let name;
|
|
@@ -2933,7 +2934,6 @@ export {
|
|
|
2933
2934
|
useContext,
|
|
2934
2935
|
upsertChildItem,
|
|
2935
2936
|
upsertChild,
|
|
2936
|
-
updateClientMarker,
|
|
2937
2937
|
unwrap,
|
|
2938
2938
|
untrack3 as untrack,
|
|
2939
2939
|
textNodeAfterComment as tAfter,
|
|
@@ -2949,19 +2949,19 @@ export {
|
|
|
2949
2949
|
rehydrateAll,
|
|
2950
2950
|
registerTemplate,
|
|
2951
2951
|
registerComponent,
|
|
2952
|
-
reconcileList,
|
|
2953
|
-
reconcileElements,
|
|
2954
2952
|
queryHref,
|
|
2955
2953
|
qsaItem,
|
|
2956
2954
|
qsaChildScopes,
|
|
2957
2955
|
qsaChildScope,
|
|
2958
2956
|
qsa,
|
|
2959
2957
|
provideContext,
|
|
2958
|
+
patchLeaf,
|
|
2960
2959
|
parseHTML,
|
|
2961
2960
|
onMount,
|
|
2962
2961
|
onCleanup,
|
|
2963
2962
|
mapArrayAnchored,
|
|
2964
2963
|
mapArray,
|
|
2964
|
+
lazySlots,
|
|
2965
2965
|
isSSRPortal,
|
|
2966
2966
|
insert,
|
|
2967
2967
|
initChild,
|
|
@@ -2970,10 +2970,8 @@ export {
|
|
|
2970
2970
|
hasTemplate,
|
|
2971
2971
|
getTemplate,
|
|
2972
2972
|
getRegisteredDef,
|
|
2973
|
-
getPropsUpdateFn,
|
|
2974
2973
|
getLoopNodes,
|
|
2975
2974
|
getLoopChildren,
|
|
2976
|
-
getComponentProps,
|
|
2977
2975
|
getComponentInit,
|
|
2978
2976
|
forwardProps,
|
|
2979
2977
|
formatDate,
|
|
@@ -2981,6 +2979,7 @@ export {
|
|
|
2981
2979
|
findSiblingSlot,
|
|
2982
2980
|
findScope,
|
|
2983
2981
|
find,
|
|
2982
|
+
escapeTextOrNode,
|
|
2984
2983
|
escapeText,
|
|
2985
2984
|
escapeAttr,
|
|
2986
2985
|
endTurn,
|
|
@@ -2999,6 +2998,7 @@ export {
|
|
|
2999
2998
|
createContext,
|
|
3000
2999
|
createComponent,
|
|
3001
3000
|
cleanupPortalPlaceholder,
|
|
3001
|
+
claimSlots,
|
|
3002
3002
|
beginTurn,
|
|
3003
3003
|
batch,
|
|
3004
3004
|
applyRestAttrs,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BarefootJS - Loop Boundary Marker Lookup
|
|
3
|
+
*
|
|
4
|
+
* `<!--bf-loop:<id>-->` / `<!--bf-/loop:<id>-->` comment markers delimit a
|
|
5
|
+
* loop's rendered range inside its container so `mapArray`/`mapArrayAnchored`
|
|
6
|
+
* (`./map-array.ts`) can reconcile only that range without disturbing
|
|
7
|
+
* non-loop siblings. These lookups used to also back the now-removed
|
|
8
|
+
* `reconcileElements`/`reconcileList` element-reconciler (slot unification
|
|
9
|
+
* A4); they remain as the compiler-facing marker API.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Get loop children from a container, respecting bf-loop boundary markers.
|
|
13
|
+
* When markers are present, returns only elements between them.
|
|
14
|
+
* When absent, returns all children (backward compatible).
|
|
15
|
+
* Exported for use by compiler-generated hydration code.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getLoopChildren(container: HTMLElement, markerId?: string): HTMLElement[];
|
|
18
|
+
/**
|
|
19
|
+
* Like {@link getLoopChildren}, but returns every node between the loop
|
|
20
|
+
* boundary markers — Comments (per-item `<!--bf-loop-i-->` markers) and
|
|
21
|
+
* text included. The branch-clearing path needs to remove the per-item
|
|
22
|
+
* marker comments alongside elements; otherwise stale markers would
|
|
23
|
+
* accumulate when a branch swap forces mapArray to start over (#1212).
|
|
24
|
+
*/
|
|
25
|
+
export declare function getLoopNodes(container: HTMLElement, markerId?: string): Node[];
|
|
26
|
+
//# sourceMappingURL=loop-markers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop-markers.d.ts","sourceRoot":"","sources":["../../src/runtime/loop-markers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAyDH;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAMxF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,CAY9E"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-place patch for flatMap leaf elements (the descriptor-based
|
|
3
|
+
* `mapArray` path — see `stringifyPlainLoop`'s flatMap branch in
|
|
4
|
+
* `@barefootjs/jsx`).
|
|
5
|
+
*
|
|
6
|
+
* flatMap leaves carry no per-slot reactive wiring (the compiler refuses
|
|
7
|
+
* leaves that would need it), so a leaf whose rendered HTML changed under a
|
|
8
|
+
* stable key is updated wholesale: attributes are synced and children are
|
|
9
|
+
* replaced from the freshly rendered string. The element's identity is
|
|
10
|
+
* preserved — `mapArray` holds the node in its keyed scope map, so the
|
|
11
|
+
* patch must never swap the node itself.
|
|
12
|
+
*
|
|
13
|
+
* `data-key` is excluded from attribute sync: reconciliation identity is
|
|
14
|
+
* owned by `mapArray` (stamped via `setAttribute`), never by leaf content.
|
|
15
|
+
*/
|
|
16
|
+
export declare function patchLeaf(el: Element, html: string): void;
|
|
17
|
+
//# sourceMappingURL=patch-leaf.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patch-leaf.d.ts","sourceRoot":"","sources":["../../src/runtime/patch-leaf.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAyBzD"}
|