@nisli/core 0.57.0 → 0.57.1
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/README.md +32 -3
- package/dist/bundler/template.js +107 -32
- package/dist/bundler/template.js.map +2 -2
- package/dist/index.js +107 -32
- package/dist/index.js.map +2 -2
- package/dist/index.production.js +1 -1
- package/dist/index.production.js.map +2 -2
- package/dist/types/template.d.ts +2 -1
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -1319,8 +1319,10 @@ function html(strings, ...values) {
|
|
|
1319
1319
|
mounted = true;
|
|
1320
1320
|
const template = parseTemplate(strings, values.length);
|
|
1321
1321
|
const fragment = template.content.cloneNode(true);
|
|
1322
|
-
|
|
1322
|
+
const afterMount = [];
|
|
1323
|
+
processNode(fragment, values, bindings, disposers, afterMount);
|
|
1323
1324
|
host.appendChild(fragment);
|
|
1325
|
+
for (const sync of afterMount) sync();
|
|
1324
1326
|
},
|
|
1325
1327
|
dispose() {
|
|
1326
1328
|
for (const d of disposers) {
|
|
@@ -1343,10 +1345,11 @@ function html(strings, ...values) {
|
|
|
1343
1345
|
}
|
|
1344
1346
|
};
|
|
1345
1347
|
}
|
|
1346
|
-
function processNode(node, values, bindings, disposers) {
|
|
1348
|
+
function processNode(node, values, bindings, disposers, afterMount) {
|
|
1349
|
+
let afterChildren;
|
|
1347
1350
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
1348
1351
|
const el2 = node;
|
|
1349
|
-
processAttributes(el2, values, bindings, disposers);
|
|
1352
|
+
afterChildren = processAttributes(el2, values, bindings, disposers, afterMount);
|
|
1350
1353
|
}
|
|
1351
1354
|
if (node.nodeType === Node.COMMENT_NODE) {
|
|
1352
1355
|
const comment = node;
|
|
@@ -1360,11 +1363,13 @@ function processNode(node, values, bindings, disposers) {
|
|
|
1360
1363
|
}
|
|
1361
1364
|
const children2 = [...node.childNodes];
|
|
1362
1365
|
for (const child of children2) {
|
|
1363
|
-
processNode(child, values, bindings, disposers);
|
|
1366
|
+
processNode(child, values, bindings, disposers, afterMount);
|
|
1364
1367
|
}
|
|
1368
|
+
if (afterChildren) for (const bind of afterChildren) bind();
|
|
1365
1369
|
}
|
|
1366
|
-
function processAttributes(el2, values, bindings, disposers) {
|
|
1370
|
+
function processAttributes(el2, values, bindings, disposers, afterMount) {
|
|
1367
1371
|
const attrsToRemove = [];
|
|
1372
|
+
let afterChildren;
|
|
1368
1373
|
for (const attr of [...el2.attributes]) {
|
|
1369
1374
|
const name = attr.name;
|
|
1370
1375
|
const attrValue = attr.value;
|
|
@@ -1423,8 +1428,9 @@ function processAttributes(el2, values, bindings, disposers) {
|
|
|
1423
1428
|
const markers = [...attrValue.matchAll(/<!--bk-(\d+)-->/g)];
|
|
1424
1429
|
if (markers.length) {
|
|
1425
1430
|
const first = markers[0];
|
|
1431
|
+
let value;
|
|
1426
1432
|
if (markers.length === 1 && first && attrValue === first[0]) {
|
|
1427
|
-
|
|
1433
|
+
value = values[Number(first[1])];
|
|
1428
1434
|
} else {
|
|
1429
1435
|
const resolve = () => attrValue.replace(/<!--bk-(\d+)-->/g, (_, i) => {
|
|
1430
1436
|
const v = values[Number(i)];
|
|
@@ -1432,7 +1438,12 @@ function processAttributes(el2, values, bindings, disposers) {
|
|
|
1432
1438
|
return raw2 == null || raw2 === false ? "" : String(raw2);
|
|
1433
1439
|
});
|
|
1434
1440
|
const hasSignals = markers.some((m) => isSignal(values[Number(m[1])]));
|
|
1435
|
-
|
|
1441
|
+
value = hasSignals ? computed(resolve) : resolve();
|
|
1442
|
+
}
|
|
1443
|
+
if (nativeFormProperty(el2, name)) {
|
|
1444
|
+
(afterChildren ??= []).push(() => bindAttribute(el2, name, value, bindings, disposers, afterMount));
|
|
1445
|
+
} else {
|
|
1446
|
+
bindAttribute(el2, name, value, bindings, disposers, afterMount);
|
|
1436
1447
|
}
|
|
1437
1448
|
}
|
|
1438
1449
|
continue;
|
|
@@ -1441,6 +1452,7 @@ function processAttributes(el2, values, bindings, disposers) {
|
|
|
1441
1452
|
for (const name of attrsToRemove) {
|
|
1442
1453
|
el2.removeAttribute(name);
|
|
1443
1454
|
}
|
|
1455
|
+
return afterChildren;
|
|
1444
1456
|
}
|
|
1445
1457
|
function mountFactoryResult(factory) {
|
|
1446
1458
|
const el2 = document.createElement(factory.tagName);
|
|
@@ -1639,7 +1651,7 @@ function replaceMarkerWithBinding(comment, value, bindings, disposers) {
|
|
|
1639
1651
|
parent.replaceChild(textNode, comment);
|
|
1640
1652
|
}
|
|
1641
1653
|
}
|
|
1642
|
-
function bindAttribute(el2, name, value, bindings, disposers) {
|
|
1654
|
+
function bindAttribute(el2, name, value, bindings, disposers, afterMount) {
|
|
1643
1655
|
if (name === "class") {
|
|
1644
1656
|
bindClassAttribute(el2, value, bindings, disposers);
|
|
1645
1657
|
return;
|
|
@@ -1660,32 +1672,69 @@ function bindAttribute(el2, name, value, bindings, disposers) {
|
|
|
1660
1672
|
}
|
|
1661
1673
|
return;
|
|
1662
1674
|
}
|
|
1663
|
-
bindPlainAttribute(el2, name, value, bindings, disposers);
|
|
1675
|
+
bindPlainAttribute(el2, name, value, bindings, disposers, afterMount);
|
|
1664
1676
|
}
|
|
1665
|
-
function bindPlainAttribute(el2, name, value, bindings, disposers) {
|
|
1677
|
+
function bindPlainAttribute(el2, name, value, bindings, disposers, afterMount) {
|
|
1678
|
+
const property = nativeFormProperty(el2, name);
|
|
1679
|
+
let current;
|
|
1680
|
+
const apply = (v) => {
|
|
1681
|
+
current = v;
|
|
1682
|
+
if (v == null || v === false) {
|
|
1683
|
+
el2.removeAttribute(name);
|
|
1684
|
+
} else {
|
|
1685
|
+
el2.setAttribute(name, v === true ? "" : String(v));
|
|
1686
|
+
}
|
|
1687
|
+
if (property) syncFormProperty(el2, property, v);
|
|
1688
|
+
};
|
|
1666
1689
|
if (isSignal(value)) {
|
|
1667
1690
|
const binding = { type: "attribute", element: el2, name };
|
|
1668
1691
|
bindings.push(binding);
|
|
1669
|
-
const dispose = effect(() =>
|
|
1670
|
-
const v = value.value;
|
|
1671
|
-
if (v == null || v === false) {
|
|
1672
|
-
el2.removeAttribute(name);
|
|
1673
|
-
} else if (v === true) {
|
|
1674
|
-
el2.setAttribute(name, "");
|
|
1675
|
-
} else {
|
|
1676
|
-
el2.setAttribute(name, String(v));
|
|
1677
|
-
}
|
|
1678
|
-
});
|
|
1692
|
+
const dispose = effect(() => apply(value.value));
|
|
1679
1693
|
binding.dispose = dispose;
|
|
1680
1694
|
disposers.push(dispose);
|
|
1681
1695
|
} else {
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
el2
|
|
1688
|
-
}
|
|
1696
|
+
apply(value);
|
|
1697
|
+
}
|
|
1698
|
+
if (property === "value" && el2.localName === "select") {
|
|
1699
|
+
let active = true;
|
|
1700
|
+
const sync = () => {
|
|
1701
|
+
if (active) syncFormProperty(el2, "value", current);
|
|
1702
|
+
};
|
|
1703
|
+
const observer = new MutationObserver(sync);
|
|
1704
|
+
observer.observe(el2, {
|
|
1705
|
+
childList: true,
|
|
1706
|
+
subtree: true,
|
|
1707
|
+
characterData: true,
|
|
1708
|
+
attributes: true,
|
|
1709
|
+
attributeFilter: ["value", "selected"]
|
|
1710
|
+
});
|
|
1711
|
+
disposers.push(() => {
|
|
1712
|
+
active = false;
|
|
1713
|
+
observer.disconnect();
|
|
1714
|
+
});
|
|
1715
|
+
afterMount.push(sync);
|
|
1716
|
+
queueMicrotask(sync);
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
function nativeFormProperty(el2, name) {
|
|
1720
|
+
const attribute = name.toLowerCase();
|
|
1721
|
+
if (attribute !== "value" && attribute !== "checked" && attribute !== "selected") return;
|
|
1722
|
+
if (el2.namespaceURI !== "http://www.w3.org/1999/xhtml") return;
|
|
1723
|
+
const tag = el2.localName;
|
|
1724
|
+
if (attribute === "value" && (tag === "input" || tag === "textarea" || tag === "select")) return attribute;
|
|
1725
|
+
if (attribute === "checked" && tag === "input") return attribute;
|
|
1726
|
+
if (attribute === "selected" && tag === "option") return attribute;
|
|
1727
|
+
}
|
|
1728
|
+
function syncFormProperty(el2, property, value) {
|
|
1729
|
+
if (property === "value") {
|
|
1730
|
+
const control = el2;
|
|
1731
|
+
const next = value == null || typeof value === "boolean" ? "" : String(value);
|
|
1732
|
+
if (el2.localName === "input" && el2.type === "file" && next !== "") return;
|
|
1733
|
+
if (el2.localName === "select" || control.value !== next) control.value = next;
|
|
1734
|
+
} else {
|
|
1735
|
+
const control = el2;
|
|
1736
|
+
const next = value != null && value !== false;
|
|
1737
|
+
if (control[property] !== next) control[property] = next;
|
|
1689
1738
|
}
|
|
1690
1739
|
}
|
|
1691
1740
|
function bindClassAttribute(el2, value, bindings, disposers) {
|
|
@@ -1941,11 +1990,28 @@ function each(items, keyFn, templateFn) {
|
|
|
1941
1990
|
entry.wrapper.parentNode?.removeChild(entry.wrapper);
|
|
1942
1991
|
}
|
|
1943
1992
|
}
|
|
1944
|
-
|
|
1945
|
-
|
|
1993
|
+
const atomic = canMoveWithin(parent);
|
|
1994
|
+
let focusedIndex = -1;
|
|
1995
|
+
if (!atomic) {
|
|
1996
|
+
const root = parent.getRootNode();
|
|
1997
|
+
let active = "activeElement" in root ? root.activeElement : null;
|
|
1998
|
+
while (active && active.parentNode !== parent) active = active.parentElement;
|
|
1999
|
+
if (active) focusedIndex = newEntries.findIndex((entry) => entry.wrapper === active);
|
|
2000
|
+
}
|
|
2001
|
+
if (focusedIndex !== -1) {
|
|
2002
|
+
let next = newEntries[focusedIndex].wrapper;
|
|
2003
|
+
for (let i = focusedIndex - 1; i >= 0; i--) {
|
|
2004
|
+
const wrapper = newEntries[i].wrapper;
|
|
2005
|
+
if (wrapper.nextSibling !== next) parent.insertBefore(wrapper, next);
|
|
2006
|
+
next = wrapper;
|
|
2007
|
+
}
|
|
2008
|
+
}
|
|
2009
|
+
let cursor = focusedIndex === -1 ? startMarker : newEntries[focusedIndex].wrapper;
|
|
2010
|
+
for (let i = focusedIndex + 1; i < newEntries.length; i++) {
|
|
2011
|
+
const entry = newEntries[i];
|
|
1946
2012
|
const nextSibling = cursor.nextSibling;
|
|
1947
2013
|
if (nextSibling !== entry.wrapper) {
|
|
1948
|
-
if (entry.wrapper.parentNode === parent &&
|
|
2014
|
+
if (entry.wrapper.parentNode === parent && atomic) {
|
|
1949
2015
|
parent.moveBefore(entry.wrapper, nextSibling);
|
|
1950
2016
|
} else {
|
|
1951
2017
|
parent.insertBefore(entry.wrapper, nextSibling);
|
|
@@ -1985,8 +2051,11 @@ function el(tag, props = {}, children2) {
|
|
|
1985
2051
|
mount(host) {
|
|
1986
2052
|
const element = document.createElement(tag);
|
|
1987
2053
|
node = element;
|
|
2054
|
+
let afterChildren;
|
|
2055
|
+
const afterMount = [];
|
|
1988
2056
|
for (const [key, val] of Object.entries(props)) {
|
|
1989
|
-
|
|
2057
|
+
const formProperty = nativeFormProperty(element, key);
|
|
2058
|
+
if (val === void 0 && !formProperty) continue;
|
|
1990
2059
|
if (key === "ref") {
|
|
1991
2060
|
if (isRef(val)) {
|
|
1992
2061
|
val.current = element;
|
|
@@ -2006,7 +2075,11 @@ function el(tag, props = {}, children2) {
|
|
|
2006
2075
|
bindClassAttribute(element, val, bindings, disposers);
|
|
2007
2076
|
continue;
|
|
2008
2077
|
}
|
|
2009
|
-
|
|
2078
|
+
if (formProperty) {
|
|
2079
|
+
(afterChildren ??= []).push(() => bindPlainAttribute(element, key, val, bindings, disposers, afterMount));
|
|
2080
|
+
} else {
|
|
2081
|
+
bindPlainAttribute(element, key, val, bindings, disposers, afterMount);
|
|
2082
|
+
}
|
|
2010
2083
|
}
|
|
2011
2084
|
const flat = [];
|
|
2012
2085
|
flattenChildren(children2, flat);
|
|
@@ -2015,7 +2088,9 @@ function el(tag, props = {}, children2) {
|
|
|
2015
2088
|
element.appendChild(anchor);
|
|
2016
2089
|
replaceMarkerWithBinding(anchor, child, bindings, disposers);
|
|
2017
2090
|
}
|
|
2091
|
+
if (afterChildren) for (const bind of afterChildren) bind();
|
|
2018
2092
|
host.appendChild(element);
|
|
2093
|
+
for (const sync of afterMount) sync();
|
|
2019
2094
|
},
|
|
2020
2095
|
dispose() {
|
|
2021
2096
|
for (const d of disposers) {
|