marko 6.3.42 → 6.3.43

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/cheatsheet.md CHANGED
@@ -7,17 +7,17 @@ Marko 6 = HTML superset, not JSX and not Marko 4/5 syntax. `.marko` files are co
7
7
  1. Text interpolation: `${expr}` inside tag bodies. A bare line at the template root parses as a tag (concise mode): `Welcome aboard` fails to compile, but `p is a tag` compiles **silently** to `<p is a tag></p>`, since any line starting with a real tag name loses its words to attributes. Wrap text in an element (`<p>Welcome aboard</p>`) or prefix the line with `--` and a space (`-- Welcome ${name}`). Attributes take raw JS after `=` with no braces or quotes: `<div title=user.name data-n=1 + 1>`.
8
8
  2. A top-level `>` hugging its operand in an attribute value **ends the tag** silently: `<button disabled=count>=8 onClick() {…}>More</button>` is `disabled=count` plus the text `=8 onClick() {…}>`, so the handler never binds. Space a `>=` (`disabled=count >= 8`), and parenthesize a bare `>` comparison (`hidden=(a > b)`) and a TS type argument `<let/s=(new Set<string>())>`. Do not move the type onto the tag variable instead: `<let/s:Set<string>=new Set()>` compiles but fails type-check with TS2322 (the annotation does not flow into the initializer). A `>` nested inside `(…)`/`{…}`/`[…]` is safe (`class={ big: n > 1 }`). `<` never closes a tag (`disabled=count<=1` is fine).
9
9
  3. State: `<let/name=initial>` (slash then var name!). Update by plain assignment in an event handler: `count++`, `text = "hi"`. No setState, no hooks.
10
- 4. Derived values: `<const/total=items.length * price>` auto-recomputes. Never use an effect to derive state. `<let>` is deliberately different: its value is an _initial_ value, so `<let/draft=input.text>` seeds from a reactive value and then de-syncs; that de-sync is the point of an editable copy. So pick by intent: recomputes → `<const>`, seeds then diverges → `<let>`. A `<let>` you never assign is just a frozen `<const>`. Updates batch: mid-handler a reassigned `<let>` reads current but its derived `<const>` reads stale, so recompute from the `<let>`.
10
+ 4. Derived values: `<const/total=items.length * price>` auto-recomputes. Never use an effect to derive state. A tag variable is whatever the tag returns, not the attribute you passed. `<let/draft=input.text>` re-runs on every `input.text` change but returns state it controls, so `draft` keeps your edits. Pick by intent: recomputes → `<const>`, seeds then diverges → `<let>`. A `<let>` you never assign is just a frozen `<const>`. Updates batch: mid-handler a reassigned `<let>` reads current but its derived `<const>` reads stale, so recompute from the `<let>`.
11
11
  5. Never mutate state in place: `items.push(x)` does not update the UI. Always reassign:
12
12
  - add: `items = items.concat(x)`
13
13
  - remove: `items = items.toSpliced(i, 1)`
14
14
  - update: `items = items.toSpliced(i, 1, { ...item, done: true })`
15
15
  - object: `user = { ...user, name }`
16
16
  6. Events: method shorthand `onClick() { ... }` or `onClick=fn`. Handlers receive `(event, element)`; delegation means the element is the second parameter, not `event.currentTarget`: `onSubmit(e) { e.preventDefault(); save() }`, `onClick(e, el) { el.focus() }`. Don't sync input values through `onInput`/`onChange`; that's what the change handlers below are for. Prefix with `async` to `await` in the body: `async onClick() { await save() }`.
17
- 7. Native inputs are uncontrolled by default: `value=` sets the default value — later writes update what `form.reset()` restores, never a dirty field's display. Adding the matching `*Change` handler is what makes them controlled: `valueChange` on `<input>`/`<textarea>`/`<select>`, `checkedChange` on checkboxes/radios, `openChange` on `<details>`/`<dialog>`. `value:=text` is the shorthand for `value=text valueChange(v) { text = v }`. (`<textarea value:=text/>`: value attribute, not body.)
17
+ 7. Native inputs are uncontrolled by default: `value=` sets the default value — later writes update what `form.reset()` restores, never a dirty field's display. Adding the matching `*Change` handler is what makes them controlled: `valueChange` on `<input>`/`<textarea>`/`<select>`, `checkedChange` on checkboxes/radios, `openChange` on `<details>`/`<dialog>`. `value:=text` is the shorthand for `value=text valueChange(v) { text = v }`. (`<textarea value:=text/>`: value attribute, not body.) `:=` differs by operand: on an identifier (`value:=text`) it assigns that variable; on a member expression (`<let/count:=input.count>` in a child) it wires `input.countChange`, so the child is controlled when the parent passes that handler and keeps its own state when it doesn't.
18
18
  8. Transform in the handler when needed; number inputs give strings: `<input type="number" value=n valueChange(v) { n = +v }>`, or `value:parseFloat:=n`.
