marko 6.3.23 → 6.3.25

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.
package/dist/html.js CHANGED
@@ -262,7 +262,7 @@ let empty = [], rest = Symbol(), unsafeStyleAttrReg = /[\\;]/g, replaceUnsafeSty
262
262
  _html(`</${renderer}>`);
263
263
  }
264
264
  let childScope = getScopeById(branchId), needsScript = childScope && (childScope.Ia || childScope.Ea);
265
- needsScript && (writeScope(branchId, { R: renderer }), _script(branchId, "d")), (shouldResume || needsScript) && _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
265
+ needsScript && _script(branchId, "d"), (shouldResume || needsScript) && _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
266
266
  })();
267
267
  } else {
268
268
  shouldResume && _html(state.mark("[", ""));
@@ -516,7 +516,7 @@ function writeScopesRoot(state, flushes) {
516
516
  let { buf } = state, nextSlotId = -1, fillIndex = -1;
517
517
  for (let flush of flushes) {
518
518
  let scopeId = flush[0], scope = flush[1], ref = state.refs.get(scope) || newScopeReference(state, scope, scopeId), openIndex = buf.push("") - 1;
519
- writeObjectProps(state, flush[2], ref) ? (buf[openIndex] = nextSlotId === -1 ? "[" + scopeId + ",{" : (scopeId > nextSlotId ? "," + (scopeId - nextSlotId) : "") + ",{", fillIndex === -1 && (fillIndex = openIndex), nextSlotId = scopeId + 1, buf.push("}")) : buf.pop();
519
+ writeObjectProps(state, flush[2], ref) ? (buf[openIndex] = nextSlotId === -1 ? "[" + scopeId + ",{" : (scopeId === nextSlotId ? "" : "," + (scopeId - nextSlotId)) + ",{", fillIndex === -1 && (fillIndex = openIndex), nextSlotId = scopeId + 1, buf.push("}")) : buf.pop();
520
520
  }
521
521
  nextSlotId !== -1 && buf.push("]");
522
522
  let extras = "";
package/dist/html.mjs CHANGED
@@ -262,7 +262,7 @@ let empty = [], rest = Symbol(), unsafeStyleAttrReg = /[\\;]/g, replaceUnsafeSty
262
262
  _html(`</${renderer}>`);
263
263
  }
264
264
  let childScope = getScopeById(branchId), needsScript = childScope && (childScope.Ia || childScope.Ea);
265
- needsScript && (writeScope(branchId, { R: renderer }), _script(branchId, "d")), (shouldResume || needsScript) && _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
265
+ needsScript && _script(branchId, "d"), (shouldResume || needsScript) && _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
266
266
  })();
