@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
|
@@ -1550,9 +1550,7 @@ function upsertChild(parent, name, slotId, props, key, anchorScope) {
|
|
|
1550
1550
|
const ph = parent.getAttribute(BF_PLACEHOLDER) === phId ? parent : parent.querySelector(`[${BF_PLACEHOLDER}="${phId}"]`);
|
|
1551
1551
|
if (ph) {
|
|
1552
1552
|
const slot = slotId ? buildSlotInfo(parent, slotId, anchorScope) : undefined;
|
|
1553
|
-
|
|
1554
|
-
ph.replaceWith(comp);
|
|
1555
|
-
return comp;
|
|
1553
|
+
return createComponent(name, props, key, slot, ph);
|
|
1556
1554
|
}
|
|
1557
1555
|
return null;
|
|
1558
1556
|
}
|
|
@@ -1758,13 +1756,30 @@ var _parentScopeId = null;
|
|
|
1758
1756
|
function setParentScopeId(id) {
|
|
1759
1757
|
_parentScopeId = id;
|
|
1760
1758
|
}
|
|
1761
|
-
var
|
|
1762
|
-
|
|
1763
|
-
|
|
1759
|
+
var _rowMountPoint = null;
|
|
1760
|
+
function setRowMountPoint(p) {
|
|
1761
|
+
const prev = _rowMountPoint;
|
|
1762
|
+
_rowMountPoint = p;
|
|
1763
|
+
return prev;
|
|
1764
|
+
}
|
|
1765
|
+
function takeRowMountPoint() {
|
|
1766
|
+
const p = _rowMountPoint;
|
|
1767
|
+
_rowMountPoint = null;
|
|
1768
|
+
return p;
|
|
1769
|
+
}
|
|
1770
|
+
function createComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
1771
|
+
const element = materializeComponent(nameOrDef, props, key, slot, mountAt);
|
|
1772
|
+
if (mountAt && mountAt.parentNode && element !== mountAt) {
|
|
1773
|
+
mountAt.replaceWith(element);
|
|
1774
|
+
}
|
|
1775
|
+
return element;
|
|
1776
|
+
}
|
|
1777
|
+
function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
1764
1778
|
if (props == null)
|
|
1765
1779
|
props = {};
|
|
1780
|
+
const rowMount = mountAt ? null : takeRowMountPoint();
|
|
1766
1781
|
if (typeof nameOrDef !== "string") {
|
|
1767
|
-
return createComponentFromDef(nameOrDef, props, key);
|
|
1782
|
+
return createComponentFromDef(nameOrDef, props, key, mountAt, rowMount);
|
|
1768
1783
|
}
|
|
1769
1784
|
const name = nameOrDef;
|
|
1770
1785
|
const templateFn = getTemplate(name);
|
|
@@ -1824,8 +1839,13 @@ function createComponent(nameOrDef, props = {}, key, slot) {
|
|
|
1824
1839
|
if (key !== undefined) {
|
|
1825
1840
|
element.setAttribute(BF_KEY, String(key));
|
|
1826
1841
|
}
|
|
1827
|
-
const prevScope = setCurrentScope(element);
|
|
1828
1842
|
const rootIsDeferredPlaceholder = element.hasAttribute(BF_PLACEHOLDER);
|
|
1843
|
+
if (mountAt && !rootIsDeferredPlaceholder) {
|
|
1844
|
+
mountAt.replaceWith(element);
|
|
1845
|
+
} else if (rowMount && !rootIsDeferredPlaceholder) {
|
|
1846
|
+
rowMount.container.insertBefore(element, rowMount.anchor);
|
|
1847
|
+
}
|
|
1848
|
+
const prevScope = setCurrentScope(element);
|
|
1829
1849
|
let placeholderWrapper = null;
|
|
1830
1850
|
if (rootIsDeferredPlaceholder) {
|
|
1831
1851
|
placeholderWrapper = parseHTML("<div></div>").firstChild;
|
|
@@ -1851,24 +1871,8 @@ function createComponent(nameOrDef, props = {}, key, slot) {
|
|
|
1851
1871
|
}
|
|
1852
1872
|
setCurrentScope(prevScope);
|
|
1853
1873
|
hydratedScopes.add(element);
|
|
1854
|
-
propsMap.set(element, props);
|
|
1855
|
-
registerPropsUpdate(element, name, props);
|
|
1856
1874
|
return element;
|
|
1857
1875
|
}
|
|
1858
|
-
function getComponentProps(element) {
|
|
1859
|
-
return propsMap.get(element);
|
|
1860
|
-
}
|
|
1861
|
-
function registerPropsUpdate(element, name, _initialProps) {
|
|
1862
|
-
propsUpdateMap.set(element, (newProps) => {
|
|
1863
|
-
const init = getComponentInit(name);
|
|
1864
|
-
if (init) {
|
|
1865
|
-
init(element, newProps);
|
|
1866
|
-
}
|
|
1867
|
-
});
|
|
1868
|
-
}
|
|
1869
|
-
function getPropsUpdateFn(element) {
|
|
1870
|
-
return propsUpdateMap.get(element);
|
|
1871
|
-
}
|
|
1872
1876
|
function renderChild(name, props, key, slotSuffix) {
|
|
1873
1877
|
const templateFn = getTemplate(name);
|
|
1874
1878
|
const suffix = slotSuffix ? `_${slotSuffix}` : "";
|
|
@@ -1934,6 +1938,11 @@ function escapeText(value) {
|
|
|
1934
1938
|
return "";
|
|
1935
1939
|
return escapeAttr(value);
|
|
1936
1940
|
}
|
|
1941
|
+
function escapeTextOrNode(value) {
|
|
1942
|
+
if (typeof Node !== "undefined" && value instanceof Node)
|
|
1943
|
+
return value;
|
|
1944
|
+
return escapeText(value);
|
|
1945
|
+
}
|
|
1937
1946
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1938
1947
|
function parseHTML(html, parent) {
|
|
1939
1948
|
const tpl = document.createElement("template");
|
|
@@ -1977,7 +1986,7 @@ function insertGetterChildren(element, children) {
|
|
|
1977
1986
|
element.appendChild(document.createTextNode(String(children)));
|
|
1978
1987
|
}
|
|
1979
1988
|
}
|
|
1980
|
-
function createComponentFromDef(def, props, key) {
|
|
1989
|
+
function createComponentFromDef(def, props, key, mountAt, rowMount) {
|
|
1981
1990
|
if (!def.template) {
|
|
1982
1991
|
throw new Error("[BarefootJS] createComponent with ComponentDef requires a template function");
|
|
1983
1992
|
}
|
|
@@ -1996,9 +2005,13 @@ function createComponentFromDef(def, props, key) {
|
|
|
1996
2005
|
if (key !== undefined) {
|
|
1997
2006
|
element.setAttribute(BF_KEY, String(key));
|
|
1998
2007
|
}
|
|
2008
|
+
if (mountAt) {
|
|
2009
|
+
mountAt.replaceWith(element);
|
|
2010
|
+
} else if (rowMount) {
|
|
2011
|
+
rowMount.container.insertBefore(element, rowMount.anchor);
|
|
2012
|
+
}
|
|
1999
2013
|
def.init(element, props);
|
|
2000
2014
|
hydratedScopes.add(element);
|
|
2001
|
-
propsMap.set(element, props);
|
|
2002
2015
|
return element;
|
|
2003
2016
|
}
|
|
2004
2017
|
|
|
@@ -2056,7 +2069,7 @@ function createPortal(children, container = document.body, options) {
|
|
|
2056
2069
|
}
|
|
2057
2070
|
};
|
|
2058
2071
|
}
|
|
2059
|
-
// src/runtime/
|
|
2072
|
+
// src/runtime/loop-markers.ts
|
|
2060
2073
|
function findLoopMarkers(container, markerId) {
|
|
2061
2074
|
let startMarker = null;
|
|
2062
2075
|
let endMarker = null;
|
|
@@ -2101,14 +2114,6 @@ function getElementsBetweenMarkers(start, end) {
|
|
|
2101
2114
|
}
|
|
2102
2115
|
return elements;
|
|
2103
2116
|
}
|
|
2104
|
-
function removeElementsBetweenMarkers(start, end) {
|
|
2105
|
-
let node = start.nextSibling;
|
|
2106
|
-
while (node && node !== end) {
|
|
2107
|
-
const next = node.nextSibling;
|
|
2108
|
-
node.parentNode?.removeChild(node);
|
|
2109
|
-
node = next;
|
|
2110
|
-
}
|
|
2111
|
-
}
|
|
2112
2117
|
function getLoopChildren(container, markerId) {
|
|
2113
2118
|
const { startMarker, endMarker } = findLoopMarkers(container, markerId);
|
|
2114
2119
|
if (startMarker && endMarker) {
|
|
@@ -2129,159 +2134,6 @@ function getLoopNodes(container, markerId) {
|
|
|
2129
2134
|
}
|
|
2130
2135
|
return Array.from(container.childNodes);
|
|
2131
2136
|
}
|
|
2132
|
-
function reconcileElements(container, items, getKey, renderItem, firstElement, markerId) {
|
|
2133
|
-
if (!container || !items)
|
|
2134
|
-
return;
|
|
2135
|
-
const { startMarker, endMarker } = findLoopMarkers(container, markerId);
|
|
2136
|
-
const existingByKey = new Map;
|
|
2137
|
-
let hasKeyedChildren = false;
|
|
2138
|
-
const loopChildren = startMarker ? getElementsBetweenMarkers(startMarker, endMarker) : Array.from(container.children);
|
|
2139
|
-
for (const child of loopChildren) {
|
|
2140
|
-
const el = child;
|
|
2141
|
-
const key = el.dataset?.key;
|
|
2142
|
-
if (key !== undefined) {
|
|
2143
|
-
existingByKey.set(key, el);
|
|
2144
|
-
hasKeyedChildren = true;
|
|
2145
|
-
}
|
|
2146
|
-
}
|
|
2147
|
-
if (!hasKeyedChildren) {
|
|
2148
|
-
if (items.length === 0) {
|
|
2149
|
-
if (startMarker) {
|
|
2150
|
-
removeElementsBetweenMarkers(startMarker, endMarker);
|
|
2151
|
-
} else {
|
|
2152
|
-
container.innerHTML = "";
|
|
2153
|
-
}
|
|
2154
|
-
return;
|
|
2155
|
-
}
|
|
2156
|
-
const fragment = document.createDocumentFragment();
|
|
2157
|
-
for (let i = 0;i < items.length; i++) {
|
|
2158
|
-
const el = i === 0 && firstElement ? firstElement : renderItem(items[i], i);
|
|
2159
|
-
const key = getKey ? getKey(items[i], i) : String(i);
|
|
2160
|
-
if (!el.dataset.key)
|
|
2161
|
-
el.setAttribute(BF_KEY, key);
|
|
2162
|
-
fragment.appendChild(el);
|
|
2163
|
-
}
|
|
2164
|
-
if (startMarker) {
|
|
2165
|
-
removeElementsBetweenMarkers(startMarker, endMarker);
|
|
2166
|
-
endMarker.parentNode.insertBefore(fragment, endMarker);
|
|
2167
|
-
} else {
|
|
2168
|
-
container.innerHTML = "";
|
|
2169
|
-
container.appendChild(fragment);
|
|
2170
|
-
}
|
|
2171
|
-
return;
|
|
2172
|
-
}
|
|
2173
|
-
let insertAnchor = endMarker ?? null;
|
|
2174
|
-
if (!startMarker) {
|
|
2175
|
-
let foundKeyed = false;
|
|
2176
|
-
for (const child of Array.from(container.childNodes)) {
|
|
2177
|
-
if (child.nodeType === Node.ELEMENT_NODE && child.dataset.key !== undefined) {
|
|
2178
|
-
foundKeyed = true;
|
|
2179
|
-
} else if (foundKeyed) {
|
|
2180
|
-
insertAnchor = child;
|
|
2181
|
-
break;
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
let focusedKey = null;
|
|
2186
|
-
const activeEl = document.activeElement;
|
|
2187
|
-
if (activeEl && activeEl !== document.body) {
|
|
2188
|
-
const tag = activeEl.tagName;
|
|
2189
|
-
if (tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || activeEl.isContentEditable) {
|
|
2190
|
-
for (const [key, el] of existingByKey) {
|
|
2191
|
-
if (el.contains(activeEl)) {
|
|
2192
|
-
focusedKey = key;
|
|
2193
|
-
break;
|
|
2194
|
-
}
|
|
2195
|
-
}
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
2198
|
-
const desiredElements = [];
|
|
2199
|
-
const toRemove = [];
|
|
2200
|
-
let focusTarget = null;
|
|
2201
|
-
for (let i = 0;i < items.length; i++) {
|
|
2202
|
-
const item = items[i];
|
|
2203
|
-
const key = getKey ? getKey(item, i) : String(i);
|
|
2204
|
-
const createEl = () => i === 0 && firstElement ? firstElement : renderItem(item, i);
|
|
2205
|
-
const existing = existingByKey.get(key);
|
|
2206
|
-
if (existing) {
|
|
2207
|
-
existingByKey.delete(key);
|
|
2208
|
-
if (existing.getAttribute(BF_SCOPE) && !hydratedScopes.has(existing)) {
|
|
2209
|
-
const newEl = createEl();
|
|
2210
|
-
if (!newEl.dataset.key)
|
|
2211
|
-
newEl.setAttribute(BF_KEY, key);
|
|
2212
|
-
desiredElements.push(newEl);
|
|
2213
|
-
toRemove.push(existing);
|
|
2214
|
-
} else if (focusedKey === key) {
|
|
2215
|
-
const newEl = createEl();
|
|
2216
|
-
if (!newEl.dataset.key)
|
|
2217
|
-
newEl.setAttribute(BF_KEY, key);
|
|
2218
|
-
focusTarget = prepareInputTransfer(existing, newEl);
|
|
2219
|
-
desiredElements.push(newEl);
|
|
2220
|
-
toRemove.push(existing);
|
|
2221
|
-
} else {
|
|
2222
|
-
const newEl = createEl();
|
|
2223
|
-
if (!newEl.dataset.key)
|
|
2224
|
-
newEl.setAttribute(BF_KEY, key);
|
|
2225
|
-
desiredElements.push(newEl);
|
|
2226
|
-
toRemove.push(existing);
|
|
2227
|
-
}
|
|
2228
|
-
} else {
|
|
2229
|
-
const el = createEl();
|
|
2230
|
-
if (!el.dataset.key)
|
|
2231
|
-
el.setAttribute(BF_KEY, key);
|
|
2232
|
-
desiredElements.push(el);
|
|
2233
|
-
}
|
|
2234
|
-
}
|
|
2235
|
-
for (const el of existingByKey.values()) {
|
|
2236
|
-
toRemove.push(el);
|
|
2237
|
-
}
|
|
2238
|
-
for (const el of toRemove) {
|
|
2239
|
-
if (el.parentNode)
|
|
2240
|
-
el.remove();
|
|
2241
|
-
}
|
|
2242
|
-
for (const el of desiredElements) {
|
|
2243
|
-
container.insertBefore(el, insertAnchor);
|
|
2244
|
-
}
|
|
2245
|
-
if (focusTarget) {
|
|
2246
|
-
focusTarget.target.focus();
|
|
2247
|
-
if (typeof focusTarget.selectionStart === "number") {
|
|
2248
|
-
focusTarget.target.selectionStart = focusTarget.selectionStart;
|
|
2249
|
-
focusTarget.target.selectionEnd = focusTarget.selectionEnd;
|
|
2250
|
-
}
|
|
2251
|
-
}
|
|
2252
|
-
}
|
|
2253
|
-
function prepareInputTransfer(oldEl, newEl) {
|
|
2254
|
-
const focused = oldEl.contains(document.activeElement) ? document.activeElement : null;
|
|
2255
|
-
if (!focused)
|
|
2256
|
-
return null;
|
|
2257
|
-
const tag = focused.tagName;
|
|
2258
|
-
const oldInputs = Array.from(oldEl.querySelectorAll(tag));
|
|
2259
|
-
const idx = oldInputs.indexOf(focused);
|
|
2260
|
-
if (idx < 0)
|
|
2261
|
-
return null;
|
|
2262
|
-
const newInputs = Array.from(newEl.querySelectorAll(tag));
|
|
2263
|
-
const target = newInputs[idx];
|
|
2264
|
-
if (!target)
|
|
2265
|
-
return null;
|
|
2266
|
-
target.value = focused.value;
|
|
2267
|
-
return {
|
|
2268
|
-
target,
|
|
2269
|
-
selectionStart: focused.selectionStart,
|
|
2270
|
-
selectionEnd: focused.selectionEnd
|
|
2271
|
-
};
|
|
2272
|
-
}
|
|
2273
|
-
|
|
2274
|
-
// src/runtime/list.ts
|
|
2275
|
-
function reconcileList(container, items, getKey, renderItem) {
|
|
2276
|
-
if (!container || !items)
|
|
2277
|
-
return;
|
|
2278
|
-
if (items.length === 0) {
|
|
2279
|
-
container.innerHTML = "";
|
|
2280
|
-
return;
|
|
2281
|
-
}
|
|
2282
|
-
const firstElement = renderItem(items[0], 0);
|
|
2283
|
-
reconcileElements(container, items, getKey, renderItem, firstElement);
|
|
2284
|
-
}
|
|
2285
2137
|
// src/runtime/qsa-item.ts
|
|
2286
2138
|
function* itemRootElements(primaryEl) {
|
|
2287
2139
|
yield primaryEl;
|
|
@@ -2338,9 +2190,7 @@ function upsertChildItem(primaryEl, name, slotId, props, key, anchorScope) {
|
|
|
2338
2190
|
const ph = qsaItem(primaryEl, `[data-bf-ph="${phId}"]`);
|
|
2339
2191
|
if (ph) {
|
|
2340
2192
|
const slot = slotId ? buildSlotInfo(primaryEl, slotId, anchorScope) : undefined;
|
|
2341
|
-
|
|
2342
|
-
ph.replaceWith(comp);
|
|
2343
|
-
return comp;
|
|
2193
|
+
return createComponent(name, props, key, slot, ph);
|
|
2344
2194
|
}
|
|
2345
2195
|
return null;
|
|
2346
2196
|
}
|
|
@@ -2452,7 +2302,7 @@ function removeScope(scope) {
|
|
|
2452
2302
|
ex.remove();
|
|
2453
2303
|
}
|
|
2454
2304
|
}
|
|
2455
|
-
function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart) {
|
|
2305
|
+
function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart, rowMount) {
|
|
2456
2306
|
let primaryEl;
|
|
2457
2307
|
let dispose;
|
|
2458
2308
|
let setItem;
|
|
@@ -2462,7 +2312,14 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
2462
2312
|
dispose = d;
|
|
2463
2313
|
const [itemAccessor, itemSetter] = createSignal(item);
|
|
2464
2314
|
setItem = itemSetter;
|
|
2465
|
-
|
|
2315
|
+
const ownsRowMount = !existingPrimary && !!rowMount;
|
|
2316
|
+
const prevRowMount = ownsRowMount ? setRowMountPoint(rowMount) : null;
|
|
2317
|
+
try {
|
|
2318
|
+
primaryEl = renderItem(itemAccessor, index, existingPrimary);
|
|
2319
|
+
} finally {
|
|
2320
|
+
if (ownsRowMount)
|
|
2321
|
+
setRowMountPoint(prevRowMount);
|
|
2322
|
+
}
|
|
2466
2323
|
if (existingPrimary) {
|
|
2467
2324
|
extras = existingExtras ?? [];
|
|
2468
2325
|
startMarker = existingStart ?? null;
|
|
@@ -2476,6 +2333,9 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
2476
2333
|
}
|
|
2477
2334
|
return;
|
|
2478
2335
|
});
|
|
2336
|
+
if (rowMount && !existingPrimary && extras.length > 0 && primaryEl.parentNode) {
|
|
2337
|
+
primaryEl.remove();
|
|
2338
|
+
}
|
|
2479
2339
|
return { startMarker, primaryEl, extras, dispose, setItem };
|
|
2480
2340
|
}
|
|
2481
2341
|
function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
@@ -2517,7 +2377,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2517
2377
|
for (let i2 = existingRanges.length;i2 < items.length; i2++) {
|
|
2518
2378
|
const item = items[i2];
|
|
2519
2379
|
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2520
|
-
const scope = createItemScope(item, i2, renderItem);
|
|
2380
|
+
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
|
|
2521
2381
|
if (!scope.primaryEl.dataset.key)
|
|
2522
2382
|
scope.primaryEl.setAttribute(BF_KEY, key);
|
|
2523
2383
|
scopes.set(key, scope);
|
|
@@ -2596,7 +2456,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2596
2456
|
existing.setItem(item);
|
|
2597
2457
|
desiredOrder.push(existing);
|
|
2598
2458
|
} else {
|
|
2599
|
-
const scope = createItemScope(item, i2, renderItem);
|
|
2459
|
+
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
|
|
2600
2460
|
if (!scope.primaryEl.dataset.key)
|
|
2601
2461
|
scope.primaryEl.setAttribute(BF_KEY, key);
|
|
2602
2462
|
scopes.set(key, scope);
|
|
@@ -2792,6 +2652,197 @@ function mapArrayAnchored(accessor, container, getKey, renderItem, markerId, bfI
|
|
|
2792
2652
|
}
|
|
2793
2653
|
}, bfId);
|
|
2794
2654
|
}
|
|
2655
|
+
// src/runtime/map-array-lazy.ts
|
|
2656
|
+
function mapArrayLazy(accessor, container, getKey, plan, markerId, bfId) {
|
|
2657
|
+
if (!container)
|
|
2658
|
+
return;
|
|
2659
|
+
const entries = new Map;
|
|
2660
|
+
let entryList = [];
|
|
2661
|
+
let hydrated = false;
|
|
2662
|
+
const needsResubscribe = plan.applyOuter !== undefined;
|
|
2663
|
+
const [generation, bumpGeneration] = needsResubscribe ? createSignal(0) : [null, null];
|
|
2664
|
+
let stranded = false;
|
|
2665
|
+
const markStranded = () => {
|
|
2666
|
+
if (needsResubscribe)
|
|
2667
|
+
stranded = true;
|
|
2668
|
+
};
|
|
2669
|
+
const flushStranded = () => {
|
|
2670
|
+
if (stranded && bumpGeneration) {
|
|
2671
|
+
stranded = false;
|
|
2672
|
+
bumpGeneration((n) => n + 1);
|
|
2673
|
+
}
|
|
2674
|
+
};
|
|
2675
|
+
let cachedStart = null;
|
|
2676
|
+
let cachedEnd = null;
|
|
2677
|
+
const resolveMarkers = () => {
|
|
2678
|
+
if (cachedStart && cachedEnd && cachedStart.isConnected && cachedEnd.isConnected) {
|
|
2679
|
+
return { start: cachedStart, end: cachedEnd };
|
|
2680
|
+
}
|
|
2681
|
+
const found = findLoopMarkers2(container, markerId);
|
|
2682
|
+
cachedStart = found.start;
|
|
2683
|
+
cachedEnd = found.end;
|
|
2684
|
+
return found;
|
|
2685
|
+
};
|
|
2686
|
+
const createEntry = (item, index, key) => {
|
|
2687
|
+
const entry = {
|
|
2688
|
+
key,
|
|
2689
|
+
primaryEl: undefined,
|
|
2690
|
+
item,
|
|
2691
|
+
refs: null,
|
|
2692
|
+
last: null
|
|
2693
|
+
};
|
|
2694
|
+
entry.primaryEl = untrack(() => plan.createRow(entry, index));
|
|
2695
|
+
if (!entry.primaryEl.dataset.key)
|
|
2696
|
+
entry.primaryEl.setAttribute(BF_KEY, key);
|
|
2697
|
+
markStranded();
|
|
2698
|
+
return entry;
|
|
2699
|
+
};
|
|
2700
|
+
createEffect(() => {
|
|
2701
|
+
const items = accessor();
|
|
2702
|
+
if (!items)
|
|
2703
|
+
return;
|
|
2704
|
+
const { start: startMarker, end: endMarker } = resolveMarkers();
|
|
2705
|
+
const anchor = endMarker ?? null;
|
|
2706
|
+
if (!hydrated) {
|
|
2707
|
+
hydrated = true;
|
|
2708
|
+
const doms = [];
|
|
2709
|
+
for (let node = startMarker ? startMarker.nextSibling : container.firstChild;node && node !== anchor; node = node.nextSibling) {
|
|
2710
|
+
if (node.nodeType === Node.ELEMENT_NODE)
|
|
2711
|
+
doms.push(node);
|
|
2712
|
+
}
|
|
2713
|
+
if (doms.length > 0 && entries.size === 0) {
|
|
2714
|
+
const list = [];
|
|
2715
|
+
const shared = Math.min(doms.length, items.length);
|
|
2716
|
+
for (let i2 = 0;i2 < shared; i2++) {
|
|
2717
|
+
const el = doms[i2];
|
|
2718
|
+
const ssrKey = el.getAttribute(BF_KEY);
|
|
2719
|
+
const key = ssrKey !== null ? ssrKey : getKey ? getKey(items[i2], i2) : String(i2);
|
|
2720
|
+
const entry = { key, primaryEl: el, item: items[i2], refs: null, last: null };
|
|
2721
|
+
entries.set(key, entry);
|
|
2722
|
+
list.push(entry);
|
|
2723
|
+
}
|
|
2724
|
+
for (let i2 = doms.length;i2 < items.length; i2++) {
|
|
2725
|
+
const item = items[i2];
|
|
2726
|
+
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2727
|
+
const entry = createEntry(item, i2, key);
|
|
2728
|
+
entries.set(key, entry);
|
|
2729
|
+
list.push(entry);
|
|
2730
|
+
container.insertBefore(entry.primaryEl, anchor);
|
|
2731
|
+
}
|
|
2732
|
+
for (let i2 = items.length;i2 < doms.length; i2++)
|
|
2733
|
+
doms[i2].remove();
|
|
2734
|
+
entryList = list;
|
|
2735
|
+
flushStranded();
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
if (items.length === 0) {
|
|
2740
|
+
if (entries.size > 0) {
|
|
2741
|
+
if (startMarker && endMarker) {
|
|
2742
|
+
const range = document.createRange();
|
|
2743
|
+
range.setStartAfter(startMarker);
|
|
2744
|
+
range.setEndBefore(endMarker);
|
|
2745
|
+
range.deleteContents();
|
|
2746
|
+
} else {
|
|
2747
|
+
let actualNodeCount = 0;
|
|
2748
|
+
for (let node = container.firstChild;node; node = node.nextSibling)
|
|
2749
|
+
actualNodeCount++;
|
|
2750
|
+
if (actualNodeCount === entries.size) {
|
|
2751
|
+
container.textContent = "";
|
|
2752
|
+
} else {
|
|
2753
|
+
for (const entry of entries.values())
|
|
2754
|
+
entry.primaryEl.remove();
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
entries.clear();
|
|
2758
|
+
entryList = [];
|
|
2759
|
+
}
|
|
2760
|
+
return;
|
|
2761
|
+
}
|
|
2762
|
+
const newKeys = new Set;
|
|
2763
|
+
const warnedKeys = new Set;
|
|
2764
|
+
const desiredOrder = [];
|
|
2765
|
+
for (let i2 = 0;i2 < items.length; i2++) {
|
|
2766
|
+
const item = items[i2];
|
|
2767
|
+
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2768
|
+
if (newKeys.has(key) && !warnedKeys.has(key)) {
|
|
2769
|
+
warnedKeys.add(key);
|
|
2770
|
+
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.`);
|
|
2771
|
+
}
|
|
2772
|
+
newKeys.add(key);
|
|
2773
|
+
const existing = entries.get(key);
|
|
2774
|
+
if (existing) {
|
|
2775
|
+
if (!Object.is(existing.item, item)) {
|
|
2776
|
+
const prevItem = existing.item;
|
|
2777
|
+
existing.item = item;
|
|
2778
|
+
untrack(() => plan.applyItem(existing, prevItem));
|
|
2779
|
+
markStranded();
|
|
2780
|
+
}
|
|
2781
|
+
desiredOrder.push(existing);
|
|
2782
|
+
} else {
|
|
2783
|
+
const entry = createEntry(item, i2, key);
|
|
2784
|
+
entries.set(key, entry);
|
|
2785
|
+
desiredOrder.push(entry);
|
|
2786
|
+
}
|
|
2787
|
+
}
|
|
2788
|
+
for (const [key, entry] of entries) {
|
|
2789
|
+
if (!newKeys.has(key)) {
|
|
2790
|
+
if (entry.primaryEl.parentNode)
|
|
2791
|
+
entry.primaryEl.remove();
|
|
2792
|
+
entries.delete(key);
|
|
2793
|
+
}
|
|
2794
|
+
}
|
|
2795
|
+
const primaryElToDesiredIndex = new Map;
|
|
2796
|
+
for (let i2 = 0;i2 < desiredOrder.length; i2++) {
|
|
2797
|
+
primaryElToDesiredIndex.set(desiredOrder[i2].primaryEl, i2);
|
|
2798
|
+
}
|
|
2799
|
+
const domOrderIndices = [];
|
|
2800
|
+
for (let node = startMarker ? startMarker.nextSibling : container.firstChild;node && node !== anchor; node = node.nextSibling) {
|
|
2801
|
+
if (node.nodeType !== Node.ELEMENT_NODE)
|
|
2802
|
+
continue;
|
|
2803
|
+
const idx = primaryElToDesiredIndex.get(node);
|
|
2804
|
+
if (idx !== undefined)
|
|
2805
|
+
domOrderIndices.push(idx);
|
|
2806
|
+
}
|
|
2807
|
+
const stationary = new Array(desiredOrder.length).fill(false);
|
|
2808
|
+
for (const pos of longestIncreasingSubsequenceIndices(domOrderIndices)) {
|
|
2809
|
+
stationary[domOrderIndices[pos]] = true;
|
|
2810
|
+
}
|
|
2811
|
+
let i = 0;
|
|
2812
|
+
while (i < desiredOrder.length) {
|
|
2813
|
+
if (stationary[i]) {
|
|
2814
|
+
i++;
|
|
2815
|
+
continue;
|
|
2816
|
+
}
|
|
2817
|
+
let j = i;
|
|
2818
|
+
while (j < desiredOrder.length && !stationary[j])
|
|
2819
|
+
j++;
|
|
2820
|
+
const before = j < desiredOrder.length ? desiredOrder[j].primaryEl : anchor;
|
|
2821
|
+
if (j - i === 1) {
|
|
2822
|
+
container.insertBefore(desiredOrder[i].primaryEl, before);
|
|
2823
|
+
} else {
|
|
2824
|
+
const runFragment = document.createDocumentFragment();
|
|
2825
|
+
for (let k = i;k < j; k++)
|
|
2826
|
+
runFragment.appendChild(desiredOrder[k].primaryEl);
|
|
2827
|
+
container.insertBefore(runFragment, before);
|
|
2828
|
+
}
|
|
2829
|
+
i = j;
|
|
2830
|
+
}
|
|
2831
|
+
entryList = desiredOrder;
|
|
2832
|
+
flushStranded();
|
|
2833
|
+
}, bfId);
|
|
2834
|
+
if (plan.applyOuter) {
|
|
2835
|
+
const applyOuter = plan.applyOuter.bind(plan);
|
|
2836
|
+
let seed = true;
|
|
2837
|
+
createEffect(() => {
|
|
2838
|
+
if (generation)
|
|
2839
|
+
generation();
|
|
2840
|
+
const isSeed = seed;
|
|
2841
|
+
seed = false;
|
|
2842
|
+
applyOuter(entryList, isSeed);
|
|
2843
|
+
});
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2795
2846
|
// src/runtime/patch-leaf.ts
|
|
2796
2847
|
function patchLeaf(el, html) {
|
|
2797
2848
|
const tpl = document.createElement("template");
|
|
@@ -2817,35 +2868,44 @@ function patchLeaf(el, html) {
|
|
|
2817
2868
|
}
|
|
2818
2869
|
el.replaceChildren(...Array.from(next.childNodes));
|
|
2819
2870
|
}
|
|
2820
|
-
// src/runtime/
|
|
2821
|
-
function
|
|
2871
|
+
// src/runtime/claim-slots.ts
|
|
2872
|
+
function resolvePath(root, path) {
|
|
2873
|
+
let node = root;
|
|
2874
|
+
for (const index of path) {
|
|
2875
|
+
const child = node.childNodes[index];
|
|
2876
|
+
if (!child)
|
|
2877
|
+
return null;
|
|
2878
|
+
node = child;
|
|
2879
|
+
}
|
|
2880
|
+
return node;
|
|
2881
|
+
}
|
|
2882
|
+
function isSlotComment(node, id) {
|
|
2883
|
+
return node != null && node.nodeType === Node.COMMENT_NODE && node.nodeValue === `bf:${id}`;
|
|
2884
|
+
}
|
|
2885
|
+
function findOwnedMarker(root, id) {
|
|
2822
2886
|
const marker = `bf:${id}`;
|
|
2823
|
-
|
|
2824
|
-
const
|
|
2825
|
-
|
|
2826
|
-
|
|
2887
|
+
const parentOwned = id.startsWith(BF_PARENT_OWNED_PREFIX);
|
|
2888
|
+
const registryInfo = commentScopeRegistry.get(root);
|
|
2889
|
+
const boundary = registryInfo ? registryInfo.commentNode.parentElement : root;
|
|
2890
|
+
for (const comment of commentsInScope(root)) {
|
|
2827
2891
|
if (comment.nodeValue !== marker)
|
|
2828
2892
|
continue;
|
|
2893
|
+
if (parentOwned)
|
|
2894
|
+
return comment;
|
|
2829
2895
|
let owned = true;
|
|
2830
|
-
for (let el = comment.parentElement;el && el !==
|
|
2896
|
+
for (let el = comment.parentElement;el && el !== boundary; el = el.parentElement) {
|
|
2831
2897
|
if (el.hasAttribute(BF_SCOPE)) {
|
|
2832
2898
|
owned = false;
|
|
2833
2899
|
break;
|
|
2834
2900
|
}
|
|
2835
2901
|
}
|
|
2836
|
-
if (owned)
|
|
2837
|
-
|
|
2838
|
-
break;
|
|
2839
|
-
}
|
|
2840
|
-
}
|
|
2841
|
-
const parent = start?.parentNode;
|
|
2842
|
-
if (!start || !parent) {
|
|
2843
|
-
console.warn(`[barefootjs] preamble region marker bf:${id} not found in row; skipping patch`);
|
|
2844
|
-
return;
|
|
2902
|
+
if (owned)
|
|
2903
|
+
return comment;
|
|
2845
2904
|
}
|
|
2905
|
+
return null;
|
|
2906
|
+
}
|
|
2907
|
+
function findMarkupEnd(start) {
|
|
2846
2908
|
let depth = 0;
|
|
2847
|
-
let end = null;
|
|
2848
|
-
const toRemove = [];
|
|
2849
2909
|
let node = start.nextSibling;
|
|
2850
2910
|
while (node) {
|
|
2851
2911
|
if (node.nodeType === Node.COMMENT_NODE) {
|
|
@@ -2853,25 +2913,192 @@ function patchSlotRange(scope, id, html) {
|
|
|
2853
2913
|
if (value.startsWith("bf:")) {
|
|
2854
2914
|
depth++;
|
|
2855
2915
|
} else if (value === "/") {
|
|
2856
|
-
if (depth === 0)
|
|
2857
|
-
|
|
2858
|
-
break;
|
|
2859
|
-
}
|
|
2916
|
+
if (depth === 0)
|
|
2917
|
+
return node;
|
|
2860
2918
|
depth--;
|
|
2861
2919
|
}
|
|
2862
2920
|
}
|
|
2863
|
-
toRemove.push(node);
|
|
2864
2921
|
node = node.nextSibling;
|
|
2865
2922
|
}
|
|
2923
|
+
return null;
|
|
2924
|
+
}
|
|
2925
|
+
function resolveAnchor(root, spec) {
|
|
2926
|
+
if (spec.path.length > 0) {
|
|
2927
|
+
const resolved = resolvePath(root, spec.path);
|
|
2928
|
+
if (isSlotComment(resolved, spec.id))
|
|
2929
|
+
return resolved;
|
|
2930
|
+
console.warn(`[barefootjs] claim path for slot ${spec.id} did not resolve to its bf:${spec.id} marker; falling back to a scan`);
|
|
2931
|
+
}
|
|
2932
|
+
const found = findOwnedMarker(root, spec.id);
|
|
2933
|
+
if (!found) {
|
|
2934
|
+
console.warn(`[barefootjs] slot ${spec.id} marker not found; skipping`);
|
|
2935
|
+
}
|
|
2936
|
+
return found;
|
|
2937
|
+
}
|
|
2938
|
+
function claimMarkerlessText(root, spec) {
|
|
2939
|
+
if (spec.path.length === 0) {
|
|
2940
|
+
console.warn(`[barefootjs] markerless slot ${spec.id} has an empty path; skipping`);
|
|
2941
|
+
return null;
|
|
2942
|
+
}
|
|
2943
|
+
const parentPath = spec.path.slice(0, -1);
|
|
2944
|
+
const idx = spec.path[spec.path.length - 1];
|
|
2945
|
+
const parent = resolvePath(root, parentPath);
|
|
2946
|
+
if (!parent) {
|
|
2947
|
+
console.warn(`[barefootjs] markerless claim path for slot ${spec.id} did not resolve to a parent node; skipping`);
|
|
2948
|
+
return null;
|
|
2949
|
+
}
|
|
2950
|
+
const existing = parent.childNodes[idx];
|
|
2951
|
+
if (existing && existing.nodeType === Node.TEXT_NODE) {
|
|
2952
|
+
return { kind: "text", ref: existing };
|
|
2953
|
+
}
|
|
2954
|
+
const node = document.createTextNode("");
|
|
2955
|
+
parent.insertBefore(node, existing ?? null);
|
|
2956
|
+
return { kind: "text", ref: node };
|
|
2957
|
+
}
|
|
2958
|
+
function claimOne(root, spec) {
|
|
2959
|
+
if (spec.kind === "text" && spec.markerless) {
|
|
2960
|
+
return claimMarkerlessText(root, spec);
|
|
2961
|
+
}
|
|
2962
|
+
const anchor = resolveAnchor(root, spec);
|
|
2963
|
+
if (!anchor)
|
|
2964
|
+
return null;
|
|
2965
|
+
if (spec.kind === "text") {
|
|
2966
|
+
const next = anchor.nextSibling;
|
|
2967
|
+
return { kind: "text", ref: next?.nodeType === Node.TEXT_NODE ? next : anchor };
|
|
2968
|
+
}
|
|
2969
|
+
const end = findMarkupEnd(anchor);
|
|
2970
|
+
if (!end) {
|
|
2971
|
+
console.warn(`[barefootjs] slot ${spec.id} has no end marker; skipping`);
|
|
2972
|
+
return null;
|
|
2973
|
+
}
|
|
2974
|
+
return { kind: "markup", start: anchor, end, last: undefined };
|
|
2975
|
+
}
|
|
2976
|
+
function materializeText(slot) {
|
|
2977
|
+
const anchor = slot.ref;
|
|
2978
|
+
const parent = anchor.parentNode;
|
|
2979
|
+
if (!parent)
|
|
2980
|
+
return null;
|
|
2981
|
+
const node = document.createTextNode("");
|
|
2982
|
+
parent.insertBefore(node, anchor.nextSibling);
|
|
2983
|
+
slot.ref = node;
|
|
2984
|
+
return node;
|
|
2985
|
+
}
|
|
2986
|
+
function readText(slot) {
|
|
2987
|
+
return slot.ref.nodeType === Node.TEXT_NODE ? slot.ref.nodeValue ?? "" : "";
|
|
2988
|
+
}
|
|
2989
|
+
function writeText(slot, value) {
|
|
2990
|
+
const node = slot.ref.nodeType === Node.TEXT_NODE ? slot.ref : materializeText(slot);
|
|
2991
|
+
if (!node)
|
|
2992
|
+
return;
|
|
2993
|
+
node.nodeValue = String(value ?? "");
|
|
2994
|
+
}
|
|
2995
|
+
function textOrNode(value) {
|
|
2996
|
+
if (typeof Node !== "undefined" && value instanceof Node)
|
|
2997
|
+
return value;
|
|
2998
|
+
return String(value);
|
|
2999
|
+
}
|
|
3000
|
+
function promoteTextToMarkup(slot, id) {
|
|
3001
|
+
const anchor = slot.ref.nodeType === Node.COMMENT_NODE ? slot.ref : isSlotComment(slot.ref.previousSibling, id) ? slot.ref.previousSibling : null;
|
|
3002
|
+
if (!anchor) {
|
|
3003
|
+
console.warn(`[barefootjs] slot ${id} was claimed as text and received a Node, but has no anchor marker to promote from; write ignored`);
|
|
3004
|
+
return null;
|
|
3005
|
+
}
|
|
3006
|
+
const end = findMarkupEnd(anchor);
|
|
2866
3007
|
if (!end) {
|
|
2867
|
-
console.warn(`[barefootjs]
|
|
3008
|
+
console.warn(`[barefootjs] slot ${id} was claimed as text and received a Node, but has no end marker; write ignored`);
|
|
3009
|
+
return null;
|
|
3010
|
+
}
|
|
3011
|
+
return { kind: "markup", start: anchor, end, last: undefined };
|
|
3012
|
+
}
|
|
3013
|
+
function clearMarkupRange(start, end) {
|
|
3014
|
+
const parent = end.parentNode;
|
|
3015
|
+
if (!parent)
|
|
2868
3016
|
return;
|
|
3017
|
+
let node = start.nextSibling;
|
|
3018
|
+
while (node && node !== end) {
|
|
3019
|
+
const next = node.nextSibling;
|
|
3020
|
+
parent.removeChild(node);
|
|
3021
|
+
node = next;
|
|
2869
3022
|
}
|
|
2870
|
-
|
|
2871
|
-
|
|
3023
|
+
}
|
|
3024
|
+
function writeMarkup(ref, value) {
|
|
3025
|
+
const { start, end } = ref;
|
|
3026
|
+
const parent = end.parentNode;
|
|
3027
|
+
if (!parent)
|
|
3028
|
+
return;
|
|
3029
|
+
if (value != null && value.__isSlot)
|
|
3030
|
+
return;
|
|
3031
|
+
if (typeof Node !== "undefined" && value instanceof Node) {
|
|
3032
|
+
if (value === ref.last)
|
|
3033
|
+
return;
|
|
3034
|
+
clearMarkupRange(start, end);
|
|
3035
|
+
parent.insertBefore(value, end);
|
|
3036
|
+
ref.last = value;
|
|
3037
|
+
return;
|
|
3038
|
+
}
|
|
3039
|
+
const text = String(value ?? "");
|
|
3040
|
+
if (text === ref.last)
|
|
3041
|
+
return;
|
|
3042
|
+
clearMarkupRange(start, end);
|
|
2872
3043
|
const tpl = document.createElement("template");
|
|
2873
|
-
tpl.innerHTML =
|
|
3044
|
+
tpl.innerHTML = text;
|
|
2874
3045
|
parent.insertBefore(tpl.content, end);
|
|
3046
|
+
ref.last = text;
|
|
3047
|
+
}
|
|
3048
|
+
function writeSlot(refs, id, value) {
|
|
3049
|
+
const ref = refs.get(id);
|
|
3050
|
+
if (!ref) {
|
|
3051
|
+
console.warn(`[barefootjs] no claimed slot for id ${id}; write ignored`);
|
|
3052
|
+
return;
|
|
3053
|
+
}
|
|
3054
|
+
if (ref.kind === "text") {
|
|
3055
|
+
if (typeof Node !== "undefined" && value instanceof Node) {
|
|
3056
|
+
const promoted = promoteTextToMarkup(ref, id);
|
|
3057
|
+
if (!promoted)
|
|
3058
|
+
return;
|
|
3059
|
+
refs.set(id, promoted);
|
|
3060
|
+
writeMarkup(promoted, value);
|
|
3061
|
+
return;
|
|
3062
|
+
}
|
|
3063
|
+
writeText(ref, value);
|
|
3064
|
+
} else {
|
|
3065
|
+
writeMarkup(ref, value);
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3068
|
+
function readSlot(refs, id) {
|
|
3069
|
+
const ref = refs.get(id);
|
|
3070
|
+
if (!ref || ref.kind !== "text")
|
|
3071
|
+
return null;
|
|
3072
|
+
return readText(ref);
|
|
3073
|
+
}
|
|
3074
|
+
function claimSlots(root, plan) {
|
|
3075
|
+
const refs = claimRefs(root, plan);
|
|
3076
|
+
return { write: (id, value) => writeSlot(refs, id, value) };
|
|
3077
|
+
}
|
|
3078
|
+
function claimRefs(root, plan) {
|
|
3079
|
+
const refs = new Map;
|
|
3080
|
+
for (const spec of plan) {
|
|
3081
|
+
const ref = claimOne(root, spec);
|
|
3082
|
+
if (ref)
|
|
3083
|
+
refs.set(spec.id, ref);
|
|
3084
|
+
}
|
|
3085
|
+
return refs;
|
|
3086
|
+
}
|
|
3087
|
+
function lazySlots(root, plan) {
|
|
3088
|
+
let claimed = null;
|
|
3089
|
+
return (id, value) => {
|
|
3090
|
+
if (!claimed)
|
|
3091
|
+
claimed = claimSlots(root, plan);
|
|
3092
|
+
claimed.write(id, value);
|
|
3093
|
+
};
|
|
3094
|
+
}
|
|
3095
|
+
function lazyClaimSlots(root, plan) {
|
|
3096
|
+
let refs = null;
|
|
3097
|
+
const ensure = () => refs ??= claimRefs(root, plan);
|
|
3098
|
+
return {
|
|
3099
|
+
write: (id, value) => writeSlot(ensure(), id, value),
|
|
3100
|
+
read: (id) => readSlot(ensure(), id)
|
|
3101
|
+
};
|
|
2875
3102
|
}
|
|
2876
3103
|
// src/runtime/style.ts
|
|
2877
3104
|
function styleToCss(value) {
|
|
@@ -3314,26 +3541,6 @@ function __bfText(current, value) {
|
|
|
3314
3541
|
}
|
|
3315
3542
|
return textNode;
|
|
3316
3543
|
}
|
|
3317
|
-
// src/runtime/client-marker.ts
|
|
3318
|
-
function updateClientMarker(scope, id, value) {
|
|
3319
|
-
if (!scope)
|
|
3320
|
-
return;
|
|
3321
|
-
const marker = `bf-client:${id}`;
|
|
3322
|
-
const walker = document.createTreeWalker(scope, NodeFilter.SHOW_COMMENT);
|
|
3323
|
-
while (walker.nextNode()) {
|
|
3324
|
-
if (walker.currentNode.nodeValue === marker) {
|
|
3325
|
-
const comment = walker.currentNode;
|
|
3326
|
-
let textNode = comment.nextSibling;
|
|
3327
|
-
if (textNode?.nodeType !== Node.TEXT_NODE || !textNode.nodeValue?.startsWith("")) {
|
|
3328
|
-
textNode = document.createTextNode("" + String(value ?? ""));
|
|
3329
|
-
comment.parentNode?.insertBefore(textNode, comment.nextSibling);
|
|
3330
|
-
} else {
|
|
3331
|
-
textNode.nodeValue = "" + String(value ?? "");
|
|
3332
|
-
}
|
|
3333
|
-
return;
|
|
3334
|
-
}
|
|
3335
|
-
}
|
|
3336
|
-
}
|
|
3337
3544
|
// src/runtime/render.ts
|
|
3338
3545
|
function render(container, nameOrDef, props = {}) {
|
|
3339
3546
|
let name;
|
|
@@ -3414,9 +3621,9 @@ export {
|
|
|
3414
3621
|
useContext,
|
|
3415
3622
|
upsertChildItem,
|
|
3416
3623
|
upsertChild,
|
|
3417
|
-
updateClientMarker,
|
|
3418
3624
|
unwrap,
|
|
3419
3625
|
untrack,
|
|
3626
|
+
textOrNode,
|
|
3420
3627
|
textNodeAfterComment as tAfter,
|
|
3421
3628
|
styleToCss,
|
|
3422
3629
|
spreadAttrs,
|
|
@@ -3430,21 +3637,21 @@ export {
|
|
|
3430
3637
|
rehydrateAll,
|
|
3431
3638
|
registerTemplate,
|
|
3432
3639
|
registerComponent,
|
|
3433
|
-
reconcileList,
|
|
3434
|
-
reconcileElements,
|
|
3435
3640
|
queryHref,
|
|
3436
3641
|
qsaItem,
|
|
3437
3642
|
qsaChildScopes,
|
|
3438
3643
|
qsaChildScope,
|
|
3439
3644
|
qsa,
|
|
3440
3645
|
provideContext,
|
|
3441
|
-
patchSlotRange,
|
|
3442
3646
|
patchLeaf,
|
|
3443
3647
|
parseHTML,
|
|
3444
3648
|
onMount,
|
|
3445
3649
|
onCleanup,
|
|
3650
|
+
mapArrayLazy,
|
|
3446
3651
|
mapArrayAnchored,
|
|
3447
3652
|
mapArray,
|
|
3653
|
+
lazySlots,
|
|
3654
|
+
lazyClaimSlots,
|
|
3448
3655
|
isSSRPortal,
|
|
3449
3656
|
insert,
|
|
3450
3657
|
initChild,
|
|
@@ -3453,10 +3660,8 @@ export {
|
|
|
3453
3660
|
hasTemplate,
|
|
3454
3661
|
getTemplate,
|
|
3455
3662
|
getRegisteredDef,
|
|
3456
|
-
getPropsUpdateFn,
|
|
3457
3663
|
getLoopNodes,
|
|
3458
3664
|
getLoopChildren,
|
|
3459
|
-
getComponentProps,
|
|
3460
3665
|
getComponentInit,
|
|
3461
3666
|
forwardProps,
|
|
3462
3667
|
formatDate,
|
|
@@ -3464,6 +3669,7 @@ export {
|
|
|
3464
3669
|
findSiblingSlot,
|
|
3465
3670
|
findScope,
|
|
3466
3671
|
find,
|
|
3672
|
+
escapeTextOrNode,
|
|
3467
3673
|
escapeText,
|
|
3468
3674
|
escapeAttr,
|
|
3469
3675
|
endTurn,
|
|
@@ -3482,6 +3688,7 @@ export {
|
|
|
3482
3688
|
createContext,
|
|
3483
3689
|
createComponent,
|
|
3484
3690
|
cleanupPortalPlaceholder,
|
|
3691
|
+
claimSlots,
|
|
3485
3692
|
beginTurn,
|
|
3486
3693
|
batch,
|
|
3487
3694
|
applyRestAttrs,
|