19
19
  9. Radio/checkbox groups: `checkedValue:=picked` on each input (shared var, distinct `value=`); the match is checked; array var for multi-checkbox. Dropdown: `<select value:=picked>`.
20
- 10. Module-level values and helpers need `static`: `static const LIMIT = 10`, `static function fmt(n) {…}`. Without it `function fmt(n) {` parses as a tag: ``Unable to find entry point for custom tag `<function>` ``, an error that never says `static`. Prefer it to `<const>` for anything that never changes: `<const/LIMIT=10>` emits a per-instance signal plus a `$setup` call.
20
+ 10. Module-level values, helpers and type aliases need `static`: `static const LIMIT = 10`, `static function fmt(n) {…}`, `static type Row = {…}`. Without it `function fmt(n) {` parses as a tag: ``Unable to find entry point for custom tag `<function>` ``, an error that never says `static`. Prefer it to `<const>` for anything that never changes: `<const/LIMIT=10>` emits a per-instance signal plus a `$setup` call. `server`/`client` narrow `static` to one platform (`client import { Chart } from "chart"`); the binding is `undefined` on the other, so read a `client` one only from `<script>`/handlers/`<lifecycle>` — reading it while rendering throws `is not a function` during SSR.
21
21
 
22
22
  ## Canonical component
23
23
 
@@ -69,7 +69,7 @@ Marko 6 = HTML superset, not JSX and not Marko 4/5 syntax. `.marko` files are co
69
69
  <show=open> stays mounted, keeps state (form drafts) when hidden </show>
