marko 6.0.40 → 6.0.42

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.
@@ -10,7 +10,9 @@ export declare function controllable_input_checkedValue(scopeId: number, nodeAcc
10
10
  export declare function controllable_detailsOrDialog_open(scopeId: number, nodeAccessor: Accessor, open: unknown, openChange: unknown): string;
11
11
  export declare function attr(name: string, value: unknown): string;
12
12
  export declare function attrs(data: Record<string, unknown>, nodeAccessor: Accessor, scopeId: number, tagName: string): string;
13
+ export declare function writeAttrsAndContent(data: Record<string, unknown>, nodeAccessor: Accessor, scopeId: number, tagName: string, serializeReason?: 1 | 0): void;
13
14
  export declare function partialAttrs(data: Record<string, unknown>, skip: Record<string, 1>, nodeAccessor: Accessor, scopeId: number, tagName: string): string;
15
+ export declare function writePartialAttrsAndContent(data: Record<string, unknown>, skip: Record<string, 1>, nodeAccessor: Accessor, scopeId: number, tagName: string, serializeReason?: 1 | 0): void;
14
16
  export declare function attrAssignment(value: string): string;
15
17
  export declare function escapeSingleQuotedAttrValue(value: string): string;
16
18
  export declare function escapeDoubleQuotedAttrValue(value: string): string;
@@ -1,5 +1,6 @@
1
1
  import { type $Global, type Accessor, type Falsy, ResumeSymbol } from "../common/types";
2
2
  import { Serializer } from "./serializer";
3
+ import type { ServerRenderer } from "./template";
3
4
  export type PartialScope = Record<Accessor, unknown>;
4
5
  type ScopeInternals = PartialScope & {
5
6
  [K_SCOPE_ID]?: number;
@@ -17,6 +18,8 @@ export declare function getScopeId(scope: unknown): number | undefined;
17
18
  export declare function write(html: string): void;
18
19
  export declare function writeScript(script: string): void;
19
20
  export declare function writeEffect(scopeId: number, registryId: string): void;
21
+ export declare function writeContent(nodeAccessor: Accessor, scopeId: number, content: unknown, serializeReason?: 1 | 0): void;
22
+ export declare function normalizeServerRender(value: unknown): ServerRenderer | undefined;
20
23
  export declare function withContext<T>(key: PropertyKey, value: unknown, cb: () => T): T;
21
24
  export declare function setTagVar(parentScopeId: number, scopeOffsetAccessor: Accessor, childScopeId: number, registryId: string): void;
22
25
  export declare function register<T extends WeakKey>(val: T, id: string, scopeId?: number): T;
package/dist/html.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { attrTag, attrTags } from "./common/attr-tag";
2
- export { attr, attrs, classAttr, controllable_detailsOrDialog_open, controllable_input_checked, controllable_input_checkedValue, controllable_input_value, controllable_select_value, controllable_textarea_value, optionValueAttr, partialAttrs, styleAttr, } from "./html/attrs";
2
+ export { attr, attrs, classAttr, controllable_detailsOrDialog_open, controllable_input_checked, controllable_input_checkedValue, controllable_input_value, controllable_select_value, controllable_textarea_value, optionValueAttr, partialAttrs, styleAttr, writeAttrsAndContent, writePartialAttrsAndContent, } from "./html/attrs";
3
3
  export { compat } from "./html/compat";
4
4
  export { escapeScript, escapeStyle, escapeXML, toString } from "./html/content";
5
5
  export { createContent, dynamicTag, registerContent } from "./html/dynamic-tag";
6
6
  export { forIn, forInBy, forOf, forOfBy, forTo, forToBy } from "./html/for";
7
7
  export { createTemplate } from "./html/template";
8
- export { $global, commentSeparator, ensureScopeWithId, fork, getScopeById, hoist, markResumeNode, nextScopeId, nextTagId, nodeRef, peekNextScopeId, register, resumeClosestBranch, resumeConditional, resumeForIn, resumeForOf, resumeForTo, serializeGuard, serializeIf, setTagVar, tryContent, write, writeEffect, writeExistingScope, writeScope, writeSubscribe, writeTrailers, } from "./html/writer";
8
+ export { $global, commentSeparator, ensureScopeWithId, fork, getScopeById, hoist, markResumeNode, nextScopeId, nextTagId, nodeRef, peekNextScopeId, register, resumeClosestBranch, resumeConditional, resumeForIn, resumeForOf, resumeForTo, serializeGuard, serializeIf, setTagVar, tryContent, write, writeContent, writeEffect, writeExistingScope, writeScope, writeSubscribe, writeTrailers, } from "./html/writer";
package/dist/html.js CHANGED
@@ -68,8 +68,11 @@ __export(html_exports, {
68
68
  toString: () => toString,
69
69
  tryContent: () => tryContent,
70
70
  write: () => write,
71
+ writeAttrsAndContent: () => writeAttrsAndContent,
72
+ writeContent: () => writeContent,
71
73
  writeEffect: () => writeEffect,
72
74
  writeExistingScope: () => writeExistingScope,
75
+ writePartialAttrsAndContent: () => writePartialAttrsAndContent,
73
76
  writeScope: () => writeScope,
74
77
  writeSubscribe: () => writeSubscribe,
75
78
  writeTrailers: () => writeTrailers
@@ -1102,6 +1105,21 @@ function writeScript(script) {
1102
1105
  function writeEffect(scopeId, registryId) {
1103
1106
  $chunk.boundary.state.needsMainRuntime = !0, $chunk.writeEffect(scopeId, registryId);
1104
1107
  }
1108
+ function writeContent(nodeAccessor, scopeId, content, serializeReason) {
1109
+ let shouldResume = serializeReason !== 0, render2 = normalizeServerRender(content), branchId = peekNextScopeId();
1110
+ render2 && (shouldResume ? withBranchId(branchId, render2) : render2()), peekNextScopeId() !== branchId ? shouldResume && writeScope(scopeId, {
1111
+ ["d" /* ConditionalScope */ + nodeAccessor]: writeScope(
1112
+ branchId,
1113
+ {}
1114
+ ),
1115
+ ["c" /* ConditionalRenderer */ + nodeAccessor]: render2?.h
1116
+ }) : nextScopeId();
1117
+ }
1118
+ function normalizeServerRender(value) {
1119
+ let renderer = normalizeDynamicRenderer(value);
1120
+ if (renderer && typeof renderer == "function")
1121
+ return renderer;
1122
+ }
1105
1123
  var kPendingContexts = Symbol("Pending Contexts");
1106
1124
  function withContext(key, value, cb) {
1107
1125
  let ctx = $chunk.context ||= { [kPendingContexts]: 0 }, prev = ctx[key];
@@ -1772,12 +1790,18 @@ function attrs(data, nodeAccessor, scopeId, tagName) {
1772
1790
  }
1773
1791
  return result;
1774
1792
  }
1793
+ function writeAttrsAndContent(data, nodeAccessor, scopeId, tagName, serializeReason) {
1794
+ write(`${attrs(data, nodeAccessor, scopeId, tagName)}>`), writeContent(nodeAccessor, scopeId, data?.content, serializeReason);
1795
+ }
1775
1796
  function partialAttrs(data, skip, nodeAccessor, scopeId, tagName) {
1776
1797
  let partial = {};
1777
1798
  for (let key in data)
1778
1799
  skip[key] || (partial[key] = data[key]);
1779
1800
  return attrs(partial, nodeAccessor, scopeId, tagName);
1780
1801
  }
1802
+ function writePartialAttrsAndContent(data, skip, nodeAccessor, scopeId, tagName, serializeReason) {
1803
+ write(`${partialAttrs(data, skip, nodeAccessor, scopeId, tagName)}>`), writeContent(nodeAccessor, scopeId, data?.content, serializeReason);
1804
+ }
1781
1805
  function writeControlledScope(type, scopeId, nodeAccessor, value, valueChange) {
1782
1806
  writeScope(scopeId, {
1783
1807
  ["f" /* ControlledType */ + nodeAccessor]: type,
@@ -1981,23 +2005,31 @@ function NOOP2() {
1981
2005
  var voidElementsReg = /^(?:area|b(?:ase|r)|col|embed|hr|i(?:mg|nput)|link|meta|param|source|track|wbr)$/, dynamicTag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, serializeReason) => {
1982
2006
  let shouldResume = serializeReason !== 0, renderer = normalizeDynamicRenderer(tag), state = getState(), branchId = peekNextScopeId(), result;
1983
2007
  if (typeof renderer == "string") {
1984
- let input = (inputIsArgs ? inputOrArgs[0] : inputOrArgs) || {};
2008
+ let input = (inputIsArgs ? inputOrArgs[0] : inputOrArgs) || {}, renderContent = content || normalizeDynamicRenderer(input.content);
1985
2009
  if (nextScopeId(), write(`<${renderer}${attrs(input, accessor, scopeId, renderer)}>`), !voidElementsReg.test(renderer)) {
1986
2010
  let renderNativeTag = () => {
1987
- renderer === "textarea" ? write(
1988
- controllable_textarea_value(
2011
+ if (renderer === "textarea")
2012
+ write(
2013
+ controllable_textarea_value(
2014
+ scopeId,
2015
+ accessor,
2016
+ input.value,
2017
+ input.valueChange
2018
+ )
2019
+ );
2020
+ else if (renderContent) {
2021
+ if (typeof renderContent != "function")
2022
+ throw new Error(
2023
+ `Body content is not supported for the \`<${renderer}>\` tag.`
2024
+ );
2025
+ renderer === "select" && ("value" in input || "valueChange" in input) ? controllable_select_value(
1989
2026
  scopeId,
1990
2027
  accessor,
1991
2028
  input.value,
1992
- input.valueChange
1993
- )
1994
- ) : content && (renderer === "select" && ("value" in input || "valueChange" in input) ? controllable_select_value(
1995
- scopeId,
1996
- accessor,
1997
- input.value,
1998
- input.valueChange,
1999
- content
2000
- ) : content());
2029
+ input.valueChange,
2030
+ renderContent
2031
+ ) : renderContent();
2032
+ }
2001
2033
  };
2002
2034
  shouldResume ? withBranchId(branchId, renderNativeTag) : renderNativeTag(), write(`</${renderer}>`);
2003
2035
  }
@@ -2177,8 +2209,11 @@ var K_TAGS_API_STATE = Symbol(), COMPAT_REGISTRY = /* @__PURE__ */ new WeakMap()
2177
2209
  toString,
2178
2210
  tryContent,
2179
2211
  write,
2212
+ writeAttrsAndContent,
2213
+ writeContent,
2180
2214
  writeEffect,
2181
2215
  writeExistingScope,
2216
+ writePartialAttrsAndContent,
2182
2217
  writeScope,
2183
2218
  writeSubscribe,
2184
2219
  writeTrailers
package/dist/html.mjs CHANGED
@@ -1024,6 +1024,21 @@ function writeScript(script) {
1024
1024
  function writeEffect(scopeId, registryId) {
1025
1025
  $chunk.boundary.state.needsMainRuntime = !0, $chunk.writeEffect(scopeId, registryId);
1026
1026
  }
1027
+ function writeContent(nodeAccessor, scopeId, content, serializeReason) {
1028
+ let shouldResume = serializeReason !== 0, render2 = normalizeServerRender(content), branchId = peekNextScopeId();
1029
+ render2 && (shouldResume ? withBranchId(branchId, render2) : render2()), peekNextScopeId() !== branchId ? shouldResume && writeScope(scopeId, {
1030
+ ["d" /* ConditionalScope */ + nodeAccessor]: writeScope(
1031
+ branchId,
1032
+ {}
1033
+ ),
1034
+ ["c" /* ConditionalRenderer */ + nodeAccessor]: render2?.h
1035
+ }) : nextScopeId();
1036
+ }
1037
+ function normalizeServerRender(value) {
1038
+ let renderer = normalizeDynamicRenderer(value);
1039
+ if (renderer && typeof renderer == "function")
1040
+ return renderer;
1041
+ }
1027
1042
  var kPendingContexts = Symbol("Pending Contexts");
1028
1043
  function withContext(key, value, cb) {
1029
1044
  let ctx = $chunk.context ||= { [kPendingContexts]: 0 }, prev = ctx[key];
@@ -1694,12 +1709,18 @@ function attrs(data, nodeAccessor, scopeId, tagName) {
1694
1709
  }
1695
1710
  return result;
1696
1711
  }
1712
+ function writeAttrsAndContent(data, nodeAccessor, scopeId, tagName, serializeReason) {
1713
+ write(`${attrs(data, nodeAccessor, scopeId, tagName)}>`), writeContent(nodeAccessor, scopeId, data?.content, serializeReason);
1714
+ }
1697
1715
  function partialAttrs(data, skip, nodeAccessor, scopeId, tagName) {
1698
1716
  let partial = {};
1699
1717
  for (let key in data)
1700
1718
  skip[key] || (partial[key] = data[key]);
1701
1719
  return attrs(partial, nodeAccessor, scopeId, tagName);
1702
1720
  }
1721
+ function writePartialAttrsAndContent(data, skip, nodeAccessor, scopeId, tagName, serializeReason) {
1722
+ write(`${partialAttrs(data, skip, nodeAccessor, scopeId, tagName)}>`), writeContent(nodeAccessor, scopeId, data?.content, serializeReason);
1723
+ }
1703
1724
  function writeControlledScope(type, scopeId, nodeAccessor, value, valueChange) {
1704
1725
  writeScope(scopeId, {
1705
1726
  ["f" /* ControlledType */ + nodeAccessor]: type,
@@ -1903,23 +1924,31 @@ function NOOP2() {
1903
1924
  var voidElementsReg = /^(?:area|b(?:ase|r)|col|embed|hr|i(?:mg|nput)|link|meta|param|source|track|wbr)$/, dynamicTag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, serializeReason) => {
1904
1925
  let shouldResume = serializeReason !== 0, renderer = normalizeDynamicRenderer(tag), state = getState(), branchId = peekNextScopeId(), result;
1905
1926
  if (typeof renderer == "string") {
1906
- let input = (inputIsArgs ? inputOrArgs[0] : inputOrArgs) || {};
1927
+ let input = (inputIsArgs ? inputOrArgs[0] : inputOrArgs) || {}, renderContent = content || normalizeDynamicRenderer(input.content);
1907
1928
  if (nextScopeId(), write(`<${renderer}${attrs(input, accessor, scopeId, renderer)}>`), !voidElementsReg.test(renderer)) {
1908
1929
  let renderNativeTag = () => {
1909
- renderer === "textarea" ? write(
1910
- controllable_textarea_value(
1930
+ if (renderer === "textarea")
1931
+ write(
1932
+ controllable_textarea_value(
1933
+ scopeId,
1934
+ accessor,
1935
+ input.value,
1936
+ input.valueChange
1937
+ )
1938
+ );
1939
+ else if (renderContent) {
1940
+ if (typeof renderContent != "function")
1941
+ throw new Error(
1942
+ `Body content is not supported for the \`<${renderer}>\` tag.`
1943
+ );
1944
+ renderer === "select" && ("value" in input || "valueChange" in input) ? controllable_select_value(
1911
1945
  scopeId,
1912
1946
  accessor,
1913
1947
  input.value,
1914
- input.valueChange
1915
- )
1916
- ) : content && (renderer === "select" && ("value" in input || "valueChange" in input) ? controllable_select_value(
1917
- scopeId,
1918
- accessor,
1919
- input.value,
1920
- input.valueChange,
1921
- content
1922
- ) : content());
1948
+ input.valueChange,
1949
+ renderContent
1950
+ ) : renderContent();
1951
+ }
1923
1952
  };
1924
1953
  shouldResume ? withBranchId(branchId, renderNativeTag) : renderNativeTag(), write(`</${renderer}>`);
1925
1954
  }
@@ -2098,8 +2127,11 @@ export {
2098
2127
  toString,
2099
2128
  tryContent,
2100
2129
  write,
2130
+ writeAttrsAndContent,
2131
+ writeContent,
2101
2132
  writeEffect,
2102
2133
  writeExistingScope,
2134
+ writePartialAttrsAndContent,
2103
2135
  writeScope,
2104
2136
  writeSubscribe,
2105
2137
  writeTrailers
@@ -802,6 +802,7 @@ function getFnRoot(path5) {
802
802
  fnPath = curPath;
803
803
  } else {
804
804
  switch (curPath.type) {
805
+ case "OptionalCallExpression":
805
806
  case "CallExpression":
806
807
  case "NewExpression":
807
808
  fnPath = void 0;
@@ -850,6 +851,7 @@ function isInvokedFunction(expr) {
850
851
  while (curPath) {
851
852
  const { parent, node } = curPath;
852
853
  switch (parent.type) {
854
+ case "OptionalCallExpression":
853
855
  case "CallExpression":
854
856
  return parent.callee === node;
855
857
  case "TSNonNullExpression":
@@ -3412,24 +3414,33 @@ function generateSignalName(referencedBindings) {
3412
3414
  return name2;
3413
3415
  }
3414
3416
  function replaceNullishAndEmptyFunctionsWith0(args) {
3415
- for (let i = args.length; i--; ) {
3417
+ const len = args.length;
3418
+ let finalLen = void 0;
3419
+ for (let i = len; i--; ) {
3416
3420
  const arg = args[i];
3417
3421
  if (!arg) {
3418
3422
  args[i] = import_compiler20.types.numericLiteral(0);
3419
- } else if (import_compiler20.types.isArrowFunctionExpression(arg) && import_compiler20.types.isBlockStatement(arg.body)) {
3423
+ continue;
3424
+ }
3425
+ if (import_compiler20.types.isNullLiteral(arg) || import_compiler20.types.isUnaryExpression(arg) && arg.operator === "void") {
3426
+ args[i] = import_compiler20.types.numericLiteral(0);
3427
+ continue;
3428
+ }
3429
+ if (import_compiler20.types.isArrowFunctionExpression(arg) && import_compiler20.types.isBlockStatement(arg.body)) {
3420
3430
  const body = arg.body.body;
3421
3431
  if (body.length === 0) {
3422
3432
  args[i] = import_compiler20.types.numericLiteral(0);
3423
- } else if (body.length === 1 && import_compiler20.types.isExpressionStatement(body[0])) {
3433
+ continue;
3434
+ }
3435
+ if (body.length === 1 && import_compiler20.types.isExpressionStatement(body[0])) {
3424
3436
  arg.body = toParenthesizedExpressionIfNeeded(body[0].expression);
3425
3437
  }
3426
- } else if (import_compiler20.types.isNullLiteral(arg) || import_compiler20.types.isUnaryExpression(arg) && arg.operator === "void") {
3427
- args[i] = import_compiler20.types.numericLiteral(0);
3438
+ }
3439
+ if (finalLen === void 0) {
3440
+ finalLen = i + 1;
3428
3441
  }
3429
3442
  }
3430
- for (let i = args.length - 1; import_compiler20.types.isNumericLiteral(args[i]) && args[i].value === 0; ) {
3431
- args.length = i--;
3432
- }
3443
+ args.length = finalLen || 0;
3433
3444
  return args;
3434
3445
  }
3435
3446
  function addStatement(type, targetSection, referencedBindings, statement, usedReferences) {
@@ -3949,25 +3960,34 @@ function replaceBindingReadNode2(node) {
3949
3960
  }
3950
3961
  }
3951
3962
  }
3963
+ var updateExpressions = /* @__PURE__ */ new WeakSet();
3952
3964
  function replaceAssignedNode(node) {
3953
3965
  switch (node.type) {
3966
+ case "ExpressionStatement": {
3967
+ if (node.expression.type === "SequenceExpression" && updateExpressions.delete(node.expression)) {
3968
+ return node.expression.expressions[0];
3969
+ }
3970
+ break;
3971
+ }
3954
3972
  case "UpdateExpression": {
3955
3973
  const { extra } = node.argument;
3956
3974
  if (isAssignedBindingExtra(extra)) {
3957
3975
  const buildAssignment = getBuildAssignment(extra);
3958
3976
  if (buildAssignment) {
3959
- const replacement = buildAssignment(
3960
- extra.section,
3961
- import_compiler20.types.binaryExpression(
3962
- node.operator === "++" ? "+" : "-",
3963
- node.argument,
3964
- import_compiler20.types.numericLiteral(1)
3965
- )
3966
- );
3967
3977
  if (!node.prefix) {
3968
- return import_compiler20.types.sequenceExpression([replacement, node.argument]);
3978
+ node.prefix = true;
3979
+ const replacement = import_compiler20.types.sequenceExpression([
3980
+ buildAssignment(extra.section, node),
3981
+ import_compiler20.types.binaryExpression(
3982
+ node.operator === "++" ? "-" : "+",
3983
+ node.argument,
3984
+ import_compiler20.types.numericLiteral(1)
3985
+ )
3986
+ ]);
3987
+ updateExpressions.add(replacement);
3988
+ return replacement;
3969
3989
  }
3970
- return replacement;
3990
+ return buildAssignment(extra.section, node);
3971
3991
  }
3972
3992
  }
3973
3993
  break;
@@ -3979,17 +3999,24 @@ function replaceAssignedNode(node) {
3979
3999
  if (isAssignedBindingExtra(extra)) {
3980
4000
  const buildAssignment = getBuildAssignment(extra);
3981
4001
  if (buildAssignment) {
3982
- return buildAssignment(
3983
- extra.section,
3984
- node.operator === "=" ? node.right : import_compiler20.types.binaryExpression(
3985
- node.operator.slice(
3986
- 0,
3987
- -1
3988
- ),
3989
- node.left,
3990
- node.right
3991
- )
3992
- );
4002
+ if (bindingUtil.has(
4003
+ extra.fnExtra?.referencedBindingsInFunction,
4004
+ extra.assignment
4005
+ )) {
4006
+ return buildAssignment(extra.section, node);
4007
+ } else {
4008
+ return buildAssignment(
4009
+ extra.section,
4010
+ node.operator === "=" ? node.right : import_compiler20.types.binaryExpression(
4011
+ node.operator.slice(
4012
+ 0,
4013
+ -1
4014
+ ),
4015
+ node.left,
4016
+ node.right
4017
+ )
4018
+ );
4019
+ }
3993
4020
  }
3994
4021
  }
3995
4022
  break;
@@ -4003,19 +4030,24 @@ function replaceAssignedNode(node) {
4003
4030
  if (isAssignedBindingExtra(extra)) {
4004
4031
  const buildAssignment = getBuildAssignment(extra);
4005
4032
  if (buildAssignment) {
4006
- id.name = generateUid(id.name);
4007
- (params ||= []).push(import_compiler20.types.identifier(id.name));
4033
+ if (!bindingUtil.has(
4034
+ extra.fnExtra?.referencedBindingsInFunction,
4035
+ extra.assignment
4036
+ )) {
4037
+ id.name = generateUid(id.name);
4038
+ (params ||= []).push(import_compiler20.types.identifier(id.name));
4039
+ }
4008
4040
  (assignments ||= []).push(
4009
4041
  buildAssignment(extra.section, import_compiler20.types.identifier(id.name))
4010
4042
  );
4011
4043
  }
4012
4044
  }
4013
4045
  });
4014
- if (params && assignments) {
4046
+ if (assignments) {
4015
4047
  const resultId = generateUid("result");
4016
4048
  return import_compiler20.types.callExpression(
4017
4049
  import_compiler20.types.arrowFunctionExpression(
4018
- [import_compiler20.types.identifier(resultId), ...params],
4050
+ [import_compiler20.types.identifier(resultId), ...params || []],
4019
4051
  import_compiler20.types.sequenceExpression([
4020
4052
  import_compiler20.types.assignmentExpression(
4021
4053
  "=",
@@ -4620,6 +4652,8 @@ function trackReferencesForBinding(babelBinding, binding) {
4620
4652
  }
4621
4653
  }
4622
4654
  function trackAssignment(assignment, binding) {
4655
+ const fnRoot = getFnRoot(assignment);
4656
+ const fnExtra = fnRoot && (fnRoot.node.extra ??= {});
4623
4657
  const section = getOrCreateSection(assignment);
4624
4658
  setReferencesScope(assignment);
4625
4659
  forEachIdentifierPath(assignment, (id) => {
@@ -4646,6 +4680,7 @@ function trackAssignment(assignment, binding) {
4646
4680
  );
4647
4681
  extra.assignment = binding;
4648
4682
  extra.section = section;
4683
+ extra.fnExtra = fnExtra;
4649
4684
  }
4650
4685
  });
4651
4686
  }
@@ -5273,6 +5308,7 @@ function addReadToExpression(root, binding) {
5273
5308
  if (fnRoot) {
5274
5309
  const readsByFn = getReadsByFunction();
5275
5310
  const fnExtra = fnRoot.node.extra ??= {};
5311
+ exprExtra.fnExtra = fnExtra;
5276
5312
  fnExtra.section = section;
5277
5313
  readsByFn.set(fnExtra, push(readsByFn.get(fnExtra), read));
5278
5314
  }
@@ -5981,6 +6017,7 @@ var import_babel_utils23 = require("@marko/compiler/babel-utils");
5981
6017
  var kNativeTagBinding = Symbol("native tag binding");
5982
6018
  var kSkipEndTag = Symbol("skip native tag mark");
5983
6019
  var kGetterId = Symbol("node getter id");
6020
+ var kTagContentAttr = Symbol("tag could have dynamic content attribute");
5984
6021
  var htmlSelectArgs = /* @__PURE__ */ new WeakMap();
5985
6022
  var native_tag_default = {
5986
6023
  transform: {
@@ -6245,15 +6282,19 @@ var native_tag_default = {
6245
6282
  break;
6246
6283
  }
6247
6284
  }
6285
+ const isOpenOnly = !!(tagDef && tagDef.parseOptions?.openTagOnly);
6286
+ const hasChildren = !!tag.node.body.body.length;
6248
6287
  if (spreadExpression) {
6249
6288
  addHTMLEffectCall(tagSection, tagExtra.referencedBindings);
6250
- if (skipExpression) {
6251
- write2`${callRuntime("partialAttrs", spreadExpression, skipExpression, visitAccessor, getScopeIdIdentifier(tagSection), tag.node.name)}`;
6252
- } else {
6253
- write2`${callRuntime("attrs", spreadExpression, visitAccessor, getScopeIdIdentifier(tagSection), tag.node.name)}`;
6289
+ if (isOpenOnly || hasChildren || usedAttrs.staticContentAttr) {
6290
+ if (skipExpression) {
6291
+ write2`${callRuntime("partialAttrs", spreadExpression, skipExpression, visitAccessor, getScopeIdIdentifier(tagSection), tag.node.name)}`;
6292
+ } else {
6293
+ write2`${callRuntime("attrs", spreadExpression, visitAccessor, getScopeIdIdentifier(tagSection), tag.node.name)}`;
6294
+ }
6254
6295
  }
6255
6296
  }
6256
- if (tagDef && tagDef.parseOptions?.openTagOnly) {
6297
+ if (isOpenOnly) {
6257
6298
  switch (tagDef.htmlType) {
6258
6299
  case "svg":
6259
6300
  case "math":
@@ -6264,7 +6305,54 @@ var native_tag_default = {
6264
6305
  break;
6265
6306
  }
6266
6307
  } else {
6267
- write2`>`;
6308
+ if (usedAttrs.staticContentAttr) {
6309
+ write2`>`;
6310
+ tagExtra[kTagContentAttr] = true;
6311
+ tag.node.body.body = [
6312
+ import_compiler31.types.expressionStatement(
6313
+ callRuntime(
6314
+ "writeContent",
6315
+ visitAccessor,
6316
+ getScopeIdIdentifier(tagSection),
6317
+ usedAttrs.staticContentAttr.value,
6318
+ getSerializeGuard(
6319
+ nodeBinding && getBindingSerializeReason(tagSection, nodeBinding),
6320
+ true
6321
+ )
6322
+ )
6323
+ )
6324
+ ];
6325
+ } else if (spreadExpression && !hasChildren) {
6326
+ const serializeReason = getSerializeGuard(
6327
+ nodeBinding && getBindingSerializeReason(tagSection, nodeBinding),
6328
+ true
6329
+ );
6330
+ tagExtra[kTagContentAttr] = true;
6331
+ tag.node.body.body = [
6332
+ skipExpression ? import_compiler31.types.expressionStatement(
6333
+ callRuntime(
6334
+ "writePartialAttrsAndContent",
6335
+ spreadExpression,
6336
+ skipExpression,
6337
+ visitAccessor,
6338
+ getScopeIdIdentifier(tagSection),
6339
+ tag.node.name,
6340
+ serializeReason
6341
+ )
6342
+ ) : import_compiler31.types.expressionStatement(
6343
+ callRuntime(
6344
+ "writeAttrsAndContent",
6345
+ spreadExpression,
6346
+ visitAccessor,
6347
+ getScopeIdIdentifier(tagSection),
6348
+ tag.node.name,
6349
+ serializeReason
6350
+ )
6351
+ )
6352
+ ];
6353
+ } else {
6354
+ write2`>`;
6355
+ }
6268
6356
  }
6269
6357
  if (tagExtra.tagNameNullable) {
6270
6358
  tag.insertBefore(
@@ -6282,6 +6370,9 @@ var native_tag_default = {
6282
6370
  const selectArgs = htmlSelectArgs.get(tag.node);
6283
6371
  const tagName = getTagName(tag);
6284
6372
  const tagSection = getSection(tag);
6373
+ if (tagExtra[kTagContentAttr]) {
6374
+ flushBefore(tag);
6375
+ }
6285
6376
  if (tagExtra.tagNameNullable) {
6286
6377
  flushInto(tag);
6287
6378
  }
@@ -6395,6 +6486,8 @@ var native_tag_default = {
6395
6486
  const usedAttrs = getUsedAttrs(tagName, tag.node);
6396
6487
  const { staticAttrs, staticControllable, skipExpression } = usedAttrs;
6397
6488
  const { spreadExpression } = usedAttrs;
6489
+ const isOpenOnly = !!(tagDef && tagDef.parseOptions?.openTagOnly);
6490
+ const hasChildren = !!tag.node.body.body.length;
6398
6491
  if (staticControllable) {
6399
6492
  const { helper, attrs: attrs2 } = staticControllable;
6400
6493
  const firstAttr = attrs2.find(Boolean);
@@ -6521,6 +6614,7 @@ var native_tag_default = {
6521
6614
  }
6522
6615
  }
6523
6616
  if (spreadExpression) {
6617
+ const canHaveAttrContent = !(isOpenOnly || hasChildren || usedAttrs.staticContentAttr);
6524
6618
  if (skipExpression) {
6525
6619
  addStatement(
6526
6620
  "render",
@@ -6528,7 +6622,7 @@ var native_tag_default = {
6528
6622
  tagExtra.referencedBindings,
6529
6623
  import_compiler31.types.expressionStatement(
6530
6624
  callRuntime(
6531
- "partialAttrs",
6625
+ canHaveAttrContent ? "partialAttrsAndContent" : "partialAttrs",
6532
6626
  scopeIdentifier,
6533
6627
  visitAccessor,
6534
6628
  spreadExpression,
@@ -6543,7 +6637,7 @@ var native_tag_default = {
6543
6637
  tagExtra.referencedBindings,
6544
6638
  import_compiler31.types.expressionStatement(
6545
6639
  callRuntime(
6546
- "attrs",
6640
+ canHaveAttrContent ? "attrsAndContent" : "attrs",
6547
6641
  scopeIdentifier,
6548
6642
  visitAccessor,
6549
6643
  spreadExpression
@@ -6561,7 +6655,23 @@ var native_tag_default = {
6561
6655
  false
6562
6656
  );
6563
6657
  }
6564
- if (tagDef && tagDef.parseOptions?.openTagOnly) {
6658
+ if (usedAttrs.staticContentAttr) {
6659
+ const contentAttrValue = usedAttrs.staticContentAttr.value;
6660
+ addStatement(
6661
+ "render",
6662
+ tagSection,
6663
+ contentAttrValue.extra?.referencedBindings,
6664
+ import_compiler31.types.expressionStatement(
6665
+ callRuntime(
6666
+ "insertContent",
6667
+ scopeIdentifier,
6668
+ visitAccessor,
6669
+ contentAttrValue
6670
+ )
6671
+ )
6672
+ );
6673
+ }
6674
+ if (isOpenOnly) {
6565
6675
  switch (tagDef.htmlType) {
6566
6676
  case "svg":
6567
6677
  case "math":
@@ -6665,6 +6775,7 @@ function getUsedAttrs(tagName, tag) {
6665
6775
  let spreadProps;
6666
6776
  let skipProps;
6667
6777
  let staticControllable;
6778
+ let staticContentAttr;
6668
6779
  for (let i = attributes.length; i--; ) {
6669
6780
  const attr2 = attributes[i];
6670
6781
  const { value } = attr2;
@@ -6683,10 +6794,12 @@ function getUsedAttrs(tagName, tag) {
6683
6794
  }
6684
6795
  }
6685
6796
  spreadProps.push(import_compiler31.types.spreadElement(value));
6686
- } else if (!seen[attr2.name]) {
6797
+ } else if (!seen[attr2.name] || !(attr2.name === "content" && tag.body.body.length)) {
6687
6798
  seen[attr2.name] = attr2;
6688
6799
  if (spreadProps) {
6689
6800
  spreadProps.push(toObjectProperty(attr2.name, attr2.value));
6801
+ } else if (attr2.name === "content") {
6802
+ staticContentAttr = attr2;
6690
6803
  } else {
6691
6804
  maybeStaticAttrs.add(attr2);
6692
6805
  }
@@ -6720,13 +6833,14 @@ function getUsedAttrs(tagName, tag) {
6720
6833
  for (const { name: name2 } of staticAttrs) {
6721
6834
  (skipProps ||= []).push(toObjectProperty(name2, import_compiler31.types.numericLiteral(1)));
6722
6835
  }
6723
- if (skipProps) {
6724
- skipExpression = import_compiler31.types.objectExpression(skipProps);
6725
- }
6726
6836
  spreadExpression = propsToExpression(spreadProps);
6727
6837
  }
6838
+ if (skipProps) {
6839
+ skipExpression = import_compiler31.types.objectExpression(skipProps);
6840
+ }
6728
6841
  return {
6729
6842
  staticAttrs,
6843
+ staticContentAttr,
6730
6844
  staticControllable,
6731
6845
  spreadExpression,
6732
6846
  skipExpression
@@ -1,5 +1,5 @@
1
1
  import { types as t } from "@marko/compiler";
2
2
  export default function isInvokedFunction(expr: t.NodePath<t.Node>): expr is typeof expr & {
3
- parent: t.CallExpression;
3
+ parent: t.CallExpression | t.OptionalCallExpression;
4
4
  parentPath: t.NodePath<t.CallExpression>;
5
5
  };
@@ -45,6 +45,9 @@ export interface InputBinding extends Binding {
45
45
  }
46
46
  export type ReferencedBindings = Opt<Binding>;
47
47
  export type Intersection = Many<Binding>;
48
+ type FnExtra = (t.FunctionExpressionExtra | t.ArrowFunctionExpressionExtra | t.FunctionDeclarationExtra) & {
49
+ section: Section;
50
+ };
48
51
  declare module "@marko/compiler/dist/types" {
49
52
  interface NodeExtra {
50
53
  section?: Section;
@@ -103,6 +106,7 @@ export declare function getSectionInstancesAccessorLiteral(section: Section): t.
103
106
  export declare function getReadReplacement(node: t.Identifier | t.MemberExpression): t.Node | undefined;
104
107
  export interface ReferencedExtra extends t.NodeExtra {
105
108
  section: Section;
109
+ fnExtra?: FnExtra;
106
110
  }
107
111
  export declare function isReferencedExtra(extra: t.NodeExtra | undefined): extra is ReferencedExtra;
108
112
  export interface AssignedBindingExtra extends ReferencedExtra {
@@ -3,11 +3,13 @@ import { type Binding } from "../../util/references";
3
3
  export declare const kNativeTagBinding: unique symbol;
4
4
  export declare const kSkipEndTag: unique symbol;
5
5
  declare const kGetterId: unique symbol;
6
+ declare const kTagContentAttr: unique symbol;
6
7
  declare module "@marko/compiler/dist/types" {
7
8
  interface NodeExtra {
8
9
  [kNativeTagBinding]?: Binding;
9
10
  [kSkipEndTag]?: true;
10
11
  [kGetterId]?: string;
12
+ [kTagContentAttr]?: true;
11
13
  }
12
14
  }
13
15
  declare const _default: {