marko 6.1.9 → 6.1.11

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.
@@ -239,6 +239,9 @@ function getEventHandlerName(name) {
239
239
  function isVoid(value) {
240
240
  return value == null || value === false;
241
241
  }
242
+ function isNotVoid(value) {
243
+ return value != null && value !== false;
244
+ }
242
245
  function normalizeDynamicRenderer(value) {
243
246
  if (value) {
244
247
  if (typeof value === "string") return value;
@@ -1932,7 +1935,7 @@ function _attr_input_value(scopeId, nodeAccessor, value, valueChange) {
1932
1935
  }
1933
1936
  function _attr_input_checked(scopeId, nodeAccessor, checked, checkedChange) {
1934
1937
  if (checkedChange) writeControlledScope(0, scopeId, nodeAccessor, void 0, checkedChange);
1935
- return normalizeBoolAttrValue(checked) ? " checked" : "";
1938
+ return isNotVoid(checked) ? " checked" : "";
1936
1939
  }
1937
1940
  function _attr_input_checkedValue(scopeId, nodeAccessor, checkedValue, checkedValueChange, value) {
1938
1941
  const valueAttr = _attr("value", value);
@@ -1951,8 +1954,8 @@ function getCheckedValueRef(checkedValue) {
1951
1954
  }
1952
1955
  }
1953
1956
  function _attr_details_or_dialog_open(scopeId, nodeAccessor, open, openChange) {
1954
- const normalizedOpen = normalizeBoolAttrValue(open);
1955
- if (openChange) writeControlledScope(4, scopeId, nodeAccessor, normalizedOpen, openChange);
1957
+ const normalizedOpen = isNotVoid(open);
1958
+ if (openChange) writeControlledScope(4, scopeId, nodeAccessor, normalizedOpen || void 0, openChange);
1956
1959
  return normalizedOpen ? " open" : "";
1957
1960
  }
1958
1961
  function _attr(name, value) {
@@ -1965,17 +1968,17 @@ function _attrs(data, nodeAccessor, scopeId, tagName) {
1965
1968
  switch (tagName) {
1966
1969
  case "input":
1967
1970
  if (data.checkedChange) result += _attr_input_checked(scopeId, nodeAccessor, data.checked, data.checkedChange);
1968
- else if (data.checkedValue || data.checkedValueChange) result += _attr_input_checkedValue(scopeId, nodeAccessor, data.checkedValue, data.checkedValueChange, data.value);
1971
+ else if ("checkedValue" in data || data.checkedValueChange) result += _attr_input_checkedValue(scopeId, nodeAccessor, data.checkedValue, data.checkedValueChange, data.value);
1969
1972
  else if (data.valueChange) result += _attr_input_value(scopeId, nodeAccessor, data.value, data.valueChange);
1970
1973
  else break;
1971
1974
  skip = /^(?:value|checked(?:Value)?)(?:Change)?$|[\s/>"'=]/;
1972
1975
  break;
1973
1976
  case "select":
1974
1977
  case "textarea":
1975
- if (data.value || data.valueChange) skip = /^value(?:Change)?$|[\s/>"'=]/;
1978
+ if ("value" in data || data.valueChange) skip = /^value(?:Change)?$|[\s/>"'=]/;
1976
1979
  break;
1977
1980
  case "option":
1978
- if (data.value) {
1981
+ if ("value" in data) {
1979
1982
  result += _attr_option_value(data.value);
1980
1983
  skip = /^value$|[\s/>"'=]/;
1981
1984
  }
@@ -2059,9 +2062,6 @@ function normalizedValueMatches(a, b) {
2059
2062
  function normalizeStrAttrValue(value) {
2060
2063
  return value && value !== true || value === 0 ? value + "" : "";
2061
2064
  }
2062
- function normalizeBoolAttrValue(value) {
2063
- if (value != null && value !== false) return true;
2064
- }
2065
2065
  //#endregion
2066
2066
  //#region src/html/dynamic-tag.ts
2067
2067
  const voidElementsReg = /^(?:area|b(?:ase|r)|col|embed|hr|i(?:mg|nput)|link|meta|param|source|track|wbr)$/;
@@ -3249,9 +3249,21 @@ function writeHTMLResumeStatements(path) {
3249
3249
  const writeSerializedBinding = (binding) => {
3250
3250
  const reason = getSerializeReason(section, binding);
3251
3251
  if (!reason) return;
3252
+ if (binding.noSerialize) {
3253
+ serializedLookup.delete(getScopeAccessor(binding));
3254
+ return;
3255
+ }
3252
3256
  const accessor = getScopeAccessor(binding);
3253
3257
  serializedLookup.delete(accessor);
3254
- serializedProperties.push(toObjectProperty(accessor, ifSerialized(reason, getDeclaredBindingExpression(binding))));
3258
+ let expr = getDeclaredBindingExpression(binding);
3259
+ if (binding.noSerializeProperties) {
3260
+ const props = [_marko_compiler.types.spreadElement(expr)];
3261
+ forEach(binding.noSerializeProperties, (prop) => {
3262
+ props.push(toObjectProperty(prop, _marko_compiler.types.identifier("undefined")));
3263
+ });
3264
+ expr = _marko_compiler.types.objectExpression(props);
3265
+ }
3266
+ serializedProperties.push(toObjectProperty(accessor, ifSerialized(reason, expr)));
3255
3267
  if (debug) {
3256
3268
  const { root, access } = getDebugScopeAccess(binding);
3257
3269
  const locExpr = root.loc && _marko_compiler.types.stringLiteral(`${root.loc.start.line}:${root.loc.start.column + 1}`);
@@ -4064,10 +4076,16 @@ function finalizeTagDownstreams(section) {
4064
4076
  function crawlSectionsAndSetBinding(tag, binding, properties, skip) {
4065
4077
  if (!skip) {
4066
4078
  const contentSection = getSectionForBody(tag.get("body"));
4067
- if (contentSection) contentSection.downstreamBinding = {
4068
- binding,
4069
- properties: concat(properties, "content")
4070
- };
4079
+ if (contentSection) {
4080
+ let target = binding;
4081
+ forEach(properties, (property) => {
4082
+ target = target?.propertyAliases.get(property);
4083
+ });
4084
+ contentSection.downstreamBinding = target && (target.noSerialize || includes(target.noSerializeProperties, "content")) ? false : {
4085
+ binding,
4086
+ properties: concat(properties, "content")
4087
+ };
4088
+ }
4071
4089
  }
4072
4090
  const attrTagLookup = analyzeAttributeTags(tag);
4073
4091
  if (!attrTagLookup) return;
@@ -4194,11 +4212,26 @@ var native_tag_default = {
4194
4212
  const nodeBinding = tagExtra[kNativeTagBinding] = createBinding("#" + getCanonicalTagName(tag), 0, tagSection, void 0, void 0, void 0, void 0, !!node.var);
4195
4213
  if (hasEventHandlers) (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
4196
4214
  if (spreadReferenceNodes) {
4215
+ const isMergedSpread = !!relatedControllable;
4197
4216
  if (relatedControllable && !relatedControllable.attrs.every(Boolean)) {
4198
4217
  for (const attr of relatedControllable.attrs) if (attr) spreadReferenceNodes.push(attr.value);
4199
4218
  relatedControllable = void 0;
4200
4219
  }
4201
- mergeReferences(tagSection, tag.node, spreadReferenceNodes);
4220
+ const spreadExtra = mergeReferences(tagSection, tag.node, spreadReferenceNodes);
4221
+ spreadExtra.nativeTagSpread = true;
4222
+ if (isMergedSpread) spreadExtra.nativeTagSpreadMerged = true;
4223
+ let carveProperties = getSpreadControllableValueProps(tagName);
4224
+ if (!tag.node.body.body.length && !isTextOnly && !(0, _marko_compiler_babel_utils.getTagDef)(tag)?.parseOptions?.openTagOnly && !seen.content) if (carveProperties) carveProperties.push("content");
4225
+ else carveProperties = ["content"];
4226
+ for (const node of spreadReferenceNodes) {
4227
+ const spreadBinding = node.extra?.spreadFrom;
4228
+ if (spreadBinding) {
4229
+ spreadBinding.noSerialize = true;
4230
+ if (carveProperties) {
4231
+ for (const property of carveProperties) if (!includes(spreadBinding.noSerializeProperties, property)) spreadBinding.noSerializeProperties = push(spreadBinding.noSerializeProperties, property);
4232
+ }
4233
+ }
4234
+ }
4202
4235
  } else relatedControllable = getRelatedControllable(tagName, seen);
4203
4236
  if (relatedControllable) mergeReferences(tagSection, relatedControllable.attrs.find(Boolean).value, relatedControllable.attrs.map((it) => it?.value));
4204
4237
  if (textPlaceholders) exprExtras = push(exprExtras, textPlaceholders.length === 1 ? textPlaceholders[0].extra ??= {} : mergeReferences(tagSection, textPlaceholders[0], textPlaceholders.slice(1)));
@@ -4428,6 +4461,19 @@ var native_tag_default = {
4428
4461
  }
4429
4462
  })
4430
4463
  };
4464
+ function getSpreadControllableValueProps(tagName) {
4465
+ switch (tagName) {
4466
+ case "input": return [
4467
+ "value",
4468
+ "checked",
4469
+ "checkedValue"
4470
+ ];
4471
+ case "select":
4472
+ case "textarea": return ["value"];
4473
+ case "details":
4474
+ case "dialog": return ["open"];
4475
+ }
4476
+ }
4431
4477
  function getRelatedControllable(tagName, attrs) {
4432
4478
  switch (tagName) {
4433
4479
  case "input":
@@ -5687,6 +5733,8 @@ function createBinding(name, type, refSection, upstreamAlias, property, excludeP
5687
5733
  closureSections: void 0,
5688
5734
  assignmentSections: void 0,
5689
5735
  excludeProperties,
5736
+ noSerialize: false,
5737
+ noSerializeProperties: void 0,
5690
5738
  sources: void 0,
5691
5739
  reads: /* @__PURE__ */ new Set(),
5692
5740
  aliases: /* @__PURE__ */ new Set(),
@@ -5993,8 +6041,22 @@ function finalizeReferences() {
5993
6041
  }
5994
6042
  }
5995
6043
  }
5996
- for (const binding of bindings) if (binding.type !== 0) {
5997
- if (pruneBinding(binding)) bindings.delete(binding);
6044
+ for (const binding of bindings) {
6045
+ if (binding.type !== 0) {
6046
+ if (pruneBinding(binding)) bindings.delete(binding);
6047
+ }
6048
+ if (binding.noSerialize) if (isPureSpreadResolved(binding)) if (hasAnyMemberAccess(binding)) {
6049
+ let kept = void 0;
6050
+ binding.noSerialize = false;
6051
+ forEach(binding.noSerializeProperties, (property) => {
6052
+ if (!isPropertyMemberAccessed(binding, property)) kept = push(kept, property);
6053
+ });
6054
+ binding.noSerializeProperties = kept;
6055
+ } else binding.noSerializeProperties = void 0;
6056
+ else {
6057
+ binding.noSerialize = false;
6058
+ binding.noSerializeProperties = void 0;
6059
+ }
5998
6060
  }
5999
6061
  forEachSection(finalizeTagDownstreams);
6000
6062
  for (const binding of bindings) {
@@ -6722,6 +6784,21 @@ function getAllSerializeReasonsForBinding(binding, properties) {
6722
6784
  }
6723
6785
  return reason;
6724
6786
  }
6787
+ function isPureSpreadResolved(binding) {
6788
+ for (const read of binding.reads) if (!read.nativeTagSpread || read.nativeTagSpreadMerged) return false;
6789
+ for (const alias of binding.aliases) if (!isPureSpreadResolved(alias)) return false;
6790
+ return true;
6791
+ }
6792
+ function hasAnyMemberAccess(binding) {
6793
+ if (binding.propertyAliases.size) return true;
6794
+ for (const alias of binding.aliases) if (hasAnyMemberAccess(alias)) return true;
6795
+ return false;
6796
+ }
6797
+ function isPropertyMemberAccessed(binding, property) {
6798
+ if (binding.propertyAliases.has(property)) return true;
6799
+ for (const alias of binding.aliases) if (isPropertyMemberAccessed(alias, property)) return true;
6800
+ return false;
6801
+ }
6725
6802
  function addNumericPropertiesUntil(props, len) {
6726
6803
  let result = props;
6727
6804
  for (let i = len; i--;) result = propsUtil.add(result, i + "");
@@ -8117,7 +8194,7 @@ function isStaticText(node) {
8117
8194
  case "MarkoText": return true;
8118
8195
  case "MarkoPlaceholder": if (node.escape) {
8119
8196
  const { confident, computed } = evaluate(node.value);
8120
- return confident && !isVoid(computed);
8197
+ return confident && isNotVoid(computed);
8121
8198
  } else return false;
8122
8199
  }
8123
8200
  }
@@ -37,6 +37,8 @@ export interface Binding {
37
37
  property: string | undefined;
38
38
  propertyAliases: Map<string, Binding>;
39
39
  excludeProperties: Opt<string>;
40
+ noSerialize: boolean;
41
+ noSerializeProperties: Opt<string>;
40
42
  upstreamAlias: Binding | undefined;
41
43
  restOffset: number | undefined;
42
44
  scopeOffset: Binding | undefined;
@@ -84,6 +86,8 @@ declare module "@marko/compiler/dist/types" {
84
86
  pruned?: true;
85
87
  isEffect?: true;
86
88
  spreadFrom?: Binding;
89
+ nativeTagSpread?: true;
90
+ nativeTagSpreadMerged?: true;
87
91
  merged?: NodeExtra;
88
92
  }
89
93
  interface FunctionExtra {
@@ -45,7 +45,7 @@ export interface Section {
45
45
  downstreamBinding: {
46
46
  binding: Binding;
47
47
  properties: Opt<string>;
48
- } | undefined;
48
+ } | false | undefined;
49
49
  hasAbortSignal: boolean;
50
50
  readsOwner: boolean;
51
51
  isBranch: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.1.9",
3
+ "version": "6.1.11",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",