tutuca 0.9.66 → 0.9.68

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.
@@ -50,6 +50,7 @@ __export(exports_extra, {
50
50
  component: () => component,
51
51
  compileClassesToStyleText: () => compileClassesToStyleText,
52
52
  compileClassesToStyle: () => compileClassesToStyle,
53
+ collectIterBindings: () => collectIterBindings,
53
54
  check: () => check,
54
55
  SEQ_INFO: () => SEQ_INFO,
55
56
  ParseContext: () => ParseContext,
@@ -1282,40 +1283,67 @@ class RequestHandler {
1282
1283
  }
1283
1284
 
1284
1285
  // src/vdom.js
1285
- var isHtmlAttribute = (propName) => propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
1286
1286
  var HTML_NS = "http://www.w3.org/1999/xhtml";
1287
+ var SVG_NS = "http://www.w3.org/2000/svg";
1288
+ var MATH_NS = "http://www.w3.org/1998/Math/MathML";
1287
1289
  var isNamespaced = (node) => {
1288
1290
  const ns = node.namespaceURI;
1289
1291
  return ns !== null && ns !== HTML_NS;
1290
1292
  };
1291
- function applyProperties(node, props, previous) {
1293
+ var isForeignObject = (tag) => tag.length === 13 && tag.toLowerCase() === "foreignobject";
1294
+ var effectiveNs = (vnode, opts) => vnode.namespace ?? opts.namespace ?? null;
1295
+ function childOpts(vnode, ns, opts) {
1296
+ const target = ns === SVG_NS && isForeignObject(vnode.tag) ? null : ns;
1297
+ return target === (opts.namespace ?? null) ? opts : { ...opts, namespace: target };
1298
+ }
1299
+ var NEVER_ASSIGN = new Set([
1300
+ "width",
1301
+ "height",
1302
+ "href",
1303
+ "list",
1304
+ "form",
1305
+ "tabIndex",
1306
+ "download",
1307
+ "rowSpan",
1308
+ "colSpan",
1309
+ "role",
1310
+ "popover"
1311
+ ]);
1312
+ function applyProperties(node, props) {
1292
1313
  const namespaced = isNamespaced(node);
1293
- for (const propName in props) {
1294
- const propValue = props[propName];
1295
- if (propValue === undefined)
1296
- removeProperty(node, propName, previous);
1297
- else if (propName === "dangerouslySetInnerHTML")
1298
- node.innerHTML = propValue.__html ?? "";
1299
- else if (propName === "className")
1300
- node.setAttribute("class", propValue);
1301
- else if (namespaced || isHtmlAttribute(propName))
1302
- node.setAttribute(propName, propValue);
1303
- else
1304
- node[propName] = propValue;
1305
- }
1306
- }
1307
- function removeProperty(node, propName, previous) {
1308
- const previousValue = previous[propName];
1309
- if (propName === "dangerouslySetInnerHTML")
1310
- node.replaceChildren();
1311
- else if (propName === "className")
1312
- node.removeAttribute("class");
1313
- else if (propName === "htmlFor")
1314
- node.removeAttribute("for");
1315
- else if (isNamespaced(node) || typeof previousValue === "string" || isHtmlAttribute(propName))
1316
- node.removeAttribute(propName);
1314
+ for (const name in props)
1315
+ setProp(node, name, props[name], namespaced);
1316
+ }
1317
+ function setProp(node, name, value, namespaced) {
1318
+ if (name === "dangerouslySetInnerHTML") {
1319
+ if (value === undefined)
1320
+ node.replaceChildren();
1321
+ else {
1322
+ const html = value.__html ?? "";
1323
+ if (html !== node.innerHTML)
1324
+ node.innerHTML = html;
1325
+ }
1326
+ return;
1327
+ }
1328
+ if (typeof value === "function")
1329
+ return;
1330
+ if (!namespaced && !NEVER_ASSIGN.has(name) && name in node) {
1331
+ try {
1332
+ node[name] = value == null ? "" : value;
1333
+ return;
1334
+ } catch {}
1335
+ }
1336
+ if (value == null || value === false && name[4] !== "-")
1337
+ node.removeAttribute(name);
1317
1338
  else
1318
- node[propName] = null;
1339
+ node.setAttribute(name, value);
1340
+ }
1341
+ function applyValueLast(node, value) {
1342
+ if (node.tagName === "PROGRESS" && (value == null || value === 0)) {
1343
+ node.removeAttribute("value");
1344
+ } else {
1345
+ setProp(node, "value", value, isNamespaced(node));
1346
+ }
1319
1347
  }
1320
1348
 
1321
1349
  class VBase {
@@ -1435,15 +1463,23 @@ class VNode extends VBase {
1435
1463
  }
1436
1464
  toDom(opts) {
1437
1465
  const doc = opts.document;
1438
- const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
1439
- if (this.tag === "SELECT" && "value" in this.attrs) {
1440
- const { value, ...rest } = this.attrs;
1441
- applyProperties(node, rest, {});
1442
- appendChildNodes(node, this.childs, opts);
1443
- applyProperties(node, { value }, {});
1466
+ const ns = effectiveNs(this, opts);
1467
+ const tag = ns !== null && this.tag === this.tag.toUpperCase() ? this.tag.toLowerCase() : this.tag;
1468
+ const attrs = this.attrs;
1469
+ const createOpts = attrs.is != null ? { is: attrs.is } : undefined;
1470
+ const node = ns === null ? doc.createElement(tag, createOpts) : doc.createElementNS(ns, tag, createOpts);
1471
+ const cOpts = childOpts(this, ns, opts);
1472
+ if ("value" in attrs || "checked" in attrs) {
1473
+ const { value, checked, ...rest } = attrs;
1474
+ applyProperties(node, rest);
1475
+ appendChildNodes(node, this.childs, cOpts);
1476
+ if (value !== undefined)
1477
+ applyValueLast(node, value);
1478
+ if (checked !== undefined)
1479
+ setProp(node, "checked", checked, false);
1444
1480
  } else {
1445
- applyProperties(node, this.attrs, {});
1446
- appendChildNodes(node, this.childs, opts);
1481
+ applyProperties(node, attrs);
1482
+ appendChildNodes(node, this.childs, cOpts);
1447
1483
  }
1448
1484
  return node;
1449
1485
  }
@@ -1480,18 +1516,37 @@ function morphNode(domNode, source, target, opts) {
1480
1516
  }
1481
1517
  if (type === 1 && source.isSameKind(target)) {
1482
1518
  const propsDiff = diffProps(source.attrs, target.attrs);
1483
- const isSelect = source.tag === "SELECT";
1519
+ let pendingValue;
1520
+ let pendingChecked;
1521
+ let applyValue = false;
1522
+ let applyChecked = false;
1484
1523
  if (propsDiff) {
1485
- if (isSelect && "value" in propsDiff) {
1486
- const { value: _v, ...rest } = propsDiff;
1487
- applyProperties(domNode, rest, source.attrs);
1524
+ if ("value" in propsDiff || "checked" in propsDiff) {
1525
+ const { value, checked, ...rest } = propsDiff;
1526
+ applyProperties(domNode, rest);
1527
+ if ("value" in propsDiff) {
1528
+ pendingValue = value;
1529
+ applyValue = true;
1530
+ }
1531
+ if ("checked" in propsDiff) {
1532
+ pendingChecked = checked;
1533
+ applyChecked = true;
1534
+ }
1488
1535
  } else
1489
- applyProperties(domNode, propsDiff, source.attrs);
1536
+ applyProperties(domNode, propsDiff);
1537
+ }
1538
+ if (!target.attrs.dangerouslySetInnerHTML) {
1539
+ const ns = effectiveNs(target, opts);
1540
+ morphChildren(domNode, source.childs, target.childs, childOpts(target, ns, opts));
1541
+ }
1542
+ if (!applyValue && source.tag === "SELECT" && target.attrs.value !== undefined) {
1543
+ pendingValue = target.attrs.value;
1544
+ applyValue = true;
1490
1545
  }
1491
- if (!target.attrs.dangerouslySetInnerHTML)
1492
- morphChildren(domNode, source.childs, target.childs, opts);
1493
- if (isSelect && target.attrs.value !== undefined)
1494
- applyProperties(domNode, { value: target.attrs.value }, source.attrs);
1546
+ if (applyValue)
1547
+ applyValueLast(domNode, pendingValue);
1548
+ if (applyChecked)
1549
+ setProp(domNode, "checked", pendingChecked, false);
1495
1550
  return domNode;
1496
1551
  }
1497
1552
  if (type === 11) {
@@ -1587,26 +1642,26 @@ function h(tagName, properties, children, namespace) {
1587
1642
  if (properties) {
1588
1643
  for (const propName in properties) {
1589
1644
  const propVal = properties[propName];
1590
- switch (propName) {
1591
- case "key":
1592
- key = propVal;
1593
- break;
1594
- case "namespace":
1595
- namespace = namespace ?? propVal;
1596
- break;
1597
- case "class":
1598
- props.className = propVal;
1599
- break;
1600
- case "for":
1601
- props.htmlFor = propVal;
1602
- break;
1603
- default:
1604
- props[propName] = isHtmlAttribute(propName) ? String(propVal) : propVal;
1605
- }
1645
+ if (propName === "key")
1646
+ key = propVal;
1647
+ else if (propName === "namespace")
1648
+ namespace = namespace ?? propVal;
1649
+ else
1650
+ props[propName] = propVal;
1651
+ }
1652
+ }
1653
+ if (namespace == null) {
1654
+ const lower = tagName.toLowerCase();
1655
+ if (lower === "svg") {
1656
+ namespace = SVG_NS;
1657
+ tagName = "svg";
1658
+ } else if (lower === "math") {
1659
+ namespace = MATH_NS;
1660
+ tagName = "math";
1606
1661
  }
1607
1662
  }
1608
1663
  const c = tagName.charCodeAt(0);
1609
- const tag = namespace == null && c >= 97 && c <= 122 ? tagName.toUpperCase() : tagName;
1664
+ const tag = namespace == null && c >= 97 && c <= 122 && tagName === tagName.toLowerCase() ? tagName.toUpperCase() : tagName;
1610
1665
  const normalizedChildren = [];
1611
1666
  addChild(normalizedChildren, children);
1612
1667
  return new VNode(tag, props, normalizedChildren, key, namespace);
@@ -4106,6 +4161,7 @@ __export(exports_tutuca, {
4106
4161
  html: () => html,
4107
4162
  css: () => css,
4108
4163
  component: () => component,
4164
+ collectIterBindings: () => collectIterBindings,
4109
4165
  check: () => check,
4110
4166
  SEQ_INFO: () => SEQ_INFO,
4111
4167
  ParseContext: () => ParseContext,
@@ -4132,6 +4188,10 @@ function check(_app) {
4132
4188
  async function test(_opts) {
4133
4189
  return null;
4134
4190
  }
4191
+ function collectIterBindings() {
4192
+ console.warn("collectIterBindings is a no-op in the core tutuca build; use the tutuca-dev build for a functional implementation");
4193
+ return [];
4194
+ }
4135
4195
  function tutuca(nodeOrSelector) {
4136
4196
  const rootNode = typeof nodeOrSelector === "string" ? document.querySelector(nodeOrSelector) : nodeOrSelector;
4137
4197
  const comps = new Components;
@@ -4173,6 +4233,7 @@ export {
4173
4233
  component,
4174
4234
  compileClassesToStyleText,
4175
4235
  compileClassesToStyle,
4236
+ collectIterBindings,
4176
4237
  check,
4177
4238
  SEQ_INFO,
4178
4239
  ParseContext,
@@ -5545,40 +5545,67 @@ class RequestHandler {
5545
5545
  }
5546
5546
 
5547
5547
  // src/vdom.js
5548
- var isHtmlAttribute = (propName) => propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
5549
5548
  var HTML_NS = "http://www.w3.org/1999/xhtml";
5549
+ var SVG_NS = "http://www.w3.org/2000/svg";
5550
+ var MATH_NS = "http://www.w3.org/1998/Math/MathML";
5550
5551
  var isNamespaced = (node) => {
5551
5552
  const ns = node.namespaceURI;
5552
5553
  return ns !== null && ns !== HTML_NS;
5553
5554
  };
5554
- function applyProperties(node, props, previous) {
5555
+ var isForeignObject = (tag) => tag.length === 13 && tag.toLowerCase() === "foreignobject";
5556
+ var effectiveNs = (vnode, opts) => vnode.namespace ?? opts.namespace ?? null;
5557
+ function childOpts(vnode, ns, opts) {
5558
+ const target = ns === SVG_NS && isForeignObject(vnode.tag) ? null : ns;
5559
+ return target === (opts.namespace ?? null) ? opts : { ...opts, namespace: target };
5560
+ }
5561
+ var NEVER_ASSIGN = new Set([
5562
+ "width",
5563
+ "height",
5564
+ "href",
5565
+ "list",
5566
+ "form",
5567
+ "tabIndex",
5568
+ "download",
5569
+ "rowSpan",
5570
+ "colSpan",
5571
+ "role",
5572
+ "popover"
5573
+ ]);
5574
+ function applyProperties(node, props) {
5555
5575
  const namespaced = isNamespaced(node);
5556
- for (const propName in props) {
5557
- const propValue = props[propName];
5558
- if (propValue === undefined)
5559
- removeProperty(node, propName, previous);
5560
- else if (propName === "dangerouslySetInnerHTML")
5561
- node.innerHTML = propValue.__html ?? "";
5562
- else if (propName === "className")
5563
- node.setAttribute("class", propValue);
5564
- else if (namespaced || isHtmlAttribute(propName))
5565
- node.setAttribute(propName, propValue);
5566
- else
5567
- node[propName] = propValue;
5568
- }
5569
- }
5570
- function removeProperty(node, propName, previous) {
5571
- const previousValue = previous[propName];
5572
- if (propName === "dangerouslySetInnerHTML")
5573
- node.replaceChildren();
5574
- else if (propName === "className")
5575
- node.removeAttribute("class");
5576
- else if (propName === "htmlFor")
5577
- node.removeAttribute("for");
5578
- else if (isNamespaced(node) || typeof previousValue === "string" || isHtmlAttribute(propName))
5579
- node.removeAttribute(propName);
5576
+ for (const name in props)
5577
+ setProp2(node, name, props[name], namespaced);
5578
+ }
5579
+ function setProp2(node, name, value, namespaced) {
5580
+ if (name === "dangerouslySetInnerHTML") {
5581
+ if (value === undefined)
5582
+ node.replaceChildren();
5583
+ else {
5584
+ const html = value.__html ?? "";
5585
+ if (html !== node.innerHTML)
5586
+ node.innerHTML = html;
5587
+ }
5588
+ return;
5589
+ }
5590
+ if (typeof value === "function")
5591
+ return;
5592
+ if (!namespaced && !NEVER_ASSIGN.has(name) && name in node) {
5593
+ try {
5594
+ node[name] = value == null ? "" : value;
5595
+ return;
5596
+ } catch {}
5597
+ }
5598
+ if (value == null || value === false && name[4] !== "-")
5599
+ node.removeAttribute(name);
5580
5600
  else
5581
- node[propName] = null;
5601
+ node.setAttribute(name, value);
5602
+ }
5603
+ function applyValueLast(node, value) {
5604
+ if (node.tagName === "PROGRESS" && (value == null || value === 0)) {
5605
+ node.removeAttribute("value");
5606
+ } else {
5607
+ setProp2(node, "value", value, isNamespaced(node));
5608
+ }
5582
5609
  }
5583
5610
 
5584
5611
  class VBase {
@@ -5698,15 +5725,23 @@ class VNode2 extends VBase {
5698
5725
  }
5699
5726
  toDom(opts) {
5700
5727
  const doc = opts.document;
5701
- const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
5702
- if (this.tag === "SELECT" && "value" in this.attrs) {
5703
- const { value, ...rest } = this.attrs;
5704
- applyProperties(node, rest, {});
5705
- appendChildNodes(node, this.childs, opts);
5706
- applyProperties(node, { value }, {});
5728
+ const ns = effectiveNs(this, opts);
5729
+ const tag = ns !== null && this.tag === this.tag.toUpperCase() ? this.tag.toLowerCase() : this.tag;
5730
+ const attrs = this.attrs;
5731
+ const createOpts = attrs.is != null ? { is: attrs.is } : undefined;
5732
+ const node = ns === null ? doc.createElement(tag, createOpts) : doc.createElementNS(ns, tag, createOpts);
5733
+ const cOpts = childOpts(this, ns, opts);
5734
+ if ("value" in attrs || "checked" in attrs) {
5735
+ const { value, checked, ...rest } = attrs;
5736
+ applyProperties(node, rest);
5737
+ appendChildNodes(node, this.childs, cOpts);
5738
+ if (value !== undefined)
5739
+ applyValueLast(node, value);
5740
+ if (checked !== undefined)
5741
+ setProp2(node, "checked", checked, false);
5707
5742
  } else {
5708
- applyProperties(node, this.attrs, {});
5709
- appendChildNodes(node, this.childs, opts);
5743
+ applyProperties(node, attrs);
5744
+ appendChildNodes(node, this.childs, cOpts);
5710
5745
  }
5711
5746
  return node;
5712
5747
  }
@@ -5743,18 +5778,37 @@ function morphNode(domNode, source, target, opts) {
5743
5778
  }
5744
5779
  if (type === 1 && source.isSameKind(target)) {
5745
5780
  const propsDiff = diffProps(source.attrs, target.attrs);
5746
- const isSelect = source.tag === "SELECT";
5781
+ let pendingValue;
5782
+ let pendingChecked;
5783
+ let applyValue = false;
5784
+ let applyChecked = false;
5747
5785
  if (propsDiff) {
5748
- if (isSelect && "value" in propsDiff) {
5749
- const { value: _v, ...rest } = propsDiff;
5750
- applyProperties(domNode, rest, source.attrs);
5786
+ if ("value" in propsDiff || "checked" in propsDiff) {
5787
+ const { value, checked, ...rest } = propsDiff;
5788
+ applyProperties(domNode, rest);
5789
+ if ("value" in propsDiff) {
5790
+ pendingValue = value;
5791
+ applyValue = true;
5792
+ }
5793
+ if ("checked" in propsDiff) {
5794
+ pendingChecked = checked;
5795
+ applyChecked = true;
5796
+ }
5751
5797
  } else
5752
- applyProperties(domNode, propsDiff, source.attrs);
5798
+ applyProperties(domNode, propsDiff);
5799
+ }
5800
+ if (!target.attrs.dangerouslySetInnerHTML) {
5801
+ const ns = effectiveNs(target, opts);
5802
+ morphChildren(domNode, source.childs, target.childs, childOpts(target, ns, opts));
5803
+ }
5804
+ if (!applyValue && source.tag === "SELECT" && target.attrs.value !== undefined) {
5805
+ pendingValue = target.attrs.value;
5806
+ applyValue = true;
5753
5807
  }
5754
- if (!target.attrs.dangerouslySetInnerHTML)
5755
- morphChildren(domNode, source.childs, target.childs, opts);
5756
- if (isSelect && target.attrs.value !== undefined)
5757
- applyProperties(domNode, { value: target.attrs.value }, source.attrs);
5808
+ if (applyValue)
5809
+ applyValueLast(domNode, pendingValue);
5810
+ if (applyChecked)
5811
+ setProp2(domNode, "checked", pendingChecked, false);
5758
5812
  return domNode;
5759
5813
  }
5760
5814
  if (type === 11) {
@@ -5850,26 +5904,26 @@ function h(tagName, properties, children, namespace) {
5850
5904
  if (properties) {
5851
5905
  for (const propName in properties) {
5852
5906
  const propVal = properties[propName];
5853
- switch (propName) {
5854
- case "key":
5855
- key = propVal;
5856
- break;
5857
- case "namespace":
5858
- namespace = namespace ?? propVal;
5859
- break;
5860
- case "class":
5861
- props.className = propVal;
5862
- break;
5863
- case "for":
5864
- props.htmlFor = propVal;
5865
- break;
5866
- default:
5867
- props[propName] = isHtmlAttribute(propName) ? String(propVal) : propVal;
5868
- }
5907
+ if (propName === "key")
5908
+ key = propVal;
5909
+ else if (propName === "namespace")
5910
+ namespace = namespace ?? propVal;
5911
+ else
5912
+ props[propName] = propVal;
5913
+ }
5914
+ }
5915
+ if (namespace == null) {
5916
+ const lower = tagName.toLowerCase();
5917
+ if (lower === "svg") {
5918
+ namespace = SVG_NS;
5919
+ tagName = "svg";
5920
+ } else if (lower === "math") {
5921
+ namespace = MATH_NS;
5922
+ tagName = "math";
5869
5923
  }
5870
5924
  }
5871
5925
  const c = tagName.charCodeAt(0);
5872
- const tag = namespace == null && c >= 97 && c <= 122 ? tagName.toUpperCase() : tagName;
5926
+ const tag = namespace == null && c >= 97 && c <= 122 && tagName === tagName.toLowerCase() ? tagName.toUpperCase() : tagName;
5873
5927
  const normalizedChildren = [];
5874
5928
  addChild(normalizedChildren, children);
5875
5929
  return new VNode2(tag, props, normalizedChildren, key, namespace);
@@ -8309,6 +8363,10 @@ function check(_app) {
8309
8363
  async function test(_opts) {
8310
8364
  return null;
8311
8365
  }
8366
+ function collectIterBindings() {
8367
+ console.warn("collectIterBindings is a no-op in the core tutuca build; use the tutuca-dev build for a functional implementation");
8368
+ return [];
8369
+ }
8312
8370
  function tutuca(nodeOrSelector) {
8313
8371
  const rootNode = typeof nodeOrSelector === "string" ? document.querySelector(nodeOrSelector) : nodeOrSelector;
8314
8372
  const comps = new Components;
@@ -8383,6 +8441,7 @@ export {
8383
8441
  component,
8384
8442
  compileClassesToStyleText,
8385
8443
  compileClassesToStyle,
8444
+ collectIterBindings,
8386
8445
  check,
8387
8446
  Stack,
8388
8447
  Set2 as Set,