marko 6.1.24 → 6.2.1

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.
@@ -800,7 +800,8 @@ function isControlFlowTag(tag) {
800
800
  case "else":
801
801
  case "for":
802
802
  case "await":
803
- case "try": return true;
803
+ case "try":
804
+ case "show": return true;
804
805
  }
805
806
  return false;
806
807
  }
@@ -1200,6 +1201,12 @@ function addOwnerSerializeReason(from, to, reason) {
1200
1201
  function isReasonDynamic(reason) {
1201
1202
  return !!reason && reason !== true && !reason.state;
1202
1203
  }
1204
+ function isStaticSerializeReason(reason) {
1205
+ return !!reason && !isReasonDynamic(reason);
1206
+ }
1207
+ function isStateSerializeReason(reason) {
1208
+ return !!reason && reason !== true && !!reason.state;
1209
+ }
1203
1210
  function getSerializeReason(section, prop, prefix) {
1204
1211
  if (prop) return section.serializeReasons.get(getPropKey(section, prop, prefix));
1205
1212
  else return section.serializeReason;
@@ -1536,10 +1543,12 @@ function getNodeContentType(path, extraMember, contentInfo) {
1536
1543
  case "html-comment": return 0;
1537
1544
  case "html-script":
1538
1545
  case "html-style": return 3;
1546
+ case "style": return tag.node.body.body.some((child) => _marko_compiler.types.isMarkoPlaceholder(child)) ? 3 : null;
1539
1547
  case "for":
1540
1548
  case "if":
1541
1549
  case "await":
1542
- case "try": return 1;
1550
+ case "try":
1551
+ case "show": return 1;
1543
1552
  default: return null;
1544
1553
  }
1545
1554
  else if ((0, _marko_compiler_babel_utils.isNativeTag)(tag)) return 3;
@@ -1645,7 +1654,9 @@ function isNativeNode(tag) {
1645
1654
  if (isCoreTag(tag)) switch (tag.node.name.value) {
1646
1655
  case "html-comment":
1647
1656
  case "html-script":
1648
- case "html-style": return true;
1657
+ case "html-style":
1658
+ case "show": return true;
1659
+ case "style": return tag.node.body.body.some((child) => _marko_compiler.types.isMarkoPlaceholder(child));
1649
1660
  default: return false;
1650
1661
  }
1651
1662
  return analyzeTagNameType(tag) === 0;
@@ -2242,6 +2253,7 @@ const pureDOMFunctions = new Set([
2242
2253
  "_child_setup",
2243
2254
  "_if",
2244
2255
  "_if_closure",
2256
+ "_show",
2245
2257
  "_try",
2246
2258
  "_dynamic_tag",
2247
2259
  "_dynamic_tag_content",
@@ -2257,6 +2269,7 @@ const pureDOMFunctions = new Set([
2257
2269
  "_for_of",
2258
2270
  "_for_to",
2259
2271
  "_for_until",
2272
+ "_hoist",
2260
2273
  "_let",
2261
2274
  "_let_change",
2262
2275
  "_const",
@@ -2307,6 +2320,40 @@ function getCompatRuntimeFile() {
2307
2320
  return `marko/${markoOpts.optimize ? "dist" : "src"}/runtime/helpers/tags-compat/${isOutputHTML() ? "html" : "dom"}${markoOpts.optimize ? "" : "-debug"}.${markoOpts.modules === "esm" ? "mjs" : "js"}`;
2308
2321
  }
2309
2322
  //#endregion
2323
+ //#region src/translator/util/setup-statements.ts
2324
+ /**
2325
+ * Tracks, during analyze, whether translate will add statements to a
2326
+ * section's setup signal (the signal keyed by no referenced bindings).
2327
+ * Sites that key statements by an expression's resolved references register
2328
+ * the expression with `addSetupExpr`; sites that always target the setup
2329
+ * signal call `addSetupStatement`. Expressions that resolve references
2330
+ * through `mergeReferences` are covered centrally by `finalizeReferences`.
2331
+ *
2332
+ * This lets a template's analyze phase prove its setup export is a noop so
2333
+ * parent templates can skip importing and calling it. The proof is checked
2334
+ * when the template itself is translated (see `visitors/program/dom.ts`).
2335
+ */
2336
+ const [getSetupInfo] = createSectionState("setupStatements", () => ({
2337
+ forced: false,
2338
+ exprs: /* @__PURE__ */ new Set()
2339
+ }));
2340
+ function addSetupStatement(section) {
2341
+ getSetupInfo(section).forced = true;
2342
+ }
2343
+ function addSetupExpr(section, node) {
2344
+ if (node) getSetupInfo(section).exprs.add(node.extra ??= {});
2345
+ else getSetupInfo(section).forced = true;
2346
+ }
2347
+ function sectionHasSetupStatements(section) {
2348
+ const info = getSetupInfo(section);
2349
+ if (info.forced) return true;
2350
+ for (let extra of info.exprs) {
2351
+ while (extra.merged) extra = extra.merged;
2352
+ if (!extra.pruned && !extra.referencedBindings) return true;
2353
+ }
2354
+ return false;
2355
+ }
2356
+ //#endregion
2310
2357
  //#region src/translator/util/binding-has-prop.ts
2311
2358
  function bindingHasProperty(binding, properties) {
2312
2359
  if (binding.pruned) return false;
@@ -2747,8 +2794,10 @@ var return_default = {
2747
2794
  if (!attrs.value) throw tag.get("name").buildCodeFrameError("The [`<return>` tag](https://markojs.com/docs/reference/core-tag#return) requires a [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value).");
2748
2795
  if (attrs.valueChange) {
2749
2796
  (attrs.valueChange.extra ??= {}).isEffect = true;
2797
+ addSetupExpr(section, attrs.valueChange);
2750
2798
  addSerializeReason(section, true, getAccessorProp().TagVariableChange);
2751
2799
  }
2800
+ addSetupExpr(section, attrs.value);
2752
2801
  section.returnValueExpr = attrs.value.extra ??= {};
2753
2802
  },
2754
2803
  translate: translateByTarget({
@@ -2984,6 +3033,10 @@ function setClosureSignalBuilder(tag, builder) {
2984
3033
  _setClosureSignalBuilder(getSectionForBody(tag.get("body")), builder);
2985
3034
  }
2986
3035
  const [getTryHasPlaceholder, setTryHasPlaceholder] = createSectionState("tryWithPlaceholder");
3036
+ const [getOwnerResumedByMarker, setOwnerResumedByMarker] = createSectionState("ownerResumedByMarker");
3037
+ function setSectionOwnerResumedByMarker(section) {
3038
+ setOwnerResumedByMarker(section, true);
3039
+ }
2987
3040
  const [getSerializedAccessors] = createSectionState("serializedScopeProperties", () => /* @__PURE__ */ new Map());
2988
3041
  function setSectionSerializedValue(section, prop, expression) {
2989
3042
  const reason = getSerializeReason(section, prop);
@@ -3094,6 +3147,7 @@ function underTryPlaceholder(section) {
3094
3147
  function initValue(binding, isLet = false) {
3095
3148
  const section = binding.section;
3096
3149
  const signal = getSignal(section, binding);
3150
+ if (binding.forcePersist) signal.forcePersist = true;
3097
3151
  signal.build = () => {
3098
3152
  if (isPureMemberForwarder(binding)) return;
3099
3153
  const fn = getSignalFn(signal);
@@ -3466,7 +3520,7 @@ function writeHTMLResumeStatements(path) {
3466
3520
  const ownerReason = getSerializeReason(section, ownerAccessor);
3467
3521
  if (ownerReason) {
3468
3522
  serializedLookup.delete(ownerAccessor);
3469
- serializedProperties.push(toObjectProperty(ownerAccessor, ifSerialized(ownerReason, callRuntime("_scope_with_id", getScopeIdIdentifier(section.parent)))));
3523
+ if (!getOwnerResumedByMarker(section)) serializedProperties.push(toObjectProperty(ownerAccessor, ifSerialized(ownerReason, callRuntime("_scope_with_id", getScopeIdIdentifier(section.parent)))));
3470
3524
  }
3471
3525
  }
3472
3526
  for (const [key, { expression, reason }] of serializedLookup) serializedProperties.push(toObjectProperty(key, ifSerialized(reason, expression)));
@@ -3711,9 +3765,11 @@ var dom_default = { translate: {
3711
3765
  if (decls) extraDecls = extraDecls ? [...decls, ...extraDecls] : decls;
3712
3766
  }
3713
3767
  });
3714
- writeSignals(section);
3768
+ const written = writeSignals(section);
3715
3769
  writeRegisteredFns();
3716
- if (!getSetup(section)) program.node.body.unshift(_marko_compiler.types.exportNamedDeclaration(_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(setupIdentifier, _marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([])))])));
3770
+ const setup = getSetup(section);
3771
+ if (domExports.setupEmpty && setup && written.has(setup)) throw program.buildCodeFrameError("Marko internal error: analysis marked this template's setup export as empty but translation produced statements for it. Please open an issue with a reproduction.");
3772
+ if (!setup) program.node.body.unshift(_marko_compiler.types.exportNamedDeclaration(_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(setupIdentifier, _marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([])))])));
3717
3773
  program.node.body.unshift(_marko_compiler.types.exportNamedDeclaration(_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(templateIdentifier, writes || _marko_compiler.types.stringLiteral(""))])), _marko_compiler.types.exportNamedDeclaration(_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(walksIdentifier, walks || _marko_compiler.types.stringLiteral(""))])));
3718
3774
  if (extraDecls) program.node.body.unshift(_marko_compiler.types.variableDeclaration("const", extraDecls));
3719
3775
  program.node.body.push(_marko_compiler.types.exportDefaultDeclaration(callRuntime("_template", _marko_compiler.types.stringLiteral(program.hub.file.metadata.marko.id), templateIdentifier, walksIdentifier, setupIdentifier, programInputSignal?.identifier)));
@@ -3876,7 +3932,8 @@ function isNonHTMLText(placeholder) {
3876
3932
  if (isCoreTag(parentTag)) switch (parentTag.node.name.value) {
3877
3933
  case "html-comment":
3878
3934
  case "html-script":
3879
- case "html-style": return true;
3935
+ case "html-style":
3936
+ case "style": return true;
3880
3937
  }
3881
3938
  else if (isTextOnlyNativeTag(parentTag)) return true;
3882
3939
  }
@@ -3888,7 +3945,7 @@ function isTextOnlyNativeTag(tag) {
3888
3945
  }
3889
3946
  //#endregion
3890
3947
  //#region src/translator/core/for.ts
3891
- const kStatefulReason$1 = Symbol("<for> stateful reason");
3948
+ const kStatefulReason$2 = Symbol("<for> stateful reason");
3892
3949
  var for_default = {
3893
3950
  analyze(tag) {
3894
3951
  const tagSection = getOrCreateSection(tag);
@@ -3933,7 +3990,7 @@ var for_default = {
3933
3990
  }
3934
3991
  const nodeBinding = getOptimizedOnlyChildNodeBinding(tag, tagSection);
3935
3992
  const tagExtra = mergeReferences(tagSection, tag.node, getAllTagReferenceNodes(tag.node));
3936
- addSerializeExpr(tagSection, tagExtra, kStatefulReason$1);
3993
+ addSerializeExpr(tagSection, tagExtra, kStatefulReason$2);
3937
3994
  if (paramsBinding) {
3938
3995
  setBindingDownstream(paramsBinding, tagExtra);
3939
3996
  const byAttr = getKnownAttrValues(tag.node).by;
@@ -3985,6 +4042,7 @@ var for_default = {
3985
4042
  const singleChild = bodySection.content?.singleChild && bodySection.content.startType !== 4;
3986
4043
  const branchSerializeReason = getSerializeReason(bodySection, kBranchSerializeReason);
3987
4044
  const markerSerializeReason = getSerializeReason(tagSection, nodeBinding);
4045
+ if (isStateSerializeReason(getSerializeReason(tagSection, kStatefulReason$2)) && isStaticSerializeReason(branchSerializeReason) && isStaticSerializeReason(markerSerializeReason)) setSectionOwnerResumedByMarker(bodySection);
3988
4046
  flushInto(tag);
3989
4047
  writeHTMLResumeStatements(tagBody);
3990
4048
  const forTagArgs = getBaseArgsInForTag(forType, forAttrs);
@@ -3992,7 +4050,7 @@ var for_default = {
3992
4050
  forTagArgs.push(_marko_compiler.types.arrowFunctionExpression(params, _marko_compiler.types.blockStatement(bodyStatements)));
3993
4051
  if (branchSerializeReason) {
3994
4052
  const skipParentEnd = onlyChildParentTagName && markerSerializeReason;
3995
- const statefulSerializeArg = getSerializeGuard(tagSection, getSerializeReason(tagSection, kStatefulReason$1), !(skipParentEnd || singleChild));
4053
+ const statefulSerializeArg = getSerializeGuard(tagSection, getSerializeReason(tagSection, kStatefulReason$2), !(skipParentEnd || singleChild));
3996
4054
  const markerSerializeArg = getSerializeGuard(tagSection, markerSerializeReason, !statefulSerializeArg);
3997
4055
  forTagArgs.push(forAttrs.by || _marko_compiler.types.numericLiteral(0), getScopeIdIdentifier(tagSection), getScopeAccessorLiteral(nodeBinding), getSerializeGuard(tagSection, branchSerializeReason, !markerSerializeArg), markerSerializeArg, statefulSerializeArg);
3998
4056
  if (skipParentEnd) {
@@ -4477,6 +4535,7 @@ var native_tag_default = {
4477
4535
  if (isEventOrChangeHandler(attr.name)) assertNativeHandlerAttr(tag, attr);
4478
4536
  if (isEventHandler(attr.name)) {
4479
4537
  valueExtra.isEffect = true;
4538
+ valueExtra.invokeOnly = true;
4480
4539
  hasEventHandlers = true;
4481
4540
  } else {
4482
4541
  assertValidNativeEventHandlerAttr(tag, attr);
@@ -4516,6 +4575,7 @@ var native_tag_default = {
4516
4575
  }
4517
4576
  const spreadExtra = mergeReferences(tagSection, tag.node, spreadReferenceNodes);
4518
4577
  spreadExtra.nativeTagSpread = true;
4578
+ spreadExtra.invokeOnly = true;
4519
4579
  if (isMergedSpread) spreadExtra.nativeTagSpreadMerged = true;
4520
4580
  let carveProperties = getSpreadControllableValueProps(tagName);
4521
4581
  if (!tag.node.body.body.length && !isTextOnly && !(0, _marko_compiler_babel_utils.getTagDef)(tag)?.parseOptions?.openTagOnly && !seen.content) if (carveProperties) carveProperties.push("content");
@@ -4531,7 +4591,16 @@ var native_tag_default = {
4531
4591
  }
4532
4592
  } else relatedControllable = getRelatedControllable(tagName, seen);
4533
4593
  if (relatedControllable) mergeReferences(tagSection, relatedControllable.attrs.find(Boolean).value, relatedControllable.attrs.map((it) => it?.value));
4534
- if (textPlaceholders) exprExtras = push(exprExtras, textPlaceholders.length === 1 ? textPlaceholders[0].extra ??= {} : mergeReferences(tagSection, textPlaceholders[0], textPlaceholders.slice(1)));
4594
+ if (textPlaceholders) {
4595
+ exprExtras = push(exprExtras, textPlaceholders.length === 1 ? textPlaceholders[0].extra ??= {} : mergeReferences(tagSection, textPlaceholders[0], textPlaceholders.slice(1)));
4596
+ addSetupExpr(tagSection, textPlaceholders[0]);
4597
+ }
4598
+ if (injectNonce) addSetupStatement(tagSection);
4599
+ if (relatedControllable?.attrs[1]) addSetupStatement(tagSection);
4600
+ for (const name in seen) {
4601
+ const attr = seen[name];
4602
+ if (isEventHandler(name) || name === "content" || !evaluate(attr.value).confident) addSetupExpr(tagSection, attr.value);
4603
+ }
4535
4604
  addSerializeExpr(tagSection, !!(node.var || hasEventHandlers), nodeBinding);
4536
4605
  trackDomVarReferences(tag, nodeBinding);
4537
4606
  addSerializeExpr(tagSection, push(exprExtras, tagExtra), nodeBinding);
@@ -5117,7 +5186,7 @@ function toFirstStatementOrBlock(body) {
5117
5186
  }
5118
5187
  //#endregion
5119
5188
  //#region src/translator/core/if.ts
5120
- const kStatefulReason = Symbol("<if> stateful reason");
5189
+ const kStatefulReason$1 = Symbol("<if> stateful reason");
5121
5190
  const BRANCHES_LOOKUP = /* @__PURE__ */ new WeakMap();
5122
5191
  const IfTag = {
5123
5192
  analyze(tag) {
@@ -5142,7 +5211,7 @@ const IfTag = {
5142
5211
  if (branchTag.node.attributes.length) mergeReferenceNodes.push(branchTag.node.attributes[0].value);
5143
5212
  }
5144
5213
  mergeReferences(ifTagSection, ifTag.node, mergeReferenceNodes);
5145
- addSerializeExpr(ifTagSection, ifTagExtra, kStatefulReason);
5214
+ addSerializeExpr(ifTagSection, ifTagExtra, kStatefulReason$1);
5146
5215
  }
5147
5216
  },
5148
5217
  translate: translateByTarget({
@@ -5160,7 +5229,11 @@ const IfTag = {
5160
5229
  exit(tag) {
5161
5230
  if (tag.node.body.attributeTags) return;
5162
5231
  const tagBody = tag.get("body");
5163
- if (getSectionForBody(tagBody)) {
5232
+ const bodySection = getSectionForBody(tagBody);
5233
+ if (bodySection) {
5234
+ const [[ifTag]] = getBranches(tag);
5235
+ const ifTagSection = getSection(ifTag);
5236
+ if (isStateSerializeReason(getSerializeReason(ifTagSection, kStatefulReason$1)) && isStaticSerializeReason(getSerializeReason(bodySection, kBranchSerializeReason)) && isStaticSerializeReason(getSerializeReason(ifTagSection, getOptimizedOnlyChildNodeBinding(ifTag, ifTagSection)))) setSectionOwnerResumedByMarker(bodySection);
5164
5237
  flushInto(tag);
5165
5238
  writeHTMLResumeStatements(tagBody);
5166
5239
  }
@@ -5200,7 +5273,7 @@ const IfTag = {
5200
5273
  if (branchSerializeReasons) {
5201
5274
  const skipParentEnd = onlyChildParentTagName && markerSerializeReason;
5202
5275
  if (skipParentEnd) getParentTag(ifTag).node.extra[kSkipEndTag] = true;
5203
- const statefulSerializeArg = getSerializeGuard(ifTagSection, getSerializeReason(ifTagSection, kStatefulReason), !(skipParentEnd || singleChild));
5276
+ const statefulSerializeArg = getSerializeGuard(ifTagSection, getSerializeReason(ifTagSection, kStatefulReason$1), !(skipParentEnd || singleChild));
5204
5277
  const markerSerializeArg = getSerializeGuard(ifTagSection, markerSerializeReason, !statefulSerializeArg);
5205
5278
  const cbNode = _marko_compiler.types.arrowFunctionExpression([], _marko_compiler.types.blockStatement([statement]));
5206
5279
  statement = _marko_compiler.types.expressionStatement(callRuntime("_if", cbNode, getScopeIdIdentifier(ifTagSection), getScopeAccessorLiteral(nodeBinding), getSerializeGuardForAny(ifTagSection, branchSerializeReasons, !markerSerializeArg), markerSerializeArg, statefulSerializeArg, skipParentEnd ? _marko_compiler.types.stringLiteral(`</${onlyChildParentTagName}>`) : singleChild ? _marko_compiler.types.numericLiteral(0) : void 0, singleChild ? _marko_compiler.types.numericLiteral(1) : void 0));
@@ -5312,14 +5385,14 @@ function assertValidCondition(tag) {
5312
5385
  (0, _marko_compiler_babel_utils.assertNoVar)(tag);
5313
5386
  (0, _marko_compiler_babel_utils.assertNoArgs)(tag);
5314
5387
  (0, _marko_compiler_babel_utils.assertNoParams)(tag);
5315
- assertHasBody(tag);
5388
+ assertHasBody$1(tag);
5316
5389
  assertNoSpreadAttrs(tag);
5317
5390
  switch (getTagName(tag)) {
5318
5391
  case "if":
5319
- assertHasValueAttribute(tag);
5392
+ assertHasValueAttribute$1(tag);
5320
5393
  break;
5321
5394
  case "else-if":
5322
- assertHasValueAttribute(tag);
5395
+ assertHasValueAttribute$1(tag);
5323
5396
  assertHasPrecedingCondition(tag);
5324
5397
  break;
5325
5398
  case "else":
@@ -5333,10 +5406,10 @@ function assertHasPrecedingCondition(tag) {
5333
5406
  while (prev.node && prev.isMarkoComment()) prev = prev.getPrevSibling();
5334
5407
  if (!isConditionTag(prev) || getTagName(prev) === "else" && !prev.node.attributes.length) throw tag.buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#if--else) must have a preceding \`<if=cond>\` or \`<else if=cond>\`.`);
5335
5408
  }
5336
- function assertHasBody(tag) {
5409
+ function assertHasBody$1(tag) {
5337
5410
  if (!(tag.node.body.body.length || tag.node.attributeTags.length)) throw tag.get("name").buildCodeFrameError(`The [\`${getTagName(tag)}\` tag](https://markojs.com/docs/reference/core-tag#if--else) requires [body content](https://markojs.com/docs/reference/language#tag-content).`);
5338
5411
  }
5339
- function assertHasValueAttribute(tag) {
5412
+ function assertHasValueAttribute$1(tag) {
5340
5413
  const { node } = tag;
5341
5414
  const [valueAttr] = node.attributes;
5342
5415
  if (!_marko_compiler.types.isMarkoAttribute(valueAttr) || !valueAttr.default) throw tag.get("name").buildCodeFrameError(`The [\`${getTagName(tag)}\` tag](https://markojs.com/docs/reference/core-tag#if--else) requires a [\`value=\` attribute](https://markojs.com/docs/reference/language#shorthand-value).`);
@@ -5662,6 +5735,8 @@ var program_default = {
5662
5735
  const programExtra = program.node.extra;
5663
5736
  const paramsBinding = programExtra.binding;
5664
5737
  if (paramsBinding && !paramsBinding.pruned) programExtra.domExports.params = getBindingPropTree(paramsBinding);
5738
+ const section = programExtra.section;
5739
+ if (!section.hoistedTo && !sectionHasSetupStatements(section)) programExtra.domExports.setupEmpty = true;
5665
5740
  }
5666
5741
  },
5667
5742
  translate: {
@@ -5674,7 +5749,7 @@ var program_default = {
5674
5749
  const isDOMPageEntry = output === "dom" && entry === "page" || output === "hydrate";
5675
5750
  const isServerEntry = output === "html" && entry === "page";
5676
5751
  if (entry && !markoOpts.linkAssets) throw program.buildCodeFrameError("The \"entry\" option requires the `linkAssets` compiler option to be configured.");
5677
- if (runtimeId && !/^[_$a-z][_$a-z0-9]*$/i.test(runtimeId)) throw program.buildCodeFrameError(`Invalid runtimeId: "${runtimeId}". The runtimeId must be a valid JavaScript identifier.`);
5752
+ if (runtimeId && !/^[_a-z][_a-z0-9]*$/i.test(runtimeId)) throw program.buildCodeFrameError(`Invalid runtimeId: "${runtimeId}". The runtimeId must start with a letter or underscore and only contain letters, numbers, and underscores.`);
5678
5753
  if (isLoadEntry) {
5679
5754
  const entryFile = program.hub.file;
5680
5755
  const { filename } = entryFile.opts;
@@ -5836,6 +5911,7 @@ function knownTagAnalyze(tag, contentSection, propTree) {
5836
5911
  const varBinding = trackVarReferences(tag, 5);
5837
5912
  const exprs = tagExtra[kKnownExprs] = analyzeParams(tagExtra, section, tag, propTree, attrExprs);
5838
5913
  if (varBinding) {
5914
+ addSetupStatement(section);
5839
5915
  const mutatesTagVar = !!(tag.node.var.type === "Identifier" && tag.scope.getBinding(tag.node.var.name)?.constantViolations.length);
5840
5916
  const varExpr = tagExtra.defineBodySection ? contentSection.returnValueExpr : mapParamReasonToExpr(exprs, contentSection.returnSerializeReason && (contentSection.returnSerializeReason === true || !!contentSection.returnSerializeReason.state || contentSection.returnSerializeReason.param));
5841
5917
  varBinding.scopeOffset = tagExtra[kChildOffsetScopeBinding$1] = createBinding("#scopeOffset", 0, section);
@@ -5872,6 +5948,8 @@ function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
5872
5948
  childSerializeReasonExpr = reason && getSerializeGuard(section, reason, false);
5873
5949
  } else {
5874
5950
  const props = [];
5951
+ let bitmask = 0;
5952
+ let bitmaskNames = "";
5875
5953
  let hasDynamicReasons = false;
5876
5954
  let hasSkippedReasons = false;
5877
5955
  for (let i = 0; i < contentSection.paramReasonGroups.length; i++) {
@@ -5879,10 +5957,16 @@ function knownTagTranslateHTML(tag, tagIdentifier, contentSection, propTree) {
5879
5957
  const reason = getSerializeReason(section, childScopeBinding, group.id);
5880
5958
  if (reason) {
5881
5959
  hasDynamicReasons ||= reason !== true && !reason.state;
5882
- props.push(_marko_compiler.types.objectProperty(withLeadingComment(_marko_compiler.types.numericLiteral(i), getDebugNames(group.reason)), getSerializeGuard(section, reason, false)));
5960
+ const guard = getSerializeGuard(section, reason, false);
5961
+ if (bitmask >= 0) if (guard.type === "NumericLiteral" && guard.value === 1 && i < 30) {
5962
+ bitmask |= 1 << i + 1;
5963
+ const names = getDebugNames(group.reason);
5964
+ if (names) bitmaskNames += bitmaskNames ? ` | ${names}` : names;
5965
+ } else bitmask = -1;
5966
+ props.push(_marko_compiler.types.objectProperty(withLeadingComment(_marko_compiler.types.numericLiteral(i), getDebugNames(group.reason)), guard));
5883
5967
  } else hasSkippedReasons = true;
5884
5968
  }
5885
- if (props.length) childSerializeReasonExpr = hasDynamicReasons || hasSkippedReasons ? _marko_compiler.types.objectExpression(props) : _marko_compiler.types.numericLiteral(1);
5969
+ if (props.length) childSerializeReasonExpr = !(hasDynamicReasons || hasSkippedReasons) ? _marko_compiler.types.numericLiteral(1) : bitmask > 0 ? withLeadingComment(_marko_compiler.types.numericLiteral(bitmask), bitmaskNames) : _marko_compiler.types.objectExpression(props);
5886
5970
  }
5887
5971
  if (childSerializeReasonExpr) tag.insertBefore(_marko_compiler.types.expressionStatement(callRuntime("_set_serialize_reason", childSerializeReasonExpr)));
5888
5972
  }
@@ -5911,7 +5995,7 @@ function knownTagTranslateDOM(tag, propTree, getBindingIdentifier, callSetup) {
5911
5995
  };
5912
5996
  addStatement("render", tagSection, void 0, _marko_compiler.types.expressionStatement(callRuntime("_var", scopeIdentifier, getScopeAccessorLiteral(childScopeBinding, true), source.identifier)));
5913
5997
  }
5914
- callSetup(tagSection, childScopeBinding);
5998
+ callSetup?.(tagSection, childScopeBinding);
5915
5999
  if (propTree) writeParamsToSignals(tag, propTree, getTagName(tag) || "tag", {
5916
6000
  tagSection,
5917
6001
  getBindingIdentifier,
@@ -5948,6 +6032,7 @@ function analyzeParams(rootTagExtra, section, tag, propTree, rootAttrExprs) {
5948
6032
  const argValueExtra = arg.extra ??= {};
5949
6033
  known[i++] = { value: argValueExtra };
5950
6034
  rootAttrExprs.add(argValueExtra);
6035
+ addSetupExpr(section, arg);
5951
6036
  }
5952
6037
  const attrPropsTree = propTree.props[i];
5953
6038
  if (attrPropsTree) known[i] = analyzeAttrs(rootTagExtra, section, tag, attrPropsTree, rootAttrExprs);
@@ -6048,6 +6133,7 @@ function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs) {
6048
6133
  else {
6049
6134
  remaining.delete("content");
6050
6135
  known.content = { value: void 0 };
6136
+ addSetupStatement(section);
6051
6137
  }
6052
6138
  }
6053
6139
  }
@@ -6072,7 +6158,9 @@ function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs) {
6072
6158
  remaining.delete(attr.name);
6073
6159
  known[attr.name] = { value: attrExtra };
6074
6160
  rootAttrExprs.add(attrExtra);
6161
+ addSetupExpr(section, attr.value);
6075
6162
  setBindingDownstream(templateExportAttr.binding, attrExtra);
6163
+ if (getRootSection(templateExportAttr.binding.section) !== (0, _marko_compiler_babel_utils.getProgram)().node.extra.section && isInvokeOnlyBinding(templateExportAttr.binding)) attrExtra.invokeOnly = true;
6076
6164
  if (knownSpread && !includes(knownSpread.binding.excludeProperties, attr.name)) addRead(attrExtra, {}, getOrCreatePropertyAlias(knownSpread.binding, attr.name), section, void 0);
6077
6165
  }
6078
6166
  } else if (spreadReferenceNodes) spreadReferenceNodes.push(attr.value);
@@ -6095,9 +6183,13 @@ function analyzeAttrs(rootTagExtra, section, tag, propTree, rootAttrExprs) {
6095
6183
  inputExpr.value = mergeReferences(section, tag.node, spreadReferenceNodes);
6096
6184
  setBindingDownstream(propTree.rest?.binding || propTree.binding, inputExpr.value);
6097
6185
  } else dropNodes(spreadReferenceNodes);
6098
- else if (restReferenceNodes) {
6099
- inputExpr.value = mergeReferences(section, tag.node, restReferenceNodes);
6100
- setBindingDownstream(propTree.rest.binding, inputExpr.value);
6186
+ else {
6187
+ if (restReferenceNodes) {
6188
+ inputExpr.value = mergeReferences(section, tag.node, restReferenceNodes);
6189
+ setBindingDownstream(propTree.rest.binding, inputExpr.value);
6190
+ }
6191
+ if (remaining.size) addSetupStatement(section);
6192
+ if (propTree.rest && !propTree.rest.props) addSetupExpr(section, tag.node);
6101
6193
  }
6102
6194
  dropNodes(dropReferenceNodes);
6103
6195
  return inputExpr;
@@ -6380,6 +6472,10 @@ function isSimpleReference(expr) {
6380
6472
  default: return false;
6381
6473
  }
6382
6474
  }
6475
+ function getRootSection(section) {
6476
+ while (section.parent) section = section.parent;
6477
+ return section;
6478
+ }
6383
6479
  //#endregion
6384
6480
  //#region src/translator/util/references.ts
6385
6481
  const kBranchSerializeReason = Symbol("branch serialize reason");
@@ -6418,7 +6514,8 @@ function createBinding(name, type, refSection, upstreamAlias, property, excludeP
6418
6514
  directContentExport: void 0,
6419
6515
  nullable: !sameSection || excludeProperties === void 0,
6420
6516
  pruned: void 0,
6421
- exposed: false
6517
+ exposed: false,
6518
+ forcePersist: false
6422
6519
  };
6423
6520
  if (property) {
6424
6521
  if (declared) upstreamAlias.nullable = false;
@@ -6647,6 +6744,7 @@ function mergeReferences(section, target, nodes) {
6647
6744
  for (const node of nodes) {
6648
6745
  if (!node) continue;
6649
6746
  const extra = node.extra ??= {};
6747
+ if (extra === targetExtra) continue;
6650
6748
  extra.merged = targetExtra;
6651
6749
  if (isReferencedExtra(extra)) {
6652
6750
  const additionalReads = readsByExpression.get(extra);
@@ -6694,6 +6792,11 @@ function finalizeReferences() {
6694
6792
  for (const [expr, reads] of readsByExpression) if (isReferencedExtra(expr)) {
6695
6793
  const exprBindings = resolveReferencedBindings(expr, reads, intersectionsBySection);
6696
6794
  expr.referencedBindings = exprBindings.referencedBindings;
6795
+ expr.lazyBindings = exprBindings.lazyBindings;
6796
+ if (!exprBindings.referencedBindings) addSetupStatement(expr.section);
6797
+ forEach(exprBindings.lazyBindings, (binding) => {
6798
+ binding.forcePersist = true;
6799
+ });
6697
6800
  if (exprBindings.hoistedBindings) expr.section.referencedHoists = bindingUtil.union(expr.section.referencedHoists, exprBindings.hoistedBindings);
6698
6801
  if (expr.isEffect) {
6699
6802
  forEach(exprBindings.referencedBindings, (binding) => {
@@ -6702,12 +6805,15 @@ function finalizeReferences() {
6702
6805
  forEach(exprBindings.constantBindings, (binding) => {
6703
6806
  addSerializeReason(binding.section, true, binding);
6704
6807
  });
6808
+ forEach(exprBindings.lazyBindings, (binding) => {
6809
+ addSerializeReason(binding.section, true, binding);
6810
+ });
6705
6811
  }
6706
6812
  if (exprBindings.allBindings) {
6707
6813
  const exprFnReads = fnReadsByExpression.get(expr);
6708
6814
  if (exprFnReads) for (const [fn, fnReads] of exprFnReads) {
6709
6815
  const fnBindings = fn === expr ? exprBindings : resolveReferencedBindingsInFunction(exprBindings.allBindings, fnReads);
6710
- fn.referencedBindingsInFunction = fnBindings.referencedBindings;
6816
+ fn.referencedBindingsInFunction = fn === expr ? bindingUtil.union(fnBindings.referencedBindings, exprBindings.lazyBindings) : fnBindings.referencedBindings;
6711
6817
  fn.constantBindingsInFunction = fnBindings.constantBindings;
6712
6818
  }
6713
6819
  }
@@ -6755,14 +6861,19 @@ function finalizeReferences() {
6755
6861
  }
6756
6862
  }
6757
6863
  section.bindings = bindingUtil.add(section.bindings, getCanonicalBinding(binding));
6758
- for (const { isEffect, section } of binding.reads) if (section.depth > binding.section.depth) {
6759
- if (binding.type === 4) section.referencedLocalClosures = bindingUtil.add(section.referencedLocalClosures, binding);
6760
- else if (binding.type !== 0) {
6761
- const canonicalUpstreamAlias = getCanonicalBinding(binding);
6762
- canonicalUpstreamAlias.closureSections = sectionUtil.add(canonicalUpstreamAlias.closureSections, section);
6763
- section.referencedClosures = bindingUtil.add(section.referencedClosures, canonicalUpstreamAlias);
6764
- setReadsOwner(section, canonicalUpstreamAlias.section);
6765
- addOwnerSerializeReason(section, canonicalUpstreamAlias.section, !!isEffect || canonicalUpstreamAlias.sources);
6864
+ for (const exprExtra of binding.reads) {
6865
+ const { isEffect, section } = exprExtra;
6866
+ if (section.depth > binding.section.depth) {
6867
+ if (binding.type === 4) section.referencedLocalClosures = bindingUtil.add(section.referencedLocalClosures, binding);
6868
+ else if (binding.type !== 0) {
6869
+ const canonicalUpstreamAlias = getCanonicalBinding(binding);
6870
+ if (!bindingUtil.has(exprExtra.lazyBindings, binding)) {
6871
+ canonicalUpstreamAlias.closureSections = sectionUtil.add(canonicalUpstreamAlias.closureSections, section);
6872
+ section.referencedClosures = bindingUtil.add(section.referencedClosures, canonicalUpstreamAlias);
6873
+ }
6874
+ setReadsOwner(section, canonicalUpstreamAlias.section);
6875
+ addOwnerSerializeReason(section, canonicalUpstreamAlias.section, !!isEffect || canonicalUpstreamAlias.sources);
6876
+ }
6766
6877
  }
6767
6878
  }
6768
6879
  }
@@ -7041,7 +7152,8 @@ function addRead(exprExtra, extra, binding, section, getter) {
7041
7152
  extra,
7042
7153
  getter,
7043
7154
  ownVar: false,
7044
- comparedTo: void 0
7155
+ comparedTo: void 0,
7156
+ deferred: false
7045
7157
  };
7046
7158
  binding.reads.add(exprExtra);
7047
7159
  exprExtra.section = section;
@@ -7079,6 +7191,7 @@ function addReadToExpression(root, binding, getter) {
7079
7191
  }
7080
7192
  if (root.parent.type === "MarkoSpreadAttribute") exprExtra.spreadFrom = binding;
7081
7193
  if (fnRoot) {
7194
+ read.deferred = fnRoot.node.type !== "ObjectMethod" || fnRoot.node.kind === "method";
7082
7195
  const fnReadsByExpr = getFunctionReadsByExpression();
7083
7196
  let exprFnReads = fnReadsByExpr.get(exprExtra);
7084
7197
  if (!exprFnReads) fnReadsByExpr.set(exprExtra, exprFnReads = /* @__PURE__ */ new Map());
@@ -7223,6 +7336,12 @@ function getReadReplacement(node, signal) {
7223
7336
  return replacement && withPreviousLocation(replacement, node);
7224
7337
  } else if (binding && node.type == "Identifier" && node.name !== binding.name) node.name = binding.name;
7225
7338
  }
7339
+ function isInvokeOnlyBinding(binding) {
7340
+ if (binding.assignmentSections || binding.hoists || binding.getters.size || binding.propertyAliases.size || binding.excludeProperties) return false;
7341
+ for (const expr of binding.reads) if (!expr.invokeOnly) return false;
7342
+ for (const alias of binding.aliases) if (!isInvokeOnlyBinding(alias)) return false;
7343
+ return true;
7344
+ }
7226
7345
  function hasNonConstantPropertyAlias(ref) {
7227
7346
  for (const alias of ref.propertyAliases.values()) if (alias.type !== 6) return true;
7228
7347
  return false;
@@ -7300,11 +7419,15 @@ function addBindingGetter(binding, { invoked, hoisted }) {
7300
7419
  if (hoisted || !binding.getters.has(binding.section)) binding.getters.set(hoisted, !invoked);
7301
7420
  }
7302
7421
  }
7422
+ function isLazyRead(expr, read, binding, isChangeHandlerRead) {
7423
+ return !!(expr.invokeOnly && read.deferred && !isChangeHandlerRead && !binding.upstreamAlias && binding.type !== 0 && binding.type !== 6 && (binding.type !== 4 || binding.section === expr.section));
7424
+ }
7303
7425
  function resolveReferencedBindings(expr, reads, intersectionsBySection) {
7304
7426
  let referencedBindings;
7305
7427
  let constantBindings;
7306
7428
  let hoistedBindings;
7307
7429
  let allBindings;
7430
+ let lazyBindings;
7308
7431
  if (Array.isArray(reads)) {
7309
7432
  const rootBindings = getRootBindings(reads);
7310
7433
  for (const read of reads) {
@@ -7319,14 +7442,16 @@ function resolveReferencedBindings(expr, reads, intersectionsBySection) {
7319
7442
  hoistedBindings = bindingUtil.add(hoistedBindings, binding);
7320
7443
  }
7321
7444
  } else {
7322
- if (extra.assignmentTo === binding) {
7445
+ const isChangeHandlerRead = extra.assignmentTo === binding;
7446
+ if (isChangeHandlerRead) {
7323
7447
  const upstreamRoot = binding.upstreamAlias && findClosestReference(binding.upstreamAlias, rootBindings);
7324
7448
  if (upstreamRoot) binding = upstreamRoot;
7325
7449
  } else {
7326
7450
  extra.section = expr.section;
7327
7451
  ({binding} = extra.read ??= resolveExpressionReference(rootBindings, binding));
7328
7452
  }
7329
- if (binding.type === 6) constantBindings = bindingUtil.add(constantBindings, binding);
7453
+ if (isLazyRead(expr, read, binding, isChangeHandlerRead)) lazyBindings = bindingUtil.add(lazyBindings, binding);
7454
+ else if (binding.type === 6) constantBindings = bindingUtil.add(constantBindings, binding);
7330
7455
  else if (binding.type !== 0) referencedBindings = bindingUtil.add(referencedBindings, binding);
7331
7456
  }
7332
7457
  allBindings = bindingUtil.add(allBindings, binding);
@@ -7342,12 +7467,20 @@ function resolveReferencedBindings(expr, reads, intersectionsBySection) {
7342
7467
  }
7343
7468
  } else {
7344
7469
  extra.read = createRead(binding, void 0, ownVar);
7345
- if (binding.type === 6) constantBindings = binding;
7470
+ if (isLazyRead(expr, reads, binding, extra.assignmentTo === binding)) lazyBindings = binding;
7471
+ else if (binding.type === 6) constantBindings = binding;
7346
7472
  else if (binding.type !== 0) referencedBindings = binding;
7347
7473
  }
7348
7474
  extra.section = expr.section;
7349
7475
  allBindings = binding;
7350
7476
  }
7477
+ if (lazyBindings) {
7478
+ let onlyLazy;
7479
+ forEach(lazyBindings, (binding) => {
7480
+ if (!bindingUtil.has(referencedBindings, binding)) onlyLazy = bindingUtil.add(onlyLazy, binding);
7481
+ });
7482
+ lazyBindings = onlyLazy;
7483
+ }
7351
7484
  if (Array.isArray(referencedBindings)) {
7352
7485
  const intersections = intersectionsBySection.get(expr.section) || [];
7353
7486
  const intersection = findSorted(compareIntersections, intersections, referencedBindings);
@@ -7363,7 +7496,8 @@ function resolveReferencedBindings(expr, reads, intersectionsBySection) {
7363
7496
  referencedBindings,
7364
7497
  constantBindings,
7365
7498
  hoistedBindings,
7366
- allBindings
7499
+ allBindings,
7500
+ lazyBindings
7367
7501
  };
7368
7502
  }
7369
7503
  function resolveExpressionReference(rootBindings, readBinding) {
@@ -7528,6 +7662,7 @@ var await_default = {
7528
7662
  const paramsBinding = trackParamsReferences(tagBody, 5);
7529
7663
  if (paramsBinding) setBindingDownstream(paramsBinding, valueExtra);
7530
7664
  bodySection.upstreamExpression = valueAttr.value.extra;
7665
+ addSetupStatement(section);
7531
7666
  },
7532
7667
  translate: translateByTarget({
7533
7668
  html: {
@@ -7635,7 +7770,10 @@ var const_default = {
7635
7770
  }
7636
7771
  }
7637
7772
  if (!valueExtra.nullable) binding.nullable = false;
7638
- if (!upstreamAlias) setBindingDownstream(binding, valueExtra);
7773
+ if (!upstreamAlias) {
7774
+ setBindingDownstream(binding, valueExtra);
7775
+ addSetupExpr(getOrCreateSection(tag), valueAttr.value);
7776
+ }
7639
7777
  }
7640
7778
  },
7641
7779
  translate: { exit(tag) {
@@ -7670,6 +7808,7 @@ var debug_default = {
7670
7808
  (0, _marko_compiler_babel_utils.assertNoParams)(tag);
7671
7809
  assertNoBodyContent(tag);
7672
7810
  if (tag.node.attributes.length > 1 || tag.node.attributes.length === 1 && (!_marko_compiler.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value")) throw tag.get("name").buildCodeFrameError("The [`<debug>` tag](https://markojs.com/docs/reference/core-tag#debug) only supports the [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value).");
7811
+ addSetupExpr(getOrCreateSection(tag), valueAttr?.value);
7673
7812
  },
7674
7813
  translate: { exit(tag) {
7675
7814
  const section = getSection(tag);
@@ -7919,6 +8058,7 @@ var id_default = {
7919
8058
  if (tag.node.attributes.length > 1 || tag.node.attributes.length === 1 && (!_marko_compiler.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value")) throw tag.get("name").buildCodeFrameError("The [`<id>` tag](https://markojs.com/docs/reference/core-tag#id) only supports the [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value).");
7920
8059
  const binding = trackVarReferences(tag, 5);
7921
8060
  if (binding) setBindingDownstream(binding, !!valueAttr && evaluate(valueAttr.value));
8061
+ addSetupExpr(getOrCreateSection(tag), valueAttr?.value);
7922
8062
  },
7923
8063
  translate: { exit(tag) {
7924
8064
  const { node } = tag;
@@ -7995,7 +8135,7 @@ var let_default = {
7995
8135
  const tagExtra = mergeReferences(tagSection, tag.node, [valueAttr?.value, valueChangeAttr?.value]);
7996
8136
  if (valueChangeAttr) {
7997
8137
  setBindingDownstream(binding, tagExtra);
7998
- addSerializeReason(tagSection, true, binding, getAccessorPrefix().TagVariableChange);
8138
+ if (binding.assignmentSections) addSerializeReason(tagSection, true, binding, getAccessorPrefix().TagVariableChange);
7999
8139
  } else setBindingDownstream(binding, false);
8000
8140
  },
8001
8141
  translate: { exit(tag) {
@@ -8077,6 +8217,7 @@ var log_default = {
8077
8217
  assertNoBodyContent(tag);
8078
8218
  if (!valueAttr) throw tag.get("name").buildCodeFrameError("The [`<log>` tag](https://markojs.com/docs/reference/core-tag#log) requires a [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value).");
8079
8219
  if (tag.node.attributes.length > 1 || !_marko_compiler.types.isMarkoAttribute(valueAttr) || !valueAttr.default && valueAttr.name !== "value") throw tag.get("name").buildCodeFrameError("The [`<log>` tag](https://markojs.com/docs/reference/core-tag#log) only supports the [`value=` attribute](https://markojs.com/docs/reference/language#shorthand-value).");
8220
+ addSetupExpr(getOrCreateSection(tag), valueAttr.value);
8080
8221
  },
8081
8222
  translate: { exit(tag) {
8082
8223
  const section = getSection(tag);
@@ -8131,6 +8272,7 @@ var script_default = {
8131
8272
  if (seenValueAttr) throw tag.hub.buildError(attr, "Invalid duplicate value attribute.");
8132
8273
  seenValueAttr = true;
8133
8274
  (attr.value.extra ??= {}).isEffect = true;
8275
+ addSetupExpr(getOrCreateSection(tag), attr.value);
8134
8276
  (0, _marko_compiler_babel_utils.getProgram)().node.extra.isInteractive = true;
8135
8277
  } else throw tag.hub.buildError(attr, "The [`<script>` tag](https://markojs.com/docs/reference/core-tag#script) does not support html attributes." + htmlScriptTagAlternateMsg);
8136
8278
  if (!seenValueAttr) dropNodes(getAllTagReferenceNodes(node));
@@ -8209,6 +8351,163 @@ var server_default = {
8209
8351
  }]
8210
8352
  };
8211
8353
  //#endregion
8354
+ //#region src/translator/core/show.ts
8355
+ const kStatefulReason = Symbol("<show> stateful reason");
8356
+ const kStartBinding = Symbol("<show> range start binding");
8357
+ const kStaticDisplay = Symbol("<show> static display");
8358
+ const kSingleNodeBody = Symbol("<show> single node body");
8359
+ const kDisplayRef = Symbol("<show> hoisted display reference");
8360
+ var show_default = {
8361
+ analyze: {
8362
+ enter(tag) {
8363
+ assertValidShow(tag);
8364
+ const tagExtra = tag.node.extra ??= {};
8365
+ const display = tag.node.attributes[0].value;
8366
+ const displayEval = evaluate(display);
8367
+ tagExtra[kSingleNodeBody] = isSingleNodeBody(tag);
8368
+ if (displayEval.confident) tagExtra[kStaticDisplay] = !!displayEval.computed;
8369
+ if (tagExtra[kStaticDisplay] === true) return;
8370
+ const tagSection = getOrCreateSection(tag);
8371
+ if (getOnlyChildParentTagName(tag)) getOptimizedOnlyChildNodeBinding(tag, tagSection);
8372
+ else tagExtra[kStartBinding] = createBinding("#text", 0, tagSection);
8373
+ if (tagExtra[kStaticDisplay] === void 0) {
8374
+ mergeReferences(tagSection, tag.node, [display]);
8375
+ addSerializeExpr(tagSection, tagExtra, kStatefulReason);
8376
+ } else addSetupStatement(tagSection);
8377
+ },
8378
+ exit(tag) {
8379
+ const tagExtra = tag.node.extra;
8380
+ if (tagExtra[kStaticDisplay] === true) return;
8381
+ const tagSection = getSection(tag);
8382
+ const nodeBinding = getOptimizedOnlyChildNodeBinding(tag, tagSection);
8383
+ if (tagExtra[kStaticDisplay] === void 0) addSerializeExpr(tagSection, tagExtra, nodeBinding);
8384
+ }
8385
+ },
8386
+ translate: translateByTarget({
8387
+ html: {
8388
+ enter(tag) {
8389
+ const tagExtra = tag.node.extra;
8390
+ flushBefore(tag);
8391
+ const staticDisplay = tagExtra[kStaticDisplay];
8392
+ if (staticDisplay === true) return;
8393
+ if (staticDisplay === false) {
8394
+ writeTo(tag)`<t hidden>`;
8395
+ return;
8396
+ }
8397
+ const display = tag.node.attributes[0].value;
8398
+ if (!_marko_compiler.types.isIdentifier(display) && !isLiteral(display)) {
8399
+ const displayRef = generateUidIdentifier("show");
8400
+ tag.insertBefore(_marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(displayRef, display)]));
8401
+ tagExtra[kDisplayRef] = displayRef;
8402
+ }
8403
+ },
8404
+ exit(tag) {
8405
+ const tagExtra = tag.node.extra;
8406
+ const staticDisplay = tagExtra[kStaticDisplay];
8407
+ if (staticDisplay === false) writeTo(tag)`</t>`;
8408
+ flushInto(tag);
8409
+ const bodyStatements = tag.node.body.body;
8410
+ if (staticDisplay !== void 0) {
8411
+ for (const replacement of tag.replaceWithMultiple(bodyStatements)) replacement.skip();
8412
+ return;
8413
+ }
8414
+ const tagSection = getSection(tag);
8415
+ const display = tagExtra[kDisplayRef] || tag.node.attributes[0].value;
8416
+ const nodeBinding = getOptimizedOnlyChildNodeBinding(tag, tagSection);
8417
+ const onlyChildParentTagName = getOnlyChildParentTagName(tag);
8418
+ const singleNode = tagExtra[kSingleNodeBody];
8419
+ const statefulReason = getSerializeReason(tagSection, kStatefulReason);
8420
+ const markerSerializeReason = getSerializeReason(tagSection, nodeBinding);
8421
+ const skipParentEnd = onlyChildParentTagName && markerSerializeReason;
8422
+ if (skipParentEnd) getParentTag(tag).node.extra[kSkipEndTag] = true;
8423
+ const statefulSerializeArg = getSerializeGuard(tagSection, statefulReason, !(skipParentEnd || singleNode));
8424
+ const markerSerializeArg = getSerializeGuard(tagSection, markerSerializeReason, !statefulSerializeArg);
8425
+ let startMark;
8426
+ if (!singleNode) {
8427
+ startMark = getSerializeGuard(tagSection, markerSerializeReason, false);
8428
+ if (skipParentEnd) startMark = _marko_compiler.types.logicalExpression("&&", startMark, getSerializeGuard(tagSection, statefulReason, false));
8429
+ }
8430
+ for (const replacement of tag.replaceWithMultiple([
8431
+ _marko_compiler.types.expressionStatement(callRuntime("_show_start", _marko_compiler.types.cloneNode(display, true), startMark)),
8432
+ ...bodyStatements,
8433
+ _marko_compiler.types.expressionStatement(callRuntime("_show_end", getScopeIdIdentifier(tagSection), getScopeAccessorLiteral(nodeBinding), display, markerSerializeArg, statefulSerializeArg, skipParentEnd ? _marko_compiler.types.stringLiteral(`</${onlyChildParentTagName}>`) : singleNode ? _marko_compiler.types.numericLiteral(0) : void 0, singleNode ? _marko_compiler.types.numericLiteral(1) : void 0))
8434
+ ])) replacement.skip();
8435
+ }
8436
+ },
8437
+ dom: {
8438
+ enter(tag) {
8439
+ if (tag.node.extra[kStartBinding]) {
8440
+ visit(tag, 37);
8441
+ enterShallow(tag);
8442
+ }
8443
+ },
8444
+ exit(tag) {
8445
+ const tagExtra = tag.node.extra;
8446
+ if (tagExtra[kStaticDisplay] === true) {
8447
+ tag.remove();
8448
+ return;
8449
+ }
8450
+ const tagSection = getSection(tag);
8451
+ const nodeBinding = getOptimizedOnlyChildNodeBinding(tag, tagSection);
8452
+ const startBinding = tagExtra[kStartBinding];
8453
+ const display = tagExtra[kStaticDisplay] === false ? _marko_compiler.types.booleanLiteral(false) : tag.node.attributes[0].value;
8454
+ if (startBinding) {
8455
+ visit(tag, 37);
8456
+ enterShallow(tag);
8457
+ }
8458
+ const signal = getSignal(tagSection, nodeBinding, "show");
8459
+ signal.build = () => {
8460
+ return callRuntime("_show", getScopeAccessorLiteral(nodeBinding, true), startBinding ? getScopeAccessorLiteral(startBinding, true) : void 0);
8461
+ };
8462
+ addValue(tagSection, tagExtra.referencedBindings, signal, display);
8463
+ tag.remove();
8464
+ }
8465
+ }
8466
+ }),
8467
+ parseOptions: { controlFlow: true },
8468
+ autocomplete: [{
8469
+ snippet: "show=${1:condition}",
8470
+ description: "Use to render content that is always mounted but only displayed when the condition is met.",
8471
+ descriptionMoreURL: "https://markojs.com/docs/reference/core-tag#show"
8472
+ }]
8473
+ };
8474
+ function isSingleNodeBody(tag) {
8475
+ let elements = 0;
8476
+ for (const child of tag.get("body").get("body")) {
8477
+ if (child.isMarkoComment()) continue;
8478
+ if (child.isMarkoTag() && analyzeTagNameType(child) === 0 && _marko_compiler.types.isStringLiteral(child.node.name)) elements++;
8479
+ else return false;
8480
+ }
8481
+ return elements === 1;
8482
+ }
8483
+ function isLiteral(expr) {
8484
+ switch (expr.type) {
8485
+ case "BooleanLiteral":
8486
+ case "NumericLiteral":
8487
+ case "StringLiteral":
8488
+ case "NullLiteral": return true;
8489
+ default: return false;
8490
+ }
8491
+ }
8492
+ function assertValidShow(tag) {
8493
+ (0, _marko_compiler_babel_utils.assertNoVar)(tag);
8494
+ (0, _marko_compiler_babel_utils.assertNoArgs)(tag);
8495
+ (0, _marko_compiler_babel_utils.assertNoParams)(tag);
8496
+ assertNoSpreadAttrs(tag);
8497
+ assertHasBody(tag);
8498
+ assertHasValueAttribute(tag);
8499
+ }
8500
+ function assertHasBody(tag) {
8501
+ if (!tag.node.body.body.length) throw tag.get("name").buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#show) requires [body content](https://markojs.com/docs/reference/language#tag-content).`);
8502
+ if (tag.node.body.attributeTags) throw tag.get("name").buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#show) does not support [attribute tags](https://markojs.com/docs/reference/language#attribute-tags).`);
8503
+ }
8504
+ function assertHasValueAttribute(tag) {
8505
+ const { node } = tag;
8506
+ const [valueAttr] = node.attributes;
8507
+ if (!_marko_compiler.types.isMarkoAttribute(valueAttr) || !valueAttr.default) throw tag.get("name").buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#show) requires a [\`value=\` attribute](https://markojs.com/docs/reference/language#shorthand-value).`);
8508
+ if (node.attributes.length > 1) throw tag.get("name").buildCodeFrameError(`The [\`<${getTagName(tag)}>\` tag](https://markojs.com/docs/reference/core-tag#show) only supports the [\`value=\` attribute](https://markojs.com/docs/reference/language#shorthand-value).`);
8509
+ }
8510
+ //#endregion
8212
8511
  //#region src/translator/core/static.ts
8213
8512
  var static_default = {
8214
8513
  parse(tag) {
@@ -8231,36 +8530,112 @@ var static_default = {
8231
8530
  }]
8232
8531
  };
8233
8532
  //#endregion
8533
+ //#region src/translator/util/style-interpolation.ts
8534
+ const htmlStyleTagAlternateMsg = " For a native html [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) use the `html-style` core tag instead.";
8535
+ function checkStyleInterpolations(tag) {
8536
+ const { body } = tag.node.body;
8537
+ let stringQuote = "";
8538
+ let inComment = false;
8539
+ let groupDepth = 0;
8540
+ let blockDepth = 0;
8541
+ let valueColon = false;
8542
+ let runPlaceholder;
8543
+ let runAfterColon = false;
8544
+ let runDecl = false;
8545
+ const endRun = (selector) => {
8546
+ if (runPlaceholder && !runAfterColon && (selector || runDecl)) throw tag.hub.buildError(runPlaceholder, selector ? styleSelectorMsg : stylePropertyMsg);
8547
+ valueColon = false;
8548
+ runPlaceholder = void 0;
8549
+ };
8550
+ for (let i = 0; i < body.length; i++) {
8551
+ const child = body[i];
8552
+ if (_marko_compiler.types.isMarkoPlaceholder(child)) {
8553
+ if (stringQuote) throw tag.hub.buildError(child, styleStringMsg);
8554
+ if (!runPlaceholder) {
8555
+ runPlaceholder = child;
8556
+ runAfterColon = valueColon;
8557
+ runDecl = blockDepth > 0;
8558
+ }
8559
+ const prev = body[i - 1];
8560
+ if (_marko_compiler.types.isMarkoText(prev) && cssGluedBefore.test(prev.value)) throw tag.hub.buildError(child, styleGluedBeforeMsg);
8561
+ const next = body[i + 1];
8562
+ if (_marko_compiler.types.isMarkoText(next) && cssGluedValue.test(next.value)) throw tag.hub.buildError(child, styleGluedMsg);
8563
+ continue;
8564
+ }
8565
+ const text = child.value;
8566
+ for (let j = 0; j < text.length; j++) {
8567
+ const c = text[j];
8568
+ if (inComment) {
8569
+ if (c === "*" && text[j + 1] === "/") {
8570
+ inComment = false;
8571
+ j++;
8572
+ }
8573
+ } else if (stringQuote) {
8574
+ if (c === "\\") j++;
8575
+ else if (c === stringQuote) stringQuote = "";
8576
+ } else if (c === "\\") j++;
8577
+ else if (c === "/" && text[j + 1] === "*") {
8578
+ inComment = true;
8579
+ j++;
8580
+ } else if (c === "\"" || c === "'") stringQuote = c;
8581
+ else if (c === "(" || c === "[") groupDepth++;
8582
+ else if (c === ")" || c === "]") {
8583
+ if (groupDepth) groupDepth--;
8584
+ } else if (!groupDepth) switch (c) {
8585
+ case ":":
8586
+ if (blockDepth) valueColon = true;
8587
+ break;
8588
+ case "{":
8589
+ endRun(true);
8590
+ blockDepth++;
8591
+ break;
8592
+ case ";":
8593
+ endRun(!blockDepth);
8594
+ break;
8595
+ case "}":
8596
+ endRun(false);
8597
+ if (blockDepth) blockDepth--;
8598
+ break;
8599
+ }
8600
+ }
8601
+ }
8602
+ endRun(!blockDepth);
8603
+ }
8604
+ const styleInterpolationMsg = "A `${...}` interpolation in a [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) is substituted as a `var(--…)` custom property reference, which";
8605
+ const styleSelectorMsg = `${styleInterpolationMsg} only resolves in a declaration value, not in a selector or at-rule prelude. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
8606
+ const stylePropertyMsg = `${styleInterpolationMsg} cannot be used as a property name. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
8607
+ const styleStringMsg = `${styleInterpolationMsg} is not substituted inside a quoted CSS string — the literal text \`var(--…)\` would be rendered instead of the value. For a native html [\`<style>\` tag](https://markojs.com/docs/reference/core-tag#style) use the \`html-style\` core tag instead.`;
8608
+ const styleGluedMsg = `${styleInterpolationMsg} CSS does not re-tokenize, so a unit written directly after it (eg \`\${x}px\`) becomes the invalid \`var(--…)px\`. Move the unit into the interpolated value (so it resolves to eg \`"10px"\`) or use \`calc(var(--…) * 1px)\`.`;
8609
+ const styleGluedBeforeMsg = `${styleInterpolationMsg} CSS does not re-tokenize, so text written directly before it (eg \`10\${x}\`) merges with the \`var(--…)\` into a single invalid token. Add whitespace before the interpolation or move the text into the interpolated value.`;
8610
+ const cssGluedValue = /^(?:[%.\d]|(?:p[xtc]|in|[cm]m|q|r?em|ex|ch|r?lh|v[whib]|vmin|vmax|fr|deg|g?rad|turn|m?s|k?hz|dp(?:i|cm|px)|cq[whib]|cqmin|cqmax)(?![\w-]))/i;
8611
+ const cssGluedBefore = /[\w%]$/;
8612
+ //#endregion
8234
8613
  //#region src/translator/core/style.ts
8235
8614
  const STYLE_EXT_REG = /^style((?:\.[a-zA-Z0-9$_-]+)+)?/;
8236
- const htmlStyleTagAlternateMsg = " For a native html [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) use the `html-style` core tag instead.";
8237
8615
  var style_default = {
8238
8616
  analyze(tag) {
8239
8617
  (0, _marko_compiler_babel_utils.assertNoArgs)(tag);
8240
8618
  (0, _marko_compiler_babel_utils.assertNoParams)(tag);
8241
8619
  (0, _marko_compiler_babel_utils.assertNoAttributeTags)(tag);
8242
8620
  const { node, hub: { file } } = tag;
8243
- const extClass = (STYLE_EXT_REG.exec(node.rawValue || "")?.[1]?.slice(1))?.replace(/\./g, " ");
8244
- for (const attr of node.attributes) {
8245
- if (attr.start == null && attr.type === "MarkoAttribute" && attr.name === "class" && attr.value.type === "StringLiteral" && attr.value.value === extClass) continue;
8246
- throw tag.hub.buildError(attr.value, "The `style` does not support html attributes." + htmlStyleTagAlternateMsg);
8621
+ assertNoStyleAttributes(tag);
8622
+ const names = collectDynamicStyleNames(tag);
8623
+ if (names) {
8624
+ checkStyleInterpolations(tag);
8625
+ checkDynamicStylePlacement(tag);
8247
8626
  }
8248
- for (const child of node.body.body) if (child.type !== "MarkoText") throw tag.hub.buildError(child, "The [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) currently only supports static content." + htmlStyleTagAlternateMsg);
8249
- const importPath = getStyleImportPath(file, node);
8627
+ const importPath = getStyleImportPath(file, node, names);
8250
8628
  (node.extra ??= {}).styleImportPath = importPath;
8251
8629
  if (importPath) addAssetImport(file, importPath);
8252
- },
8253
- translate(tag) {
8254
- const { node, hub: { file } } = tag;
8255
- const importPath = node.extra?.styleImportPath;
8256
- if (importPath) if (!node.var) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(importPath)));
8257
- else if (_marko_compiler.types.isIdentifier(node.var)) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.importDeclaration([_marko_compiler.types.importNamespaceSpecifier(node.var)], _marko_compiler.types.stringLiteral(importPath)));
8258
- else {
8259
- const varDecl = _marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(node.var, (0, _marko_compiler_babel_utils.importStar)(file, importPath, "style"))]);
8260
- (0, _marko_compiler_babel_utils.getProgram)().node.body.push(isOutputDOM() ? varDecl : _marko_compiler.types.markoScriptlet([varDecl], true));
8630
+ if (names) {
8631
+ analyzeDynamicStyle(tag, names);
8632
+ addSetupStatement(getOrCreateSection(tag));
8261
8633
  }
8262
- tag.remove();
8263
8634
  },
8635
+ translate: translateByTarget({
8636
+ html: { exit: translateHTML$1 },
8637
+ dom: { exit: translateDOM$1 }
8638
+ }),
8264
8639
  parseOptions: {
8265
8640
  html: false,
8266
8641
  text: true,
@@ -8269,34 +8644,154 @@ var style_default = {
8269
8644
  },
8270
8645
  attributes: {}
8271
8646
  };
8647
+ function analyzeDynamicStyle(tag, names) {
8648
+ const { node } = tag;
8649
+ const section = getOrCreateSection(tag);
8650
+ const binding = createBinding("#style", 0, section);
8651
+ node.extra.dynamicStyle = {
8652
+ names,
8653
+ binding
8654
+ };
8655
+ let exprExtras = mergeReferences(section, node, []);
8656
+ for (const value of dynamicStyleValues(node)) exprExtras = push(exprExtras, value.extra ??= {});
8657
+ addSerializeExpr(section, exprExtras, binding);
8658
+ }
8659
+ function collectDynamicStyleNames(tag) {
8660
+ let names;
8661
+ let index = 0;
8662
+ for (const child of tag.node.body.body) if (_marko_compiler.types.isMarkoPlaceholder(child)) {
8663
+ if (!names) {
8664
+ names = [];
8665
+ index = dynamicStyleNameOffset(tag);
8666
+ }
8667
+ names.push(dynamicStyleName(tag, index++));
8668
+ } else if (!_marko_compiler.types.isMarkoText(child)) throw tag.hub.buildError(child, "The [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) only supports text and `${...}` interpolations." + htmlStyleTagAlternateMsg);
8669
+ return names;
8670
+ }
8671
+ function dynamicStyleNameOffset(tag) {
8672
+ const { start } = tag.node;
8673
+ let offset = 0;
8674
+ if (start != null) _marko_compiler.types.traverseFast((0, _marko_compiler_babel_utils.getProgram)().node, (node) => {
8675
+ const dynamicStyle = node.extra?.dynamicStyle;
8676
+ if (dynamicStyle && node.start != null && node.start < start) offset += dynamicStyle.names.length;
8677
+ });
8678
+ return offset;
8679
+ }
8680
+ const styleNameUnsafeReg = /[^a-zA-Z0-9_]/g;
8681
+ const encodeStyleNameChar = (c) => "-" + c.charCodeAt(0).toString(36);
8682
+ function dynamicStyleName(tag, index) {
8683
+ const { file } = tag.hub;
8684
+ const id = (0, _marko_compiler_babel_utils.getTemplateId)(file.markoOpts, file.opts.filename, index.toString(36));
8685
+ return "--" + ((file.markoOpts.runtimeId || "M_") + id).replace(styleNameUnsafeReg, encodeStyleNameChar);
8686
+ }
8687
+ function checkDynamicStylePlacement(tag) {
8688
+ for (const sibling of tag.getAllPrevSiblings()) {
8689
+ if (isCoreTagName(sibling, "style")) continue;
8690
+ if (sibling.isMarkoText() ? /\S/.test(sibling.node.value) : getNodeContentType(sibling, "startType") !== null) {
8691
+ (0, _marko_compiler_babel_utils.diagnosticWarn)(tag, { label: "The `${...}` values of a [`<style>` tag](https://markojs.com/docs/reference/core-tag#style) only apply to elements rendered after it, so the content before this tag will not receive them. Move the `<style>` tag above the content it styles." });
8692
+ return;
8693
+ }
8694
+ }
8695
+ }
8696
+ function assertNoStyleAttributes(tag) {
8697
+ const { node } = tag;
8698
+ const extClass = (STYLE_EXT_REG.exec(node.rawValue || "")?.[1]?.slice(1))?.replace(/\./g, " ");
8699
+ for (const attr of node.attributes) {
8700
+ if (attr.start == null && attr.type === "MarkoAttribute" && attr.name === "class" && attr.value.type === "StringLiteral" && attr.value.value === extClass) continue;
8701
+ throw tag.hub.buildError(attr.value, "The `style` does not support html attributes." + htmlStyleTagAlternateMsg);
8702
+ }
8703
+ }
8704
+ function translateHTML$1(tag) {
8705
+ const { node } = tag;
8706
+ const dynamic = node.extra?.dynamicStyle;
8707
+ if (dynamic) {
8708
+ const { binding } = dynamic;
8709
+ const section = getSection(tag);
8710
+ writeTo(tag)`${callRuntime("_style_html", buildStyleDecls(node))}`;
8711
+ markNode(tag, binding, getSerializeReason(section, binding));
8712
+ }
8713
+ emitStyleImport(tag);
8714
+ tag.remove();
8715
+ }
8716
+ function translateDOM$1(tag) {
8717
+ const { node } = tag;
8718
+ const dynamic = node.extra?.dynamicStyle;
8719
+ if (dynamic) {
8720
+ const { names, binding } = dynamic;
8721
+ const section = getSection(tag);
8722
+ const write = writeTo(tag);
8723
+ const readEl = () => createScopeReadExpression(binding);
8724
+ visit(tag, 32);
8725
+ write`<style>`;
8726
+ addStatement("render", section, void 0, _marko_compiler.types.expressionStatement(callRuntime("_style_shell", scopeIdentifier, getScopeAccessorLiteral(binding))), void 0, true);
8727
+ dynamicStyleValues(node).forEach((value, i) => {
8728
+ const valueRef = value.extra?.referencedBindings;
8729
+ addStatement("render", section, valueRef, _marko_compiler.types.expressionStatement(callRuntime("_style_rule_item", readEl(), _marko_compiler.types.stringLiteral(names[i]), value)), void 0, !valueRef);
8730
+ });
8731
+ write`</style>`;
8732
+ }
8733
+ emitStyleImport(tag);
8734
+ tag.remove();
8735
+ }
8736
+ function dynamicStyleValues(node) {
8737
+ const values = [];
8738
+ for (const child of node.body.body) if (_marko_compiler.types.isMarkoPlaceholder(child)) values.push(child.value);
8739
+ return values;
8740
+ }
8741
+ function emitStyleImport(tag) {
8742
+ const { node, hub: { file } } = tag;
8743
+ const importPath = node.extra?.styleImportPath;
8744
+ if (!importPath) return;
8745
+ if (!node.var) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.importDeclaration([], _marko_compiler.types.stringLiteral(importPath)));
8746
+ else if (_marko_compiler.types.isIdentifier(node.var)) (0, _marko_compiler_babel_utils.getProgram)().node.body.push(_marko_compiler.types.importDeclaration([_marko_compiler.types.importNamespaceSpecifier(node.var)], _marko_compiler.types.stringLiteral(importPath)));
8747
+ else {
8748
+ const varDecl = _marko_compiler.types.variableDeclaration("const", [_marko_compiler.types.variableDeclarator(node.var, (0, _marko_compiler_babel_utils.importStar)(file, importPath, "style"))]);
8749
+ (0, _marko_compiler_babel_utils.getProgram)().node.body.push(isOutputDOM() ? varDecl : _marko_compiler.types.markoScriptlet([varDecl], true));
8750
+ }
8751
+ }
8752
+ function buildStyleDecls(node) {
8753
+ const { names } = node.extra.dynamicStyle;
8754
+ const parts = [];
8755
+ dynamicStyleValues(node).forEach((value, i) => {
8756
+ parts.push(`${names[i]}:`);
8757
+ parts.push(callRuntime("_escape_style_value", value));
8758
+ parts.push(";");
8759
+ });
8760
+ return normalizeStringExpression(parts);
8761
+ }
8272
8762
  /**
8273
8763
  * Resolves a `<style>` block's text content to its client side import path
8274
8764
  * (eg `./template.marko.css`) by handing the css off to the configured
8275
8765
  * `resolveVirtualDependency` hook.
8276
8766
  */
8277
- function getStyleImportPath(file, node) {
8767
+ function getStyleImportPath(file, node, names) {
8278
8768
  const { resolveVirtualDependency } = file.markoOpts;
8279
8769
  if (!resolveVirtualDependency) return;
8280
8770
  const { filename, sourceMaps } = file.opts;
8281
8771
  let ext = STYLE_EXT_REG.exec(node.rawValue || "")?.[1] || ".css";
8282
8772
  if (node.var && !/\.module\./.test(ext)) ext = ".module" + ext;
8283
- let magicString;
8773
+ const magicString = sourceMaps ? new magic_string.default(file.code, { filename }) : void 0;
8284
8774
  let code = "";
8285
8775
  let last = 0;
8286
8776
  let map;
8777
+ let nameIndex = 0;
8287
8778
  for (const child of node.body.body) {
8288
- code += child.value;
8289
- if (sourceMaps) {
8779
+ const placeholder = _marko_compiler.types.isMarkoPlaceholder(child);
8780
+ const text = placeholder ? `var(${names[nameIndex++]})` : child.value;
8781
+ if (magicString) {
8290
8782
  const start = (0, _marko_compiler_babel_utils.getStart)(file, child);
8291
- if (start !== null) {
8292
- magicString ||= new magic_string.default(file.code, { filename });
8783
+ if (start === null) magicString.appendLeft(last, text);
8784
+ else {
8785
+ const end = (0, _marko_compiler_babel_utils.getEnd)(file, child);
8293
8786
  if (start > last) magicString.remove(last, start);
8294
- last = (0, _marko_compiler_babel_utils.getEnd)(file, child);
8787
+ if (placeholder) magicString.update(start, end, text);
8788
+ last = end;
8295
8789
  }
8296
- }
8790
+ } else code += text;
8297
8791
  }
8298
8792
  if (magicString) {
8299
8793
  if (file.code.length > last) magicString.remove(last, file.code.length);
8794
+ code = magicString.toString();
8300
8795
  map = magicString.generateMap({
8301
8796
  source: filename,
8302
8797
  includeContent: true
@@ -8424,6 +8919,7 @@ var core_default = {
8424
8919
  "<return>": return_default,
8425
8920
  "<script>": script_default,
8426
8921
  "<server>": server_default,
8922
+ "<show>": show_default,
8427
8923
  "<static>": static_default,
8428
8924
  "<style>": style_default,
8429
8925
  "<try>": try_default
@@ -8591,6 +9087,7 @@ var placeholder_default = {
8591
9087
  const section = getOrCreateSection(placeholder);
8592
9088
  const nodeBinding = (node.extra ??= {})[kNodeBinding] = createBinding("#text", 0, section);
8593
9089
  analyzeSiblingText(placeholder);
9090
+ addSetupExpr(section, node.value);
8594
9091
  addSerializeExpr(section, valueExtra, nodeBinding);
8595
9092
  }
8596
9093
  },
@@ -8656,23 +9153,49 @@ function buildEscapedTextExpression(value) {
8656
9153
  function analyzeSiblingText(placeholder) {
8657
9154
  const placeholderExtra = placeholder.node.extra;
8658
9155
  let prev = placeholder.getPrevSibling();
8659
- while (prev.node) {
9156
+ let prevParent = placeholder.parentPath;
9157
+ for (;;) {
9158
+ if (!prev.node) {
9159
+ const showTag = getInlinedBodyTag(prevParent);
9160
+ if (showTag) {
9161
+ prev = showTag.getPrevSibling();
9162
+ prevParent = showTag.parentPath;
9163
+ continue;
9164
+ }
9165
+ break;
9166
+ }
8660
9167
  const contentType = getNodeContentType(prev, "endType");
8661
9168
  if (contentType === null) prev = prev.getPrevSibling();
8662
9169
  else if (contentType === 4 || contentType === 1 || contentType === 2) return placeholderExtra[kSiblingText] = 1;
8663
9170
  else break;
8664
9171
  }
8665
- if (!prev.node && _marko_compiler.types.isProgram(placeholder.parent)) return placeholderExtra[kSiblingText] = 1;
9172
+ if (!prev.node && prevParent.isProgram()) return placeholderExtra[kSiblingText] = 1;
8666
9173
  let next = placeholder.getNextSibling();
8667
- while (next.node) {
9174
+ let nextParent = placeholder.parentPath;
9175
+ for (;;) {
9176
+ if (!next.node) {
9177
+ const showTag = getInlinedBodyTag(nextParent);
9178
+ if (showTag) {
9179
+ next = showTag.getNextSibling();
9180
+ nextParent = showTag.parentPath;
9181
+ continue;
9182
+ }
9183
+ break;
9184
+ }
8668
9185
  const contentType = getNodeContentType(next, "startType");
8669
9186
  if (contentType === null) next = next.getNextSibling();
8670
9187
  else if (contentType === 4 || contentType === 1 || contentType === 2) return placeholderExtra[kSiblingText] = 2;
8671
9188
  else break;
8672
9189
  }
8673
- if (!next.node && _marko_compiler.types.isProgram(placeholder.parent)) return placeholderExtra[kSiblingText] = 2;
9190
+ if (!next.node && nextParent.isProgram()) return placeholderExtra[kSiblingText] = 2;
8674
9191
  return placeholderExtra[kSiblingText] = 0;
8675
9192
  }
9193
+ function getInlinedBodyTag(parent) {
9194
+ if (parent.isMarkoTagBody()) {
9195
+ const tag = parent.parentPath;
9196
+ if (tag.isMarkoTag() && isCoreTagName(tag, "show")) return tag;
9197
+ }
9198
+ }
8676
9199
  function isStaticText(node) {
8677
9200
  switch (node?.type) {
8678
9201
  case "MarkoText": return true;
@@ -8819,6 +9342,7 @@ var custom_tag_default = {
8819
9342
  const childSection = childExtra.section;
8820
9343
  if (childExtra.page) programExtra.page ??= true;
8821
9344
  if (tagExtra.tagNameLoad) tagExtra[kLoadTagBinding] = createBinding("#text", 0, getOrCreateSection(tag));
9345
+ if (tagExtra.tagNameLoad || !childExtra.domExports?.setupEmpty) addSetupStatement(getOrCreateSection(tag));
8822
9346
  knownTagAnalyze(tag, childSection, programSection === childSection ? programSection.params && getBindingPropTree(programSection.params) : childExtra.domExports?.params);
8823
9347
  } },
8824
9348
  translate: {
@@ -8887,13 +9411,13 @@ function translateDOM(tag) {
8887
9411
  injectWalks(tag, tagName);
8888
9412
  enterShallow(tag);
8889
9413
  } else if (programSection === childSection) {
8890
- knownTagTranslateDOM(tag, childExports.params, (binding, preferredName) => getSignal(programSection, binding, preferredName).identifier, (section, childBinding) => {
9414
+ knownTagTranslateDOM(tag, childExports.params, (binding, preferredName) => getSignal(programSection, binding, preferredName).identifier, childExports.setupEmpty ? void 0 : (section, childBinding) => {
8891
9415
  addStatement("render", section, void 0, _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(_marko_compiler.types.identifier(childExports.setup), [createScopeReadExpression(childBinding, section)])));
8892
9416
  });
8893
9417
  write`${_marko_compiler.types.identifier(childExports.template)}`;
8894
9418
  injectWalks(tag, tagName, _marko_compiler.types.identifier(childExports.walks));
8895
9419
  } else {
8896
- knownTagTranslateDOM(tag, childExports.params, (binding, preferredName, directContent) => importOrSelfReferenceName(tag.hub.file, relativePath, directContent && binding.directContentExport || binding.export, preferredName), (section, childBinding) => {
9420
+ knownTagTranslateDOM(tag, childExports.params, (binding, preferredName, directContent) => importOrSelfReferenceName(tag.hub.file, relativePath, directContent && binding.directContentExport || binding.export, preferredName), childExports.setupEmpty ? void 0 : (section, childBinding) => {
8897
9421
  addStatement("render", section, void 0, _marko_compiler.types.expressionStatement(_marko_compiler.types.callExpression(importOrSelfReferenceName(file, relativePath, childExports.setup, tagName), [createScopeReadExpression(childBinding, section)])));
8898
9422
  });
8899
9423
  write`${(0, _marko_compiler_babel_utils.importNamed)(file, relativePath, childExports.template, `${tagName}_template`)}`;
@@ -8967,6 +9491,7 @@ var dynamic_tag_default = {
8967
9491
  analyze: { enter(tag) {
8968
9492
  (0, _marko_compiler_babel_utils.assertAttributesOrArgs)(tag);
8969
9493
  const { node } = tag;
9494
+ addSetupStatement(getOrCreateSection(tag));
8970
9495
  const definedBodySection = node.extra?.defineBodySection;
8971
9496
  if (definedBodySection) {
8972
9497
  knownTagAnalyze(tag, definedBodySection, definedBodySection.params && getBindingPropTree(definedBodySection.params));