marko 6.0.4 → 6.0.6

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.
@@ -999,48 +999,44 @@ var import_babel_utils8 = require("@marko/compiler/babel-utils");
999
999
  var rest = false ? Symbol("Attribute Tag") : Symbol();
1000
1000
 
1001
1001
  // src/common/helpers.ts
1002
- function classValue(value) {
1003
- return toDelimitedString(value, " ", stringifyClassObject);
1002
+ function classValue(classValue2) {
1003
+ return toDelimitedString(classValue2, " ", stringifyClassObject);
1004
1004
  }
1005
1005
  function stringifyClassObject(name2, value) {
1006
1006
  return value ? name2 : "";
1007
1007
  }
1008
- function styleValue(value) {
1009
- return toDelimitedString(value, ";", stringifyStyleObject);
1008
+ function styleValue(styleValue2) {
1009
+ return toDelimitedString(styleValue2, ";", stringifyStyleObject);
1010
1010
  }
1011
1011
  function stringifyStyleObject(name2, value) {
1012
- return value || value === 0 ? `${name2}:${typeof value === "number" && value && !/^(--|ta|or|li|z)|cou|nk|it|ag|we|do|w$/.test(name2) ? value + "px" : value}` : "";
1012
+ return value || value === 0 ? `${name2}:${value && typeof value === "number" && !/^(--|ta|or|li|z)|cou|nk|it|ag|we|do|w$/.test(name2) ? value + "px" : value}` : "";
1013
1013
  }
1014
1014
  function toDelimitedString(val, delimiter, stringify) {
1015
- switch (typeof val) {
1016
- case "string":
1017
- return val;
1018
- case "object":
1019
- if (val !== null) {
1020
- let result = "";
1021
- let curDelimiter = "";
1022
- if (Array.isArray(val)) {
1023
- for (const v of val) {
1024
- const part = toDelimitedString(v, delimiter, stringify);
1025
- if (part !== "") {
1026
- result += curDelimiter + part;
1027
- curDelimiter = delimiter;
1028
- }
1029
- }
1030
- } else {
1031
- for (const name2 in val) {
1032
- const v = val[name2];
1033
- const part = stringify(name2, v);
1034
- if (part !== "") {
1035
- result += curDelimiter + part;
1036
- curDelimiter = delimiter;
1037
- }
1038
- }
1015
+ let str = "";
1016
+ let sep = "";
1017
+ let part;
1018
+ if (val) {
1019
+ if (typeof val !== "object") {
1020
+ str += val;
1021
+ } else if (Array.isArray(val)) {
1022
+ for (const v of val) {
1023
+ part = toDelimitedString(v, delimiter, stringify);
1024
+ if (part) {
1025
+ str += sep + part;
1026
+ sep = delimiter;
1027
+ }
1028
+ }
1029
+ } else {
1030
+ for (const name2 in val) {
1031
+ part = stringify(name2, val[name2]);
1032
+ if (part) {
1033
+ str += sep + part;
1034
+ sep = delimiter;
1039
1035
  }
1040
- return result;
1041
1036
  }
1037
+ }
1042
1038
  }
1043
- return "";
1039
+ return str;
1044
1040
  }
1045
1041
  function isEventHandler(name2) {
1046
1042
  return /^on[A-Z-]/.test(name2);
@@ -5627,78 +5623,70 @@ var import_babel_utils24 = require("@marko/compiler/babel-utils");
5627
5623
  // src/translator/visitors/tag/native-tag.ts
5628
5624
  var import_compiler31 = require("@marko/compiler");
5629
5625
  var import_babel_utils23 = require("@marko/compiler/babel-utils");
5626
+
5627
+ // src/translator/util/css-px-props.ts
5628
+ var css_px_props_default = /* @__PURE__ */ new Set([
5629
+ "background-size",
5630
+ "baseline-shift",
5631
+ "border-bottom-left-radius",
5632
+ "border-bottom-right-radius",
5633
+ "border-bottom-width",
5634
+ "border-left-width",
5635
+ "border-right-width",
5636
+ "border-top-left-radius",
5637
+ "border-top-right-radius",
5638
+ "border-top-width",
5639
+ "bottom",
5640
+ "column-gap",
5641
+ "column-rule-width",
5642
+ "column-width",
5643
+ "cx",
5644
+ "cy",
5645
+ "flex-basis",
5646
+ "font-size",
5647
+ "grid-auto-columns",
5648
+ "grid-auto-rows",
5649
+ "height",
5650
+ "left",
5651
+ "letter-spacing",
5652
+ "margin-bottom",
5653
+ "margin-left",
5654
+ "margin-right",
5655
+ "margin-top",
5656
+ "max-height",
5657
+ "max-width",
5658
+ "min-height",
5659
+ "min-width",
5660
+ "offset-distance",
5661
+ "outline-offset",
5662
+ "outline-width",
5663
+ "padding-bottom",
5664
+ "padding-left",
5665
+ "padding-right",
5666
+ "padding-top",
5667
+ "perspective",
5668
+ "r",
5669
+ "right",
5670
+ "row-gap",
5671
+ "rx",
5672
+ "ry",
5673
+ "shape-margin",
5674
+ "stroke-dashoffset",
5675
+ "stroke-width",
5676
+ "text-indent",
5677
+ "top",
5678
+ "vertical-align",
5679
+ "width",
5680
+ "word-spacing",
5681
+ "x",
5682
+ "y"
5683
+ ]);
5684
+
5685
+ // src/translator/visitors/tag/native-tag.ts
5630
5686
  var kNativeTagBinding = Symbol("native tag binding");
5631
5687
  var kSkipMark = Symbol("skip native tag mark");
5632
5688
  var kGetterId = Symbol("node getter id");
5633
5689
  var htmlSelectArgs = /* @__PURE__ */ new WeakMap();
5634
- function assertExclusiveControllableGroups(tag, attrs2) {
5635
- const exclusiveGroups = [
5636
- attrs2.open || attrs2.openChange,
5637
- attrs2.checked || attrs2.checkedChange,
5638
- attrs2.checkedValue || attrs2.checkedValueChange,
5639
- attrs2.valueChange
5640
- ].filter(Boolean);
5641
- if (exclusiveGroups.length > 1) {
5642
- throw tag.get("name").buildCodeFrameError(
5643
- `The attributes ${exclusiveGroups.map((attr2) => `"${attr2.name}"`).join(", ")} are mutually exclusive.`
5644
- );
5645
- }
5646
- }
5647
- function getRelatedControllable(tagName, attrs2) {
5648
- switch (tagName) {
5649
- case "input":
5650
- if (attrs2.checked || attrs2.checkedChange) {
5651
- return {
5652
- special: false,
5653
- helper: "controllable_input_checked",
5654
- attrs: [attrs2.checked, attrs2.checkedChange]
5655
- };
5656
- }
5657
- if (attrs2.checkedValue || attrs2.checkedValueChange) {
5658
- return {
5659
- special: true,
5660
- helper: "controllable_input_checkedValue",
5661
- attrs: [attrs2.checkedValue, attrs2.checkedValueChange, attrs2.value]
5662
- };
5663
- }
5664
- if (attrs2.value || attrs2.valueChange) {
5665
- return {
5666
- special: false,
5667
- helper: "controllable_input_value",
5668
- attrs: [attrs2.value, attrs2.valueChange]
5669
- };
5670
- }
5671
- break;
5672
- case "select":
5673
- if (attrs2.value || attrs2.valueChange) {
5674
- return {
5675
- special: true,
5676
- helper: "controllable_select_value",
5677
- attrs: [attrs2.value, attrs2.valueChange]
5678
- };
5679
- }
5680
- break;
5681
- case "textarea":
5682
- if (attrs2.value || attrs2.valueChange) {
5683
- return {
5684
- special: true,
5685
- helper: "controllable_textarea_value",
5686
- attrs: [attrs2.value, attrs2.valueChange]
5687
- };
5688
- }
5689
- break;
5690
- case "details":
5691
- case "dialog":
5692
- if (attrs2.open || attrs2.openChange) {
5693
- return {
5694
- special: false,
5695
- helper: "controllable_detailsOrDialog_open",
5696
- attrs: [attrs2.open, attrs2.openChange]
5697
- };
5698
- }
5699
- break;
5700
- }
5701
- }
5702
5690
  var native_tag_default = {
5703
5691
  transform: {
5704
5692
  enter(tag) {
@@ -5840,24 +5828,20 @@ var native_tag_default = {
5840
5828
  }
5841
5829
  }
5842
5830
  },
5843
- translate: {
5844
- enter(tag) {
5845
- const tagName = getTagName(tag);
5846
- const tagExtra = tag.node.extra;
5847
- const nodeBinding = tagExtra[kNativeTagBinding];
5848
- const isHTML = isOutputHTML();
5849
- const name2 = tag.get("name");
5850
- const tagDef = (0, import_babel_utils23.getTagDef)(tag);
5851
- const write2 = writeTo(tag);
5852
- const tagSection = getSection(tag);
5853
- if (isHTML && tagExtra.tagNameNullable) {
5854
- flushBefore(tag);
5855
- }
5856
- if (tag.has("var")) {
5857
- const varName = tag.node.var.name;
5858
- const varBinding = tag.scope.getBinding(varName);
5859
- const getterId = tagExtra[kGetterId];
5860
- if (isHTML) {
5831
+ translate: translateByTarget({
5832
+ html: {
5833
+ enter(tag) {
5834
+ const tagName = getTagName(tag);
5835
+ const tagExtra = tag.node.extra;
5836
+ const nodeBinding = tagExtra[kNativeTagBinding];
5837
+ const tagDef = (0, import_babel_utils23.getTagDef)(tag);
5838
+ const write2 = writeTo(tag);
5839
+ const tagSection = getSection(tag);
5840
+ if (tagExtra.tagNameNullable) {
5841
+ flushBefore(tag);
5842
+ }
5843
+ if (tag.node.var) {
5844
+ const getterId = tagExtra[kGetterId];
5861
5845
  translateVar(
5862
5846
  tag,
5863
5847
  callRuntime(
@@ -5866,96 +5850,21 @@ var native_tag_default = {
5866
5850
  getterId && import_compiler31.types.stringLiteral(getterId)
5867
5851
  )
5868
5852
  );
5869
- } else {
5870
- let getterFnIdentifier;
5871
- if (getterId) {
5872
- getterFnIdentifier = generateUidIdentifier(`get_${varName}`);
5873
- (0, import_babel_utils23.getProgram)().node.body.push(
5874
- import_compiler31.types.variableDeclaration("const", [
5875
- import_compiler31.types.variableDeclarator(
5876
- getterFnIdentifier,
5877
- callRuntime(
5878
- "nodeRef",
5879
- import_compiler31.types.stringLiteral(getterId),
5880
- import_compiler31.types.stringLiteral(
5881
- getAccessorPrefix().Getter + getScopeAccessorLiteral(nodeBinding).value
5882
- )
5883
- )
5884
- )
5885
- ])
5886
- );
5887
- }
5888
- for (const reference of varBinding.referencePaths) {
5889
- const referenceSection = getSection(reference);
5890
- if (isSameOrChildSection(tagSection, referenceSection)) {
5891
- if (isInvokedFunction(reference)) {
5892
- reference.parentPath.replaceWith(
5893
- import_compiler31.types.expressionStatement(
5894
- createScopeReadExpression(referenceSection, nodeBinding)
5895
- )
5896
- );
5897
- } else if (getterFnIdentifier) {
5898
- reference.replaceWith(
5899
- import_compiler31.types.callExpression(getterFnIdentifier, [
5900
- getScopeExpression(referenceSection, getSection(tag))
5901
- ])
5902
- );
5903
- } else {
5904
- reference.replaceWith(
5905
- import_compiler31.types.expressionStatement(
5906
- import_compiler31.types.memberExpression(
5907
- getScopeExpression(tagSection, referenceSection),
5908
- import_compiler31.types.stringLiteral(
5909
- getAccessorPrefix().Getter + getScopeAccessorLiteral(nodeBinding).value
5910
- ),
5911
- true
5912
- )
5913
- )
5914
- );
5915
- }
5916
- }
5917
- }
5918
5853
  }
5919
- }
5920
- const visitAccessor = nodeBinding && getScopeAccessorLiteral(nodeBinding);
5921
- if (visitAccessor) {
5922
- visit(tag, 32 /* Get */);
5923
- }
5924
- write2`<${name2.node}`;
5925
- const usedAttrs = getUsedAttrs(tagName, tag.node);
5926
- const { staticAttrs, staticControllable, skipExpression } = usedAttrs;
5927
- let { spreadExpression } = usedAttrs;
5928
- if (staticControllable) {
5929
- const { helper, attrs: attrs2 } = staticControllable;
5930
- const firstAttr = attrs2.find(Boolean);
5931
- const referencedBindings = firstAttr.value.extra?.referencedBindings;
5932
- const values = attrs2.map((attr2) => attr2?.value);
5933
- if (isHTML) {
5854
+ const visitAccessor = nodeBinding && getScopeAccessorLiteral(nodeBinding);
5855
+ write2`<${tag.node.name}`;
5856
+ const usedAttrs = getUsedAttrs(tagName, tag.node);
5857
+ const { staticAttrs, staticControllable, skipExpression } = usedAttrs;
5858
+ let { spreadExpression } = usedAttrs;
5859
+ if (staticControllable) {
5860
+ const { helper, attrs: attrs2 } = staticControllable;
5934
5861
  if (tagName !== "select" && tagName !== "textarea") {
5862
+ const values = attrs2.map((attr2) => attr2?.value);
5935
5863
  write2`${callRuntime(helper, getScopeIdIdentifier(tagSection), visitAccessor, ...values)}`;
5936
5864
  }
5937
5865
  addHTMLEffectCall(tagSection, void 0);
5938
- } else {
5939
- addStatement(
5940
- "render",
5941
- tagSection,
5942
- referencedBindings,
5943
- import_compiler31.types.expressionStatement(
5944
- callRuntime(helper, scopeIdentifier, visitAccessor, ...values)
5945
- )
5946
- );
5947
- addStatement(
5948
- "effect",
5949
- tagSection,
5950
- void 0,
5951
- import_compiler31.types.expressionStatement(
5952
- callRuntime(`${helper}_effect`, scopeIdentifier, visitAccessor)
5953
- )
5954
- );
5955
5866
  }
5956
- }
5957
- let writeAtStartOfBody;
5958
- if (isHTML) {
5867
+ let writeAtStartOfBody;
5959
5868
  if (tagName === "select") {
5960
5869
  if (staticControllable) {
5961
5870
  htmlSelectArgs.set(tag.node, {
@@ -6011,89 +5920,313 @@ var native_tag_default = {
6011
5920
  );
6012
5921
  }
6013
5922
  }
6014
- }
6015
- for (const attr2 of staticAttrs) {
6016
- const { name: name3, value } = attr2;
6017
- const { confident, computed } = value.extra || {};
6018
- const valueReferences = value.extra?.referencedBindings;
6019
- if (isHTML && tagName === "option" && name3 === "value") {
6020
- write2`${callRuntime("optionValueAttr", value)}`;
6021
- continue;
6022
- }
6023
- switch (name3) {
6024
- case "class":
6025
- case "style": {
6026
- const helper = `${name3}Attr`;
6027
- if (confident) {
6028
- write2`${getHTMLRuntime()[helper](computed)}`;
6029
- } else if (isHTML) {
6030
- write2`${callRuntime(helper, value)}`;
6031
- } else {
6032
- addStatement(
6033
- "render",
6034
- tagSection,
6035
- valueReferences,
6036
- import_compiler31.types.expressionStatement(
6037
- callRuntime(
6038
- helper,
6039
- import_compiler31.types.memberExpression(scopeIdentifier, visitAccessor, true),
6040
- value
6041
- )
6042
- )
6043
- );
6044
- }
6045
- break;
5923
+ for (const attr2 of staticAttrs) {
5924
+ const { name: name2, value } = attr2;
5925
+ const { confident, computed } = value.extra || {};
5926
+ const valueReferences = value.extra?.referencedBindings;
5927
+ if (tagName === "option" && name2 === "value") {
5928
+ write2`${callRuntime("optionValueAttr", value)}`;
5929
+ continue;
6046
5930
  }
6047
- default:
6048
- if (confident) {
6049
- write2`${getHTMLRuntime().attr(name3, computed)}`;
6050
- } else if (isHTML) {
6051
- if (isEventHandler(name3)) {
5931
+ switch (name2) {
5932
+ case "class":
5933
+ case "style": {
5934
+ const helper = `${name2}Attr`;
5935
+ if (confident) {
5936
+ write2`${getHTMLRuntime()[helper](computed)}`;
5937
+ } else {
5938
+ write2`${callRuntime(helper, value)}`;
5939
+ }
5940
+ break;
5941
+ }
5942
+ default:
5943
+ if (confident) {
5944
+ write2`${getHTMLRuntime().attr(name2, computed)}`;
5945
+ } else if (isEventHandler(name2)) {
6052
5946
  addHTMLEffectCall(tagSection, valueReferences);
6053
5947
  } else {
6054
- write2`${callRuntime("attr", import_compiler31.types.stringLiteral(name3), value)}`;
5948
+ write2`${callRuntime("attr", import_compiler31.types.stringLiteral(name2), value)}`;
6055
5949
  }
6056
- } else if (isEventHandler(name3)) {
6057
- addStatement(
6058
- "effect",
6059
- tagSection,
6060
- valueReferences,
6061
- import_compiler31.types.expressionStatement(
6062
- callRuntime(
6063
- "on",
6064
- import_compiler31.types.memberExpression(scopeIdentifier, visitAccessor, true),
6065
- import_compiler31.types.stringLiteral(getEventHandlerName(name3)),
6066
- value
6067
- )
5950
+ break;
5951
+ }
5952
+ }
5953
+ if (spreadExpression) {
5954
+ addHTMLEffectCall(tagSection, tagExtra.referencedBindings);
5955
+ if (skipExpression) {
5956
+ write2`${callRuntime("partialAttrs", spreadExpression, skipExpression, visitAccessor, getScopeIdIdentifier(tagSection), tag.node.name)}`;
5957
+ } else {
5958
+ write2`${callRuntime("attrs", spreadExpression, visitAccessor, getScopeIdIdentifier(tagSection), tag.node.name)}`;
5959
+ }
5960
+ }
5961
+ if (tagDef && tagDef.parseOptions?.openTagOnly) {
5962
+ switch (tagDef.htmlType) {
5963
+ case "svg":
5964
+ case "math":
5965
+ write2`/>`;
5966
+ break;
5967
+ default:
5968
+ write2`>`;
5969
+ break;
5970
+ }
5971
+ } else {
5972
+ write2`>`;
5973
+ }
5974
+ if (tagExtra.tagNameNullable) {
5975
+ tag.insertBefore(
5976
+ import_compiler31.types.ifStatement(tag.node.name, consumeHTML(tag))
5977
+ )[0].skip();
5978
+ }
5979
+ if (writeAtStartOfBody) {
5980
+ write2`${writeAtStartOfBody}`;
5981
+ }
5982
+ },
5983
+ exit(tag) {
5984
+ const tagExtra = tag.node.extra;
5985
+ const nodeBinding = tagExtra[kNativeTagBinding];
5986
+ const openTagOnly = (0, import_babel_utils23.getTagDef)(tag)?.parseOptions?.openTagOnly;
5987
+ const selectArgs = htmlSelectArgs.get(tag.node);
5988
+ const tagName = getTagName(tag);
5989
+ const tagSection = getSection(tag);
5990
+ if (tagExtra.tagNameNullable) {
5991
+ flushInto(tag);
5992
+ }
5993
+ if (selectArgs) {
5994
+ writeTo(tag)`</${tag.node.name}>`;
5995
+ flushInto(tag);
5996
+ tag.insertBefore(
5997
+ import_compiler31.types.expressionStatement(
5998
+ callRuntime(
5999
+ "controllable_select_value",
6000
+ getScopeIdIdentifier(getSection(tag)),
6001
+ getScopeAccessorLiteral(nodeBinding),
6002
+ selectArgs.value,
6003
+ selectArgs.valueChange,
6004
+ import_compiler31.types.arrowFunctionExpression(
6005
+ [],
6006
+ import_compiler31.types.blockStatement(tag.node.body.body)
6068
6007
  )
6069
- );
6070
- } else {
6071
- addStatement(
6072
- "render",
6073
- tagSection,
6074
- valueReferences,
6075
- import_compiler31.types.expressionStatement(
6008
+ )
6009
+ )
6010
+ );
6011
+ } else {
6012
+ tag.insertBefore(tag.node.body.body).forEach((child) => child.skip());
6013
+ }
6014
+ const markerSerializeReason = nodeBinding && !tagExtra[kSkipMark] && getBindingSerializeReason(tagSection, nodeBinding);
6015
+ if (!openTagOnly && !selectArgs) {
6016
+ writeTo(
6017
+ tag,
6018
+ !markerSerializeReason && (tagName === "html" || tagName === "body")
6019
+ )`</${tag.node.name}>`;
6020
+ }
6021
+ if (tagExtra.tagNameNullable) {
6022
+ tag.insertBefore(
6023
+ import_compiler31.types.ifStatement(tag.node.name, consumeHTML(tag))
6024
+ )[0].skip();
6025
+ }
6026
+ if (markerSerializeReason) {
6027
+ markNode(tag, nodeBinding, markerSerializeReason);
6028
+ }
6029
+ tag.remove();
6030
+ }
6031
+ },
6032
+ dom: {
6033
+ enter(tag) {
6034
+ const tagName = getTagName(tag);
6035
+ const tagExtra = tag.node.extra;
6036
+ const nodeBinding = tagExtra[kNativeTagBinding];
6037
+ const tagDef = (0, import_babel_utils23.getTagDef)(tag);
6038
+ const write2 = writeTo(tag);
6039
+ const tagSection = getSection(tag);
6040
+ if (tag.node.var) {
6041
+ const varName = tag.node.var.name;
6042
+ const varBinding = tag.scope.getBinding(varName);
6043
+ const getterId = tagExtra[kGetterId];
6044
+ let getterFnIdentifier;
6045
+ if (getterId) {
6046
+ getterFnIdentifier = generateUidIdentifier(`get_${varName}`);
6047
+ (0, import_babel_utils23.getProgram)().node.body.push(
6048
+ import_compiler31.types.variableDeclaration("const", [
6049
+ import_compiler31.types.variableDeclarator(
6050
+ getterFnIdentifier,
6076
6051
  callRuntime(
6077
- "attr",
6078
- import_compiler31.types.memberExpression(scopeIdentifier, visitAccessor, true),
6079
- import_compiler31.types.stringLiteral(name3),
6080
- value
6052
+ "nodeRef",
6053
+ import_compiler31.types.stringLiteral(getterId),
6054
+ import_compiler31.types.stringLiteral(
6055
+ getAccessorPrefix().Getter + getScopeAccessorLiteral(nodeBinding).value
6056
+ )
6081
6057
  )
6082
6058
  )
6083
- );
6059
+ ])
6060
+ );
6061
+ }
6062
+ for (const reference of varBinding.referencePaths) {
6063
+ const referenceSection = getSection(reference);
6064
+ if (isSameOrChildSection(tagSection, referenceSection)) {
6065
+ if (isInvokedFunction(reference)) {
6066
+ reference.parentPath.replaceWith(
6067
+ import_compiler31.types.expressionStatement(
6068
+ createScopeReadExpression(referenceSection, nodeBinding)
6069
+ )
6070
+ );
6071
+ } else if (getterFnIdentifier) {
6072
+ reference.replaceWith(
6073
+ import_compiler31.types.callExpression(getterFnIdentifier, [
6074
+ getScopeExpression(referenceSection, getSection(tag))
6075
+ ])
6076
+ );
6077
+ } else {
6078
+ reference.replaceWith(
6079
+ import_compiler31.types.expressionStatement(
6080
+ import_compiler31.types.memberExpression(
6081
+ getScopeExpression(tagSection, referenceSection),
6082
+ import_compiler31.types.stringLiteral(
6083
+ getAccessorPrefix().Getter + getScopeAccessorLiteral(nodeBinding).value
6084
+ ),
6085
+ true
6086
+ )
6087
+ )
6088
+ );
6089
+ }
6084
6090
  }
6085
- break;
6091
+ }
6086
6092
  }
6087
- }
6088
- if (spreadExpression) {
6089
- if (isHTML) {
6090
- addHTMLEffectCall(tagSection, tagExtra.referencedBindings);
6091
- if (skipExpression) {
6092
- write2`${callRuntime("partialAttrs", spreadExpression, skipExpression, visitAccessor, getScopeIdIdentifier(tagSection), name2.node)}`;
6093
- } else {
6094
- write2`${callRuntime("attrs", spreadExpression, visitAccessor, getScopeIdIdentifier(tagSection), name2.node)}`;
6093
+ const visitAccessor = nodeBinding && getScopeAccessorLiteral(nodeBinding);
6094
+ if (visitAccessor) {
6095
+ visit(tag, 32 /* Get */);
6096
+ }
6097
+ write2`<${tag.node.name}`;
6098
+ const usedAttrs = getUsedAttrs(tagName, tag.node);
6099
+ const { staticAttrs, staticControllable, skipExpression } = usedAttrs;
6100
+ const { spreadExpression } = usedAttrs;
6101
+ if (staticControllable) {
6102
+ const { helper, attrs: attrs2 } = staticControllable;
6103
+ const firstAttr = attrs2.find(Boolean);
6104
+ const referencedBindings = firstAttr.value.extra?.referencedBindings;
6105
+ const values = attrs2.map((attr2) => attr2?.value);
6106
+ addStatement(
6107
+ "render",
6108
+ tagSection,
6109
+ referencedBindings,
6110
+ import_compiler31.types.expressionStatement(
6111
+ callRuntime(helper, scopeIdentifier, visitAccessor, ...values)
6112
+ )
6113
+ );
6114
+ addStatement(
6115
+ "effect",
6116
+ tagSection,
6117
+ void 0,
6118
+ import_compiler31.types.expressionStatement(
6119
+ callRuntime(`${helper}_effect`, scopeIdentifier, visitAccessor)
6120
+ )
6121
+ );
6122
+ }
6123
+ for (const attr2 of staticAttrs) {
6124
+ const { name: name2, value } = attr2;
6125
+ const { confident, computed } = value.extra || {};
6126
+ const valueReferences = value.extra?.referencedBindings;
6127
+ switch (name2) {
6128
+ case "class":
6129
+ case "style": {
6130
+ const helper = `${name2}Attr`;
6131
+ if (confident) {
6132
+ write2`${getHTMLRuntime()[helper](computed)}`;
6133
+ } else {
6134
+ const nodeExpr = import_compiler31.types.memberExpression(
6135
+ scopeIdentifier,
6136
+ visitAccessor,
6137
+ true
6138
+ );
6139
+ const meta = {
6140
+ staticItems: void 0,
6141
+ dynamicItems: void 0,
6142
+ dynamicValues: void 0
6143
+ };
6144
+ let stmt;
6145
+ trackDelimitedAttrValue(value, meta);
6146
+ if (meta.dynamicItems) {
6147
+ stmt = import_compiler31.types.expressionStatement(
6148
+ callRuntime(helper, nodeExpr, value)
6149
+ );
6150
+ } else {
6151
+ if (meta.staticItems) {
6152
+ write2`${getHTMLRuntime()[helper](computed)}`;
6153
+ }
6154
+ if (meta.dynamicValues) {
6155
+ const keys = Object.keys(meta.dynamicValues);
6156
+ if (keys.length === 1) {
6157
+ const [key] = keys;
6158
+ const value2 = meta.dynamicValues[key];
6159
+ stmt = import_compiler31.types.expressionStatement(
6160
+ callRuntime(
6161
+ `${name2}Item`,
6162
+ nodeExpr,
6163
+ import_compiler31.types.stringLiteral(key),
6164
+ name2 === "style" && css_px_props_default.has(name2) ? callRuntime("styleItemValue", value2) : value2
6165
+ )
6166
+ );
6167
+ } else {
6168
+ const props = [];
6169
+ for (const key of keys) {
6170
+ const value2 = meta.dynamicValues[key];
6171
+ props.push(
6172
+ import_compiler31.types.objectProperty(
6173
+ toPropertyName(key),
6174
+ name2 === "style" && css_px_props_default.has(name2) ? callRuntime("styleItemValue", value2) : value2
6175
+ )
6176
+ );
6177
+ }
6178
+ stmt = import_compiler31.types.expressionStatement(
6179
+ callRuntime(
6180
+ `${name2}Items`,
6181
+ nodeExpr,
6182
+ import_compiler31.types.objectExpression(props)
6183
+ )
6184
+ );
6185
+ }
6186
+ }
6187
+ }
6188
+ if (stmt) {
6189
+ addStatement("render", tagSection, valueReferences, stmt);
6190
+ }
6191
+ }
6192
+ break;
6193
+ }
6194
+ default:
6195
+ if (confident) {
6196
+ write2`${getHTMLRuntime().attr(name2, computed)}`;
6197
+ } else if (isEventHandler(name2)) {
6198
+ addStatement(
6199
+ "effect",
6200
+ tagSection,
6201
+ valueReferences,
6202
+ import_compiler31.types.expressionStatement(
6203
+ callRuntime(
6204
+ "on",
6205
+ import_compiler31.types.memberExpression(scopeIdentifier, visitAccessor, true),
6206
+ import_compiler31.types.stringLiteral(getEventHandlerName(name2)),
6207
+ value
6208
+ )
6209
+ )
6210
+ );
6211
+ } else {
6212
+ addStatement(
6213
+ "render",
6214
+ tagSection,
6215
+ valueReferences,
6216
+ import_compiler31.types.expressionStatement(
6217
+ callRuntime(
6218
+ "attr",
6219
+ import_compiler31.types.memberExpression(scopeIdentifier, visitAccessor, true),
6220
+ import_compiler31.types.stringLiteral(name2),
6221
+ value
6222
+ )
6223
+ )
6224
+ );
6225
+ }
6226
+ break;
6095
6227
  }
6096
- } else {
6228
+ }
6229
+ if (spreadExpression) {
6097
6230
  if (skipExpression) {
6098
6231
  addStatement(
6099
6232
  "render",
@@ -6134,80 +6267,101 @@ var native_tag_default = {
6134
6267
  false
6135
6268
  );
6136
6269
  }
6137
- }
6138
- if (tagDef && tagDef.parseOptions?.openTagOnly) {
6139
- switch (tagDef.htmlType) {
6140
- case "svg":
6141
- case "math":
6142
- write2`/>`;
6143
- break;
6144
- default:
6145
- write2`>`;
6146
- break;
6270
+ if (tagDef && tagDef.parseOptions?.openTagOnly) {
6271
+ switch (tagDef.htmlType) {
6272
+ case "svg":
6273
+ case "math":
6274
+ write2`/>`;
6275
+ break;
6276
+ default:
6277
+ write2`>`;
6278
+ break;
6279
+ }
6280
+ } else {
6281
+ write2`>`;
6147
6282
  }
6148
- } else {
6149
- write2`>`;
6150
- }
6151
- if (isHTML && tagExtra.tagNameNullable) {
6152
- tag.insertBefore(import_compiler31.types.ifStatement(name2.node, consumeHTML(tag)))[0].skip();
6283
+ enter2(tag);
6284
+ },
6285
+ exit(tag) {
6286
+ const openTagOnly = (0, import_babel_utils23.getTagDef)(tag)?.parseOptions?.openTagOnly;
6287
+ tag.insertBefore(tag.node.body.body).forEach((child) => child.skip());
6288
+ if (!openTagOnly) {
6289
+ writeTo(tag)`</${tag.node.name}>`;
6290
+ }
6291
+ exit2(tag);
6292
+ tag.remove();
6153
6293
  }
6154
- if (writeAtStartOfBody) {
6155
- write2`${writeAtStartOfBody}`;
6294
+ }
6295
+ })
6296
+ };
6297
+ function assertExclusiveControllableGroups(tag, attrs2) {
6298
+ const exclusiveGroups = [
6299
+ attrs2.open || attrs2.openChange,
6300
+ attrs2.checked || attrs2.checkedChange,
6301
+ attrs2.checkedValue || attrs2.checkedValueChange,
6302
+ attrs2.valueChange
6303
+ ].filter(Boolean);
6304
+ if (exclusiveGroups.length > 1) {
6305
+ throw tag.get("name").buildCodeFrameError(
6306
+ `The attributes ${exclusiveGroups.map((attr2) => `"${attr2.name}"`).join(", ")} are mutually exclusive.`
6307
+ );
6308
+ }
6309
+ }
6310
+ function getRelatedControllable(tagName, attrs2) {
6311
+ switch (tagName) {
6312
+ case "input":
6313
+ if (attrs2.checked || attrs2.checkedChange) {
6314
+ return {
6315
+ special: false,
6316
+ helper: "controllable_input_checked",
6317
+ attrs: [attrs2.checked, attrs2.checkedChange]
6318
+ };
6156
6319
  }
6157
- enter2(tag);
6158
- },
6159
- exit(tag) {
6160
- const tagExtra = tag.node.extra;
6161
- const nodeBinding = tagExtra[kNativeTagBinding];
6162
- const isHTML = isOutputHTML();
6163
- const openTagOnly = (0, import_babel_utils23.getTagDef)(tag)?.parseOptions?.openTagOnly;
6164
- const selectArgs = isHTML && htmlSelectArgs.get(tag.node);
6165
- const tagName = getTagName(tag);
6166
- const tagSection = getSection(tag);
6167
- if (isHTML && tagExtra.tagNameNullable) {
6168
- flushInto(tag);
6320
+ if (attrs2.checkedValue || attrs2.checkedValueChange) {
6321
+ return {
6322
+ special: true,
6323
+ helper: "controllable_input_checkedValue",
6324
+ attrs: [attrs2.checkedValue, attrs2.checkedValueChange, attrs2.value]
6325
+ };
6169
6326
  }
6170
- if (selectArgs) {
6171
- writeTo(tag)`</${tag.node.name}>`;
6172
- flushInto(tag);
6173
- tag.insertBefore(
6174
- import_compiler31.types.expressionStatement(
6175
- callRuntime(
6176
- "controllable_select_value",
6177
- getScopeIdIdentifier(getSection(tag)),
6178
- getScopeAccessorLiteral(nodeBinding),
6179
- selectArgs.value,
6180
- selectArgs.valueChange,
6181
- import_compiler31.types.arrowFunctionExpression(
6182
- [],
6183
- import_compiler31.types.blockStatement(tag.node.body.body)
6184
- )
6185
- )
6186
- )
6187
- );
6188
- } else {
6189
- tag.insertBefore(tag.node.body.body).forEach((child) => child.skip());
6327
+ if (attrs2.value || attrs2.valueChange) {
6328
+ return {
6329
+ special: false,
6330
+ helper: "controllable_input_value",
6331
+ attrs: [attrs2.value, attrs2.valueChange]
6332
+ };
6190
6333
  }
6191
- const markerSerializeReason = nodeBinding && !tagExtra[kSkipMark] && getBindingSerializeReason(tagSection, nodeBinding);
6192
- if (!openTagOnly && !selectArgs) {
6193
- writeTo(
6194
- tag,
6195
- isHTML && !markerSerializeReason && (tagName === "html" || tagName === "body")
6196
- )`</${tag.node.name}>`;
6334
+ break;
6335
+ case "select":
6336
+ if (attrs2.value || attrs2.valueChange) {
6337
+ return {
6338
+ special: true,
6339
+ helper: "controllable_select_value",
6340
+ attrs: [attrs2.value, attrs2.valueChange]
6341
+ };
6197
6342
  }
6198
- if (isHTML && tagExtra.tagNameNullable) {
6199
- tag.insertBefore(
6200
- import_compiler31.types.ifStatement(tag.node.name, consumeHTML(tag))
6201
- )[0].skip();
6343
+ break;
6344
+ case "textarea":
6345
+ if (attrs2.value || attrs2.valueChange) {
6346
+ return {
6347
+ special: true,
6348
+ helper: "controllable_textarea_value",
6349
+ attrs: [attrs2.value, attrs2.valueChange]
6350
+ };
6202
6351
  }
6203
- if (markerSerializeReason) {
6204
- markNode(tag, nodeBinding, markerSerializeReason);
6352
+ break;
6353
+ case "details":
6354
+ case "dialog":
6355
+ if (attrs2.open || attrs2.openChange) {
6356
+ return {
6357
+ special: false,
6358
+ helper: "controllable_detailsOrDialog_open",
6359
+ attrs: [attrs2.open, attrs2.openChange]
6360
+ };
6205
6361
  }
6206
- exit2(tag);
6207
- tag.remove();
6208
- }
6362
+ break;
6209
6363
  }
6210
- };
6364
+ }
6211
6365
  function getUsedAttrs(tagName, tag) {
6212
6366
  const seen = {};
6213
6367
  const { attributes } = tag;
@@ -6284,6 +6438,86 @@ function getUsedAttrs(tagName, tag) {
6284
6438
  skipExpression
6285
6439
  };
6286
6440
  }
6441
+ function trackDelimitedAttrValue(expr, meta) {
6442
+ switch (expr.type) {
6443
+ case "ObjectExpression":
6444
+ trackDelimitedAttrObjectProperties(expr, meta);
6445
+ break;
6446
+ case "ArrayExpression":
6447
+ trackDelimitedAttrArrayItems(expr, meta);
6448
+ break;
6449
+ default:
6450
+ (meta.dynamicItems ||= []).push(expr);
6451
+ break;
6452
+ }
6453
+ }
6454
+ function trackDelimitedAttrArrayItems(arr, meta) {
6455
+ for (const item of arr.elements) {
6456
+ if (item) {
6457
+ switch (item.type) {
6458
+ case "ArrayExpression": {
6459
+ trackDelimitedAttrArrayItems(item, meta);
6460
+ break;
6461
+ }
6462
+ case "ObjectExpression": {
6463
+ trackDelimitedAttrObjectProperties(item, meta);
6464
+ break;
6465
+ }
6466
+ case "SpreadElement":
6467
+ if (item.argument.type === "ArrayExpression") {
6468
+ trackDelimitedAttrArrayItems(item.argument, meta);
6469
+ } else {
6470
+ (meta.dynamicItems ||= []).push(item);
6471
+ }
6472
+ break;
6473
+ default: {
6474
+ const evalItem = evaluate(item);
6475
+ if (evalItem.confident) {
6476
+ (meta.staticItems ||= []).push(evalItem.computed);
6477
+ } else {
6478
+ (meta.dynamicItems ||= []).push(item);
6479
+ }
6480
+ break;
6481
+ }
6482
+ }
6483
+ }
6484
+ }
6485
+ }
6486
+ function trackDelimitedAttrObjectProperties(obj, meta) {
6487
+ let staticProps;
6488
+ let dynamicProps;
6489
+ for (const prop of obj.properties) {
6490
+ if (prop.type !== "ObjectProperty" || prop.computed) {
6491
+ (dynamicProps ||= []).push(prop);
6492
+ continue;
6493
+ }
6494
+ let key;
6495
+ if (prop.key.type === "Identifier") {
6496
+ key = prop.key.name;
6497
+ } else {
6498
+ const keyEval = evaluate(prop.key);
6499
+ if (keyEval.confident) {
6500
+ key = keyEval.computed + "";
6501
+ } else {
6502
+ (dynamicProps ||= []).push(prop);
6503
+ continue;
6504
+ }
6505
+ }
6506
+ const value = prop.value;
6507
+ const propEval = evaluate(value);
6508
+ if (propEval.confident) {
6509
+ (staticProps ||= {})[key] = propEval.computed;
6510
+ } else {
6511
+ (meta.dynamicValues ||= {})[key] = value;
6512
+ }
6513
+ }
6514
+ if (staticProps) {
6515
+ (meta.staticItems ||= []).push(staticProps);
6516
+ }
6517
+ if (dynamicProps) {
6518
+ (meta.dynamicItems ||= []).push(import_compiler31.types.objectExpression(dynamicProps));
6519
+ }
6520
+ }
6287
6521
  function isChangeHandler(propName) {
6288
6522
  return /^(?:value|checked(?:Value)?|open)Change/.test(propName);
6289
6523
  }