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.
@@ -5367,34 +5367,45 @@ var init_attribute = __esm(() => {
5367
5367
  });
5368
5368
 
5369
5369
  // src/vdom.js
5370
- function applyProperties(node, props, previous) {
5370
+ function childOpts(vnode, ns, opts) {
5371
+ const target = ns === SVG_NS && isForeignObject(vnode.tag) ? null : ns;
5372
+ return target === (opts.namespace ?? null) ? opts : { ...opts, namespace: target };
5373
+ }
5374
+ function applyProperties(node, props) {
5371
5375
  const namespaced = isNamespaced(node);
5372
- for (const propName in props) {
5373
- const propValue = props[propName];
5374
- if (propValue === undefined)
5375
- removeProperty(node, propName, previous);
5376
- else if (propName === "dangerouslySetInnerHTML")
5377
- node.innerHTML = propValue.__html ?? "";
5378
- else if (propName === "className")
5379
- node.setAttribute("class", propValue);
5380
- else if (namespaced || isHtmlAttribute(propName))
5381
- node.setAttribute(propName, propValue);
5382
- else
5383
- node[propName] = propValue;
5384
- }
5385
- }
5386
- function removeProperty(node, propName, previous) {
5387
- const previousValue = previous[propName];
5388
- if (propName === "dangerouslySetInnerHTML")
5389
- node.replaceChildren();
5390
- else if (propName === "className")
5391
- node.removeAttribute("class");
5392
- else if (propName === "htmlFor")
5393
- node.removeAttribute("for");
5394
- else if (isNamespaced(node) || typeof previousValue === "string" || isHtmlAttribute(propName))
5395
- node.removeAttribute(propName);
5376
+ for (const name in props)
5377
+ setProp2(node, name, props[name], namespaced);
5378
+ }
5379
+ function setProp2(node, name, value, namespaced) {
5380
+ if (name === "dangerouslySetInnerHTML") {
5381
+ if (value === undefined)
5382
+ node.replaceChildren();
5383
+ else {
5384
+ const html = value.__html ?? "";
5385
+ if (html !== node.innerHTML)
5386
+ node.innerHTML = html;
5387
+ }
5388
+ return;
5389
+ }
5390
+ if (typeof value === "function")
5391
+ return;
5392
+ if (!namespaced && !NEVER_ASSIGN.has(name) && name in node) {
5393
+ try {
5394
+ node[name] = value == null ? "" : value;
5395
+ return;
5396
+ } catch {}
5397
+ }
5398
+ if (value == null || value === false && name[4] !== "-")
5399
+ node.removeAttribute(name);
5396
5400
  else
5397
- node[propName] = null;
5401
+ node.setAttribute(name, value);
5402
+ }
5403
+ function applyValueLast(node, value) {
5404
+ if (node.tagName === "PROGRESS" && (value == null || value === 0)) {
5405
+ node.removeAttribute("value");
5406
+ } else {
5407
+ setProp2(node, "value", value, isNamespaced(node));
5408
+ }
5398
5409
  }
5399
5410
 
5400
5411
  class VBase {
@@ -5457,18 +5468,37 @@ function morphNode(domNode, source, target, opts) {
5457
5468
  }
5458
5469
  if (type === 1 && source.isSameKind(target)) {
5459
5470
  const propsDiff = diffProps(source.attrs, target.attrs);
5460
- const isSelect = source.tag === "SELECT";
5471
+ let pendingValue;
5472
+ let pendingChecked;
5473
+ let applyValue = false;
5474
+ let applyChecked = false;
5461
5475
  if (propsDiff) {
5462
- if (isSelect && "value" in propsDiff) {
5463
- const { value: _v, ...rest } = propsDiff;
5464
- applyProperties(domNode, rest, source.attrs);
5476
+ if ("value" in propsDiff || "checked" in propsDiff) {
5477
+ const { value, checked, ...rest } = propsDiff;
5478
+ applyProperties(domNode, rest);
5479
+ if ("value" in propsDiff) {
5480
+ pendingValue = value;
5481
+ applyValue = true;
5482
+ }
5483
+ if ("checked" in propsDiff) {
5484
+ pendingChecked = checked;
5485
+ applyChecked = true;
5486
+ }
5465
5487
  } else
5466
- applyProperties(domNode, propsDiff, source.attrs);
5488
+ applyProperties(domNode, propsDiff);
5467
5489
  }
5468
- if (!target.attrs.dangerouslySetInnerHTML)
5469
- morphChildren(domNode, source.childs, target.childs, opts);
5470
- if (isSelect && target.attrs.value !== undefined)
5471
- applyProperties(domNode, { value: target.attrs.value }, source.attrs);
5490
+ if (!target.attrs.dangerouslySetInnerHTML) {
5491
+ const ns = effectiveNs(target, opts);
5492
+ morphChildren(domNode, source.childs, target.childs, childOpts(target, ns, opts));
5493
+ }
5494
+ if (!applyValue && source.tag === "SELECT" && target.attrs.value !== undefined) {
5495
+ pendingValue = target.attrs.value;
5496
+ applyValue = true;
5497
+ }
5498
+ if (applyValue)
5499
+ applyValueLast(domNode, pendingValue);
5500
+ if (applyChecked)
5501
+ setProp2(domNode, "checked", pendingChecked, false);
5472
5502
  return domNode;
5473
5503
  }
5474
5504
  if (type === 11) {
@@ -5564,35 +5594,48 @@ function h(tagName, properties, children, namespace) {
5564
5594
  if (properties) {
5565
5595
  for (const propName in properties) {
5566
5596
  const propVal = properties[propName];
5567
- switch (propName) {
5568
- case "key":
5569
- key = propVal;
5570
- break;
5571
- case "namespace":
5572
- namespace = namespace ?? propVal;
5573
- break;
5574
- case "class":
5575
- props.className = propVal;
5576
- break;
5577
- case "for":
5578
- props.htmlFor = propVal;
5579
- break;
5580
- default:
5581
- props[propName] = isHtmlAttribute(propName) ? String(propVal) : propVal;
5582
- }
5597
+ if (propName === "key")
5598
+ key = propVal;
5599
+ else if (propName === "namespace")
5600
+ namespace = namespace ?? propVal;
5601
+ else
5602
+ props[propName] = propVal;
5603
+ }
5604
+ }
5605
+ if (namespace == null) {
5606
+ const lower = tagName.toLowerCase();
5607
+ if (lower === "svg") {
5608
+ namespace = SVG_NS;
5609
+ tagName = "svg";
5610
+ } else if (lower === "math") {
5611
+ namespace = MATH_NS;
5612
+ tagName = "math";
5583
5613
  }
5584
5614
  }
5585
5615
  const c = tagName.charCodeAt(0);
5586
- const tag = namespace == null && c >= 97 && c <= 122 ? tagName.toUpperCase() : tagName;
5616
+ const tag = namespace == null && c >= 97 && c <= 122 && tagName === tagName.toLowerCase() ? tagName.toUpperCase() : tagName;
5587
5617
  const normalizedChildren = [];
5588
5618
  addChild(normalizedChildren, children);
5589
5619
  return new VNode2(tag, props, normalizedChildren, key, namespace);
5590
5620
  }
5591
- var isHtmlAttribute = (propName) => propName[4] === "-" && (propName[0] === "d" || propName[0] === "a"), HTML_NS = "http://www.w3.org/1999/xhtml", isNamespaced = (node) => {
5621
+ var HTML_NS = "http://www.w3.org/1999/xhtml", SVG_NS = "http://www.w3.org/2000/svg", MATH_NS = "http://www.w3.org/1998/Math/MathML", isNamespaced = (node) => {
5592
5622
  const ns = node.namespaceURI;
5593
5623
  return ns !== null && ns !== HTML_NS;
5594
- }, getKey = (child) => child instanceof VNode2 ? child.key : undefined, isIterable = (obj) => obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function", VText, VComment, VFragment, VNode2;
5624
+ }, isForeignObject = (tag) => tag.length === 13 && tag.toLowerCase() === "foreignobject", effectiveNs = (vnode, opts) => vnode.namespace ?? opts.namespace ?? null, NEVER_ASSIGN, getKey = (child) => child instanceof VNode2 ? child.key : undefined, isIterable = (obj) => obj != null && typeof obj !== "string" && typeof obj[Symbol.iterator] === "function", VText, VComment, VFragment, VNode2;
5595
5625
  var init_vdom = __esm(() => {
5626
+ NEVER_ASSIGN = new Set([
5627
+ "width",
5628
+ "height",
5629
+ "href",
5630
+ "list",
5631
+ "form",
5632
+ "tabIndex",
5633
+ "download",
5634
+ "rowSpan",
5635
+ "colSpan",
5636
+ "role",
5637
+ "popover"
5638
+ ]);
5596
5639
  VText = class VText extends VBase {
5597
5640
  constructor(text) {
5598
5641
  super();
@@ -5676,15 +5719,23 @@ var init_vdom = __esm(() => {
5676
5719
  }
5677
5720
  toDom(opts) {
5678
5721
  const doc = opts.document;
5679
- const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
5680
- if (this.tag === "SELECT" && "value" in this.attrs) {
5681
- const { value, ...rest } = this.attrs;
5682
- applyProperties(node, rest, {});
5683
- appendChildNodes(node, this.childs, opts);
5684
- applyProperties(node, { value }, {});
5722
+ const ns = effectiveNs(this, opts);
5723
+ const tag = ns !== null && this.tag === this.tag.toUpperCase() ? this.tag.toLowerCase() : this.tag;
5724
+ const attrs = this.attrs;
5725
+ const createOpts = attrs.is != null ? { is: attrs.is } : undefined;
5726
+ const node = ns === null ? doc.createElement(tag, createOpts) : doc.createElementNS(ns, tag, createOpts);
5727
+ const cOpts = childOpts(this, ns, opts);
5728
+ if ("value" in attrs || "checked" in attrs) {
5729
+ const { value, checked, ...rest } = attrs;
5730
+ applyProperties(node, rest);
5731
+ appendChildNodes(node, this.childs, cOpts);
5732
+ if (value !== undefined)
5733
+ applyValueLast(node, value);
5734
+ if (checked !== undefined)
5735
+ setProp2(node, "checked", checked, false);
5685
5736
  } else {
5686
- applyProperties(node, this.attrs, {});
5687
- appendChildNodes(node, this.childs, opts);
5737
+ applyProperties(node, attrs);
5738
+ appendChildNodes(node, this.childs, cOpts);
5688
5739
  }
5689
5740
  return node;
5690
5741
  }
@@ -8680,6 +8731,7 @@ function classifyBadValue(value) {
8680
8731
  function checkComponent(Comp, lx = new LintContext, { wellKnownExtras = EMPTY_SET2 } = {}) {
8681
8732
  return lx.push({ componentName: Comp.name }, () => {
8682
8733
  checkUnknownSpecKeys(lx, Comp, wellKnownExtras);
8734
+ checkFieldDeclarations(lx, Comp);
8683
8735
  const referencedAlters = new Set;
8684
8736
  const referencedInputs = new Set;
8685
8737
  const referencedDynamics = new Set;
@@ -9074,6 +9126,31 @@ function checkUnknownSpecKeys(lx, Comp, wellKnownExtras) {
9074
9126
  lx.warn(UNKNOWN_COMPONENT_SPEC_KEY, { key }, replaceNameSuggestion(key, candidates));
9075
9127
  }
9076
9128
  }
9129
+ function checkFieldDeclarations(lx, Comp) {
9130
+ const fields = Comp.Class?.getMetaClass?.().fields;
9131
+ if (!fields)
9132
+ return;
9133
+ for (const fieldName in fields) {
9134
+ const field = fields[fieldName];
9135
+ if (!Object.hasOwn(field, "args"))
9136
+ continue;
9137
+ if (typeof field.type !== "string") {
9138
+ lx.error(COMP_FIELD_BAD_SHAPE, {
9139
+ fieldName,
9140
+ kind: "component-not-string",
9141
+ got: typeof field.type,
9142
+ gotName: field.type?.name ?? null
9143
+ });
9144
+ }
9145
+ if (field.args == null || field.args.constructor !== Object) {
9146
+ lx.error(COMP_FIELD_BAD_SHAPE, {
9147
+ fieldName,
9148
+ kind: "args-not-object",
9149
+ got: field.args === null ? "null" : typeof field.args
9150
+ });
9151
+ }
9152
+ }
9153
+ }
9077
9154
  function checkUnreferencedAlterHandlers(lx, Comp, referencedAlters) {
9078
9155
  for (const name in Comp.alter) {
9079
9156
  if (!referencedAlters.has(name)) {
@@ -9124,7 +9201,7 @@ class LintContext {
9124
9201
  this.reports.push({ id, info, level, context: { ...this.frame }, suggestion });
9125
9202
  }
9126
9203
  }
9127
- var KNOWN_COMPONENT_SPEC_KEYS, EMPTY_SET2, KNOWN_DIRECTIVE_NAMES, ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", DYN_VAL_NOT_DEFINED = "DYN_VAL_NOT_DEFINED", DYN_ALIAS_NOT_REFERENCED = "DYN_ALIAS_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", FIELD_VAL_IS_METHOD = "FIELD_VAL_IS_METHOD", METHOD_VAL_NOT_DEFINED = "METHOD_VAL_NOT_DEFINED", METHOD_VAL_IS_FIELD = "METHOD_VAL_IS_FIELD", DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION", IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE", UNKNOWN_X_OP = "UNKNOWN_X_OP", UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR", MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX", BAD_VALUE = "BAD_VALUE", UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX", REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING", PLACEHOLDERLESS_TEMPLATE_STRING = "PLACEHOLDERLESS_TEMPLATE_STRING", UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY", PARSE_ISSUE_KIND_TO_LINT_ID, X_KNOWN_OP_NAMES, X_KNOWN_ATTR_NAMES, AT_PREFIX_HINT_KNOWN_BY_KIND, LEVEL_WARN2 = "warn", LEVEL_ERROR2 = "error", LEVEL_HINT = "hint", PARSE_ISSUE_KIND_TO_KNOWN_NAMES, UNSUPPORTED_EXPR_GUIDANCE, HTML_LINT_OPTS, NO_WRAPPERS, KNOWN_HANDLER_NAMES, NODE_KIND_TO_CTX, LintParseContext;
9204
+ var KNOWN_COMPONENT_SPEC_KEYS, EMPTY_SET2, KNOWN_DIRECTIVE_NAMES, ALT_HANDLER_NOT_DEFINED = "ALT_HANDLER_NOT_DEFINED", ALT_HANDLER_NOT_REFERENCED = "ALT_HANDLER_NOT_REFERENCED", DYN_VAL_NOT_DEFINED = "DYN_VAL_NOT_DEFINED", DYN_ALIAS_NOT_REFERENCED = "DYN_ALIAS_NOT_REFERENCED", RENDER_IT_OUTSIDE_OF_LOOP = "RENDER_IT_OUTSIDE_OF_LOOP", UNKNOWN_EVENT_MODIFIER = "UNKNOWN_EVENT_MODIFIER", UNKNOWN_HANDLER_ARG_NAME = "UNKNOWN_HANDLER_ARG_NAME", INPUT_HANDLER_NOT_IMPLEMENTED = "INPUT_HANDLER_NOT_IMPLEMENTED", INPUT_HANDLER_NOT_REFERENCED = "INPUT_HANDLER_NOT_REFERENCED", INPUT_HANDLER_METHOD_NOT_IMPLEMENTED = "INPUT_HANDLER_METHOD_NOT_IMPLEMENTED", INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD = "INPUT_HANDLER_FOR_INPUT_HANDLER_METHOD", INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER = "INPUT_HANDLER_METHOD_FOR_INPUT_HANDLER", FIELD_VAL_NOT_DEFINED = "FIELD_VAL_NOT_DEFINED", FIELD_VAL_IS_METHOD = "FIELD_VAL_IS_METHOD", METHOD_VAL_NOT_DEFINED = "METHOD_VAL_NOT_DEFINED", METHOD_VAL_IS_FIELD = "METHOD_VAL_IS_FIELD", DUPLICATE_ATTR_DEFINITION = "DUPLICATE_ATTR_DEFINITION", IF_NO_BRANCH_SET = "IF_NO_BRANCH_SET", UNKNOWN_REQUEST_NAME = "UNKNOWN_REQUEST_NAME", UNKNOWN_COMPONENT_NAME = "UNKNOWN_COMPONENT_NAME", UNKNOWN_MACRO_ARG = "UNKNOWN_MACRO_ARG", UNKNOWN_DIRECTIVE = "UNKNOWN_DIRECTIVE", UNKNOWN_X_OP = "UNKNOWN_X_OP", UNKNOWN_X_ATTR = "UNKNOWN_X_ATTR", MAYBE_DROP_AT_PREFIX = "MAYBE_DROP_AT_PREFIX", BAD_VALUE = "BAD_VALUE", UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX", REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING", PLACEHOLDERLESS_TEMPLATE_STRING = "PLACEHOLDERLESS_TEMPLATE_STRING", UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY", COMP_FIELD_BAD_SHAPE = "COMP_FIELD_BAD_SHAPE", PARSE_ISSUE_KIND_TO_LINT_ID, X_KNOWN_OP_NAMES, X_KNOWN_ATTR_NAMES, AT_PREFIX_HINT_KNOWN_BY_KIND, LEVEL_WARN2 = "warn", LEVEL_ERROR2 = "error", LEVEL_HINT = "hint", PARSE_ISSUE_KIND_TO_KNOWN_NAMES, UNSUPPORTED_EXPR_GUIDANCE, HTML_LINT_OPTS, NO_WRAPPERS, KNOWN_HANDLER_NAMES, NODE_KIND_TO_CTX, LintParseContext;
9128
9205
  var init_lint_check = __esm(() => {
9129
9206
  init_anode();
9130
9207
  init_htmllinter();
@@ -9424,6 +9501,12 @@ var init_lint_rules = __esm(() => {
9424
9501
  level: "warn",
9425
9502
  group: "Component spec",
9426
9503
  summary: "`component({...})` has an unrecognized key; its value is ignored at runtime."
9504
+ },
9505
+ {
9506
+ code: COMP_FIELD_BAD_SHAPE,
9507
+ level: "error",
9508
+ group: "Component field declarations",
9509
+ summary: "`fields: { x: { component, args } }` shape is wrong: `component` must be a string and `args` must be a plain object."
9427
9510
  }
9428
9511
  ];
9429
9512
  });
@@ -57,7 +57,7 @@ __export(exports_dev, {
57
57
  component: () => component,
58
58
  compileClassesToStyleText: () => compileClassesToStyleText,
59
59
  compileClassesToStyle: () => compileClassesToStyle,
60
- collectIterBindings: () => collectIterBindings,
60
+ collectIterBindings: () => collectIterBindings2,
61
61
  checkComponent: () => checkComponent,
62
62
  check: () => check2,
63
63
  UNSUPPORTED_EXPR_SYNTAX: () => UNSUPPORTED_EXPR_SYNTAX,
@@ -116,6 +116,7 @@ __export(exports_dev, {
116
116
  ComponentSummary: () => ComponentSummary,
117
117
  ComponentList: () => ComponentList,
118
118
  ComponentDocs: () => ComponentDocs,
119
+ COMP_FIELD_BAD_SHAPE: () => COMP_FIELD_BAD_SHAPE,
119
120
  BAD_VALUE: () => BAD_VALUE,
120
121
  ALT_HANDLER_NOT_REFERENCED: () => ALT_HANDLER_NOT_REFERENCED,
121
122
  ALT_HANDLER_NOT_DEFINED: () => ALT_HANDLER_NOT_DEFINED
@@ -4633,40 +4634,67 @@ class RequestHandler {
4633
4634
  }
4634
4635
 
4635
4636
  // src/vdom.js
4636
- var isHtmlAttribute = (propName) => propName[4] === "-" && (propName[0] === "d" || propName[0] === "a");
4637
4637
  var HTML_NS = "http://www.w3.org/1999/xhtml";
4638
+ var SVG_NS = "http://www.w3.org/2000/svg";
4639
+ var MATH_NS = "http://www.w3.org/1998/Math/MathML";
4638
4640
  var isNamespaced = (node) => {
4639
4641
  const ns = node.namespaceURI;
4640
4642
  return ns !== null && ns !== HTML_NS;
4641
4643
  };
4642
- function applyProperties(node, props, previous) {
4644
+ var isForeignObject = (tag) => tag.length === 13 && tag.toLowerCase() === "foreignobject";
4645
+ var effectiveNs = (vnode, opts) => vnode.namespace ?? opts.namespace ?? null;
4646
+ function childOpts(vnode, ns, opts) {
4647
+ const target = ns === SVG_NS && isForeignObject(vnode.tag) ? null : ns;
4648
+ return target === (opts.namespace ?? null) ? opts : { ...opts, namespace: target };
4649
+ }
4650
+ var NEVER_ASSIGN = new Set([
4651
+ "width",
4652
+ "height",
4653
+ "href",
4654
+ "list",
4655
+ "form",
4656
+ "tabIndex",
4657
+ "download",
4658
+ "rowSpan",
4659
+ "colSpan",
4660
+ "role",
4661
+ "popover"
4662
+ ]);
4663
+ function applyProperties(node, props) {
4643
4664
  const namespaced = isNamespaced(node);
4644
- for (const propName in props) {
4645
- const propValue = props[propName];
4646
- if (propValue === undefined)
4647
- removeProperty(node, propName, previous);
4648
- else if (propName === "dangerouslySetInnerHTML")
4649
- node.innerHTML = propValue.__html ?? "";
4650
- else if (propName === "className")
4651
- node.setAttribute("class", propValue);
4652
- else if (namespaced || isHtmlAttribute(propName))
4653
- node.setAttribute(propName, propValue);
4654
- else
4655
- node[propName] = propValue;
4656
- }
4657
- }
4658
- function removeProperty(node, propName, previous) {
4659
- const previousValue = previous[propName];
4660
- if (propName === "dangerouslySetInnerHTML")
4661
- node.replaceChildren();
4662
- else if (propName === "className")
4663
- node.removeAttribute("class");
4664
- else if (propName === "htmlFor")
4665
- node.removeAttribute("for");
4666
- else if (isNamespaced(node) || typeof previousValue === "string" || isHtmlAttribute(propName))
4667
- node.removeAttribute(propName);
4665
+ for (const name in props)
4666
+ setProp(node, name, props[name], namespaced);
4667
+ }
4668
+ function setProp(node, name, value, namespaced) {
4669
+ if (name === "dangerouslySetInnerHTML") {
4670
+ if (value === undefined)
4671
+ node.replaceChildren();
4672
+ else {
4673
+ const html = value.__html ?? "";
4674
+ if (html !== node.innerHTML)
4675
+ node.innerHTML = html;
4676
+ }
4677
+ return;
4678
+ }
4679
+ if (typeof value === "function")
4680
+ return;
4681
+ if (!namespaced && !NEVER_ASSIGN.has(name) && name in node) {
4682
+ try {
4683
+ node[name] = value == null ? "" : value;
4684
+ return;
4685
+ } catch {}
4686
+ }
4687
+ if (value == null || value === false && name[4] !== "-")
4688
+ node.removeAttribute(name);
4668
4689
  else
4669
- node[propName] = null;
4690
+ node.setAttribute(name, value);
4691
+ }
4692
+ function applyValueLast(node, value) {
4693
+ if (node.tagName === "PROGRESS" && (value == null || value === 0)) {
4694
+ node.removeAttribute("value");
4695
+ } else {
4696
+ setProp(node, "value", value, isNamespaced(node));
4697
+ }
4670
4698
  }
4671
4699
 
4672
4700
  class VBase {
@@ -4786,15 +4814,23 @@ class VNode extends VBase {
4786
4814
  }
4787
4815
  toDom(opts) {
4788
4816
  const doc = opts.document;
4789
- const node = this.namespace === null ? doc.createElement(this.tag) : doc.createElementNS(this.namespace, this.tag);
4790
- if (this.tag === "SELECT" && "value" in this.attrs) {
4791
- const { value, ...rest } = this.attrs;
4792
- applyProperties(node, rest, {});
4793
- appendChildNodes(node, this.childs, opts);
4794
- applyProperties(node, { value }, {});
4817
+ const ns = effectiveNs(this, opts);
4818
+ const tag = ns !== null && this.tag === this.tag.toUpperCase() ? this.tag.toLowerCase() : this.tag;
4819
+ const attrs = this.attrs;
4820
+ const createOpts = attrs.is != null ? { is: attrs.is } : undefined;
4821
+ const node = ns === null ? doc.createElement(tag, createOpts) : doc.createElementNS(ns, tag, createOpts);
4822
+ const cOpts = childOpts(this, ns, opts);
4823
+ if ("value" in attrs || "checked" in attrs) {
4824
+ const { value, checked, ...rest } = attrs;
4825
+ applyProperties(node, rest);
4826
+ appendChildNodes(node, this.childs, cOpts);
4827
+ if (value !== undefined)
4828
+ applyValueLast(node, value);
4829
+ if (checked !== undefined)
4830
+ setProp(node, "checked", checked, false);
4795
4831
  } else {
4796
- applyProperties(node, this.attrs, {});
4797
- appendChildNodes(node, this.childs, opts);
4832
+ applyProperties(node, attrs);
4833
+ appendChildNodes(node, this.childs, cOpts);
4798
4834
  }
4799
4835
  return node;
4800
4836
  }
@@ -4831,18 +4867,37 @@ function morphNode(domNode, source, target, opts) {
4831
4867
  }
4832
4868
  if (type3 === 1 && source.isSameKind(target)) {
4833
4869
  const propsDiff = diffProps(source.attrs, target.attrs);
4834
- const isSelect = source.tag === "SELECT";
4870
+ let pendingValue;
4871
+ let pendingChecked;
4872
+ let applyValue = false;
4873
+ let applyChecked = false;
4835
4874
  if (propsDiff) {
4836
- if (isSelect && "value" in propsDiff) {
4837
- const { value: _v, ...rest } = propsDiff;
4838
- applyProperties(domNode, rest, source.attrs);
4875
+ if ("value" in propsDiff || "checked" in propsDiff) {
4876
+ const { value, checked, ...rest } = propsDiff;
4877
+ applyProperties(domNode, rest);
4878
+ if ("value" in propsDiff) {
4879
+ pendingValue = value;
4880
+ applyValue = true;
4881
+ }
4882
+ if ("checked" in propsDiff) {
4883
+ pendingChecked = checked;
4884
+ applyChecked = true;
4885
+ }
4839
4886
  } else
4840
- applyProperties(domNode, propsDiff, source.attrs);
4887
+ applyProperties(domNode, propsDiff);
4888
+ }
4889
+ if (!target.attrs.dangerouslySetInnerHTML) {
4890
+ const ns = effectiveNs(target, opts);
4891
+ morphChildren(domNode, source.childs, target.childs, childOpts(target, ns, opts));
4892
+ }
4893
+ if (!applyValue && source.tag === "SELECT" && target.attrs.value !== undefined) {
4894
+ pendingValue = target.attrs.value;
4895
+ applyValue = true;
4841
4896
  }
4842
- if (!target.attrs.dangerouslySetInnerHTML)
4843
- morphChildren(domNode, source.childs, target.childs, opts);
4844
- if (isSelect && target.attrs.value !== undefined)
4845
- applyProperties(domNode, { value: target.attrs.value }, source.attrs);
4897
+ if (applyValue)
4898
+ applyValueLast(domNode, pendingValue);
4899
+ if (applyChecked)
4900
+ setProp(domNode, "checked", pendingChecked, false);
4846
4901
  return domNode;
4847
4902
  }
4848
4903
  if (type3 === 11) {
@@ -4938,26 +4993,26 @@ function h(tagName, properties, children, namespace) {
4938
4993
  if (properties) {
4939
4994
  for (const propName in properties) {
4940
4995
  const propVal = properties[propName];
4941
- switch (propName) {
4942
- case "key":
4943
- key = propVal;
4944
- break;
4945
- case "namespace":
4946
- namespace = namespace ?? propVal;
4947
- break;
4948
- case "class":
4949
- props.className = propVal;
4950
- break;
4951
- case "for":
4952
- props.htmlFor = propVal;
4953
- break;
4954
- default:
4955
- props[propName] = isHtmlAttribute(propName) ? String(propVal) : propVal;
4956
- }
4996
+ if (propName === "key")
4997
+ key = propVal;
4998
+ else if (propName === "namespace")
4999
+ namespace = namespace ?? propVal;
5000
+ else
5001
+ props[propName] = propVal;
5002
+ }
5003
+ }
5004
+ if (namespace == null) {
5005
+ const lower = tagName.toLowerCase();
5006
+ if (lower === "svg") {
5007
+ namespace = SVG_NS;
5008
+ tagName = "svg";
5009
+ } else if (lower === "math") {
5010
+ namespace = MATH_NS;
5011
+ tagName = "math";
4957
5012
  }
4958
5013
  }
4959
5014
  const c = tagName.charCodeAt(0);
4960
- const tag = namespace == null && c >= 97 && c <= 122 ? tagName.toUpperCase() : tagName;
5015
+ const tag = namespace == null && c >= 97 && c <= 122 && tagName === tagName.toLowerCase() ? tagName.toUpperCase() : tagName;
4961
5016
  const normalizedChildren = [];
4962
5017
  addChild(normalizedChildren, children);
4963
5018
  return new VNode(tag, props, normalizedChildren, key, namespace);
@@ -5812,6 +5867,7 @@ __export(exports_lint_check, {
5812
5867
  DYN_VAL_NOT_DEFINED: () => DYN_VAL_NOT_DEFINED,
5813
5868
  DYN_ALIAS_NOT_REFERENCED: () => DYN_ALIAS_NOT_REFERENCED,
5814
5869
  DUPLICATE_ATTR_DEFINITION: () => DUPLICATE_ATTR_DEFINITION,
5870
+ COMP_FIELD_BAD_SHAPE: () => COMP_FIELD_BAD_SHAPE,
5815
5871
  BAD_VALUE: () => BAD_VALUE,
5816
5872
  ALT_HANDLER_NOT_REFERENCED: () => ALT_HANDLER_NOT_REFERENCED,
5817
5873
  ALT_HANDLER_NOT_DEFINED: () => ALT_HANDLER_NOT_DEFINED
@@ -8123,6 +8179,7 @@ var UNSUPPORTED_EXPR_SYNTAX = "UNSUPPORTED_EXPR_SYNTAX";
8123
8179
  var REDUNDANT_TEMPLATE_STRING = "REDUNDANT_TEMPLATE_STRING";
8124
8180
  var PLACEHOLDERLESS_TEMPLATE_STRING = "PLACEHOLDERLESS_TEMPLATE_STRING";
8125
8181
  var UNKNOWN_COMPONENT_SPEC_KEY = "UNKNOWN_COMPONENT_SPEC_KEY";
8182
+ var COMP_FIELD_BAD_SHAPE = "COMP_FIELD_BAD_SHAPE";
8126
8183
  var PARSE_ISSUE_KIND_TO_LINT_ID = {
8127
8184
  "unknown-directive": UNKNOWN_DIRECTIVE,
8128
8185
  "unknown-x-op": UNKNOWN_X_OP,
@@ -8207,6 +8264,7 @@ var UNSUPPORTED_EXPR_GUIDANCE = {
8207
8264
  function checkComponent(Comp, lx = new LintContext, { wellKnownExtras = EMPTY_SET } = {}) {
8208
8265
  return lx.push({ componentName: Comp.name }, () => {
8209
8266
  checkUnknownSpecKeys(lx, Comp, wellKnownExtras);
8267
+ checkFieldDeclarations(lx, Comp);
8210
8268
  const referencedAlters = new Set;
8211
8269
  const referencedInputs = new Set;
8212
8270
  const referencedDynamics = new Set;
@@ -8635,6 +8693,31 @@ function checkUnknownSpecKeys(lx, Comp, wellKnownExtras) {
8635
8693
  lx.warn(UNKNOWN_COMPONENT_SPEC_KEY, { key }, replaceNameSuggestion(key, candidates));
8636
8694
  }
8637
8695
  }
8696
+ function checkFieldDeclarations(lx, Comp) {
8697
+ const fields = Comp.Class?.getMetaClass?.().fields;
8698
+ if (!fields)
8699
+ return;
8700
+ for (const fieldName in fields) {
8701
+ const field = fields[fieldName];
8702
+ if (!Object.hasOwn(field, "args"))
8703
+ continue;
8704
+ if (typeof field.type !== "string") {
8705
+ lx.error(COMP_FIELD_BAD_SHAPE, {
8706
+ fieldName,
8707
+ kind: "component-not-string",
8708
+ got: typeof field.type,
8709
+ gotName: field.type?.name ?? null
8710
+ });
8711
+ }
8712
+ if (field.args == null || field.args.constructor !== Object) {
8713
+ lx.error(COMP_FIELD_BAD_SHAPE, {
8714
+ fieldName,
8715
+ kind: "args-not-object",
8716
+ got: field.args === null ? "null" : typeof field.args
8717
+ });
8718
+ }
8719
+ }
8720
+ }
8638
8721
  function checkUnreferencedAlterHandlers(lx, Comp, referencedAlters) {
8639
8722
  for (const name in Comp.alter) {
8640
8723
  if (!referencedAlters.has(name)) {
@@ -9421,6 +9504,7 @@ __export(exports_extra, {
9421
9504
  component: () => component,
9422
9505
  compileClassesToStyleText: () => compileClassesToStyleText,
9423
9506
  compileClassesToStyle: () => compileClassesToStyle,
9507
+ collectIterBindings: () => collectIterBindings,
9424
9508
  check: () => check,
9425
9509
  SEQ_INFO: () => SEQ_INFO,
9426
9510
  ParseContext: () => ParseContext,
@@ -11124,6 +11208,7 @@ __export(exports_tutuca, {
11124
11208
  html: () => html,
11125
11209
  css: () => css,
11126
11210
  component: () => component,
11211
+ collectIterBindings: () => collectIterBindings,
11127
11212
  check: () => check,
11128
11213
  SEQ_INFO: () => SEQ_INFO,
11129
11214
  ParseContext: () => ParseContext,
@@ -11150,6 +11235,10 @@ function check(_app) {
11150
11235
  async function test2(_opts) {
11151
11236
  return null;
11152
11237
  }
11238
+ function collectIterBindings() {
11239
+ console.warn("collectIterBindings is a no-op in the core tutuca build; use the tutuca-dev build for a functional implementation");
11240
+ return [];
11241
+ }
11153
11242
  function tutuca(nodeOrSelector) {
11154
11243
  const rootNode = typeof nodeOrSelector === "string" ? document.querySelector(nodeOrSelector) : nodeOrSelector;
11155
11244
  const comps = new Components;
@@ -11361,7 +11450,7 @@ function docComponents(normalized, { name = null } = {}) {
11361
11450
  // src/util/testing.js
11362
11451
  var exports_testing = {};
11363
11452
  __export(exports_testing, {
11364
- collectIterBindings: () => collectIterBindings
11453
+ collectIterBindings: () => collectIterBindings2
11365
11454
  });
11366
11455
  var filterAlwaysTrue2 = () => true;
11367
11456
  var nullLoopWith2 = (seq) => ({ iterData: { seq } });
@@ -11397,7 +11486,7 @@ function resolveAlter(Comp, name) {
11397
11486
  }
11398
11487
  return fn;
11399
11488
  }
11400
- function collectIterBindings(Comp, compInstance, seq, opts = {}) {
11489
+ function collectIterBindings2(Comp, compInstance, seq, opts = {}) {
11401
11490
  const whenFn = resolveAlter(Comp, opts.when) ?? filterAlwaysTrue2;
11402
11491
  const loopWithFn = resolveAlter(Comp, opts.loopWith) ?? nullLoopWith2;
11403
11492
  const enrichFn = resolveAlter(Comp, opts.enrichWith);
@@ -11501,7 +11590,7 @@ export {
11501
11590
  component,
11502
11591
  compileClassesToStyleText,
11503
11592
  compileClassesToStyle,
11504
- collectIterBindings,
11593
+ collectIterBindings2 as collectIterBindings,
11505
11594
  checkComponent,
11506
11595
  check2 as check,
11507
11596
  UNSUPPORTED_EXPR_SYNTAX,
@@ -11560,6 +11649,7 @@ export {
11560
11649
  ComponentSummary,
11561
11650
  ComponentList,
11562
11651
  ComponentDocs,
11652
+ COMP_FIELD_BAD_SHAPE,
11563
11653
  BAD_VALUE,
11564
11654
  ALT_HANDLER_NOT_REFERENCED,
11565
11655
  ALT_HANDLER_NOT_DEFINED