marko 6.0.57 → 6.0.59

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.
@@ -56,16 +56,19 @@ var import_babel_utils = require("@marko/compiler/babel-utils");
56
56
  function assertNoSpreadAttrs(tag) {
57
57
  for (const attr2 of tag.get("attributes")) {
58
58
  if (attr2.isMarkoSpreadAttribute()) {
59
+ const tagName = tag.get("name").node.value;
59
60
  throw attr2.buildCodeFrameError(
60
- `The \`${tag.get("name").node.value}\` tag does not support \`...spread\` attributes.`
61
+ `The [\`<${tagName}>\`](https://next.markojs.com/docs/reference/core-tag#${tagName}) tag does not support \`...spread\` attributes.`
61
62
  );
62
63
  }
63
64
  }
64
65
  }
65
66
  function assertNoBodyContent(tag) {
66
67
  if (tag.node.body.body.length) {
67
- throw tag.get("name").buildCodeFrameError(
68
- `The \`${tag.get("name").node.value}\` tag does not support body content.`
68
+ const tagName = tag.get("name");
69
+ const tagNameLiteral = tagName.node.value;
70
+ throw tagName.buildCodeFrameError(
71
+ `The [\`<${tagNameLiteral}>\`](https://next.markojs.com/docs/reference/core-tag#${tagNameLiteral}) tag does not support body content.`
69
72
  );
70
73
  }
71
74
  }
@@ -3067,7 +3070,7 @@ function getSectionMeta(section) {
3067
3070
  function markNode(path5, nodeBinding, reason) {
3068
3071
  if (nodeBinding.type !== 0 /* dom */) {
3069
3072
  throw path5.buildCodeFrameError(
3070
- "Tried to mark a node that was not determined to need a mark during analyze."
3073
+ "POTENTIAL MARKO BUG: Tried to mark a node that was not determined to need a mark during analyze."
3071
3074
  );
3072
3075
  }
3073
3076
  if (isOutputHTML()) {
@@ -3097,24 +3100,26 @@ var return_default = {
3097
3100
  if (parentTag) {
3098
3101
  if ((0, import_babel_utils15.isNativeTag)(parentTag)) {
3099
3102
  throw tag.get("name").buildCodeFrameError(
3100
- "The `return` tag can not be used in a native tag."
3103
+ "The [`<return>` tag](https://next.markojs.com/docs/reference/core-tag#return) can not be used in a [native tag](https://next.markojs.com/docs/reference/native-tag)."
3101
3104
  );
3102
3105
  } else if (isControlFlowTag(parentTag)) {
3103
3106
  throw tag.get("name").buildCodeFrameError(
3104
- `The \`return\` tag can not be used under an \`${parentTag.get("name").toString()}\` tag.`
3107
+ `The [\`<return>\` tag](https://next.markojs.com/docs/reference/core-tag#return) can not be used under the \`<${parentTag.get("name").toString()}>\` tag.`
3105
3108
  );
3106
3109
  }
3107
3110
  }
3108
3111
  if (tagsWithReturn.has(tag.parentPath)) {
3109
3112
  throw tag.get("name").buildCodeFrameError(
3110
- `Cannot have multiple \`return\` tags ${tag.parent.type === "Program" ? "for the template" : "within a tag's body content"}.`
3113
+ `Cannot have multiple [\`<return>\` tags](https://next.markojs.com/docs/reference/core-tag#return) ${tag.parent.type === "Program" ? "for the template" : "within a tag's body content"}.`
3111
3114
  );
3112
3115
  } else {
3113
3116
  tagsWithReturn.add(tag.parentPath);
3114
3117
  }
3115
3118
  const attrs2 = getKnownAttrValues(tag.node);
3116
3119
  if (!attrs2.value) {
3117
- throw tag.get("name").buildCodeFrameError("The `return` tag requires a value.");
3120
+ throw tag.get("name").buildCodeFrameError(
3121
+ "The [`<return>` tag](https://next.markojs.com/docs/reference/core-tag#return) requires a [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
3122
+ );
3118
3123
  }
3119
3124
  if (attrs2.valueChange) {
3120
3125
  (attrs2.valueChange.extra ??= {}).isEffect = true;
@@ -3188,7 +3193,7 @@ var return_default = {
3188
3193
  displayText: "return=<value>",
3189
3194
  description: "Provides a value for use in a parent template.",
3190
3195
  snippet: "return=${1:value}",
3191
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#return"
3196
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#return"
3192
3197
  }
3193
3198
  ]
3194
3199
  };
@@ -4860,7 +4865,7 @@ function trackAssignment(assignment, binding) {
4860
4865
  const changePropName = binding.property + "Change";
4861
4866
  const changeBinding = binding.upstreamAlias.propertyAliases.get(changePropName) || createBinding(
4862
4867
  generateUid(changePropName),
4863
- 5 /* derived */,
4868
+ binding.type === 2 /* input */ ? binding.type : 5 /* derived */,
4864
4869
  binding.section,
4865
4870
  binding.upstreamAlias,
4866
4871
  changePropName,
@@ -5849,19 +5854,23 @@ var await_default = {
5849
5854
  const tagExtra = tag.node.extra ??= {};
5850
5855
  tagExtra[kDOMBinding] = createBinding("#text", 0 /* dom */, section);
5851
5856
  if (!valueAttr) {
5852
- throw tag.get("name").buildCodeFrameError("The `await` tag requires a value.");
5857
+ throw tag.get("name").buildCodeFrameError(
5858
+ "The [`<await>` tag](https://next.markojs.com/docs/reference/core-tag#await) requires a [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
5859
+ );
5853
5860
  }
5854
5861
  if (node.attributes.length > 1 || !import_compiler26.types.isMarkoAttribute(valueAttr) || valueAttr.name !== "value") {
5855
5862
  throw tag.get("name").buildCodeFrameError(
5856
- "The `await` tag only supports the `value` attribute."
5863
+ "The [`<await>` tag](https://next.markojs.com/docs/reference/core-tag#await) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
5857
5864
  );
5858
5865
  }
5859
5866
  if (!node.body.body.length) {
5860
- throw tag.get("name").buildCodeFrameError("The `await` tag requires body content.");
5867
+ throw tag.get("name").buildCodeFrameError(
5868
+ "The [`<await>` tag](https://next.markojs.com/docs/reference/core-tag#await) requires [content](https://next.markojs.com/docs/reference/language#tag-content)."
5869
+ );
5861
5870
  }
5862
5871
  if (node.body.params.length && (node.body.params.length > 1 || import_compiler26.types.isSpreadElement(node.body.params[0]))) {
5863
5872
  throw tag.get("name").buildCodeFrameError(
5864
- "The `await` tag only supports a single parameter."
5873
+ "The [`<await>` tag](https://next.markojs.com/docs/reference/core-tag#await) only supports a single parameter."
5865
5874
  );
5866
5875
  }
5867
5876
  const bodySection = startSection(tagBody);
@@ -5955,7 +5964,7 @@ var await_default = {
5955
5964
  autocomplete: [
5956
5965
  {
5957
5966
  description: "Use to consume asynchronous an data.",
5958
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#await"
5967
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#await"
5959
5968
  }
5960
5969
  ],
5961
5970
  types: runtime_info_default.name + "/tags/await.d.marko"
@@ -6045,14 +6054,18 @@ var const_default = {
6045
6054
  const { node } = tag;
6046
6055
  const [valueAttr] = node.attributes;
6047
6056
  if (!node.var) {
6048
- throw tag.get("name").buildCodeFrameError("The `const` tag requires a tag variable.");
6057
+ throw tag.get("name").buildCodeFrameError(
6058
+ "The [`<const>` tag](https://next.markojs.com/docs/reference/core-tag#const) requires a [tag variable](https://next.markojs.com/docs/reference/language#tag-variables)."
6059
+ );
6049
6060
  }
6050
6061
  if (!valueAttr) {
6051
- throw tag.get("name").buildCodeFrameError("The `const` tag requires a value.");
6062
+ throw tag.get("name").buildCodeFrameError(
6063
+ "The [`<const>` tag](https://next.markojs.com/docs/reference/core-tag#const) requires a [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
6064
+ );
6052
6065
  }
6053
6066
  if (node.attributes.length > 1 || !import_compiler29.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value") {
6054
6067
  throw tag.get("name").buildCodeFrameError(
6055
- "The `const` tag only supports the `value` attribute."
6068
+ "The [`<const>` tag](https://next.markojs.com/docs/reference/core-tag#const) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
6056
6069
  );
6057
6070
  }
6058
6071
  const valueExtra = evaluate(valueAttr.value);
@@ -6091,7 +6104,7 @@ var const_default = {
6091
6104
  autocomplete: [
6092
6105
  {
6093
6106
  description: "Use to create an constant binding.",
6094
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#const"
6107
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#const"
6095
6108
  }
6096
6109
  ],
6097
6110
  types: runtime_info_default.name + "/tags/const.d.marko"
@@ -6109,7 +6122,7 @@ var debug_default = {
6109
6122
  assertNoBodyContent(tag);
6110
6123
  if (tag.node.attributes.length > 1 || tag.node.attributes.length === 1 && (!import_compiler30.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value")) {
6111
6124
  throw tag.get("name").buildCodeFrameError(
6112
- "The `debug` tag only supports the `value` attribute."
6125
+ "The [`<debug>` tag](https://next.markojs.com/docs/reference/core-tag#debug) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
6113
6126
  );
6114
6127
  }
6115
6128
  },
@@ -6134,7 +6147,7 @@ var debug_default = {
6134
6147
  autocomplete: [
6135
6148
  {
6136
6149
  description: "Debug on value change.",
6137
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#debug"
6150
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#debug"
6138
6151
  }
6139
6152
  ],
6140
6153
  types: runtime_info_default.name + "/tags/debug.d.marko"
@@ -6321,7 +6334,7 @@ var native_tag_default = {
6321
6334
  const { node } = tag;
6322
6335
  if (node.var && !import_compiler32.types.isIdentifier(node.var)) {
6323
6336
  throw tag.get("var").buildCodeFrameError(
6324
- "Tag variables on native elements cannot be destructured."
6337
+ "Tag variables on [native tags](https://next.markojs.com/docs/reference/native-tag) cannot be destructured."
6325
6338
  );
6326
6339
  }
6327
6340
  const tagName = getTagName(tag);
@@ -7255,7 +7268,7 @@ var for_default = {
7255
7268
  break;
7256
7269
  default:
7257
7270
  throw tag.buildCodeFrameError(
7258
- "Invalid `for` tag, missing an `of=`, `in=`, `to=` attribute."
7271
+ "The [`<for>` tag](https://next.markojs.com/docs/reference/core-tag#for) requires an `of=`, `in=`, or `to=` attribute."
7259
7272
  );
7260
7273
  }
7261
7274
  if (!isAttrTag) {
@@ -7465,15 +7478,15 @@ var for_default = {
7465
7478
  {
7466
7479
  snippet: "for|${1:value, index}| of=${3:array}",
7467
7480
  description: "Use to iterate over lists, object properties, or between ranges.",
7468
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#iterating-over-a-list"
7481
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#for"
7469
7482
  },
7470
7483
  {
7471
7484
  snippet: "for|${1:name, value}| in=${3:object}",
7472
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#iterating-over-an-objects-properties"
7485
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#for"
7473
7486
  },
7474
7487
  {
7475
7488
  snippet: "for|${1:index}| to=${2:number}",
7476
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#iterating-between-a-range-of-numbers"
7489
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#for"
7477
7490
  }
7478
7491
  ]
7479
7492
  };
@@ -7895,7 +7908,9 @@ var define_default = {
7895
7908
  analyze(tag) {
7896
7909
  (0, import_babel_utils29.assertNoArgs)(tag);
7897
7910
  if (!tag.node.var) {
7898
- throw tag.get("name").buildCodeFrameError("The `define` tag requires a tag variable.");
7911
+ throw tag.get("name").buildCodeFrameError(
7912
+ "The [`<define>` tag](https://next.markojs.com/docs/reference/core-tag#define) requires a [tag variable](https://next.markojs.com/docs/reference/language#tag-variables)."
7913
+ );
7899
7914
  }
7900
7915
  const tagBody = tag.get("body");
7901
7916
  const bodySection = startSection(tagBody);
@@ -7956,7 +7971,7 @@ var define_default = {
7956
7971
  autocomplete: [
7957
7972
  {
7958
7973
  description: "Use to create a constant object binding that can be rendered.",
7959
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#define"
7974
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#define"
7960
7975
  }
7961
7976
  ],
7962
7977
  types: runtime_info_default.name + "/tags/define.d.marko"
@@ -8032,7 +8047,7 @@ var html_comment_default = {
8032
8047
  if (tagVar) {
8033
8048
  if (!import_compiler38.types.isIdentifier(tagVar)) {
8034
8049
  throw tag.get("var").buildCodeFrameError(
8035
- "The `html-comment` tag variable cannot be destructured."
8050
+ "The [`<html-comment>` tag](https://next.markojs.com/docs/reference/core-tag#html-comment) tag variable cannot be destructured."
8036
8051
  );
8037
8052
  }
8038
8053
  needsBinding = true;
@@ -8199,7 +8214,7 @@ var html_comment_default = {
8199
8214
  autocomplete: [
8200
8215
  {
8201
8216
  description: "Use to create an html comment that is not stripped from the output.",
8202
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#html-comment"
8217
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#html-comment"
8203
8218
  }
8204
8219
  ]
8205
8220
  };
@@ -8577,7 +8592,13 @@ var html_script_default = {
8577
8592
  parseOptions: {
8578
8593
  text: true,
8579
8594
  preserveWhitespace: true
8580
- }
8595
+ },
8596
+ autocomplete: [
8597
+ {
8598
+ description: "Use instead of `<script>` to render a native tag directly, without processing by Marko.",
8599
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#html-script--html-style"
8600
+ }
8601
+ ]
8581
8602
  };
8582
8603
  function getUsedAttrs2(tag) {
8583
8604
  const seen = {};
@@ -8990,7 +9011,13 @@ var html_style_default = {
8990
9011
  parseOptions: {
8991
9012
  text: true,
8992
9013
  preserveWhitespace: true
8993
- }
9014
+ },
9015
+ autocomplete: [
9016
+ {
9017
+ description: "Use instead of `<style>` to render a native tag directly, without processing by Marko.",
9018
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#html-script--html-style"
9019
+ }
9020
+ ]
8994
9021
  };
8995
9022
  function getUsedAttrs3(tag) {
8996
9023
  const seen = {};
@@ -9042,32 +9069,58 @@ var id_default = {
9042
9069
  analyze(tag) {
9043
9070
  (0, import_babel_utils35.assertNoArgs)(tag);
9044
9071
  (0, import_babel_utils35.assertNoParams)(tag);
9045
- (0, import_babel_utils35.assertNoAttributes)(tag);
9046
9072
  assertNoBodyContent(tag);
9047
9073
  (0, import_babel_utils35.assertNoAttributeTags)(tag);
9048
9074
  const { node } = tag;
9075
+ const [valueAttr] = node.attributes;
9049
9076
  if (!node.var) {
9050
- throw tag.get("name").buildCodeFrameError("The `id` tag requires a tag variable.");
9077
+ throw tag.get("name").buildCodeFrameError(
9078
+ "The [`<id>` tag](https://next.markojs.com/docs/reference/core-tag#id) requires a [tag variable](https://next.markojs.com/docs/reference/language#tag-variables)."
9079
+ );
9051
9080
  }
9052
9081
  if (!import_compiler41.types.isIdentifier(node.var)) {
9053
- throw tag.get("var").buildCodeFrameError("The `id` tag cannot be destructured");
9082
+ throw tag.get("var").buildCodeFrameError(
9083
+ "The [`<id>` tag](https://next.markojs.com/docs/reference/core-tag#id) cannot be destructured."
9084
+ );
9085
+ }
9086
+ if (tag.node.attributes.length > 1 || tag.node.attributes.length === 1 && (!import_compiler41.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value")) {
9087
+ throw tag.get("name").buildCodeFrameError(
9088
+ "The [`<id>` tag](https://next.markojs.com/docs/reference/core-tag#id) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
9089
+ );
9054
9090
  }
9055
9091
  const binding = trackVarReferences(tag, 5 /* derived */);
9056
9092
  if (binding) {
9057
- setBindingDownstream(binding, false);
9093
+ setBindingDownstream(binding, !!valueAttr && evaluate(valueAttr.value));
9058
9094
  }
9059
9095
  },
9060
9096
  translate: {
9061
9097
  exit(tag) {
9062
9098
  const { node } = tag;
9063
9099
  const id = isOutputHTML() ? callRuntime("nextTagId") : callRuntime("nextTagId", scopeIdentifier);
9100
+ const [valueAttr] = tag.node.attributes;
9064
9101
  if (isOutputHTML()) {
9065
9102
  tag.replaceWith(
9066
- import_compiler41.types.variableDeclaration("const", [import_compiler41.types.variableDeclarator(node.var, id)])
9103
+ import_compiler41.types.variableDeclaration("const", [
9104
+ import_compiler41.types.variableDeclarator(
9105
+ node.var,
9106
+ valueAttr ? import_compiler41.types.logicalExpression("||", valueAttr.value, id) : id
9107
+ )
9108
+ ])
9067
9109
  );
9068
9110
  } else {
9111
+ const section = getSection(tag);
9069
9112
  const source = initValue(node.var.extra.binding);
9070
- addValue(getSection(tag), void 0, source, id);
9113
+ if (valueAttr) {
9114
+ const { value } = valueAttr;
9115
+ addValue(
9116
+ section,
9117
+ value.extra?.referencedBindings,
9118
+ source,
9119
+ import_compiler41.types.logicalExpression("||", value, id)
9120
+ );
9121
+ } else {
9122
+ addValue(section, void 0, source, id);
9123
+ }
9071
9124
  tag.remove();
9072
9125
  }
9073
9126
  }
@@ -9081,7 +9134,7 @@ var id_default = {
9081
9134
  displayText: "id/<name>",
9082
9135
  description: "Use to create a unique identifier.",
9083
9136
  snippet: "id/${1:name}",
9084
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#id"
9137
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#id"
9085
9138
  }
9086
9139
  ],
9087
9140
  types: runtime_info_default.name + "/tags/id.d.marko"
@@ -9314,7 +9367,7 @@ var IfTag = {
9314
9367
  {
9315
9368
  snippet: "if=${1:condition}",
9316
9369
  description: "Use to display content only if the condition is met.",
9317
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#if-else-if-else"
9370
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#if--else"
9318
9371
  }
9319
9372
  ]
9320
9373
  };
@@ -9324,7 +9377,7 @@ var ElseIfTag = {
9324
9377
  {
9325
9378
  snippet: "else-if=${1:condition}",
9326
9379
  description: "Use after an <if> or <else-if> tag to display content if those conditions do not match and this one does.",
9327
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#if-else-if-else"
9380
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#if--else"
9328
9381
  }
9329
9382
  ]
9330
9383
  };
@@ -9333,7 +9386,7 @@ var ElseTag = {
9333
9386
  autocomplete: [
9334
9387
  {
9335
9388
  description: "Use after an <if> or <else-if> tag to display content if those conditions do not match.",
9336
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#if-else-if-else"
9389
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#if--else"
9337
9390
  }
9338
9391
  ]
9339
9392
  };
@@ -9362,14 +9415,14 @@ function assertHasPrecedingCondition(tag) {
9362
9415
  while (prev.node && prev.isMarkoComment()) prev = prev.getPrevSibling();
9363
9416
  if (!isConditionTag(prev) || getTagName(prev) !== "else" && !prev.node.attributes.length) {
9364
9417
  throw tag.buildCodeFrameError(
9365
- `The \`<${getTagName(tag)}>\` must have a preceding \`<if=cond>\`, \`<else-if=cond>\`, or \`<else if=cond>\`.`
9418
+ `The [\`<${getTagName(tag)}>\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) must have a preceding \`<if=cond>\` or \`<else if=cond>\`.`
9366
9419
  );
9367
9420
  }
9368
9421
  }
9369
9422
  function assertHasBody(tag) {
9370
9423
  if (!(tag.node.body.body.length || tag.node.attributeTags.length)) {
9371
9424
  throw tag.get("name").buildCodeFrameError(
9372
- `The \`${getTagName(tag)}\` tag requires body content.`
9425
+ `The [\`${getTagName(tag)}\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) requires [body content](https://next.markojs.com/docs/reference/language#tag-content).`
9373
9426
  );
9374
9427
  }
9375
9428
  }
@@ -9377,12 +9430,14 @@ function assertHasValueAttribute(tag) {
9377
9430
  const { node } = tag;
9378
9431
  const [valueAttr] = node.attributes;
9379
9432
  if (!import_compiler43.types.isMarkoAttribute(valueAttr) || !valueAttr.default) {
9380
- throw tag.get("name").buildCodeFrameError(`The \`${getTagName(tag)}\` tag requires a value.`);
9433
+ throw tag.get("name").buildCodeFrameError(
9434
+ `The [\`${getTagName(tag)}\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) requires a [\`value=\` attribute](https://next.markojs.com/docs/reference/language#shorthand-value).`
9435
+ );
9381
9436
  }
9382
9437
  if (node.attributes.length > 1) {
9383
9438
  const start = node.attributes[1].loc?.start;
9384
9439
  const end = node.attributes[node.attributes.length - 1].loc?.end;
9385
- const msg = `The \`${getTagName(tag)}\` tag only supports the \`value\` attribute.`;
9440
+ const msg = `The [\`${getTagName(tag)}\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) only supports the [\`value=\` attribute](https://next.markojs.com/docs/reference/language#shorthand-value).`;
9386
9441
  if (start == null || end == null) {
9387
9442
  throw tag.get("name").buildCodeFrameError(msg);
9388
9443
  } else {
@@ -9400,7 +9455,7 @@ function assertOptionalIfAttribute(tag) {
9400
9455
  if (node.attributes.length > 1 || ifAttr && ifAttr.name !== "if") {
9401
9456
  const start = node.attributes[1].loc?.start;
9402
9457
  const end = node.attributes[node.attributes.length - 1].loc?.end;
9403
- const msg = `The \`${getTagName(tag)}\` tag only supports an \`if=\` attribute.`;
9458
+ const msg = `The [\`${getTagName(tag)}\` tag](https://next.markojs.com/docs/reference/core-tag#if--else) only supports an \`if=\` attribute.`;
9404
9459
  if (start == null || end == null) {
9405
9460
  throw tag.get("name").buildCodeFrameError(msg);
9406
9461
  } else {
@@ -9477,7 +9532,7 @@ var let_default = {
9477
9532
  } else {
9478
9533
  const start = attr2.loc?.start;
9479
9534
  const end = attr2.loc?.end;
9480
- const msg = "The `let` tag only supports the `value` attribute and its change handler.";
9535
+ const msg = "The [`<let>` tag](https://next.markojs.com/docs/reference/core-tag#let) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value) and its change handler.";
9481
9536
  if (start == null || end == null) {
9482
9537
  throw tag.get("name").buildCodeFrameError(msg);
9483
9538
  } else {
@@ -9495,14 +9550,18 @@ var let_default = {
9495
9550
  assertNoBodyContent(tag);
9496
9551
  assertNoSpreadAttrs(tag);
9497
9552
  if (!tagVar) {
9498
- throw tag.get("name").buildCodeFrameError("The `let` tag requires a tag variable.");
9553
+ throw tag.get("name").buildCodeFrameError(
9554
+ "The [`<let>` tag](https://next.markojs.com/docs/reference/core-tag#let) requires a [tag variable](https://next.markojs.com/docs/reference/language#tag-variables)."
9555
+ );
9499
9556
  }
9500
9557
  if (!import_compiler44.types.isIdentifier(tagVar)) {
9501
- throw tag.get("var").buildCodeFrameError("The `let` tag variable cannot be destructured.");
9558
+ throw tag.get("var").buildCodeFrameError(
9559
+ "The [`<let>` tag](https://next.markojs.com/docs/reference/core-tag#let) variable cannot be destructured."
9560
+ );
9502
9561
  }
9503
9562
  if (valueChangeAttr && (0, import_babel_utils38.computeNode)(valueChangeAttr.value)) {
9504
9563
  throw tag.get("attributes").find((attr2) => attr2.node === valueChangeAttr).get("value").buildCodeFrameError(
9505
- "The `let` tag `valueChange` attribute must be a function."
9564
+ "The [`<let>` tag](https://next.markojs.com/docs/reference/core-tag#let) [`valueChange=` attribute](https://next.markojs.com/docs/reference/core-tag#controllable-let) must be a function."
9506
9565
  );
9507
9566
  }
9508
9567
  const tagSection = getOrCreateSection(tag);
@@ -9566,7 +9625,7 @@ var let_default = {
9566
9625
  autocomplete: [
9567
9626
  {
9568
9627
  description: "Use to create a mutable binding.",
9569
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#let"
9628
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#let"
9570
9629
  }
9571
9630
  ],
9572
9631
  types: runtime_info_default.name + "/tags/let.d.marko"
@@ -9597,13 +9656,13 @@ var lifecycle_default = {
9597
9656
  binding.downstreamExpressions.add(tagExtra);
9598
9657
  if (node.attributes.length === 0) {
9599
9658
  throw tag.get("name").buildCodeFrameError(
9600
- "The `lifecycle` tag requires at least one attribute."
9659
+ "The [`<lifecycle>` tag](https://next.markojs.com/docs/reference/core-tag#lifecycle) requires at least one attribute."
9601
9660
  );
9602
9661
  }
9603
9662
  for (const attr2 of node.attributes) {
9604
9663
  if (import_compiler45.types.isMarkoSpreadAttribute(attr2)) {
9605
9664
  throw tag.get("name").buildCodeFrameError(
9606
- "The `lifecycle` tag does not support `...spread` attributes."
9665
+ "The [`<lifecycle>` tag](https://next.markojs.com/docs/reference/core-tag#lifecycle) does not support [`...spread` attributes](https://next.markojs.com/docs/reference/language#spread-attributes)."
9607
9666
  );
9608
9667
  }
9609
9668
  (attr2.value.extra ??= {}).isEffect = true;
@@ -9648,7 +9707,7 @@ var lifecycle_default = {
9648
9707
  autocomplete: [
9649
9708
  {
9650
9709
  description: "Use to create a side effects.",
9651
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#effect"
9710
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#lifecycle"
9652
9711
  }
9653
9712
  ],
9654
9713
  types: runtime_info_default.name + "/tags/lifecycle.d.marko"
@@ -9665,11 +9724,13 @@ var log_default = {
9665
9724
  (0, import_babel_utils40.assertNoParams)(tag);
9666
9725
  assertNoBodyContent(tag);
9667
9726
  if (!valueAttr) {
9668
- throw tag.get("name").buildCodeFrameError("The `log` tag requires a value.");
9727
+ throw tag.get("name").buildCodeFrameError(
9728
+ "The [`<log>` tag](https://next.markojs.com/docs/reference/core-tag#log) requires a [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
9729
+ );
9669
9730
  }
9670
9731
  if (tag.node.attributes.length > 1 || !import_compiler46.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value") {
9671
9732
  throw tag.get("name").buildCodeFrameError(
9672
- "The `log` tag only supports the `value` attribute."
9733
+ "The [`<log>` tag](https://next.markojs.com/docs/reference/core-tag#log) only supports the [`value=` attribute](https://next.markojs.com/docs/reference/language#shorthand-value)."
9673
9734
  );
9674
9735
  }
9675
9736
  },
@@ -9700,7 +9761,7 @@ var log_default = {
9700
9761
  autocomplete: [
9701
9762
  {
9702
9763
  description: "Use to log a value to the console.",
9703
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#log"
9764
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#log"
9704
9765
  }
9705
9766
  ],
9706
9767
  types: runtime_info_default.name + "/tags/log.d.marko"
@@ -9709,7 +9770,7 @@ var log_default = {
9709
9770
  // src/translator/core/script.ts
9710
9771
  var import_compiler47 = require("@marko/compiler");
9711
9772
  var import_babel_utils41 = require("@marko/compiler/babel-utils");
9712
- var htmlScriptTagAlternateMsg = " For a native html `script` tag use the `html-script` core tag instead.";
9773
+ var htmlScriptTagAlternateMsg = " For a native html [`<script>` tag](https://next.markojs.com/docs/reference/core-tag#script) use the `html-script` core tag instead.";
9713
9774
  var script_default = {
9714
9775
  parse(tag) {
9715
9776
  const { node } = tag;
@@ -9720,7 +9781,7 @@ var script_default = {
9720
9781
  if (child.type !== "MarkoText") {
9721
9782
  throw tag.hub.file.hub.buildError(
9722
9783
  child,
9723
- "Unexpected content in `script` tag. Only javascript and typescript is supported." + htmlScriptTagAlternateMsg,
9784
+ "Unexpected content in [`<script>` tag](https://next.markojs.com/docs/reference/core-tag#script). Only javascript and typescript is supported." + htmlScriptTagAlternateMsg,
9724
9785
  SyntaxError
9725
9786
  );
9726
9787
  }
@@ -9747,7 +9808,7 @@ var script_default = {
9747
9808
  if (node.var) {
9748
9809
  throw tag.hub.buildError(
9749
9810
  node.var,
9750
- "The `script` tag does not support a tag variable reference." + htmlScriptTagAlternateMsg
9811
+ "The [`<script>` tag](https://next.markojs.com/docs/reference/core-tag#script) does not support a tag variable reference." + htmlScriptTagAlternateMsg
9751
9812
  );
9752
9813
  }
9753
9814
  let seenValueAttr = false;
@@ -9762,7 +9823,7 @@ var script_default = {
9762
9823
  } else {
9763
9824
  throw tag.hub.buildError(
9764
9825
  attr2,
9765
- "The `script` tag does not support html attributes." + htmlScriptTagAlternateMsg
9826
+ "The [`<script>` tag](https://next.markojs.com/docs/reference/core-tag#script) does not support html attributes." + htmlScriptTagAlternateMsg
9766
9827
  );
9767
9828
  }
9768
9829
  }
@@ -9912,7 +9973,7 @@ var import_babel_utils44 = require("@marko/compiler/babel-utils");
9912
9973
  var import_magic_string = __toESM(require("magic-string"));
9913
9974
  var import_path3 = __toESM(require("path"));
9914
9975
  var STYLE_EXT_REG = /^style((?:\.[a-zA-Z0-9$_-]+)+)?/;
9915
- var htmlStyleTagAlternateMsg = " For a native html `style` tag use the `html-style` core tag instead.";
9976
+ var htmlStyleTagAlternateMsg = " For a native html [`<style>` tag](https://next.markojs.com/docs/reference/core-tag#style) use the `html-style` core tag instead.";
9916
9977
  var style_default = {
9917
9978
  analyze(tag) {
9918
9979
  (0, import_babel_utils44.assertNoArgs)(tag);
@@ -9933,14 +9994,14 @@ var style_default = {
9933
9994
  if (child.type !== "MarkoText") {
9934
9995
  throw tag.hub.buildError(
9935
9996
  child,
9936
- "The `style` tag currently only supports static content." + htmlStyleTagAlternateMsg
9997
+ "The [`<style>` tag](https://next.markojs.com/docs/reference/core-tag#style) currently only supports static content." + htmlStyleTagAlternateMsg
9937
9998
  );
9938
9999
  }
9939
10000
  }
9940
10001
  if (node.body.body.length > 1) {
9941
10002
  throw tag.hub.buildError(
9942
10003
  node.name,
9943
- "The `style` tag currently only supports static content." + htmlStyleTagAlternateMsg
10004
+ "The [`<style>` tag](https://next.markojs.com/docs/reference/core-tag#style) currently only supports static content." + htmlStyleTagAlternateMsg
9944
10005
  );
9945
10006
  }
9946
10007
  },
@@ -10035,7 +10096,9 @@ var try_default = {
10035
10096
  );
10036
10097
  tagExtra[kDOMBinding2] = createBinding("#text", 0 /* dom */, section);
10037
10098
  if (!tag.node.body.body.length) {
10038
- throw tag.get("name").buildCodeFrameError("The `try` tag requires body content.");
10099
+ throw tag.get("name").buildCodeFrameError(
10100
+ "The [`<try>` tag](https://next.markojs.com/docs/reference/core-tag#try) requires [body content](https://next.markojs.com/docs/reference/language#tag-content)."
10101
+ );
10039
10102
  }
10040
10103
  startSection(tag.get("body"));
10041
10104
  },
@@ -10141,7 +10204,7 @@ var try_default = {
10141
10204
  autocomplete: [
10142
10205
  {
10143
10206
  description: "Used to capture errors and display placeholders for nested content.",
10144
- descriptionMoreURL: "https://markojs.com/docs/core-tags/#try"
10207
+ descriptionMoreURL: "https://next.markojs.com/docs/reference/core-tag#try"
10145
10208
  }
10146
10209
  ],
10147
10210
  types: runtime_info_default.name + "/tags/try.d.marko"
@@ -10588,7 +10651,9 @@ var attribute_tag_default = {
10588
10651
  startSection(body);
10589
10652
  trackParamsReferences(body, 3 /* param */);
10590
10653
  if (!(0, import_babel_utils48.findParentTag)(tag)) {
10591
- throw tag.get("name").buildCodeFrameError("@tags must be nested within another tag.");
10654
+ throw tag.get("name").buildCodeFrameError(
10655
+ "[Attribute tags](https://next.markojs.com/docs/reference/language#attribute-tags) must be nested within another tag."
10656
+ );
10592
10657
  }
10593
10658
  }
10594
10659
  },
@@ -10626,11 +10691,11 @@ var custom_tag_default = {
10626
10691
  const tagName = getTagName(tag);
10627
10692
  if (tagName && tag.scope.hasBinding(tagName)) {
10628
10693
  throw tag.get("name").buildCodeFrameError(
10629
- `Local variables must be in a dynamic tag unless they are PascalCase. Use \`<\${${tagName}}/>\` or rename to \`${tagName.charAt(0).toUpperCase() + tagName.slice(1)}\`.`
10694
+ `Local variables must be in a [dynamic tag](https://next.markojs.com/docs/reference/language#dynamic-tags) unless they are PascalCase. Use \`<\${${tagName}}/>\` or rename to \`${tagName.charAt(0).toUpperCase() + tagName.slice(1)}\`.`
10630
10695
  );
10631
10696
  }
10632
10697
  throw tag.get("name").buildCodeFrameError(
10633
- `Unable to find entry point for custom tag \`<${tagName}>\`.`
10698
+ `Unable to find entry point for [custom tag](https://next.markojs.com/docs/reference/custom-tag#relative-custom-tags) \`<${tagName}>\`.`
10634
10699
  );
10635
10700
  }
10636
10701
  const section = getOrCreateSection(tag);
@@ -10969,11 +11034,11 @@ function getTagRelativePath(tag) {
10969
11034
  const tagName = getTagName(tag);
10970
11035
  if (tagName && tag.scope.hasBinding(tagName)) {
10971
11036
  throw tag.get("name").buildCodeFrameError(
10972
- `Local variables must be in a dynamic tag unless they are PascalCase. Use \`<\${${tagName}}/>\` or rename to \`${tagName.charAt(0).toUpperCase() + tagName.slice(1)}\`.`
11037
+ `Local variables must be in a [dynamic tag](https://next.markojs.com/docs/reference/language#dynamic-tags) unless they are PascalCase. Use \`<\${${tagName}}/>\` or rename to \`${tagName.charAt(0).toUpperCase() + tagName.slice(1)}\`.`
10973
11038
  );
10974
11039
  }
10975
11040
  throw tag.get("name").buildCodeFrameError(
10976
- `Unable to find entry point for custom tag \`<${tagName}>\`.`
11041
+ `Unable to find entry point for [custom tag](https://next.markojs.com/docs/reference/custom-tag#relative-custom-tags) \`<${tagName}>\`.`
10977
11042
  );
10978
11043
  }
10979
11044
  return relativePath;
@@ -11854,9 +11919,16 @@ function getChangeHandler(tag, attr2) {
11854
11919
  );
11855
11920
  const existingChangedAttr = BINDING_CHANGE_HANDLER.get(binding.identifier);
11856
11921
  if (!existingChangedAttr) {
11922
+ const bindingIdentifierPath = binding.path.getOuterBindingIdentifierPaths()[binding.identifier.name];
11923
+ const changeAttrExpr = bindingIdentifierPath ? bindingIdentifierPath.parentPath === binding.path ? buildChangeHandlerFunction(attr2.value) : bindingIdentifierPath.parentPath.isObjectProperty() ? getChangeHandlerFromObjectPattern(
11924
+ bindingIdentifierPath.parentPath
11925
+ ) : void 0 : void 0;
11926
+ if (!changeAttrExpr) {
11927
+ throw tag.hub.buildError(attr2.value, "Unable to bind to value.");
11928
+ }
11857
11929
  const changeHandlerAttr = import_compiler58.types.markoAttribute(
11858
11930
  changeAttrName,
11859
- buildChangeHandlerFunction(attr2.value)
11931
+ changeAttrExpr
11860
11932
  );
11861
11933
  BINDING_CHANGE_HANDLER.set(binding.identifier, changeHandlerAttr);
11862
11934
  return changeHandlerAttr;
@@ -11932,6 +12004,51 @@ function buildChangeHandlerFunction(id) {
11932
12004
  ])
11933
12005
  );
11934
12006
  }
12007
+ function getChangeHandlerFromObjectPattern(parent) {
12008
+ let changeKey;
12009
+ const pattern = parent.parentPath;
12010
+ if (parent.node.computed) {
12011
+ changeKey = generateUidIdentifier(`dynamicChange`);
12012
+ pattern.pushContainer(
12013
+ "properties",
12014
+ import_compiler58.types.objectProperty(
12015
+ import_compiler58.types.binaryExpression(
12016
+ "+",
12017
+ parent.get("key").node,
12018
+ import_compiler58.types.stringLiteral("Change")
12019
+ ),
12020
+ changeKey,
12021
+ true
12022
+ )
12023
+ );
12024
+ } else {
12025
+ const key = parent.get("key");
12026
+ const searchKey = `${getStringOrIdentifierValue(key)}Change`;
12027
+ for (const prop of pattern.get("properties")) {
12028
+ if (prop.isObjectProperty()) {
12029
+ const propKey = prop.get("key");
12030
+ const propValue = prop.get("value");
12031
+ if (!prop.node.computed && getStringOrIdentifierValue(propKey) === searchKey && propValue.isIdentifier()) {
12032
+ changeKey = propValue.node;
12033
+ break;
12034
+ }
12035
+ }
12036
+ }
12037
+ if (!changeKey) {
12038
+ pattern.unshiftContainer(
12039
+ "properties",
12040
+ import_compiler58.types.objectProperty(
12041
+ import_compiler58.types.stringLiteral(searchKey),
12042
+ changeKey = generateUidIdentifier(searchKey)
12043
+ )
12044
+ );
12045
+ }
12046
+ }
12047
+ return changeKey;
12048
+ }
12049
+ function getStringOrIdentifierValue(path5) {
12050
+ return path5.isStringLiteral() ? path5.node.value : path5.node.name;
12051
+ }
11935
12052
 
11936
12053
  // src/translator/visitors/text.ts
11937
12054
  var import_compiler59 = require("@marko/compiler");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.0.57",
3
+ "version": "6.0.59",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",