marko 6.4.0 → 6.4.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.
Files changed (123) hide show
  1. package/cheatsheet.md +1 -1
  2. package/dist/common/constants/accessor-prefix.d.ts +1 -0
  3. package/dist/common/constants/accessor-prefix.debug.d.ts +1 -0
  4. package/dist/common/constants/reserved-id.d.ts +5 -0
  5. package/dist/common/errors.d.ts +1 -1
  6. package/dist/common/types.d.ts +3 -0
  7. package/dist/debug/dom/catch.feat.js +1 -1
  8. package/dist/debug/dom/catch.feat.mjs +1 -1
  9. package/dist/debug/dom/controllable-input.feat.js +1 -1
  10. package/dist/debug/dom/controllable-input.feat.mjs +1 -1
  11. package/dist/debug/dom/controllable-open.feat.js +1 -1
  12. package/dist/debug/dom/controllable-open.feat.mjs +1 -1
  13. package/dist/debug/dom/controllable-select.feat.js +1 -1
  14. package/dist/debug/dom/controllable-select.feat.mjs +1 -1
  15. package/dist/debug/dom/controllable-textarea.feat.js +1 -1
  16. package/dist/debug/dom/controllable-textarea.feat.mjs +1 -1
  17. package/dist/debug/dom/controllable.feat.js +1 -1
  18. package/dist/debug/dom/controllable.feat.mjs +1 -1
  19. package/dist/debug/dom/dynamic-tag-script.feat.js +1 -1
  20. package/dist/debug/dom/dynamic-tag-script.feat.mjs +1 -1
  21. package/dist/debug/dom/dynamic-tag-var.feat.js +1 -1
  22. package/dist/debug/dom/dynamic-tag-var.feat.mjs +1 -1
  23. package/dist/debug/dom/lazy.feat.js +1 -1
  24. package/dist/debug/dom/lazy.feat.mjs +1 -1
  25. package/dist/debug/dom/placeholder.feat.js +1 -1
  26. package/dist/debug/dom/placeholder.feat.mjs +1 -1
  27. package/dist/debug/{dom-BRO5aArp.js → dom-ClV4kVOO.js} +32 -16
  28. package/dist/debug/{dom-Btj2QJhk.mjs → dom-LFrKxOk5.mjs} +32 -16
  29. package/dist/debug/dom.js +1 -1
  30. package/dist/debug/dom.mjs +1 -1
  31. package/dist/debug/html.js +277 -222
  32. package/dist/debug/html.mjs +275 -220
  33. package/dist/dom/catch.feat.js +1 -1
  34. package/dist/dom/catch.feat.mjs +1 -1
  35. package/dist/dom/controllable-input.feat.js +1 -1
  36. package/dist/dom/controllable-input.feat.mjs +1 -1
  37. package/dist/dom/controllable-open.feat.js +1 -1
  38. package/dist/dom/controllable-open.feat.mjs +1 -1
  39. package/dist/dom/controllable-select.feat.js +1 -1
  40. package/dist/dom/controllable-select.feat.mjs +1 -1
  41. package/dist/dom/controllable-textarea.feat.js +1 -1
  42. package/dist/dom/controllable-textarea.feat.mjs +1 -1
  43. package/dist/dom/controllable.feat.js +1 -1
  44. package/dist/dom/controllable.feat.mjs +1 -1
  45. package/dist/dom/dynamic-tag-script.feat.js +1 -1
  46. package/dist/dom/dynamic-tag-script.feat.mjs +1 -1
  47. package/dist/dom/dynamic-tag-var.feat.js +1 -1
  48. package/dist/dom/dynamic-tag-var.feat.mjs +1 -1
  49. package/dist/dom/lazy.feat.js +1 -1
  50. package/dist/dom/lazy.feat.mjs +1 -1
  51. package/dist/dom/placeholder.feat.js +1 -1
  52. package/dist/dom/placeholder.feat.mjs +1 -1
  53. package/dist/dom/signals.d.ts +3 -2
  54. package/dist/{dom-BSsI9OPC.js → dom-CNglVi8P.js} +13 -4
  55. package/dist/{dom-B-v8Gw6T.mjs → dom-DfP3MCo0.mjs} +13 -4
  56. package/dist/dom.js +1 -1
  57. package/dist/dom.mjs +1 -1
  58. package/dist/html/attrs.d.ts +2 -2
  59. package/dist/html/dynamic-tag.d.ts +1 -1
  60. package/dist/html/inlined-runtimes.d.ts +1 -1
  61. package/dist/html/inlined-runtimes.debug.d.ts +1 -1
  62. package/dist/html/serializer.d.ts +1 -1
  63. package/dist/html/writer.d.ts +34 -22
  64. package/dist/html.d.ts +1 -1
  65. package/dist/html.js +224 -167
  66. package/dist/html.mjs +224 -167
  67. package/dist/translator/core/html-comment.d.ts +0 -7
  68. package/dist/translator/core/let.d.ts +0 -5
  69. package/dist/translator/core/show.d.ts +2 -5
  70. package/dist/translator/core/style.d.ts +6 -8
  71. package/dist/translator/index.d.ts +9 -0
  72. package/dist/translator/index.js +8573 -8458
  73. package/dist/translator/util/binding-has-prop.d.ts +1 -1
  74. package/dist/translator/util/binding-prop-tree.d.ts +4 -4
  75. package/dist/translator/util/bindings.d.ts +127 -0
  76. package/dist/translator/util/body-to-text-literal.d.ts +1 -2
  77. package/dist/translator/util/branch-tag.d.ts +7 -7
  78. package/dist/translator/util/constants/binding-type.d.ts +5 -6
  79. package/dist/translator/util/constants/slot-kind.d.ts +14 -0
  80. package/dist/translator/util/constants/structure-kind.d.ts +1 -1
  81. package/dist/translator/util/evaluate.d.ts +11 -10
  82. package/dist/translator/util/finalize-references.d.ts +4 -0
  83. package/dist/translator/util/for-selector.d.ts +1 -1
  84. package/dist/translator/util/generate-uid.d.ts +3 -1
  85. package/dist/translator/util/get-declared-binding-expression.d.ts +2 -2
  86. package/dist/translator/util/is-core-tag.d.ts +0 -3
  87. package/dist/translator/util/is-only-child-in-parent.d.ts +2 -7
  88. package/dist/translator/util/known-tag.d.ts +8 -7
  89. package/dist/translator/util/read-replacement.d.ts +3 -0
  90. package/dist/translator/util/reasons.d.ts +32 -0
  91. package/dist/translator/util/references.d.ts +67 -166
  92. package/dist/translator/util/scope-accessor.d.ts +14 -0
  93. package/dist/translator/util/scope-read.d.ts +1 -1
  94. package/dist/translator/util/sections.d.ts +48 -48
  95. package/dist/translator/util/set-tag-derived-from.d.ts +7 -0
  96. package/dist/translator/util/setup-work.d.ts +1 -2
  97. package/dist/translator/util/signals.d.ts +3 -5
  98. package/dist/translator/util/slots.d.ts +50 -0
  99. package/dist/translator/util/solve-reasons.d.ts +10 -0
  100. package/dist/translator/util/sources.d.ts +21 -0
  101. package/dist/translator/util/structure.d.ts +5 -2
  102. package/dist/translator/util/tag-facts.d.ts +21 -0
  103. package/dist/translator/util/tag-name-type.d.ts +4 -1
  104. package/dist/translator/util/translate-attrs.d.ts +2 -0
  105. package/dist/translator/util/translate-var.d.ts +3 -0
  106. package/dist/translator/util/write-guard.d.ts +12 -0
  107. package/dist/translator/util/writer.d.ts +3 -3
  108. package/dist/translator/visitors/export-declaration.d.ts +9 -0
  109. package/dist/translator/visitors/function.d.ts +5 -4
  110. package/dist/translator/visitors/import-declaration.d.ts +2 -2
  111. package/dist/translator/visitors/placeholder.d.ts +0 -3
  112. package/dist/translator/visitors/program/index.d.ts +13 -3
  113. package/dist/translator/visitors/referenced-identifier.d.ts +2 -1
  114. package/dist/translator/visitors/tag/custom-tag.d.ts +1 -1
  115. package/dist/translator/visitors/tag/dynamic-tag.d.ts +0 -3
  116. package/dist/translator/visitors/tag/index.d.ts +2 -1
  117. package/dist/translator/visitors/tag/native-tag.d.ts +26 -12
  118. package/package.json +2 -2
  119. package/dist/translator/util/insertion-context.d.ts +0 -1
  120. package/dist/translator/util/is-non-html-text.d.ts +0 -3
  121. package/dist/translator/util/serialize-guard.d.ts +0 -11
  122. package/dist/translator/util/serialize-reasons.d.ts +0 -37
  123. package/dist/translator/util/set-tag-sections-downstream.d.ts +0 -6
