@barefootjs/client 0.33.0 → 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 +6 -0
- package/dist/runtime/component.d.ts +27 -1
- package/dist/runtime/component.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +141 -32
- package/dist/runtime/insert.d.ts +21 -0
- package/dist/runtime/insert.d.ts.map +1 -1
- 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 +141 -32
- 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 +304 -41
- package/src/runtime/hydrate.ts +11 -2
- package/src/runtime/index.ts +1 -1
- package/src/runtime/insert.ts +30 -0
- 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,22 +1911,46 @@ 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>`;
|
|
1938
|
+
}
|
|
1939
|
+
const prevParentScopeId = _parentScopeId;
|
|
1940
|
+
_parentScopeId = `${scopePrefix}${suffix}`;
|
|
1941
|
+
let raw;
|
|
1942
|
+
try {
|
|
1943
|
+
raw = templateFn(props);
|
|
1944
|
+
} finally {
|
|
1945
|
+
_parentScopeId = prevParentScopeId;
|
|
1895
1946
|
}
|
|
1896
|
-
const raw = templateFn(props);
|
|
1897
1947
|
let html = raw.trim().replace(PLACEHOLDER_ATTR_PATTERN, _parentScopeId ? ` bf-s="${_parentScopeId}"` : "");
|
|
1898
|
-
|
|
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);
|
|
1899
1954
|
if (!firstElMatch)
|
|
1900
1955
|
return html;
|
|
1901
1956
|
const insertPos = firstElMatch.index;
|
|
@@ -1904,9 +1959,9 @@ function renderChild(name, props, key, slotSuffix) {
|
|
|
1904
1959
|
if (ROOT_HAS_BFS_PATTERN.test(afterInsert)) {
|
|
1905
1960
|
if (!extraAttrs)
|
|
1906
1961
|
return html;
|
|
1907
|
-
return html.slice(0, insertPos) + afterInsert.replace(
|
|
1962
|
+
return html.slice(0, insertPos) + afterInsert.replace(TAG_HEAD_PATTERN, `$1${extraAttrs}`);
|
|
1908
1963
|
}
|
|
1909
|
-
return html.slice(0, insertPos) + afterInsert.replace(
|
|
1964
|
+
return html.slice(0, insertPos) + afterInsert.replace(TAG_HEAD_PATTERN, `$1 ${bfsAttr}${extraAttrs}`);
|
|
1910
1965
|
}
|
|
1911
1966
|
var PLACEHOLDER_ATTR_PATTERN = new RegExp(`\\s+bf-s="${BF_PARENT_SCOPE_PLACEHOLDER}"`, "g");
|
|
1912
1967
|
var ROOT_HAS_BFS_PATTERN = /^<\w+[^>]*\sbf-s="/;
|
|
@@ -2236,6 +2291,11 @@ function upsertChildItem(primaryEl, name, slotId, props, key, anchorScope) {
|
|
|
2236
2291
|
return null;
|
|
2237
2292
|
}
|
|
2238
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
|
+
}
|
|
2239
2299
|
function findLoopMarkers2(container, markerId) {
|
|
2240
2300
|
let start = null;
|
|
2241
2301
|
let end = null;
|
|
@@ -2273,31 +2333,55 @@ function findItemRanges(start, end) {
|
|
|
2273
2333
|
const ranges = [];
|
|
2274
2334
|
let current = null;
|
|
2275
2335
|
let sawItemMarker = false;
|
|
2336
|
+
let pendingScopeStart = null;
|
|
2337
|
+
let openScopeComments = null;
|
|
2276
2338
|
let node = start.nextSibling;
|
|
2277
2339
|
while (node && node !== end) {
|
|
2278
|
-
if (node.nodeType === Node.COMMENT_NODE
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
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
|
+
}
|
|
2282
2352
|
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
2283
2353
|
const el = node;
|
|
2354
|
+
let scopeComments = null;
|
|
2355
|
+
if (pendingScopeStart) {
|
|
2356
|
+
scopeComments = { start: pendingScopeStart, end: null };
|
|
2357
|
+
openScopeComments = scopeComments;
|
|
2358
|
+
pendingScopeStart = null;
|
|
2359
|
+
}
|
|
2284
2360
|
if (sawItemMarker) {
|
|
2285
|
-
if (!current.primaryEl)
|
|
2361
|
+
if (!current.primaryEl) {
|
|
2286
2362
|
current.primaryEl = el;
|
|
2287
|
-
|
|
2363
|
+
current.scopeComments = scopeComments;
|
|
2364
|
+
} else
|
|
2288
2365
|
current.extras.push(el);
|
|
2289
2366
|
} else {
|
|
2290
|
-
ranges.push({ startMarker: null, primaryEl: el, extras: [] });
|
|
2367
|
+
ranges.push({ startMarker: null, primaryEl: el, extras: [], scopeComments });
|
|
2291
2368
|
}
|
|
2292
2369
|
}
|
|
2293
2370
|
node = node.nextSibling;
|
|
2294
2371
|
}
|
|
2295
|
-
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
|
+
}));
|
|
2296
2376
|
}
|
|
2297
2377
|
function insertScope(scope, target, anchor) {
|
|
2298
2378
|
if (scope.startMarker)
|
|
2299
2379
|
target.insertBefore(scope.startMarker, anchor);
|
|
2380
|
+
if (scope.scopeComments)
|
|
2381
|
+
target.insertBefore(scope.scopeComments.start, anchor);
|
|
2300
2382
|
target.insertBefore(scope.primaryEl, anchor);
|
|
2383
|
+
if (scope.scopeComments)
|
|
2384
|
+
target.insertBefore(scope.scopeComments.end, anchor);
|
|
2301
2385
|
for (const ex of scope.extras)
|
|
2302
2386
|
target.insertBefore(ex, anchor);
|
|
2303
2387
|
}
|
|
@@ -2336,19 +2420,24 @@ function longestIncreasingSubsequenceIndices(arr) {
|
|
|
2336
2420
|
function removeScope(scope) {
|
|
2337
2421
|
if (scope.startMarker?.parentNode)
|
|
2338
2422
|
scope.startMarker.remove();
|
|
2423
|
+
if (scope.scopeComments?.start.parentNode)
|
|
2424
|
+
scope.scopeComments.start.remove();
|
|
2339
2425
|
if (scope.primaryEl.parentNode)
|
|
2340
2426
|
scope.primaryEl.remove();
|
|
2427
|
+
if (scope.scopeComments?.end.parentNode)
|
|
2428
|
+
scope.scopeComments.end.remove();
|
|
2341
2429
|
for (const ex of scope.extras) {
|
|
2342
2430
|
if (ex.parentNode)
|
|
2343
2431
|
ex.remove();
|
|
2344
2432
|
}
|
|
2345
2433
|
}
|
|
2346
|
-
function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart, rowMount) {
|
|
2434
|
+
function createItemScope(item, index, renderItem, existingPrimary, existingExtras, existingStart, existingScopeComments, rowMount) {
|
|
2347
2435
|
let primaryEl;
|
|
2348
2436
|
let dispose;
|
|
2349
2437
|
let setItem;
|
|
2350
2438
|
let extras = [];
|
|
2351
2439
|
let startMarker = null;
|
|
2440
|
+
let scopeComments = null;
|
|
2352
2441
|
createRoot((d) => {
|
|
2353
2442
|
dispose = d;
|
|
2354
2443
|
const [itemAccessor, itemSetter] = createSignal(item);
|
|
@@ -2371,6 +2460,7 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
2371
2460
|
if (existingPrimary) {
|
|
2372
2461
|
extras = existingExtras ?? [];
|
|
2373
2462
|
startMarker = existingStart ?? null;
|
|
2463
|
+
scopeComments = existingScopeComments ?? null;
|
|
2374
2464
|
} else {
|
|
2375
2465
|
const stashed = primaryEl.__bfExtras;
|
|
2376
2466
|
if (stashed && stashed.length > 0) {
|
|
@@ -2378,13 +2468,17 @@ function createItemScope(item, index, renderItem, existingPrimary, existingExtra
|
|
|
2378
2468
|
startMarker = document.createComment(BF_LOOP_ITEM);
|
|
2379
2469
|
}
|
|
2380
2470
|
delete primaryEl.__bfExtras;
|
|
2471
|
+
const stashedScopeComments = primaryEl.__bfScopeComments;
|
|
2472
|
+
if (stashedScopeComments)
|
|
2473
|
+
scopeComments = stashedScopeComments;
|
|
2474
|
+
delete primaryEl.__bfScopeComments;
|
|
2381
2475
|
}
|
|
2382
2476
|
return;
|
|
2383
2477
|
});
|
|
2384
2478
|
if (rowMount && !existingPrimary && extras.length > 0 && primaryEl.parentNode) {
|
|
2385
2479
|
primaryEl.remove();
|
|
2386
2480
|
}
|
|
2387
|
-
return { startMarker, primaryEl, extras, dispose, setItem };
|
|
2481
|
+
return { startMarker, primaryEl, extras, scopeComments, dispose, setItem };
|
|
2388
2482
|
}
|
|
2389
2483
|
function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
2390
2484
|
if (!container)
|
|
@@ -2410,7 +2504,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2410
2504
|
const anchor = endMarker ?? null;
|
|
2411
2505
|
if (!hydrated) {
|
|
2412
2506
|
hydrated = true;
|
|
2413
|
-
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 }));
|
|
2414
2508
|
const needsHydration = existingRanges.length > 0 && (!existingRanges[0]?.primaryEl.hasAttribute("data-key") || scopes.size === 0);
|
|
2415
2509
|
if (needsHydration) {
|
|
2416
2510
|
for (let i2 = 0;i2 < existingRanges.length && i2 < items.length; i2++) {
|
|
@@ -2418,14 +2512,14 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2418
2512
|
const item = items[i2];
|
|
2419
2513
|
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2420
2514
|
range.primaryEl.setAttribute(BF_KEY, key);
|
|
2421
|
-
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);
|
|
2422
2516
|
scopes.set(key, scope);
|
|
2423
2517
|
hydratedScopes.add(range.primaryEl);
|
|
2424
2518
|
}
|
|
2425
2519
|
for (let i2 = existingRanges.length;i2 < items.length; i2++) {
|
|
2426
2520
|
const item = items[i2];
|
|
2427
2521
|
const key = getKey ? getKey(item, i2) : String(i2);
|
|
2428
|
-
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
|
|
2522
|
+
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, undefined, { container, anchor });
|
|
2429
2523
|
if (!scope.primaryEl.dataset.key)
|
|
2430
2524
|
scope.primaryEl.setAttribute(BF_KEY, key);
|
|
2431
2525
|
scopes.set(key, scope);
|
|
@@ -2435,8 +2529,12 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2435
2529
|
const range = existingRanges[i2];
|
|
2436
2530
|
if (range.startMarker?.parentNode)
|
|
2437
2531
|
range.startMarker.remove();
|
|
2532
|
+
if (range.scopeComments?.start.parentNode)
|
|
2533
|
+
range.scopeComments.start.remove();
|
|
2438
2534
|
if (range.primaryEl.parentNode)
|
|
2439
2535
|
range.primaryEl.remove();
|
|
2536
|
+
if (range.scopeComments?.end.parentNode)
|
|
2537
|
+
range.scopeComments.end.remove();
|
|
2440
2538
|
for (const ex of range.extras) {
|
|
2441
2539
|
if (ex.parentNode)
|
|
2442
2540
|
ex.remove();
|
|
@@ -2446,7 +2544,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2446
2544
|
}
|
|
2447
2545
|
}
|
|
2448
2546
|
if (scopes.size === 0) {
|
|
2449
|
-
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 }));
|
|
2450
2548
|
for (const range of loopRanges) {
|
|
2451
2549
|
const existingKey = range.primaryEl.dataset?.key;
|
|
2452
2550
|
if (existingKey && !scopes.has(existingKey)) {
|
|
@@ -2454,6 +2552,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2454
2552
|
startMarker: range.startMarker,
|
|
2455
2553
|
primaryEl: range.primaryEl,
|
|
2456
2554
|
extras: range.extras,
|
|
2555
|
+
scopeComments: range.scopeComments,
|
|
2457
2556
|
dispose: () => {},
|
|
2458
2557
|
setItem: () => {}
|
|
2459
2558
|
});
|
|
@@ -2472,7 +2571,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2472
2571
|
} else {
|
|
2473
2572
|
let expectedNodeCount = 0;
|
|
2474
2573
|
for (const scope of scopes.values()) {
|
|
2475
|
-
expectedNodeCount += 1 + scope.extras.length + (scope.startMarker ? 1 : 0);
|
|
2574
|
+
expectedNodeCount += 1 + scope.extras.length + (scope.startMarker ? 1 : 0) + (scope.scopeComments ? 2 : 0);
|
|
2476
2575
|
}
|
|
2477
2576
|
let actualNodeCount = 0;
|
|
2478
2577
|
for (let node = container.firstChild;node; node = node.nextSibling)
|
|
@@ -2504,7 +2603,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2504
2603
|
existing.setItem(item);
|
|
2505
2604
|
desiredOrder.push(existing);
|
|
2506
2605
|
} else {
|
|
2507
|
-
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, { container, anchor });
|
|
2606
|
+
const scope = createItemScope(item, i2, renderItem, undefined, undefined, undefined, undefined, { container, anchor });
|
|
2508
2607
|
if (!scope.primaryEl.dataset.key)
|
|
2509
2608
|
scope.primaryEl.setAttribute(BF_KEY, key);
|
|
2510
2609
|
scopes.set(key, scope);
|
|
@@ -2543,7 +2642,7 @@ function mapArray(accessor, container, getKey, renderItem, markerId, bfId) {
|
|
|
2543
2642
|
let j = i;
|
|
2544
2643
|
while (j < desiredOrder.length && !stationary[j])
|
|
2545
2644
|
j++;
|
|
2546
|
-
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;
|
|
2547
2646
|
if (j - i === 1) {
|
|
2548
2647
|
insertScope(desiredOrder[i], container, before);
|
|
2549
2648
|
} else {
|
|
@@ -3316,6 +3415,15 @@ function findCondStartInRange(anchor, id) {
|
|
|
3316
3415
|
}
|
|
3317
3416
|
return null;
|
|
3318
3417
|
}
|
|
3418
|
+
function findCondContainer(scope, id) {
|
|
3419
|
+
const want = `bf-cond-start:${id}`;
|
|
3420
|
+
for (const comment of commentsInScope(scope)) {
|
|
3421
|
+
if (comment.nodeValue === want) {
|
|
3422
|
+
return comment.parentElement ?? scope;
|
|
3423
|
+
}
|
|
3424
|
+
}
|
|
3425
|
+
return scope;
|
|
3426
|
+
}
|
|
3319
3427
|
var EMPTY_SLOTS = [];
|
|
3320
3428
|
function normalizeTemplate(value) {
|
|
3321
3429
|
return typeof value === "string" ? { html: value, slots: EMPTY_SLOTS } : value;
|
|
@@ -3718,6 +3826,7 @@ export {
|
|
|
3718
3826
|
flushHydration,
|
|
3719
3827
|
findSiblingSlot,
|
|
3720
3828
|
findScope,
|
|
3829
|
+
findCondContainer,
|
|
3721
3830
|
find,
|
|
3722
3831
|
escapeTextOrNode,
|
|
3723
3832
|
escapeTextOrMarkup,
|
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"
|