267
267
  } else {
268
268
  shouldResume && _html(state.mark("[", ""));
@@ -515,7 +515,7 @@ function writeScopesRoot(state, flushes) {
515
515
  let { buf } = state, nextSlotId = -1, fillIndex = -1;
516
516
  for (let flush of flushes) {
517
517
  let scopeId = flush[0], scope = flush[1], ref = state.refs.get(scope) || newScopeReference(state, scope, scopeId), openIndex = buf.push("") - 1;
518
- writeObjectProps(state, flush[2], ref) ? (buf[openIndex] = nextSlotId === -1 ? "[" + scopeId + ",{" : (scopeId > nextSlotId ? "," + (scopeId - nextSlotId) : "") + ",{", fillIndex === -1 && (fillIndex = openIndex), nextSlotId = scopeId + 1, buf.push("}")) : buf.pop();
518
+ writeObjectProps(state, flush[2], ref) ? (buf[openIndex] = nextSlotId === -1 ? "[" + scopeId + ",{" : (scopeId === nextSlotId ? "" : "," + (scopeId - nextSlotId)) + ",{", fillIndex === -1 && (fillIndex = openIndex), nextSlotId = scopeId + 1, buf.push("}")) : buf.pop();
519
519
  }
520
520
  nextSlotId !== -1 && buf.push("]");
521
521
  let extras = "";
@@ -110,6 +110,7 @@ var accessor_prefix_debug_exports = /* @__PURE__ */ __exportAll({
110
110
  ClosureSignalIndex: () => ClosureSignalIndex$1,
111
111
  ConditionalRenderer: () => ConditionalRenderer$1,
112
112
  ControlledHandler: () => ControlledHandler$1,
113
+ ControlledObserver: () => ControlledObserver$1,
113
114
  ControlledType: () => ControlledType$1,
114
115
  ControlledValue: () => ControlledValue$1,
115
116
  DynamicHTMLLastChild: () => DynamicHTMLLastChild$1,
@@ -123,6 +124,7 @@ const BranchScopes$3 = "BranchScopes:";
123
124
  const ClosureScopes$1 = "ClosureScopes:";
124
125
  const ClosureSignalIndex$1 = "ClosureSignalIndex:";
125
126
  const ConditionalRenderer$1 = "ConditionalRenderer:";
127
+ const ControlledObserver$1 = "ControlledObserver:";
126
128
  const ControlledHandler$1 = "ControlledHandler:";
127
129
  const ControlledType$1 = "ControlledType:";
128
130
  const ControlledValue$1 = "ControlledValue:";
@@ -238,7 +240,7 @@ function isNullableExpr(expr) {
238
240
  case "|=":
239
241
  case "**=": return false;
240
242
  case "||=":
241
- case "??=": return isNullableExpr(expr.right) || isNullableExpr(expr.left);
243
+ case "??=": return isNullableExpr(expr.right);
242
244
  case "&&=": return isNullableExpr(expr.left) || isNullableExpr(expr.right);
243
245
  default: return true;
244
246
  }
@@ -246,7 +248,7 @@ function isNullableExpr(expr) {
246
248
  case "ConditionalExpression": return isNullableExpr(expr.consequent) || isNullableExpr(expr.alternate);
247
249
  case "LogicalExpression": switch (expr.operator) {
248
250
  case "||":
249
- case "??": return isNullableExpr(expr.right) || isNullableExpr(expr.left);
251
+ case "??": return isNullableExpr(expr.right);
250
252
  case "&&": return isNullableExpr(expr.left) || isNullableExpr(expr.right);
251
253
  default: return true;
252
254
  }
@@ -908,6 +910,7 @@ var accessor_prefix_exports = /* @__PURE__ */ __exportAll({
908
910
  ClosureSignalIndex: () => "C",
909
911
  ConditionalRenderer: () => "D",
910
912
  ControlledHandler: () => "E",
913
+ ControlledObserver: () => "N",
911
914
  ControlledType: () => "F",
912
915
  ControlledValue: () => "G",
913
916
  DynamicHTMLLastChild: () => "H",
@@ -2071,10 +2074,7 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
2071
2074
  }
2072
2075
  const childScope = getScopeById(branchId);
2073
2076
  const needsScript = childScope && (childScope["EventAttributes:a"] || childScope["ControlledHandler:a"]);
2074
- if (needsScript) {
2075
- writeScope(branchId, { [Renderer$1]: renderer });
2076
- _script(branchId, "d");
2077
- }
2077
+ if (needsScript) _script(branchId, "d");
2078
2078
  if (shouldResume || needsScript) _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
2079
2079
  };
2080
2080
  renderNative();
@@ -2527,7 +2527,7 @@ function visitInternal(section) {
2527
2527
  }
2528
2528
  function nCodeString(code, number) {
2529
2529
  switch (code) {
2530
- case 67: return toCharString(number, code, 20);
2530
+ case 67: return toCharString(number, code, 25);
2531
2531
  case 97: return toCharString(number, code, 10);
2532
2532
  case 107: return toCharString(number, code, 10);
2533
2533
  default: throw new Error(`Unexpected walk code: ${code}`);
@@ -2543,6 +2543,16 @@ function toCharString(number, startCode, rangeSize) {
2543
2543
  result += String.fromCharCode(startCode + number);
2544
2544
  return result;
2545
2545
  }
2546
+ /** `_content` strips trailing exit codes before it walks, so a renderer that
2547
+ * reaches the runtime through it never needs them on the wire. */
2548
+ function trimTrailingExits(walks) {
2549
+ if (!_marko_compiler.types.isStringLiteral(walks)) return walks;
2550
+ const value = walks.value.replace(/[^\0-1]+$/, "");
2551
+ return value === walks.value ? walks : value ? withLeadingComment(_marko_compiler.types.stringLiteral(value), getComment(walks)) : void 0;
2552
+ }
2553
+ function getComment(node) {
2554
+ return node.leadingComments?.[0]?.value.trim() || "";
2555
+ }
2546
2556
  function getWalkString(section) {
2547
2557
  if (section.content?.endType === 1) getSteps(section).push(0, 1);
2548
2558
  visitInternal(section);
@@ -3615,7 +3625,8 @@ var dom_default = { translate: {
3615
3625
  if (childSection !== section) {
3616
3626
  const tagParamsSignal = childSection.params && initValue(childSection.params);
3617
3627
  const tagParamsIdentifier = tagParamsSignal && signalHasStatements(tagParamsSignal) ? tagParamsSignal.identifier : void 0;
3618
- const { walks, writes, decls } = getSectionMeta(childSection);
3628
+ const { writes, decls } = getSectionMeta(childSection);
3629
+ const walks = trimTrailingExits(getSectionMeta(childSection).walks);
3619
3630
  const setup = getSetup(childSection);
3620
3631
  const written = writeSignals(childSection);
3621
3632
  const setupIdentifier = setup && written.has(setup) ? setup.identifier : void 0;
@@ -4748,8 +4759,12 @@ var native_tag_default = {
4748
4759
  }
4749
4760
  if (spreadExpression) {
4750
4761
  const canHaveAttrContent = !(isTextOnly || isOpenOnly || hasChildren || staticContentAttr);
4751
- if (skipExpression) addStatement("render", tagSection, tagExtra.referencedBindings, _marko_compiler.types.expressionStatement(callRuntime(canHaveAttrContent ? "_attrs_partial_content" : "_attrs_partial", scopeIdentifier, visitAccessor, spreadExpression, skipExpression)));
4752
- else addStatement("render", tagSection, tagExtra.referencedBindings, _marko_compiler.types.expressionStatement(callRuntime(canHaveAttrContent ? "_attrs_content" : "_attrs", scopeIdentifier, visitAccessor, spreadExpression)));
4762
+ const name = tag.get("name");
4763
+ const staticName = name.isStringLiteral() ? name.node.value : void 0;
4764
+ const controllable = controllableClaimFor(staticName);
4765
+ if (skipExpression) addStatement("render", tagSection, tagExtra.referencedBindings, _marko_compiler.types.expressionStatement(callRuntime(canHaveAttrContent ? "_attrs_partial_content" : "_attrs_partial", scopeIdentifier, visitAccessor, spreadExpression, skipExpression, controllable && importRuntime(controllable))));
4766
+ else addStatement("render", tagSection, tagExtra.referencedBindings, _marko_compiler.types.expressionStatement(callRuntime(canHaveAttrContent ? "_attrs_content" : "_attrs", scopeIdentifier, visitAccessor, spreadExpression, controllable && importRuntime(controllable))));
4767
+ enableControllable(controllableScriptLatchFor(staticName));
4753
4768
  addStatement("effect", tagSection, tagExtra.referencedBindings, _marko_compiler.types.expressionStatement(callRuntime("_attrs_script", scopeIdentifier, visitAccessor)), false);
4754
4769
  }
4755
4770
  if (staticContentAttr) addStatement("render", tagSection, staticContentAttr.value.extra?.referencedBindings, _marko_compiler.types.expressionStatement(callRuntime("_attr_content", scopeIdentifier, visitAccessor, staticContentAttr.value)), void 0, true);
@@ -5159,6 +5174,40 @@ function isDynamicControllable(controllable) {
5159
5174
  function buildUndefined$1() {
5160
5175
  return _marko_compiler.types.unaryExpression("void", _marko_compiler.types.numericLiteral(0));
5161
5176
  }
5177
+ /** How a statically named tag claims its controlled attrs during render;
5178
+ * nothing for the many tags that control nothing. */
5179
+ function controllableClaimFor(tagName) {
5180
+ switch (tagName) {
5181
+ case "input": return "_controllable_input";
5182
+ case "textarea": return "_controllable_textarea";
5183
+ case "select": return "_controllable_select";
5184
+ case "details":
5185
+ case "dialog": return "_controllable_open";
5186
+ }
5187
+ }
5188
+ /** The resume-pass latch for a tag: `_attrs_script` resolves the control kind
5189
+ * at run time, and a run-time tag name can be any of them. */
5190
+ function controllableScriptLatchFor(tagName) {
5191
+ switch (tagName) {
5192
+ case "input": return "_enable_controllable_input";
5193
+ case "textarea": return "_enable_controllable_textarea";
5194
+ case "select": return "_enable_controllable_select";
5195
+ case "details":
5196
+ case "dialog": return "_enable_controllable_open";
5197
+ case void 0: return "_enable_controllable";
5198
+ }
5199
+ }
5200
+ const enabledControllables = /* @__PURE__ */ new WeakMap();
5201
+ /** Emits the latch once per program, like `_enable_catch`. */
5202
+ function enableControllable(helper) {
5203
+ if (!helper) return;
5204
+ const program = (0, _marko_compiler_babel_utils.getProgram)().node;
5205
+ let enabled = enabledControllables.get(program);
5206
+ if (!enabled) enabledControllables.set(program, enabled = /* @__PURE__ */ new Set());
5207
+ if (enabled.has(helper)) return;
5208
+ enabled.add(helper);
5209
+ program.body.push(_marko_compiler.types.expressionStatement(callRuntime(helper)));
5210
+ }
5162
5211
  //#endregion
5163
5212
  //#region src/translator/util/is-only-child-in-parent.ts
5164
5213
  const kOnlyChildInParent = Symbol("only child in parent");
@@ -9781,13 +9830,25 @@ var dynamic_tag_default = {
9781
9830
  const argsOrInput = hasTagArgs ? _marko_compiler.types.arrayExpression(args) : args[0];
9782
9831
  if (!_marko_compiler.types.isObjectExpression(argsOrInput) || argsOrInput.properties.length) signal.extraArgs = [_marko_compiler.types.arrowFunctionExpression([], statements.length ? _marko_compiler.types.blockStatement(statements.concat(_marko_compiler.types.returnStatement(argsOrInput))) : argsOrInput)];
9783
9832
  }
9784
- if (!isClassAPI) enableDynamicTagResume(tag);
9833
+ if (!isClassAPI) {
9834
+ enableDynamicTagResume(tag);
9835
+ enableDynamicTagControllables(tag);
9836
+ }
9785
9837
  addValue(section, tagExtra.referencedBindings, signal, tagExpression);
9786
9838
  tag.remove();
9787
9839
  }
9788
9840
  }
9789
9841
  }
9790
9842
  };
9843
+ const controlledAttrs = /^(?:value|checked(?:Value)?|open)(?:Change)?$/;
9844
+ /** The name resolves at run time, so any control kind is possible. */
9845
+ function enableDynamicTagControllables(tag) {
9846
+ if (analyzeTagNameType(tag, true) === 1) return;
9847
+ for (const attr of tag.node.attributes) if (attr.type === "MarkoSpreadAttribute" || attr.type === "MarkoAttribute" && controlledAttrs.test(attr.name)) {
9848
+ enableControllable(controllableScriptLatchFor(void 0));
9849
+ return;
9850
+ }
9851
+ }
9791
9852
  function enableDynamicTagResume(tag) {
9792
9853
  const program = (0, _marko_compiler_babel_utils.getProgram)().node;
9793
9854
  if (!importedDynamicTagResume.has(program) && analyzeTagNameType(tag, true) !== 1) {
@@ -11,4 +11,7 @@ export declare function exit(path: t.NodePath<any>): void;
11
11
  export declare function enterShallow(path: t.NodePath<any>): void;
12
12
  export declare function injectWalks(tag: t.NodePath<t.MarkoTag>, name: string, expr?: Walk): void;
13
13
  export declare function visit(path: t.NodePath<t.MarkoTag | t.MarkoPlaceholder | t.Program>, code: VisitCodes): void;
14
+ /** `_content` strips trailing exit codes before it walks, so a renderer that
15
+ * reaches the runtime through it never needs them on the wire. */
16
+ export declare function trimTrailingExits(walks: t.Expression | undefined): t.ArrayExpression | t.ArrowFunctionExpression | t.AssignmentExpression | t.AwaitExpression | t.BigIntLiteral | t.BinaryExpression | t.BindExpression | t.BooleanLiteral | t.CallExpression | t.ClassExpression | t.ConditionalExpression | t.DecimalLiteral | t.DoExpression | t.FunctionExpression | t.Identifier | t.Import | t.ImportExpression | t.JSXElement | t.JSXFragment | t.LogicalExpression | t.MarkoParseError | t.MemberExpression | t.MetaProperty | t.ModuleExpression | t.NewExpression | t.NullLiteral | t.NumericLiteral | t.ObjectExpression | t.OptionalCallExpression | t.OptionalMemberExpression | t.ParenthesizedExpression | t.PipelineBareFunction | t.PipelinePrimaryTopicReference | t.PipelineTopicExpression | t.RecordExpression | t.RegExpLiteral | t.SequenceExpression | t.StringLiteral | t.Super | t.TSAsExpression | t.TSInstantiationExpression | t.TSNonNullExpression | t.TSSatisfiesExpression | t.TSTypeAssertion | t.TaggedTemplateExpression | t.TemplateLiteral | t.ThisExpression | t.TopicReference | t.TupleExpression | t.TypeCastExpression | t.UnaryExpression | t.UpdateExpression | t.YieldExpression | undefined;
14
17
  export declare function getWalkString(section: Section): t.Expression | undefined;
@@ -1,5 +1,6 @@
1
1
  import { types as t } from "@marko/compiler";
2
2
  import { type Binding } from "../../util/references";
3
+ import { type DOMRuntimeHelpers } from "../../util/runtime";
3
4
  export declare const kNativeTagBinding: unique symbol;
4
5
  export declare const kSkipEndTag: unique symbol;
5
6
  declare const kTagContentAttr: unique symbol;
@@ -20,3 +21,11 @@ declare const _default: {
20
21
  };
21
22
  };
22
23
  export default _default;
24
+ /** How a statically named tag claims its controlled attrs during render;
25
+ * nothing for the many tags that control nothing. */
26
+ export declare function controllableClaimFor(tagName: string | undefined): "_controllable_input" | "_controllable_open" | "_controllable_select" | "_controllable_textarea" | undefined;
27
+ /** The resume-pass latch for a tag: `_attrs_script` resolves the control kind
28
+ * at run time, and a run-time tag name can be any of them. */
29
+ export declare function controllableScriptLatchFor(tagName: string | undefined): "_enable_controllable" | "_enable_controllable_input" | "_enable_controllable_open" | "_enable_controllable_select" | "_enable_controllable_textarea" | undefined;
30
+ /** Emits the latch once per program, like `_enable_catch`. */
31
+ export declare function enableControllable(helper: DOMRuntimeHelpers | undefined): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.3.23",
3
+ "version": "6.3.25",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",
@@ -54,8 +54,8 @@
54
54
  "magic-string": "^0.30.21"
55
55
  },
56
56
  "devDependencies": {
57
- "@marko/runtime-tags": "npm:marko@6.3.23",
58
- "marko": "5.39.28"
57
+ "marko": "5.39.29",
58
+ "@marko/runtime-tags": "npm:marko@6.3.25"
59
59
  },
60
60
  "engines": {
61
61
  "node": ">=22"