70
70
  ```
71
71
 
72
- `<if>` destroys/rebuilds its content; `<show>` just hides it (use for toggles that must keep state).
72
+ `<if>` destroys/rebuilds its content; `<show>` renders it and hides it, on the server too (use for toggles that must keep state).
73
73
 
74
74
  ## Async (`<await>`)
75
75
 
@@ -202,6 +202,7 @@ Each left-hand habit is an error or silently wrong.
202
202
  | `$ const y = x * 2;` (scriptlets are removed) | `<const/y=x * 2>` |
203
203
  | `<let/n=a + b>` for a value that should recompute | `<const/n=a + b>`; `<let>` seeds an initial value, then de-syncs by design |
204
204
  | `function fmt(n) {…}` / `const LIMIT = 10` at module level | `static function fmt(n) {…}` / `static const LIMIT = 10` |
205
+ | `type Row = {…}` at module level | `static type Row = {…}` |
205
206
  | `<let x=0>` | `<let/x=0>` |
206
207
  | `<if(cond)>` | `<if=cond>` |
207
208
  | `items.push(x)` | `items = items.concat(x)` |
@@ -1,4 +1,4 @@
1
- let require_control_flow = require("../dom-BfloYt04.js"), handlePendingTry = (fn, scope, branch) => {
1
+ let require_control_flow = require("../dom-CKak9Qet.js"), handlePendingTry = (fn, scope, branch) => {
2
2
  for (; branch;) {
3
3
  if (branch.O?.i) return (branch.J ||= []).push(fn, scope);
4
4
  branch = branch.N;
@@ -4,7 +4,7 @@ let handlePendingTry = (fn, scope, branch) => {
4
4
  branch = branch.N;
5
5
  }
6
6
  };
7
- import { $t as placeholderShown, Qt as installCatch, Zt as caughtError, g as renderCatch } from "../dom-BVNolGe1.mjs";
7
+ import { $t as placeholderShown, Qt as installCatch, Zt as caughtError, g as renderCatch } from "../dom-HMfNm7KC.mjs";
8
8
  //#region src/dom/catch.feat.ts
9
9
  installCatch((runEffects) => (effects, checkPending = placeholderShown.has(effects)) => {
10
10
  if (checkPending || caughtError.has(effects)) {
@@ -1,3 +1,3 @@
1
- let require_control_flow = require("../dom-BfloYt04.js");
1
+ let require_control_flow = require("../dom-CKak9Qet.js");
2
2
  require_control_flow.z[0] = require_control_flow.T, require_control_flow.z[1] = require_control_flow.C, require_control_flow.z[2] = require_control_flow.A;
3
3
  //#endregion
@@ -1,3 +1,3 @@
1
- import { A as _attr_input_value_script, C as _attr_input_checkedValue_script, T as _attr_input_checked_script, z as controllableScripts } from "../dom-BVNolGe1.mjs";
1
+ import { A as _attr_input_value_script, C as _attr_input_checkedValue_script, T as _attr_input_checked_script, z as controllableScripts } from "../dom-HMfNm7KC.mjs";
2
2
  controllableScripts[0] = _attr_input_checked_script, controllableScripts[1] = _attr_input_checkedValue_script, controllableScripts[2] = _attr_input_value_script;
3
3
  //#endregion
@@ -1,4 +1,4 @@
1
- let require_control_flow = require("../dom-BfloYt04.js");
1
+ let require_control_flow = require("../dom-CKak9Qet.js");
2
2
  //#region src/dom/controllable-open.feat.ts
3
3
  require_control_flow.z[4] = require_control_flow.y;
4
4
  //#endregion
@@ -1,4 +1,4 @@
1
- import { y as _attr_details_or_dialog_open_script, z as controllableScripts } from "../dom-BVNolGe1.mjs";
1
+ import { y as _attr_details_or_dialog_open_script, z as controllableScripts } from "../dom-HMfNm7KC.mjs";
2
2
  //#region src/dom/controllable-open.feat.ts
3
3
  controllableScripts[4] = _attr_details_or_dialog_open_script;
4
4
  //#endregion
@@ -1,4 +1,4 @@
1
- let require_control_flow = require("../dom-BfloYt04.js");
1
+ let require_control_flow = require("../dom-CKak9Qet.js");
2
2
  //#region src/dom/controllable-select.feat.ts
3
3
  require_control_flow.z[3] = require_control_flow.N;
4
4
  //#endregion
@@ -1,4 +1,4 @@
1
- import { N as _attr_select_value_script, z as controllableScripts } from "../dom-BVNolGe1.mjs";
1
+ import { N as _attr_select_value_script, z as controllableScripts } from "../dom-HMfNm7KC.mjs";
2
2
  //#region src/dom/controllable-select.feat.ts
3
3
  controllableScripts[3] = _attr_select_value_script;
4
4
  //#endregion
@@ -1,4 +1,4 @@
1
- let require_control_flow = require("../dom-BfloYt04.js");
1
+ let require_control_flow = require("../dom-CKak9Qet.js");
2
2
  //#region src/dom/controllable-textarea.feat.ts
3
3
  require_control_flow.z[2] = require_control_flow.A;
4
4
  //#endregion
@@ -1,4 +1,4 @@
1
- import { A as _attr_input_value_script, z as controllableScripts } from "../dom-BVNolGe1.mjs";
1
+ import { A as _attr_input_value_script, z as controllableScripts } from "../dom-HMfNm7KC.mjs";
2
2
  //#region src/dom/controllable-textarea.feat.ts
3
3
  controllableScripts[2] = _attr_input_value_script;
4
4
  //#endregion
@@ -1,3 +1,3 @@
1
- let require_control_flow = require("../dom-BfloYt04.js");
1
+ let require_control_flow = require("../dom-CKak9Qet.js");
2
2
  require("./controllable-input.feat.js"), require("./controllable-open.feat.js"), require("./controllable-select.feat.js"), require_control_flow.R.INPUT = require_control_flow.P, require_control_flow.R.TEXTAREA = require_control_flow.L, require_control_flow.R.SELECT = require_control_flow.I, require_control_flow.R.DETAILS = require_control_flow.R.DIALOG = require_control_flow.F;
3
3
  //#endregion
@@ -1,4 +1,4 @@
1
- import { F as _controllable_open, I as _controllable_select, L as _controllable_textarea, P as _controllable_input, R as controllableRenders } from "../dom-BVNolGe1.mjs";
1
+ import { F as _controllable_open, I as _controllable_select, L as _controllable_textarea, P as _controllable_input, R as controllableRenders } from "../dom-HMfNm7KC.mjs";
2
2
  import "./controllable-input.feat.mjs";
3
3
  import "./controllable-open.feat.mjs";
4
4
  import "./controllable-select.feat.mjs";
@@ -1,3 +1,3 @@
1
- let require_control_flow = require("../dom-BfloYt04.js"), elementGetter = (branch) => () => branch.S;
2
- require_control_flow.m((branch) => branch.T(elementGetter(branch))), require_control_flow.gt("e", elementGetter);
1
+ let require_control_flow = require("../dom-CKak9Qet.js"), elementGetter = (branch) => () => branch.S;
2
+ require_control_flow.m((branch) => branch.T(elementGetter(branch))), require_control_flow.gt("_e", elementGetter);
3
3
  //#endregion
@@ -1,4 +1,4 @@
1
1
  let elementGetter = (branch) => () => branch.S;
2
- import { gt as _resume, m as installDynamicTagVar } from "../dom-BVNolGe1.mjs";
3
- installDynamicTagVar((branch) => branch.T(elementGetter(branch))), _resume("e", elementGetter);
2
+ import { gt as _resume, m as installDynamicTagVar } from "../dom-HMfNm7KC.mjs";
3
+ installDynamicTagVar((branch) => branch.T(elementGetter(branch))), _resume("_e", elementGetter);
4
4
  //#endregion
@@ -1,6 +1,6 @@
1
- let require_control_flow = require("../dom-BfloYt04.js");
1
+ let require_control_flow = require("../dom-CKak9Qet.js");
2
2
  //#region src/dom/placeholder.feat.ts
3
- require_control_flow.St.f = (tryBranch) => {
3
+ require_control_flow.St._f = (tryBranch) => {
4
4
  tryBranch.P &&= (require_control_flow.Wt(tryBranch.P), 0);
5
5
  };
6
6
  //#endregion
@@ -1,6 +1,6 @@
1
- import { St as registeredValues, Wt as destroyBranch } from "../dom-BVNolGe1.mjs";
1
+ import { St as registeredValues, Wt as destroyBranch } from "../dom-HMfNm7KC.mjs";
2
2
  //#region src/dom/placeholder.feat.ts
3
- registeredValues.f = (tryBranch) => {
3
+ registeredValues._f = (tryBranch) => {
4
4
  tryBranch.P &&= (destroyBranch(tryBranch.P), 0);
5
5
  };
6
6
  //#endregion
@@ -80,7 +80,7 @@ let unsafeStyleAttrReg = /[\\;]/g, replaceUnsafeStyleAttr = (c) => c === ";" ? "
80
80
  return (scope, renderer) => {
81
81
  if (scope[rendererAccessor] !== (scope[rendererAccessor] = rendererKey(renderer)) && (setConditionalRenderer(scope, nodeAccessor, renderer, createAndSetupBranch), renderer?.f && subscribeToScopeSet(renderer.e, renderer.f, scope[childScopeAccessor])), renderer) for (let accessor in renderer.g) renderer.g[accessor](scope[childScopeAccessor], renderer.h[accessor]);
82
82
  };
83
- }), bindNativeTagVar, _resume_dynamic_tag = /*@__PURE__*/ withBranches(() => _resume("d", dynamicTagScript)), loop = /*@__PURE__*/ withBranches((forEach) => (nodeAccessor, template, walks, setup, params) => {
83
+ }), bindNativeTagVar, _resume_dynamic_tag = /*@__PURE__*/ withBranches(() => _resume("_d", dynamicTagScript)), loop = /*@__PURE__*/ withBranches((forEach) => (nodeAccessor, template, walks, setup, params) => {
84
84
  nodeAccessor = decodeAccessor(nodeAccessor);
85
85
  let scopesAccessor = "A" + nodeAccessor, keyedScopesAccessor = "O" + nodeAccessor, renderer = _content("", template, walks, setup)();
86
86
  return (scope, value) => {
@@ -80,7 +80,7 @@ let unsafeStyleAttrReg = /[\\;]/g, replaceUnsafeStyleAttr = (c) => c === ";" ? "
80
80
  return (scope, renderer) => {
81
81
  if (scope[rendererAccessor] !== (scope[rendererAccessor] = rendererKey(renderer)) && (setConditionalRenderer(scope, nodeAccessor, renderer, createAndSetupBranch), renderer?.f && subscribeToScopeSet(renderer.e, renderer.f, scope[childScopeAccessor])), renderer) for (let accessor in renderer.g) renderer.g[accessor](scope[childScopeAccessor], renderer.h[accessor]);
82
82
  };
83
- }), bindNativeTagVar, _resume_dynamic_tag = /*@__PURE__*/ withBranches(() => _resume("d", dynamicTagScript)), loop = /*@__PURE__*/ withBranches((forEach) => (nodeAccessor, template, walks, setup, params) => {
83
+ }), bindNativeTagVar, _resume_dynamic_tag = /*@__PURE__*/ withBranches(() => _resume("_d", dynamicTagScript)), loop = /*@__PURE__*/ withBranches((forEach) => (nodeAccessor, template, walks, setup, params) => {
84
84
  nodeAccessor = decodeAccessor(nodeAccessor);
85
85
  let scopesAccessor = "A" + nodeAccessor, keyedScopesAccessor = "O" + nodeAccessor, renderer = _content("", template, walks, setup)();
86
86
  return (scope, value) => {
package/dist/dom.js CHANGED
@@ -1,4 +1,4 @@
1
- let require_control_flow = require("./dom-BfloYt04.js"), empty = [], rest = Symbol(), classIdToBranch = /* @__PURE__ */ new Map(), classEventResolver, scopesByRender = /* @__PURE__ */ new WeakMap(), getRenderScopes = ($global) => {
1
+ let require_control_flow = require("./dom-CKak9Qet.js"), empty = [], rest = Symbol(), classIdToBranch = /* @__PURE__ */ new Map(), classEventResolver, scopesByRender = /* @__PURE__ */ new WeakMap(), getRenderScopes = ($global) => {
2
2
  require_control_flow.yt($global.runtimeId);
3
3
  let render = self[$global.runtimeId]?.[$global.renderId], scopes = render && scopesByRender.get(render);
4
4
  return render && !scopes && scopesByRender.set(render, scopes = {}), scopes;
package/dist/dom.mjs CHANGED
@@ -94,7 +94,7 @@ let empty = [], rest = Symbol(), classIdToBranch = /* @__PURE__ */ new Map(), cl
94
94
  pending ||= load(), scope.X || !("X" in scope) && scope.H === runId ? (scope.X ||= /* @__PURE__ */ new Map()).set(pending, { a: value }) : signal ? signal(scope, value) : pending.then((mod) => queueAsyncRender(scope, signal = mod._, value), () => 0);
95
95
  };
96
96
  });
97
- import { $ as _attrs_script, A as _attr_input_value_script, At as _for_selector, B as _attr, Bt as _script, C as _attr_input_checkedValue_script, Ct as withLazy, D as _attr_input_value_attribute_default, Dt as _const, E as _attr_input_value, Et as _closure_get, F as _controllable_open, Ft as _let, G as _attr_nonce, Gt as insertBranchBefore, H as _attr_class_item, Ht as _var_change, I as _controllable_select, It as _let_change, J as _attr_style_items, Jt as _on, K as _attr_style, Kt as removeAndDestroyBranch, L as _controllable_textarea, Lt as _or, M as _attr_select_value_default, Mt as _hoist_resume, N as _attr_select_value_script, Nt as _id, O as _attr_input_value_default, Ot as _el_read, P as _controllable_input, Pt as _if_closure, Q as _attrs_partial_content, Rt as _return, S as _attr_input_checkedValue_default, T as _attr_input_checked_script, Tt as _closure, U as _attr_class_items, Ut as _assert_init, V as _attr_class, Vt as _var, W as _attr_content, Wt as destroyBranch, X as _attrs_content, Xt as $signalReset, Y as _attrs, Yt as $signal, Z as _attrs_partial, _ as _attr_details_or_dialog_open, _t as _var_resume, a as _for_in, an as runId, at as _text_content, b as _attr_input_checked, bt as initEmbedded, c as _for_until, cn as forTo, ct as toInsertNode, d as _show, dn as _hoist_read_error, dt as _content_resume, en as prepareEffects, et as _html, f as _try, fn as _call, ft as createAndSetupBranch, g as renderCatch, gt as _resume, h as patchDynamicTag, ht as _el, i as _dynamic_tag_content, in as runEffects, it as _text, j as _attr_select_value, jt as _hoist, k as _attr_input_value_dynamic_default, kt as _for_closure, l as _if, ln as forUntil, lt as _content, mt as setupBranch, n as _await_promise, nn as queueEffect, nt as _style_rule_item, o as _for_of, on as forIn, ot as _to_text, p as addAwaitCounter, pn as decodeAccessor, pt as createBranch, q as _attr_style_item, qt as syncGen, r as _dynamic_tag, rn as run, rt as _style_shell, s as _for_to, sn as forOf, st as insertChildNodes, t as _await_content, tn as queueAsyncRender, tt as _lifecycle, u as _resume_dynamic_tag, un as _assert_hoist, ut as _content_closures, v as _attr_details_or_dialog_open_default, vt as getRegisteredWithScope, w as _attr_input_checked_default, wt as _child_setup, x as _attr_input_checkedValue, xt as ready, y as _attr_details_or_dialog_open_script, yt as init, zt as _return_change } from "./dom-BVNolGe1.mjs";
97
+ import { $ as _attrs_script, A as _attr_input_value_script, At as _for_selector, B as _attr, Bt as _script, C as _attr_input_checkedValue_script, Ct as withLazy, D as _attr_input_value_attribute_default, Dt as _const, E as _attr_input_value, Et as _closure_get, F as _controllable_open, Ft as _let, G as _attr_nonce, Gt as insertBranchBefore, H as _attr_class_item, Ht as _var_change, I as _controllable_select, It as _let_change, J as _attr_style_items, Jt as _on, K as _attr_style, Kt as removeAndDestroyBranch, L as _controllable_textarea, Lt as _or, M as _attr_select_value_default, Mt as _hoist_resume, N as _attr_select_value_script, Nt as _id, O as _attr_input_value_default, Ot as _el_read, P as _controllable_input, Pt as _if_closure, Q as _attrs_partial_content, Rt as _return, S as _attr_input_checkedValue_default, T as _attr_input_checked_script, Tt as _closure, U as _attr_class_items, Ut as _assert_init, V as _attr_class, Vt as _var, W as _attr_content, Wt as destroyBranch, X as _attrs_content, Xt as $signalReset, Y as _attrs, Yt as $signal, Z as _attrs_partial, _ as _attr_details_or_dialog_open, _t as _var_resume, a as _for_in, an as runId, at as _text_content, b as _attr_input_checked, bt as initEmbedded, c as _for_until, cn as forTo, ct as toInsertNode, d as _show, dn as _hoist_read_error, dt as _content_resume, en as prepareEffects, et as _html, f as _try, fn as _call, ft as createAndSetupBranch, g as renderCatch, gt as _resume, h as patchDynamicTag, ht as _el, i as _dynamic_tag_content, in as runEffects, it as _text, j as _attr_select_value, jt as _hoist, k as _attr_input_value_dynamic_default, kt as _for_closure, l as _if, ln as forUntil, lt as _content, mt as setupBranch, n as _await_promise, nn as queueEffect, nt as _style_rule_item, o as _for_of, on as forIn, ot as _to_text, p as addAwaitCounter, pn as decodeAccessor, pt as createBranch, q as _attr_style_item, qt as syncGen, r as _dynamic_tag, rn as run, rt as _style_shell, s as _for_to, sn as forOf, st as insertChildNodes, t as _await_content, tn as queueAsyncRender, tt as _lifecycle, u as _resume_dynamic_tag, un as _assert_hoist, ut as _content_closures, v as _attr_details_or_dialog_open_default, vt as getRegisteredWithScope, w as _attr_input_checked_default, wt as _child_setup, x as _attr_input_checkedValue, xt as ready, y as _attr_details_or_dialog_open_script, yt as init, zt as _return_change } from "./dom-HMfNm7KC.mjs";
98
98
  //#region src/common/attr-tag.ts
99
99
  function attrTag(attrs) {
100
100
  return attrs[Symbol.iterator] = attrTagIterator, attrs[rest] = empty, attrs;
package/dist/html.js CHANGED
@@ -262,8 +262,8 @@ 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 && _script(branchId, "d"), (shouldResume || needsScript) && _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
266
- })(), result = _el(branchId, "e");
265
+ needsScript && _script(branchId, "_d"), (shouldResume || needsScript) && _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
266
+ })(), result = _el(branchId, "_e");
267
267
  } else {
268
268
  let chunk = getChunk(), beforeBranch = shouldResume ? deferBranchStart(chunk) : void 0, render = () => {
269
269
  if (renderer) try {
@@ -1686,7 +1686,7 @@ var State = class {
1686
1686
  let { state } = this.boundary, { branchId, scopeId, placeholderBranchId } = placeholder, reorderId = body.reorderId = branchId ? branchId + "" : state.nextReorderId();
1687
1687
  this.writeHTML(state.mark("!^", reorderId));
1688
1688
  let { effects } = this, beforeBranch = deferBranchStart(this), after = this.render(() => withBranchId(placeholderBranchId, placeholder.render)), stateful = after === this && this.effects !== effects;
1689
- applyBranchStart(this, beforeBranch, stateful), after === this ? stateful && (this.render(() => writeScope(branchId, { P: scopeWithId(state, placeholderBranchId) })), this.writeHTML(state.mark("]", scopeId + " " + ("P" + branchId) + " " + placeholderBranchId)), body.writeEffect(branchId, "f")) : this.boundary.abort(/* @__PURE__ */ Error("An @placeholder cannot contain async content.")), this.writeHTML(state.mark("!", reorderId)), state.reorder(body);
1689
+ applyBranchStart(this, beforeBranch, stateful), after === this ? stateful && (this.render(() => writeScope(branchId, { P: scopeWithId(state, placeholderBranchId) })), this.writeHTML(state.mark("]", scopeId + " " + ("P" + branchId) + " " + placeholderBranchId)), body.writeEffect(branchId, "_f")) : this.boundary.abort(/* @__PURE__ */ Error("An @placeholder cannot contain async content.")), this.writeHTML(state.mark("!", reorderId)), state.reorder(body);
1690
1690
  } else body.next = this.next, this.next = body;
1691
1691
  this.placeholder = null;
1692
1692
  }
package/dist/html.mjs CHANGED
@@ -262,8 +262,8 @@ 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 && _script(branchId, "d"), (shouldResume || needsScript) && _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
266
- })(), result = _el(branchId, "e");
265
+ needsScript && _script(branchId, "_d"), (shouldResume || needsScript) && _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
266
+ })(), result = _el(branchId, "_e");
267
267
  } else {
268
268
  let chunk = getChunk(), beforeBranch = shouldResume ? deferBranchStart(chunk) : void 0, render = () => {
269
269
  if (renderer) try {
@@ -1685,7 +1685,7 @@ var State = class {
1685
1685
  let { state } = this.boundary, { branchId, scopeId, placeholderBranchId } = placeholder, reorderId = body.reorderId = branchId ? branchId + "" : state.nextReorderId();
1686
1686
  this.writeHTML(state.mark("!^", reorderId));
1687
1687
  let { effects } = this, beforeBranch = deferBranchStart(this), after = this.render(() => withBranchId(placeholderBranchId, placeholder.render)), stateful = after === this && this.effects !== effects;
1688
- applyBranchStart(this, beforeBranch, stateful), after === this ? stateful && (this.render(() => writeScope(branchId, { P: scopeWithId(state, placeholderBranchId) })), this.writeHTML(state.mark("]", scopeId + " " + ("P" + branchId) + " " + placeholderBranchId)), body.writeEffect(branchId, "f")) : this.boundary.abort(/* @__PURE__ */ Error("An @placeholder cannot contain async content.")), this.writeHTML(state.mark("!", reorderId)), state.reorder(body);
1688
+ applyBranchStart(this, beforeBranch, stateful), after === this ? stateful && (this.render(() => writeScope(branchId, { P: scopeWithId(state, placeholderBranchId) })), this.writeHTML(state.mark("]", scopeId + " " + ("P" + branchId) + " " + placeholderBranchId)), body.writeEffect(branchId, "_f")) : this.boundary.abort(/* @__PURE__ */ Error("An @placeholder cannot contain async content.")), this.writeHTML(state.mark("!", reorderId)), state.reorder(body);
1689
1689
  } else body.next = this.next, this.next = body;
1690
1690
  this.placeholder = null;
1691
1691
  }
@@ -784,6 +784,7 @@ function isInvokedFunction(expr) {
784
784
  //#endregion
785
785
  //#region src/translator/util/constants/structure-kind.ts
786
786
  const Visit = "visit";
787
+ const Text = "text";
787
788
  const Child = "child";
788
789
  const SectionRef = "sectionRef";
789
790
  const ExportRef = "exportRef";
@@ -2373,11 +2374,11 @@ let _dynamic_tag = (scopeId, accessor, tag, inputOrArgs, content, inputIsArgs, s
2373
2374
  }
2374
2375
  const childScope = getScopeById(branchId);
2375
2376
  const needsScript = childScope && (childScope["EventAttributes:a"] || childScope["ControlledHandler:a"]);
2376
- if (needsScript) _script(branchId, "d");
2377
+ if (needsScript) _script(branchId, "_d");
2377
2378
  if (shouldResume || needsScript) _html(state.mark("'", scopeId + " " + accessor + " " + branchId));
2378
2379
  };
2379
2380
  renderNative();
2380
- result = _el(branchId, "e");
2381
+ result = _el(branchId, "_e");
2381
2382
  } else {
2382
2383
  const chunk = void 0;
2383
2384
  const beforeBranch = shouldResume ? deferBranchStart(chunk) : void 0;
@@ -3898,6 +3899,12 @@ function writeTo(path) {
3898
3899
  }
3899
3900
  };
3900
3901
  }
3902
+ function writeTextTo(path, value) {
3903
+ if (value) getSection(path).structure?.push({
3904
+ kind: Text,
3905
+ value
3906
+ });
3907
+ }
3901
3908
  function pushMarkup(structure, str) {
3902
3909
  if (!str) return;
3903
3910
  const last = structure.length - 1;
@@ -3923,17 +3930,31 @@ function resolveStructure(section) {
3923
3930
  walkComment: [],
3924
3931
  steps: startDynamic ? [0, 1] : []
3925
3932
  };
3926
- for (const op of section.structure) if (typeof op === "string") appendLiteral(resolved.writes, op);
3927
- else if (typeof op === "number") resolved.steps.push(op);
3933
+ let textEdge;
3934
+ for (const op of section.structure) if (typeof op === "string") {
3935
+ appendLiteral(resolved.writes, op);
3936
+ textEdge = void 0;
3937
+ } else if (typeof op === "number") resolved.steps.push(op);
3928
3938
  else switch (op.kind) {
3939
+ case Text:
3940
+ if (textEdge === "child") separate(resolved);
3941
+ appendLiteral(resolved.writes, op.value);
3942
+ textEdge = "own";
3943
+ break;
3929
3944
  case Visit:
3930
3945
  if (!op.claimed) continue;
3931
3946
  flushSteps(resolved);
3932
3947
  resolved.walkComment.push(walkCodeToName[op.code]);
3933
3948
  appendLiteral(resolved.walks, String.fromCharCode(op.code));
3934
- if (op.code !== 32) appendLiteral(resolved.writes, "<!>");
3949
+ if (op.code !== 32) {
3950
+ appendLiteral(resolved.writes, "<!>");
3951
+ textEdge = void 0;
3952
+ }
3935
3953
  break;
3936
3954
  case Child: {
3955
+ const content = refContent(op.renderer);
3956
+ if (textEdge && content?.startType === 4) separate(resolved);
3957
+ textEdge = content?.endType === 4 ? "child" : void 0;
3937
3958
  flushSteps(resolved);
3938
3959
  const template = op.renderer && resolveRef(op.renderer, "template");
3939
3960
  if (template) resolved.writes.push(template, "");
@@ -3952,6 +3973,13 @@ function resolveStructure(section) {
3952
3973
  flushSteps(resolved);
3953
3974
  return resolved;
3954
3975
  }
3976
+ function separate(resolved) {
3977
+ appendLiteral(resolved.writes, "<!>");
3978
+ resolved.steps.push(0, 1);
3979
+ }
3980
+ function refContent(ref) {
3981
+ return (ref && (ref.kind === "sectionRef" ? ref.section : ref.program.section))?.content;
3982
+ }
3955
3983
  function resolveRef(ref, part) {
3956
3984
  if (ref.kind === "sectionRef") return getSectionMetaIdentifiers(ref.section)[part === "template" ? "writes" : "walks"];
3957
3985
  const name = ref.program.domExports[part];
@@ -9942,12 +9970,12 @@ var placeholder_default = {
9942
9970
  const staticText = confident ? getHTMLRuntime()[node.escape ? "_escape" : "_unescaped"](computed) : void 0;
9943
9971
  if (staticText === "") return;
9944
9972
  const extra = node.extra || {};
9945
- if (confident && node.escape) writeTo(placeholder)`${staticText}`;
9973
+ if (confident && node.escape) writeTextTo(placeholder, staticText);
9946
9974
  else {
9947
9975
  const siblingText = extra[kSiblingText];
9948
9976
  if (siblingText === 1 || siblingText === 2) visit(placeholder, 37);
9949
9977
  else {
9950
- writeTo(placeholder)` `;
9978
+ writeTextTo(placeholder, " ");
9951
9979
  visit(placeholder, 32);
9952
9980
  }
9953
9981
  }
@@ -10659,7 +10687,7 @@ var tag_default = {
10659
10687
  var text_default = {
10660
10688
  analyze: { exit(text) {
10661
10689
  if (isNonHTMLText(text)) return;
10662
- writeTo(text)`${text.node.value}`;
10690
+ writeTextTo(text, text.node.value);
10663
10691
  if (!isStaticText(getPrevStaticSibling(text))) enterShallow(text);
10664
10692
  } },
10665
10693
  translate: { exit(text) {
@@ -1,4 +1,5 @@
1
1
  export declare const Visit = "visit";
2
+ export declare const Text = "text";
2
3
  export declare const Child = "child";
3
4
  export declare const SectionRef = "sectionRef";
4
5
  export declare const ExportRef = "exportRef";
@@ -28,7 +28,11 @@ export interface StructureExportRef {
28
28
  path: string;
29
29
  hint: string;
30
30
  }
31
- export type StructureOp = string | Step.Value | StructureVisit | StructureChild;
31
+ export type StructureOp = string | Step.Value | StructureText | StructureVisit | StructureChild;
32
+ export interface StructureText {
33
+ kind: typeof StructureKind.Text;
34
+ value: string;
35
+ }
32
36
  export interface StructureVisit {
33
37
  kind: typeof StructureKind.Visit;
34
38
  code: typeof WalkCode.Get | typeof WalkCode.Replace | typeof WalkCode.DynamicTagWithVar;
@@ -6,6 +6,7 @@ export declare function exit(path: t.NodePath<any>): void;
6
6
  export declare function enterShallow(path: t.NodePath<any>): void;
7
7
  export declare function child(tag: t.NodePath<t.MarkoTag>, name: string, renderer?: StructureRef): void;
8
8
  export declare function writeTo(path: t.NodePath<any>): (strs: TemplateStringsArray, ...exprs: string[]) => void;
9
+ export declare function writeTextTo(path: t.NodePath<any>, value: string): void;
9
10
  export declare function visit(path: t.NodePath<t.MarkoTag | t.MarkoPlaceholder | t.Program>, code: StructureVisit["code"], claimed?: boolean): StructureVisit | undefined;
10
11
  type ResolvedPart = string | t.Expression;
11
12
  interface ResolvedStructure {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marko",
3
- "version": "6.3.42",
3
+ "version": "6.3.43",
4
4
  "description": "Optimized runtime for Marko templates.",
5
5
  "keywords": [
6
6
  "api",
@@ -57,7 +57,7 @@
57
57
  "magic-string": "^0.30.21"
58
58
  },
59
59
  "devDependencies": {
60
- "@marko/runtime-tags": "npm:marko@6.3.42",
60
+ "@marko/runtime-tags": "npm:marko@6.3.43",
61
61
  "marko": "5.39.35"
62
62
  },
63
63
  "engines": {