@barefootjs/client 0.33.1 → 0.33.2
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/csr-adapter.js +4 -0
- package/dist/runtime/component.d.ts +27 -1
- package/dist/runtime/component.d.ts.map +1 -1
- package/dist/runtime/index.js +123 -31
- package/dist/runtime/map-array.d.ts.map +1 -1
- package/dist/runtime/qsa-item.d.ts.map +1 -1
- package/dist/runtime/registry.d.ts.map +1 -1
- package/dist/runtime/standalone.js +123 -31
- package/dist/runtime/types.d.ts +19 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/runtime/component.ts +285 -22
- package/src/runtime/hydrate.ts +11 -2
- package/src/runtime/map-array.ts +136 -21
- package/src/runtime/qsa-item.ts +3 -1
- package/src/runtime/registry.ts +4 -1
- package/src/runtime/types.ts +19 -1
|
@@ -1737,8 +1737,7 @@ function hydrateCommentScope(comment) {
|
|
|
1737
1737
|
if (hydratedScopes.has(proxyEl))
|
|
1738
1738
|
return;
|
|
1739
1739
|
commentScopeRegistry.set(proxyEl, { commentNode: comment, scopeId });
|
|
1740
|
-
const
|
|
1741
|
-
const props = parsed[name] ?? {};
|
|
1740
|
+
const props = parseProps(propsJson || null, `comment scope ${scopeId}`);
|
|
1742
1741
|
runInit(proxyEl, def, props);
|
|
1743
1742
|
}
|
|
1744
1743
|
function nextElementSibling2(node) {
|
|
@@ -1818,8 +1817,9 @@ function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
|
1818
1817
|
});
|
|
1819
1818
|
const def = getRegisteredDef(name);
|
|
1820
1819
|
const isCommentWrapper = def?.comment === true;
|
|
1820
|
+
const isFragmentRoot = def?.fragmentRoot === true;
|
|
1821
1821
|
const derivedScopeId = slot?.parent && slot.mount ? `${slot.parent}_${slot.mount}` : null;
|
|
1822
|
-
const scopeId = isCommentWrapper ? null : derivedScopeId ?? `${def?.name ?? name}_${generateId()}`;
|
|
1822
|
+
const scopeId = isCommentWrapper && !isFragmentRoot ? null : derivedScopeId ?? `${def?.name ?? name}_${generateId()}`;
|
|
1823
1823
|
const prevParentScopeId = _parentScopeId;
|
|
1824
1824
|
if (scopeId) {
|
|
1825
1825
|
_parentScopeId = scopeId;
|
|
@@ -1832,12 +1832,18 @@ function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
|
1832
1832
|
} finally {
|
|
1833
1833
|
_parentScopeId = prevParentScopeId;
|
|
1834
1834
|
}
|
|
1835
|
-
const
|
|
1835
|
+
const parsedFragment = parseHTML(html.trim());
|
|
1836
|
+
const roots = isFragmentRoot ? Array.from(parsedFragment.childNodes) : parsedFragment.firstChild ? [parsedFragment.firstChild] : [];
|
|
1837
|
+
const element = isFragmentRoot ? roots.find((node) => node.nodeType === Node.ELEMENT_NODE) : roots[0];
|
|
1838
|
+
if (isFragmentRoot && roots.length > 0 && !element) {
|
|
1839
|
+
console.warn(`[BarefootJS] Fragment-root component ${name} rendered no element root; ` + "a scope needs at least one element to attach to. Wrap the content in an element.");
|
|
1840
|
+
return createPlaceholder(name, key);
|
|
1841
|
+
}
|
|
1836
1842
|
if (!element) {
|
|
1837
1843
|
console.warn(`[BarefootJS] Template returned empty HTML for component: ${name}`);
|
|
1838
1844
|
return createPlaceholder(name, key);
|
|
1839
1845
|
}
|
|
1840
|
-
if (scopeId) {
|
|
1846
|
+
if (scopeId && !isFragmentRoot) {
|
|
1841
1847
|
element.setAttribute(BF_SCOPE, scopeId);
|
|
1842
1848
|
}
|
|
1843
1849
|
if (slot) {
|
|
@@ -1848,11 +1854,36 @@ function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
|
1848
1854
|
if (key !== undefined) {
|
|
1849
1855
|
element.setAttribute(BF_KEY, String(key));
|
|
1850
1856
|
}
|
|
1857
|
+
const fragmentComments = isFragmentRoot && scopeId ? {
|
|
1858
|
+
start: document.createComment(`${BF_SCOPE_COMMENT_PREFIX}${scopeId}`),
|
|
1859
|
+
end: document.createComment(`${BF_SCOPE_COMMENT_END_PREFIX}${scopeId}`)
|
|
1860
|
+
} : null;
|
|
1861
|
+
if (fragmentComments) {
|
|
1862
|
+
commentScopeRegistry.set(element, { commentNode: fragmentComments.start, scopeId });
|
|
1863
|
+
}
|
|
1851
1864
|
const rootIsDeferredPlaceholder = element.hasAttribute(BF_PLACEHOLDER);
|
|
1865
|
+
let bareFragment = null;
|
|
1852
1866
|
if (mountAt && !rootIsDeferredPlaceholder) {
|
|
1853
|
-
|
|
1867
|
+
if (fragmentComments) {
|
|
1868
|
+
mountAt.replaceWith(fragmentComments.start, ...roots, fragmentComments.end);
|
|
1869
|
+
} else {
|
|
1870
|
+
mountAt.replaceWith(element);
|
|
1871
|
+
}
|
|
1854
1872
|
} else if (rowMount && !rootIsDeferredPlaceholder) {
|
|
1855
|
-
|
|
1873
|
+
if (fragmentComments) {
|
|
1874
|
+
rowMount.container.insertBefore(fragmentComments.start, rowMount.anchor);
|
|
1875
|
+
rowMount.container.insertBefore(element, rowMount.anchor);
|
|
1876
|
+
rowMount.container.insertBefore(fragmentComments.end, rowMount.anchor);
|
|
1877
|
+
element.__bfScopeComments = fragmentComments;
|
|
1878
|
+
if (roots.length > 1) {
|
|
1879
|
+
console.warn(`[BarefootJS] Fragment-root component ${name} used as a loop row renders ` + `${roots.length} top-level nodes; only the first element is connected here. ` + "See https://github.com/piconic-ai/barefootjs/issues/2733");
|
|
1880
|
+
}
|
|
1881
|
+
} else {
|
|
1882
|
+
rowMount.container.insertBefore(element, rowMount.anchor);
|
|
1883
|
+
}
|
|
1884
|
+
} else if (fragmentComments && !rootIsDeferredPlaceholder) {
|
|
1885
|
+
bareFragment = document.createDocumentFragment();
|
|
1886
|
+
bareFragment.append(fragmentComments.start, ...roots, fragmentComments.end);
|
|
1856
1887
|
}
|
|
1857
1888
|
const prevScope = setCurrentScope(element);
|
|
1858
1889
|
let placeholderWrapper = null;
|
|
@@ -1880,18 +1911,30 @@ function materializeComponent(nameOrDef, props = {}, key, slot, mountAt) {
|
|
|
1880
1911
|
}
|
|
1881
1912
|
setCurrentScope(prevScope);
|
|
1882
1913
|
hydratedScopes.add(element);
|
|
1883
|
-
return element;
|
|
1914
|
+
return bareFragment ?? element;
|
|
1915
|
+
}
|
|
1916
|
+
var FIRST_TAG_PATTERN = /<([a-zA-Z][^\s/>]*)/;
|
|
1917
|
+
var TAG_HEAD_PATTERN = /^(<[a-zA-Z][^\s/>]*)/;
|
|
1918
|
+
function spliceAttrsAfterFirstTag(html, attrs) {
|
|
1919
|
+
const firstElMatch = html.match(FIRST_TAG_PATTERN);
|
|
1920
|
+
if (!firstElMatch)
|
|
1921
|
+
return html;
|
|
1922
|
+
const insertPos = firstElMatch.index;
|
|
1923
|
+
return html.slice(0, insertPos) + html.slice(insertPos).replace(TAG_HEAD_PATTERN, `$1${attrs}`);
|
|
1884
1924
|
}
|
|
1885
1925
|
function renderChild(name, props, key, slotSuffix) {
|
|
1886
1926
|
const templateFn = getTemplate(name);
|
|
1887
1927
|
const suffix = slotSuffix ? `_${slotSuffix}` : "";
|
|
1888
|
-
const
|
|
1928
|
+
const def = getRegisteredDef(name);
|
|
1929
|
+
const displayName = def?.name ?? name;
|
|
1930
|
+
const isFragmentRoot = def?.fragmentRoot === true;
|
|
1889
1931
|
const scopePrefix = _parentScopeId && slotSuffix ? _parentScopeId : `${displayName}_${generateId()}`;
|
|
1932
|
+
const scopeId = `${scopePrefix}${suffix}`;
|
|
1890
1933
|
const keyAttr = key !== undefined ? ` ${BF_KEY}="${key}"` : "";
|
|
1891
1934
|
const slotAttrs = _parentScopeId && slotSuffix ? ` ${BF_HOST}="${_parentScopeId}" ${BF_AT}="${slotSuffix}"` : "";
|
|
1892
|
-
const bfsAttr = `${BF_SCOPE}="${
|
|
1935
|
+
const bfsAttr = `${BF_SCOPE}="${scopeId}"`;
|
|
1893
1936
|
if (!templateFn) {
|
|
1894
|
-
return `<div ${bfsAttr}${slotAttrs}${keyAttr}></div>`;
|
|
1937
|
+
return isFragmentRoot ? `<!--${BF_SCOPE_COMMENT_PREFIX}${scopeId}--><div></div><!--${BF_SCOPE_COMMENT_END_PREFIX}${scopeId}-->` : `<div ${bfsAttr}${slotAttrs}${keyAttr}></div>`;
|
|
1895
1938
|
}
|
|
1896
1939
|
const prevParentScopeId = _parentScopeId;
|
|
1897
1940
|
_parentScopeId = `${scopePrefix}${suffix}`;
|
|
@@ -1902,7 +1945,12 @@ function renderChild(name, props, key, slotSuffix) {
|
|
|
1902
1945
|
_parentScopeId = prevParentScopeId;
|
|
1903
1946
|
}
|
|
1904
1947
|
let html = raw.trim().replace(PLACEHOLDER_ATTR_PATTERN, _parentScopeId ? ` bf-s="${_parentScopeId}"` : "");
|
|
1905
|
-
|
|
1948
|
+
if (isFragmentRoot) {
|
|
1949
|
+
const hostSuffix = _parentScopeId && slotSuffix ? `|h=${_parentScopeId}|m=${slotSuffix}` : "";
|
|
1950
|
+
const keyedHtml = keyAttr ? spliceAttrsAfterFirstTag(html, keyAttr) : html;
|
|
1951
|
+
return `<!--${BF_SCOPE_COMMENT_PREFIX}${scopeId}${hostSuffix}-->${keyedHtml}<!--${BF_SCOPE_COMMENT_END_PREFIX}${scopeId}-->`;
|
|
1952
|
+
}
|
|
1953
|
+
const firstElMatch = html.match(FIRST_TAG_PATTERN);
|
|
1906
1954
|
if (!firstElMatch)
|
|
1907
1955
|
return html;
|
|
1908
1956
|
const insertPos = firstElMatch.index;
|
|
@@ -1911,9 +1959,9 @@ function renderChild(name, props, key, slotSuffix) {
|
|
|
1911
1959
|
if (ROOT_HAS_BFS_PATTERN.test(afterInsert)) {
|
|
1912
1960
|
if (!extraAttrs)
|
|
1913
1961
|
return html;
|
|
1914
|
-
return html.slice(0, insertPos) + afterInsert.replace(
|
|
1962
|
+
return html.slice(0, insertPos) + afterInsert.replace(TAG_HEAD_PATTERN, `$1${extraAttrs}`);
|
|
1915
1963
|
}
|
|
1916
|
-
return html.slice(0, insertPos) + afterInsert.replace(
|
|
1964
|
+
return html.slice(0, insertPos) + afterInsert.replace(TAG_HEAD_PATTERN, `$1 ${bfsAttr}${extraAttrs}`);
|
|
1917
1965
|
}
|
|
1918
1966
|
var PLACEHOLDER_ATTR_PATTERN = new RegExp(`\\s+bf-s="${BF_PARENT_SCOPE_PLACEHOLDER}"`, "g");
|
|
1919
1967
|
var ROOT_HAS_BFS_PATTERN = /^<\w+[^>]*\sbf-s="/;
|
|
@@ -2243,6 +2291,11 @@ function upsertChildItem(primaryEl, name, slotId, props, key, anchorScope) {
|
|
|
2243
2291
|
return null;
|
|
2244
2292
|
}
|
|
2245
2293
|
// src/runtime/map-array.ts
|
|
2294
|
+
function scopeIdOf(start) {
|
|
2295
|
+
const rest = (start.nodeValue ?? "").slice(BF_SCOPE_COMMENT_PREFIX.length);
|
|
2296
|
+
const pipe = rest.indexOf("|");
|
|
2297
|
+
return pipe >= 0 ? rest.slice(0, pipe) : rest;
|
|
2298
|
+
}
|
|
2246
2299
|
function findLoopMarkers2(container, markerId) {
|
|
2247
2300
|
let start = null;
|
|
2248
2301
|
let end = null;
|
|
@@ -2280,31 +2333,55 @@ function findItemRanges(start, end) {
|
|
|
2280
2333
|
const ranges = [];
|
|
2281
2334
|
let current = null;
|
|
2282
2335
|
let sawItemMarker = false;
|
|
2336
|
+
let pendingScopeStart = null;
|
|
2337
|
+
let openScopeComments = null;
|
|
2283
2338
|
let node = start.nextSibling;
|
|
2284
2339
|
while (node && node !== end) {
|
|
2285
|
-
if (node.nodeType === Node.COMMENT_NODE
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2340
|
+
if (node.nodeType === Node.COMMENT_NODE) {
|
|
2341
|
+
const value = node.nodeValue ?? "";
|
|
2342
|
+
if (value === BF_LOOP_ITEM) {
|
|
2343
|
+
sawItemMarker = true;
|
|
2344
|
+
current = { startMarker: node, primaryEl: null, extras: [], scopeComments: null };
|
|
2345
|
+
ranges.push(current);
|
|
2346
|
+
} else if (value.startsWith(BF_SCOPE_COMMENT_PREFIX)) {
|
|
2347
|
+
pendingScopeStart = node;
|
|
2348
|
+
} else if (openScopeComments && value === BF_SCOPE_COMMENT_END_PREFIX + scopeIdOf(openScopeComments.start)) {
|
|
2349
|
+
openScopeComments.end = node;
|
|
2350
|
+
openScopeComments = null;
|
|
2351
|
+
}
|
|
2289
2352
|
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
2290
2353
|
const el = node;
|
|
2354
|
+
let scopeComments = null;
|
|
2355
|
+
if (pendingScopeStart) {
|
|
2356
|
+
scopeComments = { start: pendingScopeStart, end: null };
|
|
2357
|
+
openScopeComments = scopeComments;
|
|
2358
|
+
pendingScopeStart = null;
|
|
2359
|
+
}
|
|
2291
2360
|
if (sawItemMarker) {
|
|
2292
|
-
if (!current.primaryEl)
|
|
2361
|
+
if (!current.primaryEl) {
|
|
2293
2362
|
current.primaryEl = el;
|
|
2294
|
-
|
|
2363
|
+
current.scopeComments = scopeComments;
|
|
2364
|
+
} else
|
|
2295
2365
|
current.extras.push(el);
|
|
2296
2366
|
} else {
|
|
2297
|
-
ranges.push({ startMarker: null, primaryEl: el, extras: [] });
|
|
2367
|
+
ranges.push({ startMarker: null, primaryEl: el, extras: [], scopeComments });
|
|
2298
2368
|
}
|
|
2299
2369
|
}
|
|
2300
2370
|
node = node.nextSibling;
|
|
2301
2371
|
}
|
|
2302
|
-
return ranges.filter((r) => r.primaryEl !== null)
|
|
2372
|
+
return ranges.filter((r) => r.primaryEl !== null).map((r) => ({
|
|
2373
|
+
...r,
|
|
2374
|
+
scopeComments: r.scopeComments?.end ? r.scopeComments : null
|
|
2375
|
+
}));
|
|
2303
2376
|
}
|
|
2304
2377
|
function insertScope(scope, target, anchor) {
|
|
2305
2378
|
if (scope.startMarker)
|
|
2306
2379
|
target.insertBefore(scope.startMarker, anchor);
|
|
2380
|
+
if (scope.scopeComments)
|
|
2381
|
+
target.insertBefore(scope.scopeComments.start, anchor);
|
|
2307
2382
|
target.insertBefore(scope.primaryEl, anchor);
|
|
2383
|
+
if (scope.scopeComments)
|
|
2384
|
+
target.insertBefore(scope.scopeComments.end, anchor);
|
|
2308
2385
|
for (const ex of scope.extras)
|
|
2309
2386
|
target.insertBefore(ex, anchor);
|
|
2310
2387
|
}
|
|
@@ -2343,19 +2420,24 @@ function longestIncreasingSubsequenceIndices(arr) {
|
|
|
2343
2420
|
function removeScope(scope) {
|
|
2344
2421
|
if (scope.startMarker?.parentNode)
|
|
2345
2422
|
scope.startMarker.remove();
|
|
2423
|
+
if (scope.scopeComments?.start.parentNode)
|
|
2424
|
+
scope.scopeComments.start.remove();
|
|
2346
2425
|
if (scope.primaryEl.parentNode)
|
|
2347
2426
|
scope.primaryEl.remove();
|
|
2427
|
+
if (scope.scopeComments?.end.parentNode)
|
|
2428
|
+
scope.scopeComments.end.remove();
|
|
2348
2429
|
for (const ex of scope.extras) {
|
|
2349
2430
|
if (ex.parentNode)
|
|
2350
2431
|
ex.remove();
|
|
2351
2432
|
}
|
|
2352
2433
|
}
|
|
2353
|
-
function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart, rowMount) {
|
|
2434
|
+
function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart, existingScopeComments, rowMount) {
|
|
2354
2435
|
let primaryEl;
|
|
2355
2436
|
let dispose;
|
|
2356
2437
|
let setItem;
|
|
2357
2438
|
let extras = [];
|
|
2358
2439
|
let startMarker = null;
|
|
2440
|
+
let scopeComments = null;
|
|
2359
2441
|
createRoot((d) => {
|
|
2360
2442
|
dispose = d;
|
|
2361
2443
|
const [itemAccessor, itemSetter] = createSignal(item);
|
|
@@ -2378,6 +2460,7 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
2378
2460
|
if (existingPrimary) {
|
|
2379
2461
|
extras = existingExtras ?? [];
|
|
2380
2462
|
startMarker = existingStart ?? null;
|
|
2463
|
+
scopeComments = existingScopeComments ?? null;
|
|
2381
2464
|
} else {
|
|
2382
2465
|
const stashed = primaryEl.__bfExtras;
|
|
2383
2466
|
if (stashed && stashed.length > 0) {
|
|
@@ -2385,13 +2468,17 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
2385
2468
|
startMarker = document.createComment(BF_LOOP_ITEM);
|
|
2386
2469
|
}
|
|
2387
2470
|
delete primaryEl.__bfExtras;
|
|
2471
|
+
const stashedScopeComments = primaryEl.__bfScopeComments;
|
|
2472
|
+
if (stashedScopeComments)
|
|
2473
|
+
scopeComments = stashedScopeComments;
|
|
2474
|
+
delete primaryEl.__bfScopeComments;
|
|
2388
2475
|
}
|
|
2389
2476
|
return;
|
|
2390
2477
|
});
|
|
2391
2478
|
if (rowMount && !existingPrimary && extras.length > 0 && primaryEl.parentNode) {
|
|
2392
2479
|
primaryEl.remove();
|
|
2393
2480
|
}
|
|
2394
|
-
return { startMarker, primaryEl, extras, dispose, setItem };
|
|
2481
|
+
return { startMarker, primaryEl, extras, scopeComments, dispose, setItem };
|
|
2395
2482
|
}
|
|
2396
2483
|
function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
2397
2484
|
if (!container)
|
|
@@ -2417,7 +2504,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2417
2504
|
const anchor = endMarker ?? null;
|
|
2418
2505
|
if (!hydrated) {
|
|
2419
2506
|
hydrated = true;
|
|
2420
|
-
const existingRanges = startMarker ? findItemRanges(startMarker, endMarker) : Array.from(container.children).map((el) => ({ startMarker: null, primaryEl: el, extras: [] }));
|
|
2507
|
+
const existingRanges = startMarker ? findItemRanges(startMarker, endMarker) : Array.from(container.children).map((el) => ({ startMarker: null, primaryEl: el, extras: [], scopeComments: null }));
|
|
2421
2508
|
const needsHydration = existingRanges.length > 0 && (!existingRanges[0]?.primaryEl.hasAttribute("data-key") || scopes.size === 0);
|
|
2422
2509
|
if (needsHydration) {
|
|
2423
2510
|
for (let i2 = 0;i2 < existingRanges.length && i2 < items.length; i2++) {
|
|
@@ -2425,14 +2512,14 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2425
2512
|
const item = items[i2];
|
|
2426
2513
|
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2427
2514
|
range.primaryEl.setAttribute(BF_KEY, key);
|
|
2428
|
-
const scope = createItemScope(item, i2, renderItem, range.primaryEl, range.extras, range.startMarker);
|
|
2515
|
+
const scope = createItemScope(item, i2, renderItem, range.primaryEl, range.extras, range.startMarker, range.scopeComments);
|
|
2429
2516
|
scopes.set(key, scope);
|
|
2430
2517
|
hydratedScopes.add(range.primaryEl);
|
|
2431
2518
|
}
|
|
2432
2519
|
for (let i2 = existingRanges.length;i2 < items.length; i2++) {
|
|
2433
2520
|
const item = items[i2];
|
|
2434
2521
|
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2435
|
-
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
|
|
2522
|
+
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, undefined, { container, anchor });
|
|
2436
2523
|
if (!scope.primaryEl.dataset.key)
|
|
2437
2524
|
scope.primaryEl.setAttribute(BF_KEY, key);
|
|
2438
2525
|
scopes.set(key, scope);
|
|
@@ -2442,8 +2529,12 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2442
2529
|
const range = existingRanges[i2];
|
|
2443
2530
|
if (range.startMarker?.parentNode)
|
|
2444
2531
|
range.startMarker.remove();
|
|
2532
|
+
if (range.scopeComments?.start.parentNode)
|
|
2533
|
+
range.scopeComments.start.remove();
|
|
2445
2534
|
if (range.primaryEl.parentNode)
|
|
2446
2535
|
range.primaryEl.remove();
|
|
2536
|
+
if (range.scopeComments?.end.parentNode)
|
|
2537
|
+
range.scopeComments.end.remove();
|
|
2447
2538
|
for (const ex of range.extras) {
|
|
2448
2539
|
if (ex.parentNode)
|
|
2449
2540
|
ex.remove();
|
|
@@ -2453,7 +2544,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2453
2544
|
}
|
|
2454
2545
|
}
|
|
2455
2546
|
if (scopes.size === 0) {
|
|
2456
|
-
const loopRanges = startMarker ? findItemRanges(startMarker, endMarker) : Array.from(container.children).map((el) => ({ startMarker: null, primaryEl: el, extras: [] }));
|
|
2547
|
+
const loopRanges = startMarker ? findItemRanges(startMarker, endMarker) : Array.from(container.children).map((el) => ({ startMarker: null, primaryEl: el, extras: [], scopeComments: null }));
|
|
2457
2548
|
for (const range of loopRanges) {
|
|
2458
2549
|
const existingKey = range.primaryEl.dataset?.key;
|
|
2459
2550
|
if (existingKey && !scopes.has(existingKey)) {
|
|
@@ -2461,6 +2552,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2461
2552
|
startMarker: range.startMarker,
|
|
2462
2553
|
primaryEl: range.primaryEl,
|
|
2463
2554
|
extras: range.extras,
|
|
2555
|
+
scopeComments: range.scopeComments,
|
|
2464
2556
|
dispose: () => {},
|
|
2465
2557
|
setItem: () => {}
|
|
2466
2558
|
});
|
|
@@ -2479,7 +2571,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2479
2571
|
} else {
|
|
2480
2572
|
let expectedNodeCount = 0;
|
|
2481
2573
|
for (const scope of scopes.values()) {
|
|
2482
|
-
expectedNodeCount += 1 + scope.extras.length + (scope.startMarker ? 1 : 0);
|
|
2574
|
+
expectedNodeCount += 1 + scope.extras.length + (scope.startMarker ? 1 : 0) + (scope.scopeComments ? 2 : 0);
|
|
2483
2575
|
}
|
|
2484
2576
|
let actualNodeCount = 0;
|
|
2485
2577
|
for (let node = container.firstChild;node; node = node.nextSibling)
|
|
@@ -2511,7 +2603,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2511
2603
|
existing.setItem(item);
|
|
2512
2604
|
desiredOrder.push(existing);
|
|
2513
2605
|
} else {
|
|
2514
|
-
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
|
|
2606
|
+
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, undefined, { container, anchor });
|
|
2515
2607
|
if (!scope.primaryEl.dataset.key)
|
|
2516
2608
|
scope.primaryEl.setAttribute(BF_KEY, key);
|
|
2517
2609
|
scopes.set(key, scope);
|
|
@@ -2550,7 +2642,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2550
2642
|
let j = i;
|
|
2551
2643
|
while (j < desiredOrder.length && !stationary[j])
|
|
2552
2644
|
j++;
|
|
2553
|
-
const before = j < desiredOrder.length ? desiredOrder[j].startMarker ?? desiredOrder[j].primaryEl : anchor;
|
|
2645
|
+
const before = j < desiredOrder.length ? desiredOrder[j].startMarker ?? desiredOrder[j].scopeComments?.start ?? desiredOrder[j].primaryEl : anchor;
|
|
2554
2646
|
if (j - i === 1) {
|
|
2555
2647
|
insertScope(desiredOrder[i], container, before);
|
|
2556
2648
|
} else {
|
package/dist/runtime/types.d.ts
CHANGED
|
@@ -20,7 +20,25 @@ export interface ComponentDef {
|
|
|
20
20
|
init: InitFn;
|
|
21
21
|
/** Template function for client-side component creation */
|
|
22
22
|
template?: (props: Record<string, unknown>) => string;
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* When true, this component's scope has no `bf-s`-carrying element of
|
|
25
|
+
* its own — a proxy element stands in for it. Set for TWO distinct
|
|
26
|
+
* shapes (see `fragmentRoot` below, which tells them apart):
|
|
27
|
+
* - a genuine fragment root (`<>...</>`), where the proxy is the
|
|
28
|
+
* fragment's own rendered content;
|
|
29
|
+
* - a root that is itself a single child component call, where the
|
|
30
|
+
* proxy is that child's own already-scoped element (#2649).
|
|
31
|
+
*/
|
|
24
32
|
comment?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* True only for the genuine-fragment-root shape of `comment` above
|
|
35
|
+
* (`ir.root.type === 'fragment'`) — never for the root-is-a-child-call
|
|
36
|
+
* shape. `materializeComponent` (component.ts) uses this to decide
|
|
37
|
+
* whether a CSR mount must generate its OWN scope id (fragment root: yes,
|
|
38
|
+
* so nested `renderChild()` calls get parent-prefixed naming matching
|
|
39
|
+
* SSR/hydrate) or leave the scope id null to avoid overwriting the
|
|
40
|
+
* child's own (#2649's shape, #2722).
|
|
41
|
+
*/
|
|
42
|
+
fragmentRoot?: boolean;
|
|
25
43
|
}
|
|
26
44
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;AAE7E;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;IACrD
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/runtime/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;AAE7E;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAA;IACrD;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@barefootjs/client",
|
|
3
|
-
"version": "0.33.
|
|
3
|
+
"version": "0.33.2",
|
|
4
4
|
"description": "BarefootJS client package: reactive primitives (SSR-safe) plus browser runtime under the `/runtime` subpath (compiler target)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"directory": "packages/client"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@barefootjs/shared": "0.33.
|
|
58
|
+
"@barefootjs/shared": "0.33.2"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@barefootjs/jsx": ">=0.2.0"
|