package/cheatsheet.md CHANGED
@@ -128,7 +128,7 @@ Don't fetch while rendering: start data loads early, pass the promise through th
128
128
  ```
129
129
 
130
130
  - Repeated attr tags (many `<@tab ...>`) arrive as the singular prop `input.tab`: the first tab's attrs, made iterable, not an array: `input.tab[i]` and `input.tab.length` are undefined. To index or count, spread first: `<const/tabs=[...input.tab ?? []]>` then `tabs[active]`/`tabs.length`. Looping directly is fine: `<for|tab| of=input.tab>`.
131
- - Text: `0` renders; `false`/`null`/`undefined`/`""`/`NaN` render nothing. `$!{html}` inserts raw HTML.
131
+ - Text: `0` renders; `false`/`null`/`undefined`/`""`/`NaN` render nothing. `$!{html}` inserts raw HTML; it must be a balanced fragment (no truncated excerpts), or updating it after SSR removes the wrong nodes.
132
132
  - Conditional attrs: `false`/`null` attrs are omitted from HTML. `aria-selected` etc. want strings: `aria-selected=(i === active && "true")`.
133
133
  - `class=` / `style=` accept strings, objects, arrays: `class=["btn", { active }]`, `style={ color }` (single braces). `style=` keys are kebab-case CSS names (`{ "background-color": c }`); camelCase keys are written verbatim. `...input` spreads attrs onto a tag; `content=` passes body content as an attr.
134
134
  - `<define/Panel|input|>` declares a local tag inline; `<${Toolbar.Undo}/>` renders a dynamic tag (falsy name → content only).
@@ -7,6 +7,7 @@ export declare const ControlledHandler = "E";
7
7
  export declare const ControlledType = "F";
8
8
  export declare const ControlledValue = "G";
9
9
  export declare const DynamicHTMLLastChild = "H";
10
+ export declare const DynamicHTMLValue = "R";
10
11
  export declare const EventAttributes = "I";
11
12
  export declare const IdFallback = "J";
12
13
  export declare const KeyedScopes = "O";
@@ -7,6 +7,7 @@ export declare const ControlledHandler = "ControlledHandler:";
7
7
  export declare const ControlledType = "ControlledType:";
8
8
  export declare const ControlledValue = "ControlledValue:";
9
9
  export declare const DynamicHTMLLastChild = "DynamicHTMLLastChild:";
10
+ export declare const DynamicHTMLValue = "DynamicHTMLValue:";
10
11
  export declare const EventAttributes = "EventAttributes:";
11
12
  export declare const IdFallback = "IdFallback:";
12
13
  export declare const KeyedScopes = "KeyedScopes:";
@@ -0,0 +1,5 @@
1
+ export declare const ChangeHandler = 1;
2
+ export declare const ScopeOffset = 1;
3
+ type Self = typeof import("./reserved-id");
4
+ export type Value = Self[keyof Self];
5
+ export {};
@@ -8,7 +8,7 @@ export declare function assertValidAttrName(name: string): void;
8
8
  export declare function _el_read_error(): void;
9
9
  export declare function _hoist_read_error(): void;
10
10
  export declare function _assert_hoist(value: unknown): void;
11
- export declare function assertExclusiveAttrs(attrs: Record<string, unknown> | undefined, onError?: typeof throwErr): void;
11
+ export declare function assertExclusiveAttrs(attrs: Record<string, unknown> | undefined, onError?: typeof throwErr, isSet?: (value: unknown) => unknown): void;
12
12
  export declare function assertNoValueBindingOnCheckable(type: unknown, valueChange: unknown): void;
13
13
  export declare function assertHandlerIsFunction(name: string, value: unknown): void;
14
14
  export declare function assertValidTagName(tagName: string): void;
@@ -4,6 +4,7 @@ import type { SignalFn } from "../dom/signals";
4
4
  import type { AccessorProp } from "./accessor.debug";
5
5
  import * as ControlledType from "./constants/controlled-type";
6
6
  import * as NodeType from "./constants/node-type";
7
+ import * as ReservedId from "./constants/reserved-id";
7
8
  import * as ResumeSymbol from "./constants/resume-symbol";
8
9
  import * as WalkCode from "./constants/walk-code";
9
10
  import * as WalkRangeSize from "./constants/walk-range-size";
@@ -53,6 +54,8 @@ type WalkCode = WalkCode.Value;
53
54
  export { WalkCode };
54
55
  type WalkRangeSize = WalkRangeSize.Value;
55
56
  export { WalkRangeSize };
57
+ type ReservedId = ReservedId.Value;
58
+ export { ReservedId };
56
59
  export type Accessor = string;
57
60
  export type EncodedAccessor = number | string;
58
61
  export interface $Global {
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BRO5aArp.js");
2
+ const require_control_flow = require("../dom-ClV4kVOO.js");
3
3
  //#region src/dom/catch.feat.ts
4
4
  const handlePendingTry = (fn, scope, branch) => {
5
5
  while (branch) {
@@ -1,4 +1,4 @@
1
- import { Dn as Scope, En as Pending, Fn as PendingEffectScopes, In as PendingEffects, Ln as PendingRenders, Pn as ParentBranch, an as installCatch, b as runPendingEffects, cn as queueEffect, kn as ClosestBranch, sn as queueAsyncRender, y as renderCatch } from "../dom-Btj2QJhk.mjs";
1
+ import { Dn as Scope, En as Pending, Fn as PendingEffectScopes, In as PendingEffects, Ln as PendingRenders, Pn as ParentBranch, an as installCatch, b as runPendingEffects, cn as queueEffect, kn as ClosestBranch, sn as queueAsyncRender, y as renderCatch } from "../dom-LFrKxOk5.mjs";
2
2
  //#region src/dom/catch.feat.ts
3
3
  const handlePendingTry = (fn, scope, branch) => {
4
4
  while (branch) {
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BRO5aArp.js");
2
+ const require_control_flow = require("../dom-ClV4kVOO.js");
3
3
  //#region src/dom/controllable-input.feat.ts
4
4
  require_control_flow.controllableScripts[0] = require_control_flow._attr_input_checked_script;
5
5
  require_control_flow.controllableScripts[1] = require_control_flow._attr_input_checkedValue_script;
@@ -1,4 +1,4 @@
1
- import { D as _attr_input_checkedValue_script, P as _attr_input_value_script, U as controllableScripts, k as _attr_input_checked_script } from "../dom-Btj2QJhk.mjs";
1
+ import { D as _attr_input_checkedValue_script, P as _attr_input_value_script, U as controllableScripts, k as _attr_input_checked_script } from "../dom-LFrKxOk5.mjs";
2
2
  //#region src/dom/controllable-input.feat.ts
3
3
  controllableScripts[0] = _attr_input_checked_script;
4
4
  controllableScripts[1] = _attr_input_checkedValue_script;
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BRO5aArp.js");
2
+ const require_control_flow = require("../dom-ClV4kVOO.js");
3
3
  //#region src/dom/controllable-open.feat.ts
4
4
  require_control_flow.controllableScripts[4] = require_control_flow._attr_details_or_dialog_open_script;
5
5
  //#endregion
@@ -1,4 +1,4 @@
1
- import { C as _attr_details_or_dialog_open_script, U as controllableScripts } from "../dom-Btj2QJhk.mjs";
1
+ import { C as _attr_details_or_dialog_open_script, U as controllableScripts } from "../dom-LFrKxOk5.mjs";
2
2
  //#region src/dom/controllable-open.feat.ts
3
3
  controllableScripts[4] = _attr_details_or_dialog_open_script;
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BRO5aArp.js");
2
+ const require_control_flow = require("../dom-ClV4kVOO.js");
3
3
  //#region src/dom/controllable-select.feat.ts
4
4
  require_control_flow.controllableScripts[3] = require_control_flow._attr_select_value_script;
5
5
  //#endregion
@@ -1,4 +1,4 @@
1
- import { L as _attr_select_value_script, U as controllableScripts } from "../dom-Btj2QJhk.mjs";
1
+ import { L as _attr_select_value_script, U as controllableScripts } from "../dom-LFrKxOk5.mjs";
2
2
  //#region src/dom/controllable-select.feat.ts
3
3
  controllableScripts[3] = _attr_select_value_script;
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BRO5aArp.js");
2
+ const require_control_flow = require("../dom-ClV4kVOO.js");
3
3
  //#region src/dom/controllable-textarea.feat.ts
4
4
  require_control_flow.controllableScripts[2] = require_control_flow._attr_input_value_script;
5
5
  //#endregion
@@ -1,4 +1,4 @@
1
- import { P as _attr_input_value_script, U as controllableScripts } from "../dom-Btj2QJhk.mjs";
1
+ import { P as _attr_input_value_script, U as controllableScripts } from "../dom-LFrKxOk5.mjs";
2
2
  //#region src/dom/controllable-textarea.feat.ts
3
3
  controllableScripts[2] = _attr_input_value_script;
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BRO5aArp.js");
2
+ const require_control_flow = require("../dom-ClV4kVOO.js");
3
3
  require("./controllable-input.feat.js");
4
4
  require("./controllable-open.feat.js");
5
5
  require("./controllable-select.feat.js");
@@ -1,4 +1,4 @@
1
- import { B as _controllable_select, H as controllableRenders, R as _controllable_input, V as _controllable_textarea, z as _controllable_open } from "../dom-Btj2QJhk.mjs";
1
+ import { B as _controllable_select, H as controllableRenders, R as _controllable_input, V as _controllable_textarea, z as _controllable_open } from "../dom-LFrKxOk5.mjs";
2
2
  import "./controllable-input.feat.mjs";
3
3
  import "./controllable-open.feat.mjs";
4
4
  import "./controllable-select.feat.mjs";
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BRO5aArp.js");
2
+ const require_control_flow = require("../dom-ClV4kVOO.js");
3
3
  //#region src/dom/dynamic-tag-script.feat.ts
4
4
  require_control_flow._resumed[require_control_flow.DYNAMIC_TAG_SCRIPT_REGISTER_ID] = require_control_flow.withBranches(require_control_flow.dynamicTagScript);
5
5
  //#endregion
@@ -1,4 +1,4 @@
1
- import { en as DYNAMIC_TAG_SCRIPT_REGISTER_ID, g as dynamicTagScript, xn as withBranches, xt as _resumed } from "../dom-Btj2QJhk.mjs";
1
+ import { en as DYNAMIC_TAG_SCRIPT_REGISTER_ID, g as dynamicTagScript, xn as withBranches, xt as _resumed } from "../dom-LFrKxOk5.mjs";
2
2
  //#region src/dom/dynamic-tag-script.feat.ts
3
3
  _resumed[DYNAMIC_TAG_SCRIPT_REGISTER_ID] = withBranches(dynamicTagScript);
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BRO5aArp.js");
2
+ const require_control_flow = require("../dom-ClV4kVOO.js");
3
3
  //#region src/dom/dynamic-tag-var.feat.ts
4
4
  require_control_flow.installDynamicTagVar((branch) => branch[require_control_flow.TagVariable](() => require_control_flow._el_read(branch[require_control_flow.StartNode])));
5
5
  //#endregion
@@ -1,4 +1,4 @@
1
- import { Bn as TagVariable, Nt as _el_read, _ as installDynamicTagVar, zn as StartNode } from "../dom-Btj2QJhk.mjs";
1
+ import { Bn as TagVariable, Nt as _el_read, _ as installDynamicTagVar, zn as StartNode } from "../dom-LFrKxOk5.mjs";
2
2
  //#region src/dom/dynamic-tag-var.feat.ts
3
3
  installDynamicTagVar((branch) => branch[TagVariable](() => _el_read(branch[StartNode])));
4
4
  //#endregion
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
2
  //#region src/dom/lazy.feat.ts
3
- require("../dom-BRO5aArp.js").withLazy();
3
+ require("../dom-ClV4kVOO.js").withLazy();
4
4
  //#endregion
@@ -1,4 +1,4 @@
1
- import { Ot as withLazy } from "../dom-Btj2QJhk.mjs";
1
+ import { Ot as withLazy } from "../dom-LFrKxOk5.mjs";
2
2
  //#region src/dom/lazy.feat.ts
3
3
  withLazy();
4
4
  //#endregion
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const require_control_flow = require("../dom-BRO5aArp.js");
2
+ const require_control_flow = require("../dom-ClV4kVOO.js");
3
3
  //#region src/dom/placeholder.feat.ts
4
4
  require_control_flow._resumed[require_control_flow.PLACEHOLDER_DISMISS_REGISTER_ID] = (tryBranch) => {
5
5
  if (tryBranch["#PlaceholderBranch"]) {
@@ -1,4 +1,4 @@
1
- import { Rn as PlaceholderBranch, Xt as destroyBranch, tn as PLACEHOLDER_DISMISS_REGISTER_ID, xt as _resumed } from "../dom-Btj2QJhk.mjs";
1
+ import { Rn as PlaceholderBranch, Xt as destroyBranch, tn as PLACEHOLDER_DISMISS_REGISTER_ID, xt as _resumed } from "../dom-LFrKxOk5.mjs";
2
2
  //#region src/dom/placeholder.feat.ts
3
3
  _resumed[PLACEHOLDER_DISMISS_REGISTER_ID] = (tryBranch) => {
4
4
  if (tryBranch["#PlaceholderBranch"]) {
@@ -9,6 +9,7 @@ const ControlledHandler = "ControlledHandler:";
9
9
  const ControlledType = "ControlledType:";
10
10
  const ControlledValue = "ControlledValue:";
11
11
  const DynamicHTMLLastChild = "DynamicHTMLLastChild:";
12
+ const DynamicHTMLValue = "DynamicHTMLValue:";
12
13
  const EventAttributes = "EventAttributes:";
13
14
  const KeyedScopes = "KeyedScopes:";
14
15
  const Lifecycle = "Lifecycle:";
@@ -256,18 +257,18 @@ function _hoist_read_error() {
256
257
  function _assert_hoist(value) {
257
258
  if (value !== void 0 && typeof value !== "function") throw new Error(`Hoisted values must be functions, received type "${typeof value}".`);
258
259
  }
259
- function assertExclusiveAttrs(attrs, onError = throwErr) {
260
+ function assertExclusiveAttrs(attrs, onError = throwErr, isSet = isTruthy) {
260
261
  if (attrs) {
261
262
  let exclusiveAttrs;
262
- if (attrs.checkedChange) (exclusiveAttrs ||= []).push("checkedChange");
263
+ if (isSet(attrs.checkedChange)) (exclusiveAttrs ||= []).push("checkedChange");
263
264
  if ("checkedValue" in attrs) {
264
265
  (exclusiveAttrs ||= []).push("checkedValue");
265
266
  if ("checked" in attrs) exclusiveAttrs.push("checked");
266
- } else if (attrs.checkedValueChange) {
267
+ } else if (isSet(attrs.checkedValueChange)) {
267
268
  (exclusiveAttrs ||= []).push("checkedValueChange");
268
269
  if ("checked" in attrs) exclusiveAttrs.push("checked");
269
270
  }
270
- if (attrs.valueChange) {
271
+ if (isSet(attrs.valueChange)) {
271
272
  (exclusiveAttrs ||= []).push("valueChange");
272
273
  if ("checked" in attrs && !exclusiveAttrs.includes("checked")) exclusiveAttrs.push("checked");
273
274
  }
@@ -283,6 +284,9 @@ function assertHandlerIsFunction(name, value) {
283
284
  function assertValidTagName(tagName) {
284
285
  if (!/^[a-z][a-z0-9._-]*$/i.test(tagName)) throw new Error(`Invalid tag name: "${tagName}". Tag names must start with a letter and contain only letters, numbers, periods, hyphens, and underscores.`);
285
286
  }
287
+ function isTruthy(value) {
288
+ return value;
289
+ }
286
290
  function throwErr(msg) {
287
291
  throw new Error(msg);
288
292
  }
@@ -808,7 +812,8 @@ function* traverse(scope, path, args, i = path.length - 1) {
808
812
  if (Symbol.iterator in scope) {
809
813
  for (const childScope of scope.values()) if (childScope["#Gen"] !== 0) yield* traverse(childScope, path, args, i);
810
814
  } else {
811
- const item = scope[path[i]];
815
+ const step = path[i];
816
+ const item = Array.isArray(step) ? (scope[step[1]] || 0) === step[2] && scope[step[0]] : scope[step];
812
817
  if (i) yield* traverse(item, path, args, i - 1);
813
818
  else yield typeof item === "function" ? item(...args) : item;
814
819
  }
@@ -1056,6 +1061,7 @@ function init(runtimeId = "M") {
1056
1061
  if (dynamicHtmlEnabled && visitType > "%" && visitType <= "'") {
1057
1062
  if (visitType === "&") htmlStart = visit;
1058
1063
  else {
1064
+ if (visit.parentNode !== htmlStart.parentNode) console.error("An unescaped placeholder (`$!{}`) rendered HTML that does not parse as a balanced fragment where it is placed (an unclosed, stray or misnested tag), so updating it removes the wrong nodes.");
1059
1065
  visitScope[nextToken()] = htmlStart;
1060
1066
  visitScope[DynamicHTMLLastChild + lastToken] = visit;
1061
1067
  if ((branchesEnabled || lazyEnabled) && pending[pending.length - 1] !== visitScope) pending.push(visitScope);
@@ -1163,6 +1169,7 @@ function _content(id, template, walks, setup, params, dynamicScopesAccessor) {
1163
1169
  function _content_resume(renderer, hasLocalValues = 0) {
1164
1170
  return _resumed[renderer()["id"]] = (owner, ...values) => {
1165
1171
  for (let i = values.length, scope = owner; i > hasLocalValues;) {
1172
+ if (!scope) throw new Error("Unable to resume registered content: its payload does not link the owner of every closure level.");
1166
1173
  const closures = values[--i];
1167
1174
  for (const key in closures) if (!(key in scope)) scope[key] = closures[key];
1168
1175
  scope = scope["_"];
@@ -1337,17 +1344,26 @@ function _attrs_script(scope, nodeAccessor) {
1337
1344
  for (const name in events) _on(el, name, events[name]);
1338
1345
  }
1339
1346
  const _html = /*@__PURE__*/ withDynamicHtml(function _html(scope, value, accessor) {
1340
- const firstChild = scope[accessor];
1341
- const parentNode = firstChild.parentNode;
1342
- const lastChild = scope["DynamicHTMLLastChild:" + accessor] || firstChild;
1343
- const newContent = parseHTML(_to_text(value), parentNode.namespaceURI);
1344
- const newFirstChild = scope[accessor] = newContent.firstChild || newContent.appendChild(new Text());
1345
- const newLastChild = scope[DynamicHTMLLastChild + accessor] = newContent.lastChild;
1346
- const branch = scope[ClosestBranch];
1347
- if (branch?.["#StartNode"] === firstChild) branch[StartNode] = newFirstChild;
1348
- if (branch?.["#EndNode"] === lastChild) branch[EndNode] = newLastChild;
1349
- insertChildNodes(parentNode, firstChild, newFirstChild, newLastChild);
1350
- removeChildNodes(firstChild, lastChild);
1347
+ const prevValue = scope[DynamicHTMLValue + accessor];
1348
+ if (prevValue !== (scope["DynamicHTMLValue:" + accessor] = _to_text(value))) {
1349
+ const firstChild = scope[accessor];
1350
+ const parentNode = firstChild.parentNode;
1351
+ const lastChild = scope["DynamicHTMLLastChild:" + accessor] || firstChild;
1352
+ const newContent = parseHTML(scope[DynamicHTMLValue + accessor], parentNode.namespaceURI);
1353
+ if (prevValue === void 0 && lastChild !== firstChild) {
1354
+ let node = firstChild;
1355
+ let newNode = newContent.firstChild;
1356
+ while ((node = node.nextSibling) !== lastChild && node.isEqualNode(newNode)) newNode = newNode.nextSibling;
1357
+ if (node === lastChild && !newNode) return;
1358
+ }
1359
+ const newFirstChild = scope[accessor] = newContent.firstChild || newContent.appendChild(new Text());
1360
+ const newLastChild = scope[DynamicHTMLLastChild + accessor] = newContent.lastChild;
1361
+ const branch = scope[ClosestBranch];
1362
+ if (branch?.["#StartNode"] === firstChild) branch[StartNode] = newFirstChild;
1363
+ if (branch?.["#EndNode"] === lastChild) branch[EndNode] = newLastChild;
1364
+ insertChildNodes(parentNode, firstChild, newFirstChild, newLastChild);
1365
+ removeChildNodes(firstChild, lastChild);
1366
+ }
1351
1367
  });
1352
1368
  function normalizeClientRender(value) {
1353
1369
  const renderer = normalizeDynamicRenderer(value);
@@ -8,6 +8,7 @@ const ControlledHandler = "ControlledHandler:";
8
8
  const ControlledType = "ControlledType:";
9
9
  const ControlledValue = "ControlledValue:";
10
10
  const DynamicHTMLLastChild = "DynamicHTMLLastChild:";
11
+ const DynamicHTMLValue = "DynamicHTMLValue:";
11
12
  const EventAttributes = "EventAttributes:";
12
13
  const KeyedScopes = "KeyedScopes:";
13
14
  const Lifecycle = "Lifecycle:";
@@ -255,18 +256,18 @@ function _hoist_read_error() {
255
256
  function _assert_hoist(value) {
256
257
  if (value !== void 0 && typeof value !== "function") throw new Error(`Hoisted values must be functions, received type "${typeof value}".`);
257
258
  }
258
- function assertExclusiveAttrs(attrs, onError = throwErr) {
259
+ function assertExclusiveAttrs(attrs, onError = throwErr, isSet = isTruthy) {
259
260
  if (attrs) {
260
261
  let exclusiveAttrs;
261
- if (attrs.checkedChange) (exclusiveAttrs ||= []).push("checkedChange");
262
+ if (isSet(attrs.checkedChange)) (exclusiveAttrs ||= []).push("checkedChange");
262
263
  if ("checkedValue" in attrs) {
263
264
  (exclusiveAttrs ||= []).push("checkedValue");
264
265
  if ("checked" in attrs) exclusiveAttrs.push("checked");
265
- } else if (attrs.checkedValueChange) {
266
+ } else if (isSet(attrs.checkedValueChange)) {
266
267
  (exclusiveAttrs ||= []).push("checkedValueChange");
267
268
  if ("checked" in attrs) exclusiveAttrs.push("checked");
268
269
  }
269
- if (attrs.valueChange) {
270
+ if (isSet(attrs.valueChange)) {
270
271
  (exclusiveAttrs ||= []).push("valueChange");
271
272
  if ("checked" in attrs && !exclusiveAttrs.includes("checked")) exclusiveAttrs.push("checked");
272
273
  }
@@ -282,6 +283,9 @@ function assertHandlerIsFunction(name, value) {
282
283
  function assertValidTagName(tagName) {
283
284
  if (!/^[a-z][a-z0-9._-]*$/i.test(tagName)) throw new Error(`Invalid tag name: "${tagName}". Tag names must start with a letter and contain only letters, numbers, periods, hyphens, and underscores.`);
284
285
  }
286
+ function isTruthy(value) {
287
+ return value;
288
+ }
285
289
  function throwErr(msg) {
286
290
  throw new Error(msg);
287
291
  }
@@ -807,7 +811,8 @@ function* traverse(scope, path, args, i = path.length - 1) {
807
811
  if (Symbol.iterator in scope) {
808
812
  for (const childScope of scope.values()) if (childScope["#Gen"] !== 0) yield* traverse(childScope, path, args, i);
809
813
  } else {
810
- const item = scope[path[i]];
814
+ const step = path[i];
815
+ const item = Array.isArray(step) ? (scope[step[1]] || 0) === step[2] && scope[step[0]] : scope[step];
811
816
  if (i) yield* traverse(item, path, args, i - 1);
812
817
  else yield typeof item === "function" ? item(...args) : item;
813
818
  }
@@ -1055,6 +1060,7 @@ function init(runtimeId = "M") {
1055
1060
  if (dynamicHtmlEnabled && visitType > "%" && visitType <= "'") {
1056
1061
  if (visitType === "&") htmlStart = visit;
1057
1062
  else {
1063
+ if (visit.parentNode !== htmlStart.parentNode) console.error("An unescaped placeholder (`$!{}`) rendered HTML that does not parse as a balanced fragment where it is placed (an unclosed, stray or misnested tag), so updating it removes the wrong nodes.");
1058
1064
  visitScope[nextToken()] = htmlStart;
1059
1065
  visitScope[DynamicHTMLLastChild + lastToken] = visit;
1060
1066
  if ((branchesEnabled || lazyEnabled) && pending[pending.length - 1] !== visitScope) pending.push(visitScope);
@@ -1162,6 +1168,7 @@ function _content(id, template, walks, setup, params, dynamicScopesAccessor) {
1162
1168
  function _content_resume(renderer, hasLocalValues = 0) {
1163
1169
  return _resumed[renderer()["id"]] = (owner, ...values) => {
1164
1170
  for (let i = values.length, scope = owner; i > hasLocalValues;) {
1171
+ if (!scope) throw new Error("Unable to resume registered content: its payload does not link the owner of every closure level.");
1165
1172
  const closures = values[--i];
1166
1173
  for (const key in closures) if (!(key in scope)) scope[key] = closures[key];
1167
1174
  scope = scope["_"];
@@ -1336,17 +1343,26 @@ function _attrs_script(scope, nodeAccessor) {
1336
1343
  for (const name in events) _on(el, name, events[name]);
1337
1344
  }
1338
1345
  const _html = /*@__PURE__*/ withDynamicHtml(function _html(scope, value, accessor) {
1339
- const firstChild = scope[accessor];
1340
- const parentNode = firstChild.parentNode;
1341
- const lastChild = scope["DynamicHTMLLastChild:" + accessor] || firstChild;
1342
- const newContent = parseHTML(_to_text(value), parentNode.namespaceURI);
1343
- const newFirstChild = scope[accessor] = newContent.firstChild || newContent.appendChild(new Text());
1344
- const newLastChild = scope[DynamicHTMLLastChild + accessor] = newContent.lastChild;
1345
- const branch = scope[ClosestBranch];
1346
- if (branch?.["#StartNode"] === firstChild) branch[StartNode] = newFirstChild;
1347
- if (branch?.["#EndNode"] === lastChild) branch[EndNode] = newLastChild;
1348
- insertChildNodes(parentNode, firstChild, newFirstChild, newLastChild);
1349
- removeChildNodes(firstChild, lastChild);
1346
+ const prevValue = scope[DynamicHTMLValue + accessor];
1347
+ if (prevValue !== (scope["DynamicHTMLValue:" + accessor] = _to_text(value))) {
1348
+ const firstChild = scope[accessor];
1349
+ const parentNode = firstChild.parentNode;
1350
+ const lastChild = scope["DynamicHTMLLastChild:" + accessor] || firstChild;
1351
+ const newContent = parseHTML(scope[DynamicHTMLValue + accessor], parentNode.namespaceURI);
1352
+ if (prevValue === void 0 && lastChild !== firstChild) {
1353
+ let node = firstChild;
1354
+ let newNode = newContent.firstChild;
1355
+ while ((node = node.nextSibling) !== lastChild && node.isEqualNode(newNode)) newNode = newNode.nextSibling;
1356
+ if (node === lastChild && !newNode) return;
1357
+ }
1358
+ const newFirstChild = scope[accessor] = newContent.firstChild || newContent.appendChild(new Text());
1359
+ const newLastChild = scope[DynamicHTMLLastChild + accessor] = newContent.lastChild;
1360
+ const branch = scope[ClosestBranch];
1361
+ if (branch?.["#StartNode"] === firstChild) branch[StartNode] = newFirstChild;
1362
+ if (branch?.["#EndNode"] === lastChild) branch[EndNode] = newLastChild;
1363
+ insertChildNodes(parentNode, firstChild, newFirstChild, newLastChild);
1364
+ removeChildNodes(firstChild, lastChild);
1365
+ }
1350
1366
  });
1351
1367
  function normalizeClientRender(value) {
1352
1368
  const renderer = normalizeDynamicRenderer(value);
package/dist/debug/dom.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const require_control_flow = require("./dom-BRO5aArp.js");
3
+ const require_control_flow = require("./dom-ClV4kVOO.js");
4
4
  //#region src/common/attr-tag.ts
5
5
  const empty = [];
6
6
  const rest = Symbol("Attribute Tag");
@@ -1,4 +1,4 @@
1
- import { $ as _attrs, $t as syncGen, A as _attr_input_value, An as EndNode, At as _closure, B as _controllable_select, Bn as TagVariable, Bt as _if_closure, C as _attr_details_or_dialog_open_script, Cn as Owner, Ct as getRegisteredWithScope, D as _attr_input_checkedValue_script, Dt as readyFailed, E as _attr_input_checkedValue_default, Et as ready, F as _attr_select_value, Ft as _for_selector, G as _attr_class, Gt as _return_change, Ht as _let_change, I as _attr_select_value_default, It as _global_read, J as _attr_content, Jt as _var_change, K as _attr_class_item, Kt as _script, L as _attr_select_value_script, Lt as _hoist, M as _attr_input_value_default, Mn as Global, Mt as _const, N as _attr_input_value_dynamic_default, Nn as Load, Nt as _el_read, O as _attr_input_checked_default, P as _attr_input_value_script, Pt as _for_closure, Q as _attr_style_items, Qt as removeAndDestroyBranch, R as _controllable_input, Rt as _hoist_resume, S as _attr_details_or_dialog_open_default, Sn as Clone, St as _var_resume, T as _attr_input_checkedValue, Tn as Setup, Tt as initEmbedded, Ut as _or, V as _controllable_textarea, Vt as _let, W as _attr, Wt as _return, X as _attr_style, Xt as destroyBranch, Y as _attr_nonce, Yt as _assert_init, Z as _attr_style_item, Zt as insertBranchBefore, _n as forUntil, _t as createBranch, a as _for_in, at as _lifecycle, bn as _call, bt as _el, c as _for_to, cn as queueEffect, ct as _text, d as _for_until_unkeyed, dn as run, dt as insertChildNodes, et as _attrs_content, f as _if, fn as runEffects, ft as toInsertNode, gn as forTo, gt as createAndSetupBranch, h as addAwaitCounter, hn as forOf, ht as _content_resume, i as _dynamic_tag_content, in as $signalReset, it as _html, j as _attr_input_value_attribute_default, jt as _closure_get, k as _attr_input_checked_script, kt as _child_setup, l as _for_to_unkeyed, ln as queueRender, lt as _text_content, m as _try, mn as forIn, mt as _content_closures, n as _await_promise, nn as _on, nt as _attrs_partial_content, o as _for_of, on as prepareEffects, ot as _style_rule_item, p as _show, pn as runId, pt as _content, q as _attr_class_items, qt as _var, r as _dynamic_tag, rn as $signal, rt as _attrs_script, s as _for_of_unkeyed, sn as queueAsyncRender, st as _style_shell, t as _await_content, tt as _attrs_partial, u as _for_until, un as rendering, ut as _to_text, v as patchDynamicTag, vn as _assert_hoist, vt as setupBranch, w as _attr_input_checked, wn as Params, wt as init, x as _attr_details_or_dialog_open, xt as _resumed, y as renderCatch, yn as _hoist_read_error, yt as _dynamic_tag_var_resume, z as _controllable_open, zn as StartNode, zt as _id } from "./dom-Btj2QJhk.mjs";
1
+ import { $ as _attrs, $t as syncGen, A as _attr_input_value, An as EndNode, At as _closure, B as _controllable_select, Bn as TagVariable, Bt as _if_closure, C as _attr_details_or_dialog_open_script, Cn as Owner, Ct as getRegisteredWithScope, D as _attr_input_checkedValue_script, Dt as readyFailed, E as _attr_input_checkedValue_default, Et as ready, F as _attr_select_value, Ft as _for_selector, G as _attr_class, Gt as _return_change, Ht as _let_change, I as _attr_select_value_default, It as _global_read, J as _attr_content, Jt as _var_change, K as _attr_class_item, Kt as _script, L as _attr_select_value_script, Lt as _hoist, M as _attr_input_value_default, Mn as Global, Mt as _const, N as _attr_input_value_dynamic_default, Nn as Load, Nt as _el_read, O as _attr_input_checked_default, P as _attr_input_value_script, Pt as _for_closure, Q as _attr_style_items, Qt as removeAndDestroyBranch, R as _controllable_input, Rt as _hoist_resume, S as _attr_details_or_dialog_open_default, Sn as Clone, St as _var_resume, T as _attr_input_checkedValue, Tn as Setup, Tt as initEmbedded, Ut as _or, V as _controllable_textarea, Vt as _let, W as _attr, Wt as _return, X as _attr_style, Xt as destroyBranch, Y as _attr_nonce, Yt as _assert_init, Z as _attr_style_item, Zt as insertBranchBefore, _n as forUntil, _t as createBranch, a as _for_in, at as _lifecycle, bn as _call, bt as _el, c as _for_to, cn as queueEffect, ct as _text, d as _for_until_unkeyed, dn as run, dt as insertChildNodes, et as _attrs_content, f as _if, fn as runEffects, ft as toInsertNode, gn as forTo, gt as createAndSetupBranch, h as addAwaitCounter, hn as forOf, ht as _content_resume, i as _dynamic_tag_content, in as $signalReset, it as _html, j as _attr_input_value_attribute_default, jt as _closure_get, k as _attr_input_checked_script, kt as _child_setup, l as _for_to_unkeyed, ln as queueRender, lt as _text_content, m as _try, mn as forIn, mt as _content_closures, n as _await_promise, nn as _on, nt as _attrs_partial_content, o as _for_of, on as prepareEffects, ot as _style_rule_item, p as _show, pn as runId, pt as _content, q as _attr_class_items, qt as _var, r as _dynamic_tag, rn as $signal, rt as _attrs_script, s as _for_of_unkeyed, sn as queueAsyncRender, st as _style_shell, t as _await_content, tt as _attrs_partial, u as _for_until, un as rendering, ut as _to_text, v as patchDynamicTag, vn as _assert_hoist, vt as setupBranch, w as _attr_input_checked, wn as Params, wt as init, x as _attr_details_or_dialog_open, xt as _resumed, y as renderCatch, yn as _hoist_read_error, yt as _dynamic_tag_var_resume, z as _controllable_open, zn as StartNode, zt as _id } from "./dom-LFrKxOk5.mjs";
2
2
  //#region src/common/attr-tag.ts
3
3
  const empty = [];
4
4
  const rest = Symbol("Attribute Tag");