marko 6.3.24 → 6.3.26

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/debug/dom.js CHANGED
@@ -26,6 +26,7 @@ const BranchScopes$1 = "BranchScopes:";
26
26
  const ClosureScopes = "ClosureScopes:";
27
27
  const ClosureSignalIndex = "ClosureSignalIndex:";
28
28
  const ConditionalRenderer = "ConditionalRenderer:";
29
+ const ControlledObserver = "ControlledObserver:";
29
30
  const ControlledHandler = "ControlledHandler:";
30
31
  const ControlledType = "ControlledType:";
31
32
  const ControlledValue = "ControlledValue:";
@@ -346,22 +347,6 @@ function handleDelegated(ev) {
346
347
  delete ev.currentTarget;
347
348
  }
348
349
  //#endregion
349
- //#region src/dom/resolve-cursor-position.ts
350
- const R = /[^\p{L}\p{N}]/gu;
351
- function resolveCursorPosition(inputType, initialPosition, initialValue, updatedValue) {
352
- if ((initialPosition || initialPosition === 0) && (initialPosition !== initialValue.length || /kw/.test(inputType))) {
353
- const before = initialValue.slice(0, initialPosition);
354
- const after = initialValue.slice(initialPosition);
355
- if (updatedValue.startsWith(before)) return initialPosition;
356
- if (updatedValue.endsWith(after)) return updatedValue.length - after.length;
357
- let count = before.replace(R, "").length;
358
- let pos = 0;
359
- while (count && updatedValue[pos]) if (updatedValue[pos++].replace(R, "")) count--;
360
- return pos;
361
- }
362
- return -1;
363
- }
364
- //#endregion
365
350
  //#region src/dom/parse-html.ts
366
351
  const parsers = {};
367
352
  function parseHTML(html, ns) {
@@ -687,7 +672,7 @@ const walkInternal = function walkInternal(currentWalkIndex, walkCodes, scope) {
687
672
  currentWalkIndex = walkInternal(currentWalkIndex, walkCodes, scope[getDebugKey(currentScopeIndex++, "#childScope")] = createScope(scope[Global], scope[ClosestBranch]));
688
673
  if (value === 48) scope[getDebugKey(currentScopeIndex++, "#scopeOffset")] = skipScope();
689
674
  } else if (value < 92) {
690
- value = 20 * currentMultiplier + value - 67;
675
+ value = 25 * currentMultiplier + value - 67;
691
676
  while (value--) walker.nextNode();
692
677
  } else if (value < 107) {
693
678
  value = 10 * currentMultiplier + value - 97;
@@ -710,77 +695,6 @@ function getDebugKey(index, node) {
710
695
  return index;
711
696
  }
712
697
  //#endregion
713
- //#region src/dom/renderer.ts
714
- function createBranch($global, renderer, parentScope, parentNode) {
715
- const branch = createScope($global);
716
- branch["_"] = renderer["owner"] || parentScope;
717
- setParentBranch(branch, parentScope?.[ClosestBranch]);
718
- branch[Renderer] = renderer;
719
- renderer[Clone]?.(branch, parentNode.namespaceURI);
720
- return branch;
721
- }
722
- function setParentBranch(branch, parentBranch) {
723
- if (parentBranch) {
724
- branch[ParentBranch] = parentBranch;
725
- (parentBranch[BranchScopes] ||= /* @__PURE__ */ new Set()).add(branch);
726
- }
727
- branch[ClosestBranch] = branch;
728
- }
729
- function createAndSetupBranch($global, renderer, parentScope, parentNode) {
730
- return setupBranch(renderer, createBranch($global, renderer, parentScope, parentNode));
731
- }
732
- function setupBranch(renderer, branch) {
733
- if (renderer["setup"]) queueRender(branch, renderer[Setup], -1);
734
- return branch;
735
- }
736
- function _content(id, template, walks, setup, params, dynamicScopesAccessor) {
737
- walks = walks ? walks.replace(/[^\0-1]+$/, "") : "";
738
- setup = setup ? setup._ || setup : void 0;
739
- params ||= void 0;
740
- const clone = template ? (branch, ns) => {
741
- ((cloneCache[ns] ||= {})[template] ||= createCloneableHTML(template, ns))(branch, walks);
742
- } : (branch) => {
743
- walk(branch[StartNode] = branch[EndNode] = new Text(), walks, branch);
744
- };
745
- return (owner) => {
746
- return {
747
- ["id"]: id,
748
- [Clone]: clone,
749
- [Owner]: owner,
750
- [Setup]: setup,
751
- [Params]: params,
752
- [Accessor]: dynamicScopesAccessor
753
- };
754
- };
755
- }
756
- function _content_resume(id, template, walks, setup, params, dynamicScopesAccessor) {
757
- return _resume(id, _content(id, template, walks, setup, params, dynamicScopesAccessor));
758
- }
759
- function _content_closures(renderer, closureFns) {
760
- const closureSignals = {};
761
- for (const key in closureFns) closureSignals[key] = _const(key, closureFns[key]);
762
- return (owner, closureValues) => {
763
- const instance = renderer(owner);
764
- instance[LocalClosures] = closureSignals;
765
- instance[LocalClosureValues] = closureValues;
766
- return instance;
767
- };
768
- }
769
- const cloneCache = {};
770
- function createCloneableHTML(html, ns) {
771
- const { firstChild, lastChild } = parseHTML(html, ns);
772
- const parent = document.createElementNS(ns, "t");
773
- insertChildNodes(parent, null, firstChild, lastChild);
774
- return firstChild === lastChild && firstChild.nodeType < 8 ? (branch, walks) => {
775
- walk(branch[StartNode] = branch[EndNode] = firstChild.cloneNode(true), walks, branch);
776
- } : (branch, walks) => {
777
- const clone = parent.cloneNode(true);
778
- walk(clone.firstChild, walks, branch);
779
- branch[StartNode] = clone.firstChild;
780
- branch[EndNode] = clone.lastChild;
781
- };
782
- }
783
- //#endregion
784
698
  //#region src/dom/resume.ts
785
699
  const registeredValues = {};
786
700
  let curRenders;
@@ -985,19 +899,295 @@ function runResumeEffects(render) {
985
899
  isResuming = 0;
986
900
  }
987
901
  }
988
- function getRegisteredWithScope(id, scope) {
989
- const val = registeredValues[id];
990
- return scope ? val(scope) : val;
902
+ function getRegisteredWithScope(id, scope) {
903
+ const val = registeredValues[id];
904
+ return scope ? val(scope) : val;
905
+ }
906
+ function _resume(id, obj) {
907
+ return registeredValues[id] = obj;
908
+ }
909
+ function _var_resume(id, signal) {
910
+ _resume(id, (scope) => (value) => signal(scope, value));
911
+ return signal;
912
+ }
913
+ function _el(id, accessor) {
914
+ return _resume(id, (scope) => () => _el_read(scope[accessor]));
915
+ }
916
+ //#endregion
917
+ //#region src/dom/renderer.ts
918
+ function createBranch($global, renderer, parentScope, parentNode) {
919
+ const branch = createScope($global);
920
+ branch["_"] = renderer["owner"] || parentScope;
921
+ setParentBranch(branch, parentScope?.[ClosestBranch]);
922
+ branch[Renderer] = renderer;
923
+ renderer[Clone]?.(branch, parentNode.namespaceURI);
924
+ return branch;
925
+ }
926
+ function setParentBranch(branch, parentBranch) {
927
+ if (parentBranch) {
928
+ branch[ParentBranch] = parentBranch;
929
+ (parentBranch[BranchScopes] ||= /* @__PURE__ */ new Set()).add(branch);
930
+ }
931
+ branch[ClosestBranch] = branch;
932
+ }
933
+ function createAndSetupBranch($global, renderer, parentScope, parentNode) {
934
+ return setupBranch(renderer, createBranch($global, renderer, parentScope, parentNode));
935
+ }
936
+ function setupBranch(renderer, branch) {
937
+ if (renderer["setup"]) queueRender(branch, renderer[Setup], -1);
938
+ return branch;
939
+ }
940
+ function _content(id, template, walks, setup, params, dynamicScopesAccessor) {
941
+ walks = walks ? walks.replace(/[^\0-1]+$/, "") : "";
942
+ setup = setup ? setup._ || setup : void 0;
943
+ params ||= void 0;
944
+ const clone = template ? (branch, ns) => {
945
+ ((cloneCache[ns] ||= {})[template] ||= createCloneableHTML(template, ns))(branch, walks);
946
+ } : (branch) => {
947
+ walk(branch[StartNode] = branch[EndNode] = new Text(), walks, branch);
948
+ };
949
+ return (owner) => {
950
+ return {
951
+ ["id"]: id,
952
+ [Clone]: clone,
953
+ [Owner]: owner,
954
+ [Setup]: setup,
955
+ [Params]: params,
956
+ [Accessor]: dynamicScopesAccessor
957
+ };
958
+ };
959
+ }
960
+ function _content_resume(id, template, walks, setup, params, dynamicScopesAccessor) {
961
+ return _resume(id, _content(id, template, walks, setup, params, dynamicScopesAccessor));
962
+ }
963
+ function _content_closures(renderer, closureFns) {
964
+ const closureSignals = {};
965
+ for (const key in closureFns) closureSignals[key] = _const(key, closureFns[key]);
966
+ return (owner, closureValues) => {
967
+ const instance = renderer(owner);
968
+ instance[LocalClosures] = closureSignals;
969
+ instance[LocalClosureValues] = closureValues;
970
+ return instance;
971
+ };
972
+ }
973
+ const cloneCache = {};
974
+ function createCloneableHTML(html, ns) {
975
+ const { firstChild, lastChild } = parseHTML(html, ns);
976
+ const parent = document.createElementNS(ns, "t");
977
+ insertChildNodes(parent, null, firstChild, lastChild);
978
+ return firstChild === lastChild && firstChild.nodeType < 8 ? (branch, walks) => {
979
+ walk(branch[StartNode] = branch[EndNode] = firstChild.cloneNode(true), walks, branch);
980
+ } : (branch, walks) => {
981
+ const clone = parent.cloneNode(true);
982
+ walk(clone.firstChild, walks, branch);
983
+ branch[StartNode] = clone.firstChild;
984
+ branch[EndNode] = clone.lastChild;
985
+ };
986
+ }
987
+ //#endregion
988
+ //#region src/dom/dom.ts
989
+ function _to_text(value) {
990
+ assertValidTextValue(value);
991
+ return value || value === 0 ? value + "" : "";
992
+ }
993
+ function _attr(element, name, value) {
994
+ assertValidAttrValue(name, value);
995
+ setAttribute(element, name, normalizeAttrValue(value));
996
+ }
997
+ function setAttribute(element, name, value) {
998
+ if (element.getAttribute(name) != value) if (value === void 0) element.removeAttribute(name);
999
+ else element.setAttribute(name, value);
1000
+ }
1001
+ function _attr_class(element, value) {
1002
+ setAttribute(element, "class", toDelimitedString(value, " ", stringifyClassObject) || void 0);
1003
+ }
1004
+ function _attr_class_items(element, items) {
1005
+ for (const key in items) _attr_class_item(element, key, items[key]);
1006
+ }
1007
+ function _attr_class_item(element, name, value) {
1008
+ element.classList.toggle(name, !!value);
1009
+ }
1010
+ function _attr_style(element, value) {
1011
+ setAttribute(element, "style", toDelimitedString(value, ";", stringifyStyleObject) || void 0);
1012
+ }
1013
+ function _attr_style_items(element, items) {
1014
+ for (const key in items) _attr_style_item(element, key, items[key]);
1015
+ }
1016
+ function _attr_style_item(element, name, value) {
1017
+ element.style.setProperty(name, _to_text(value));
1018
+ }
1019
+ function _style_shell(scope, nodeAccessor) {
1020
+ const element = scope[nodeAccessor];
1021
+ const id = _id(scope);
1022
+ _attr_nonce(scope, nodeAccessor);
1023
+ element.className = id;
1024
+ _text_content(element, "." + id + "~*{}");
1025
+ }
1026
+ function _style_rule_item(element, name, value) {
1027
+ const text = element.textContent;
1028
+ const decl = name + ":" + escapeStyleValue(_to_text(value)) + ";";
1029
+ let start = text.indexOf("{" + name + ":");
1030
+ if (!~start) start = text.indexOf(";" + name + ":");
1031
+ _text_content(element, ~start ? text.slice(0, ++start) + decl + text.slice(text.indexOf(";", start) + 1) : text.slice(0, -1) + decl + "}");
1032
+ }
1033
+ function _attr_nonce(scope, nodeAccessor) {
1034
+ _attr(scope[nodeAccessor], "nonce", scope[Global].cspNonce);
1035
+ }
1036
+ function _text(node, value) {
1037
+ const normalizedValue = _to_text(value);
1038
+ if (node.data !== normalizedValue) node.data = normalizedValue;
1039
+ }
1040
+ function _text_content(node, value) {
1041
+ const normalizedValue = _to_text(value);
1042
+ if (node.textContent !== normalizedValue) node.textContent = normalizedValue;
1043
+ }
1044
+ function _attrs(scope, nodeAccessor, nextAttrs, controllable) {
1045
+ const el = scope[nodeAccessor];
1046
+ for (let i = el.attributes.length; i--;) {
1047
+ const { name } = el.attributes.item(i);
1048
+ if (!(nextAttrs && (name in nextAttrs || hasAttrAlias(el, name, nextAttrs)))) el.removeAttribute(name);
1049
+ }
1050
+ assertExclusiveAttrs(nextAttrs);
1051
+ attrsInternal(scope, nodeAccessor, nextAttrs, controllable);
1052
+ }
1053
+ function _attrs_content(scope, nodeAccessor, nextAttrs, controllable) {
1054
+ _attrs(scope, nodeAccessor, nextAttrs, controllable);
1055
+ _attr_content(scope, nodeAccessor, nextAttrs?.content);
1056
+ }
1057
+ function hasAttrAlias(element, attr, nextAttrs) {
1058
+ return attr === "checked" && element.tagName === "INPUT" && "checkedValue" in nextAttrs;
1059
+ }
1060
+ function _attrs_partial(scope, nodeAccessor, nextAttrs, skip, controllable) {
1061
+ const el = scope[nodeAccessor];
1062
+ const partial = {};
1063
+ for (let i = el.attributes.length; i--;) {
1064
+ const { name } = el.attributes.item(i);
1065
+ if (!skip[name] && !(nextAttrs && name in nextAttrs)) el.removeAttribute(name);
1066
+ }
1067
+ for (const name in nextAttrs) {
1068
+ const key = isEventHandler(name) ? `on-${getEventHandlerName(name)}` : name;
1069
+ if (!skip[key]) partial[key] = nextAttrs[name];
1070
+ }
1071
+ assertExclusiveAttrs({
1072
+ ...nextAttrs,
1073
+ ...skip
1074
+ });
1075
+ attrsInternal(scope, nodeAccessor, partial, controllable);
1076
+ }
1077
+ function _attrs_partial_content(scope, nodeAccessor, nextAttrs, skip, controllable) {
1078
+ _attrs_partial(scope, nodeAccessor, nextAttrs, skip, controllable);
1079
+ _attr_content(scope, nodeAccessor, nextAttrs?.content);
1080
+ }
1081
+ function attrsInternal(scope, nodeAccessor, nextAttrs, controllable) {
1082
+ const el = scope[nodeAccessor];
1083
+ let events = scope[EventAttributes + nodeAccessor];
1084
+ let skip = void 0;
1085
+ for (const name in events) events[name] = 0;
1086
+ if (controllable) {
1087
+ scope[ControlledType + nodeAccessor] = 5;
1088
+ scope[ControlledHandler + nodeAccessor] = 0;
1089
+ if (nextAttrs) skip = controllable(scope, nodeAccessor, nextAttrs);
1090
+ }
1091
+ for (const name in nextAttrs) {
1092
+ const value = nextAttrs[name];
1093
+ switch (name) {
1094
+ case "class":
1095
+ _attr_class(el, value);
1096
+ break;
1097
+ case "style":
1098
+ _attr_style(el, value);
1099
+ break;
1100
+ default:
1101
+ assertValidAttrName(name);
1102
+ if (isEventHandler(name)) (events ||= scope[EventAttributes + nodeAccessor] = {})[getEventHandlerName(name)] = value;
1103
+ else if (!(skip?.test(name) || name === "content" && el.tagName !== "META")) _attr(el, name, value);
1104
+ break;
1105
+ }
1106
+ }
1107
+ }
1108
+ function _attr_content(scope, nodeAccessor, value) {
1109
+ const content = normalizeClientRender(value);
1110
+ if (scope["ConditionalRenderer:" + nodeAccessor] !== (scope["ConditionalRenderer:" + nodeAccessor] = content?.["id"])) {
1111
+ setConditionalRenderer(scope, nodeAccessor, content, createAndSetupBranch);
1112
+ if (content?.["accessor"]) subscribeToScopeSet(content[Owner], content[Accessor], scope[BranchScopes$1 + nodeAccessor]);
1113
+ }
1114
+ for (const accessor in content?.[LocalClosures]) content[LocalClosures][accessor](scope[BranchScopes$1 + nodeAccessor], content[LocalClosureValues][accessor]);
1115
+ }
1116
+ function _attrs_script(scope, nodeAccessor) {
1117
+ const el = scope[nodeAccessor];
1118
+ const events = scope[EventAttributes + nodeAccessor];
1119
+ controllableScripts[scope[ControlledType + nodeAccessor]]?.(scope, nodeAccessor);
1120
+ for (const name in events) _on(el, name, events[name]);
1121
+ }
1122
+ function _html(scope, value, accessor) {
1123
+ const firstChild = scope[accessor];
1124
+ const parentNode = firstChild.parentNode;
1125
+ const lastChild = scope["DynamicHTMLLastChild:" + accessor] || firstChild;
1126
+ const newContent = parseHTML(_to_text(value), parentNode.namespaceURI);
1127
+ insertChildNodes(parentNode, firstChild, scope[accessor] = newContent.firstChild || newContent.appendChild(new Text()), scope[DynamicHTMLLastChild + accessor] = newContent.lastChild);
1128
+ removeChildNodes(firstChild, lastChild);
1129
+ }
1130
+ function normalizeClientRender(value) {
1131
+ const renderer = normalizeDynamicRenderer(value);
1132
+ if (renderer) if (renderer["id"]) return renderer;
1133
+ else throw new Error(`Invalid \`content\` attribute. Received ${typeof value}`);
1134
+ }
1135
+ function normalizeAttrValue(value) {
1136
+ if (isNotVoid(value)) return value === true ? "" : value + "";
1137
+ }
1138
+ function _lifecycle(scope, thisObj, index = 0) {
1139
+ const accessor = Lifecycle + index;
1140
+ const instance = scope[accessor];
1141
+ if (instance) {
1142
+ Object.assign(instance, thisObj);
1143
+ instance.onUpdate?.();
1144
+ } else {
1145
+ scope[accessor] = thisObj;
1146
+ {
1147
+ const snapshot = { ...thisObj };
1148
+ Object.assign(thisObj, thisObj.onMount?.());
1149
+ for (const prop in snapshot) if (!Object.is(snapshot[prop], thisObj[prop])) throw new Error(`Tried to overwrite existing property "${prop}" in <lifecycle> onMount.`);
1150
+ }
1151
+ $signal(scope, accessor).onabort = () => thisObj.onDestroy?.();
1152
+ }
1153
+ }
1154
+ function removeChildNodes(startNode, endNode) {
1155
+ const stop = endNode.nextSibling;
1156
+ while (startNode !== stop) {
1157
+ const next = startNode.nextSibling;
1158
+ startNode.remove();
1159
+ startNode = next;
1160
+ }
991
1161
  }
992
- function _resume(id, obj) {
993
- return registeredValues[id] = obj;
1162
+ function insertChildNodes(parentNode, referenceNode, startNode, endNode) {
1163
+ parentNode.insertBefore(toInsertNode(startNode, endNode), referenceNode);
994
1164
  }
995
- function _var_resume(id, signal) {
996
- _resume(id, (scope) => (value) => signal(scope, value));
997
- return signal;
1165
+ function toInsertNode(startNode, endNode) {
1166
+ if (startNode === endNode) return startNode;
1167
+ const parent = new DocumentFragment();
1168
+ const stop = endNode.nextSibling;
1169
+ while (startNode !== stop) {
1170
+ const next = startNode.nextSibling;
1171
+ parent.appendChild(startNode);
1172
+ startNode = next;
1173
+ }
1174
+ return parent;
998
1175
  }
999
- function _el(id, accessor) {
1000
- return _resume(id, (scope) => () => _el_read(scope[accessor]));
1176
+ //#endregion
1177
+ //#region src/dom/resolve-cursor-position.ts
1178
+ const R = /[^\p{L}\p{N}]/gu;
1179
+ function resolveCursorPosition(inputType, initialPosition, initialValue, updatedValue) {
1180
+ if ((initialPosition || initialPosition === 0) && (initialPosition !== initialValue.length || /kw/.test(inputType))) {
1181
+ const before = initialValue.slice(0, initialPosition);
1182
+ const after = initialValue.slice(initialPosition);
1183
+ if (updatedValue.startsWith(before)) return initialPosition;
1184
+ if (updatedValue.endsWith(after)) return updatedValue.length - after.length;
1185
+ let count = before.replace(R, "").length;
1186
+ let pos = 0;
1187
+ while (count && updatedValue[pos]) if (updatedValue[pos++].replace(R, "")) count--;
1188
+ return pos;
1189
+ }
1190
+ return -1;
1001
1191
  }
1002
1192
  //#endregion
1003
1193
  //#region src/dom/controllable.ts
@@ -1011,6 +1201,36 @@ function _attr_input_checked_default(scope, nodeAccessor, checked) {
1011
1201
  if (restoreValue !== normalizedChecked) el.checked = restoreValue;
1012
1202
  }
1013
1203
  }
1204
+ /** Filled by the latches a compiled page emits, so a page carries only the
1205
+ * control kinds its tags can be (`_attrs_script` resolves the kind at run time). */
1206
+ const controllableScripts = {};
1207
+ /** The render pass equivalent, for a tag whose name is only known at run time;
1208
+ * a statically named tag passes its claim to `_attrs` instead. */
1209
+ const controllableRenders = {};
1210
+ function _enable_controllable_input() {
1211
+ controllableScripts[0] = _attr_input_checked_script;
1212
+ controllableScripts[1] = _attr_input_checkedValue_script;
1213
+ controllableScripts[2] = _attr_input_value_script;
1214
+ }
1215
+ function _enable_controllable_textarea() {
1216
+ controllableScripts[2] = _attr_input_value_script;
1217
+ }
1218
+ function _enable_controllable_select() {
1219
+ controllableScripts[3] = _attr_select_value_script;
1220
+ }
1221
+ function _enable_controllable_open() {
1222
+ controllableScripts[4] = _attr_details_or_dialog_open_script;
1223
+ }
1224
+ /** A run-time tag name can be any controllable, so its page enables them all. */
1225
+ function _enable_controllable() {
1226
+ _enable_controllable_input();
1227
+ _enable_controllable_select();
1228
+ _enable_controllable_open();
1229
+ controllableRenders.INPUT = _controllable_input;
1230
+ controllableRenders.TEXTAREA = _controllable_textarea;
1231
+ controllableRenders.SELECT = _controllable_select;
1232
+ controllableRenders.DETAILS = controllableRenders.DIALOG = _controllable_open;
1233
+ }
1014
1234
  function _attr_input_checked(scope, nodeAccessor, checked, checkedChange) {
1015
1235
  const el = scope[nodeAccessor];
1016
1236
  const normalizedChecked = isNotVoid(checked);
@@ -1172,12 +1392,12 @@ function _attr_select_value_script(scope, nodeAccessor) {
1172
1392
  }
1173
1393
  }
1174
1394
  syncControllableFormInput(el, hasSelectChanged, onChange);
1175
- new MutationObserver(() => {
1176
- const value = scope[ControlledValue + nodeAccessor];
1177
- if (Array.isArray(value) ? value.length !== el.selectedOptions.length || value.some((_, i) => !value.includes(el.selectedOptions[i].value)) : el.value !== value) onChange();
1178
- }).observe(el, {
1395
+ observeOnce(scope, nodeAccessor, {
1179
1396
  childList: true,
1180
1397
  subtree: true
1398
+ }, () => {
1399
+ const value = scope[ControlledValue + nodeAccessor];
1400
+ if (Array.isArray(value) ? value.length !== el.selectedOptions.length || value.some((_, i) => !value.includes(el.selectedOptions[i].value)) : el.value !== value) onChange();
1181
1401
  });
1182
1402
  }
1183
1403
  function setSelectValue(el, value, multiple) {
@@ -1207,7 +1427,10 @@ function _attr_details_or_dialog_open(scope, nodeAccessor, open, openChange) {
1207
1427
  }
1208
1428
  function _attr_details_or_dialog_open_script(scope, nodeAccessor) {
1209
1429
  const el = scope[nodeAccessor];
1210
- new MutationObserver(() => {
1430
+ observeOnce(scope, nodeAccessor, {
1431
+ attributes: true,
1432
+ attributeFilter: ["open"]
1433
+ }, () => {
1211
1434
  const openChange = scope[ControlledHandler + nodeAccessor];
1212
1435
  if (openChange && el.open === !scope["ControlledValue:" + nodeAccessor]) {
1213
1436
  const newValue = el.open;
@@ -1215,11 +1438,11 @@ function _attr_details_or_dialog_open_script(scope, nodeAccessor) {
1215
1438
  openChange(newValue);
1216
1439
  run();
1217
1440
  }
1218
- }).observe(el, {
1219
- attributes: true,
1220
- attributeFilter: ["open"]
1221
1441
  });
1222
1442
  }
1443
+ function observeOnce(scope, nodeAccessor, init, callback) {
1444
+ (scope[ControlledObserver + nodeAccessor] ||= new MutationObserver(callback)).observe(scope[nodeAccessor], init);
1445
+ }
1223
1446
  function syncControllableFormInput(el, hasChanged, onChange) {
1224
1447
  el._ = onChange;
1225
1448
  delegate("input", handleChange);
@@ -1255,240 +1478,34 @@ function updateList(arr, val, push) {
1255
1478
  const index = arr.indexOf(val);
1256
1479
  return (push ? !~index && [...arr, val] : ~index && arr.slice(0, index).concat(arr.slice(index + 1))) || arr;
1257
1480
  }
1258
- //#endregion
1259
- //#region src/dom/dom.ts
1260
- function _to_text(value) {
1261
- assertValidTextValue(value);
1262
- return value || value === 0 ? value + "" : "";
1263
- }
1264
- function _attr(element, name, value) {
1265
- assertValidAttrValue(name, value);
1266
- setAttribute(element, name, normalizeAttrValue(value));
1267
- }
1268
- function setAttribute(element, name, value) {
1269
- if (element.getAttribute(name) != value) if (value === void 0) element.removeAttribute(name);
1270
- else element.setAttribute(name, value);
1271
- }
1272
- function _attr_class(element, value) {
1273
- setAttribute(element, "class", toDelimitedString(value, " ", stringifyClassObject) || void 0);
1274
- }
1275
- function _attr_class_items(element, items) {
1276
- for (const key in items) _attr_class_item(element, key, items[key]);
1277
- }
1278
- function _attr_class_item(element, name, value) {
1279
- element.classList.toggle(name, !!value);
1280
- }
1281
- function _attr_style(element, value) {
1282
- setAttribute(element, "style", toDelimitedString(value, ";", stringifyStyleObject) || void 0);
1283
- }
1284
- function _attr_style_items(element, items) {
1285
- for (const key in items) _attr_style_item(element, key, items[key]);
1286
- }
1287
- function _attr_style_item(element, name, value) {
1288
- element.style.setProperty(name, _to_text(value));
1289
- }
1290
- function _style_shell(scope, nodeAccessor) {
1291
- const element = scope[nodeAccessor];
1292
- const id = _id(scope);
1293
- _attr_nonce(scope, nodeAccessor);
1294
- element.className = id;
1295
- _text_content(element, "." + id + "~*{}");
1296
- }
1297
- function _style_rule_item(element, name, value) {
1298
- const text = element.textContent;
1299
- const decl = name + ":" + escapeStyleValue(_to_text(value)) + ";";
1300
- let start = text.indexOf("{" + name + ":");
1301
- if (!~start) start = text.indexOf(";" + name + ":");
1302
- _text_content(element, ~start ? text.slice(0, ++start) + decl + text.slice(text.indexOf(";", start) + 1) : text.slice(0, -1) + decl + "}");
1303
- }
1304
- function _attr_nonce(scope, nodeAccessor) {
1305
- _attr(scope[nodeAccessor], "nonce", scope[Global].cspNonce);
1306
- }
1307
- function _text(node, value) {
1308
- const normalizedValue = _to_text(value);
1309
- if (node.data !== normalizedValue) node.data = normalizedValue;
1310
- }
1311
- function _text_content(node, value) {
1312
- const normalizedValue = _to_text(value);
1313
- if (node.textContent !== normalizedValue) node.textContent = normalizedValue;
1314
- }
1315
- function _attrs(scope, nodeAccessor, nextAttrs) {
1316
- const el = scope[nodeAccessor];
1317
- for (let i = el.attributes.length; i--;) {
1318
- const { name } = el.attributes.item(i);
1319
- if (!(nextAttrs && (name in nextAttrs || hasAttrAlias(el, name, nextAttrs)))) el.removeAttribute(name);
1320
- }
1321
- assertExclusiveAttrs(nextAttrs);
1322
- attrsInternal(scope, nodeAccessor, nextAttrs);
1323
- }
1324
- function _attrs_content(scope, nodeAccessor, nextAttrs) {
1325
- _attrs(scope, nodeAccessor, nextAttrs);
1326
- _attr_content(scope, nodeAccessor, nextAttrs?.content);
1327
- }
1328
- function hasAttrAlias(element, attr, nextAttrs) {
1329
- return attr === "checked" && element.tagName === "INPUT" && "checkedValue" in nextAttrs;
1330
- }
1331
- function _attrs_partial(scope, nodeAccessor, nextAttrs, skip) {
1332
- const el = scope[nodeAccessor];
1333
- const partial = {};
1334
- for (let i = el.attributes.length; i--;) {
1335
- const { name } = el.attributes.item(i);
1336
- if (!skip[name] && !(nextAttrs && name in nextAttrs)) el.removeAttribute(name);
1337
- }
1338
- for (const name in nextAttrs) {
1339
- const key = isEventHandler(name) ? `on-${getEventHandlerName(name)}` : name;
1340
- if (!skip[key]) partial[key] = nextAttrs[name];
1341
- }
1342
- assertExclusiveAttrs({
1343
- ...nextAttrs,
1344
- ...skip
1345
- });
1346
- attrsInternal(scope, nodeAccessor, partial);
1347
- }
1348
- function _attrs_partial_content(scope, nodeAccessor, nextAttrs, skip) {
1349
- _attrs_partial(scope, nodeAccessor, nextAttrs, skip);
1350
- _attr_content(scope, nodeAccessor, nextAttrs?.content);
1351
- }
1352
- function attrsInternal(scope, nodeAccessor, nextAttrs) {
1353
- const el = scope[nodeAccessor];
1354
- let events = scope[EventAttributes + nodeAccessor];
1355
- let skip;
1356
- for (const name in events) events[name] = 0;
1357
- scope[ControlledType + nodeAccessor] = 5;
1358
- scope[ControlledHandler + nodeAccessor] = 0;
1359
- switch (nextAttrs && el.tagName) {
1360
- case "INPUT":
1361
- if ("checked" in nextAttrs || "checkedChange" in nextAttrs) {
1362
- _attr_input_checked(scope, nodeAccessor, nextAttrs.checked, nextAttrs.checkedChange);
1363
- skip = /^checked(?:Value)?(?:Change)?$/;
1364
- } else if ("checkedValue" in nextAttrs || "checkedValueChange" in nextAttrs) {
1365
- _attr_input_checkedValue(scope, nodeAccessor, nextAttrs.checkedValue, nextAttrs.checkedValueChange, nextAttrs.value);
1366
- skip = /^(?:value|checked(?:Value)?)(?:Change)?$/;
1367
- } else if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1368
- _attr_input_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange, _attr_input_value_dynamic_default);
1369
- skip = /^value(?:Change)?$/;
1370
- }
1371
- break;
1372
- case "SELECT":
1373
- if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1374
- _attr_select_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
1375
- skip = /^value(?:Change)?$/;
1376
- }
1377
- break;
1378
- case "TEXTAREA":
1379
- if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1380
- _attr_input_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
1381
- skip = /^value(?:Change)?$/;
1382
- }
1383
- break;
1384
- case "DETAILS":
1385
- case "DIALOG":
1386
- if ("open" in nextAttrs || "openChange" in nextAttrs) {
1387
- _attr_details_or_dialog_open(scope, nodeAccessor, nextAttrs.open, nextAttrs.openChange);
1388
- skip = /^open(?:Change)?$/;
1389
- }
1390
- break;
1391
- }
1392
- for (const name in nextAttrs) {
1393
- const value = nextAttrs[name];
1394
- switch (name) {
1395
- case "class":
1396
- _attr_class(el, value);
1397
- break;
1398
- case "style":
1399
- _attr_style(el, value);
1400
- break;
1401
- default:
1402
- assertValidAttrName(name);
1403
- if (isEventHandler(name)) (events ||= scope[EventAttributes + nodeAccessor] = {})[getEventHandlerName(name)] = value;
1404
- else if (!(skip?.test(name) || name === "content" && el.tagName !== "META")) _attr(el, name, value);
1405
- break;
1406
- }
1407
- }
1408
- }
1409
- function _attr_content(scope, nodeAccessor, value) {
1410
- const content = normalizeClientRender(value);
1411
- if (scope["ConditionalRenderer:" + nodeAccessor] !== (scope["ConditionalRenderer:" + nodeAccessor] = content?.["id"])) {
1412
- setConditionalRenderer(scope, nodeAccessor, content, createAndSetupBranch);
1413
- if (content?.["accessor"]) subscribeToScopeSet(content[Owner], content[Accessor], scope[BranchScopes$1 + nodeAccessor]);
1481
+ function _controllable_input(scope, nodeAccessor, nextAttrs) {
1482
+ if ("checked" in nextAttrs || "checkedChange" in nextAttrs) {
1483
+ _attr_input_checked(scope, nodeAccessor, nextAttrs.checked, nextAttrs.checkedChange);
1484
+ return /^checked(?:Value)?(?:Change)?$/;
1414
1485
  }
1415
- for (const accessor in content?.[LocalClosures]) content[LocalClosures][accessor](scope[BranchScopes$1 + nodeAccessor], content[LocalClosureValues][accessor]);
1416
- }
1417
- function _attrs_script(scope, nodeAccessor) {
1418
- const el = scope[nodeAccessor];
1419
- const events = scope[EventAttributes + nodeAccessor];
1420
- switch (scope[ControlledType + nodeAccessor]) {
1421
- case 0:
1422
- _attr_input_checked_script(scope, nodeAccessor);
1423
- break;
1424
- case 1:
1425
- _attr_input_checkedValue_script(scope, nodeAccessor);
1426
- break;
1427
- case 2:
1428
- _attr_input_value_script(scope, nodeAccessor);
1429
- break;
1430
- case 3:
1431
- _attr_select_value_script(scope, nodeAccessor);
1432
- break;
1433
- case 4:
1434
- _attr_details_or_dialog_open_script(scope, nodeAccessor);
1435
- break;
1486
+ if ("checkedValue" in nextAttrs || "checkedValueChange" in nextAttrs) {
1487
+ _attr_input_checkedValue(scope, nodeAccessor, nextAttrs.checkedValue, nextAttrs.checkedValueChange, nextAttrs.value);
1488
+ return /^(?:value|checked(?:Value)?)(?:Change)?$/;
1436
1489
  }
1437
- for (const name in events) _on(el, name, events[name]);
1438
- }
1439
- function _html(scope, value, accessor) {
1440
- const firstChild = scope[accessor];
1441
- const parentNode = firstChild.parentNode;
1442
- const lastChild = scope["DynamicHTMLLastChild:" + accessor] || firstChild;
1443
- const newContent = parseHTML(_to_text(value), parentNode.namespaceURI);
1444
- insertChildNodes(parentNode, firstChild, scope[accessor] = newContent.firstChild || newContent.appendChild(new Text()), scope[DynamicHTMLLastChild + accessor] = newContent.lastChild);
1445
- removeChildNodes(firstChild, lastChild);
1446
- }
1447
- function normalizeClientRender(value) {
1448
- const renderer = normalizeDynamicRenderer(value);
1449
- if (renderer) if (renderer["id"]) return renderer;
1450
- else throw new Error(`Invalid \`content\` attribute. Received ${typeof value}`);
1451
- }
1452
- function normalizeAttrValue(value) {
1453
- if (isNotVoid(value)) return value === true ? "" : value + "";
1490
+ return _controllable_textarea(scope, nodeAccessor, nextAttrs, _attr_input_value_dynamic_default);
1454
1491
  }
1455
- function _lifecycle(scope, thisObj, index = 0) {
1456
- const accessor = Lifecycle + index;
1457
- const instance = scope[accessor];
1458
- if (instance) {
1459
- Object.assign(instance, thisObj);
1460
- instance.onUpdate?.();
1461
- } else {
1462
- scope[accessor] = thisObj;
1463
- {
1464
- const snapshot = { ...thisObj };
1465
- Object.assign(thisObj, thisObj.onMount?.());
1466
- for (const prop in snapshot) if (!Object.is(snapshot[prop], thisObj[prop])) throw new Error(`Tried to overwrite existing property "${prop}" in <lifecycle> onMount.`);
1467
- }
1468
- $signal(scope, accessor).onabort = () => thisObj.onDestroy?.();
1492
+ function _controllable_textarea(scope, nodeAccessor, nextAttrs, dynamicDefault) {
1493
+ if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1494
+ _attr_input_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange, dynamicDefault);
1495
+ return /^value(?:Change)?$/;
1469
1496
  }
1470
1497
  }
1471
- function removeChildNodes(startNode, endNode) {
1472
- const stop = endNode.nextSibling;
1473
- while (startNode !== stop) {
1474
- const next = startNode.nextSibling;
1475
- startNode.remove();
1476
- startNode = next;
1498
+ function _controllable_select(scope, nodeAccessor, nextAttrs) {
1499
+ if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1500
+ _attr_select_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
1501
+ return /^value(?:Change)?$/;
1477
1502
  }
1478
1503
  }
1479
- function insertChildNodes(parentNode, referenceNode, startNode, endNode) {
1480
- parentNode.insertBefore(toInsertNode(startNode, endNode), referenceNode);
1481
- }
1482
- function toInsertNode(startNode, endNode) {
1483
- if (startNode === endNode) return startNode;
1484
- const parent = new DocumentFragment();
1485
- const stop = endNode.nextSibling;
1486
- while (startNode !== stop) {
1487
- const next = startNode.nextSibling;
1488
- parent.appendChild(startNode);
1489
- startNode = next;
1504
+ function _controllable_open(scope, nodeAccessor, nextAttrs) {
1505
+ if ("open" in nextAttrs || "openChange" in nextAttrs) {
1506
+ _attr_details_or_dialog_open(scope, nodeAccessor, nextAttrs.open, nextAttrs.openChange);
1507
+ return /^open(?:Change)?$/;
1490
1508
  }
1491
- return parent;
1492
1509
  }
1493
1510
  //#endregion
1494
1511
  //#region src/dom/control-flow.ts
@@ -1547,6 +1564,11 @@ function _await_promise(nodeAccessor, params) {
1547
1564
  if (thisPromise === scope[promiseAccessor]) {
1548
1565
  const referenceNode = scope[nodeAccessor];
1549
1566
  scope[promiseAccessor] = 0;
1567
+ if (scope["#ClosestBranch"]?.["#Gen"] === 0) {
1568
+ awaitCounter.c();
1569
+ run();
1570
+ return;
1571
+ }
1550
1572
  queueAsyncRender(scope, () => {
1551
1573
  awaitBranch = resolveAwait(scope, referenceNode, data);
1552
1574
  const pendingRenders = awaitBranch[PendingRenders];
@@ -1724,8 +1746,9 @@ let _dynamic_tag = function dynamicTag(nodeAccessor, getContent, getTagVar, inpu
1724
1746
  const childScope = scope[childScopeAccessor];
1725
1747
  const args = getInput?.();
1726
1748
  if (typeof normalizedRenderer === "string") {
1727
- (getContent ? _attrs : _attrs_content)(childScope, `#${normalizedRenderer}/0`, (inputIsArgs ? args[0] : args) || {});
1728
- if (childScope[`EventAttributes:#${normalizedRenderer}/0`] || childScope[`ControlledHandler:#${normalizedRenderer}/0`]) queueEffect(childScope, dynamicTagScript);
1749
+ const nodeAccessor = `#${normalizedRenderer}/0`;
1750
+ (getContent ? _attrs : _attrs_content)(childScope, nodeAccessor, (inputIsArgs ? args[0] : args) || {}, controllableRenders[childScope[nodeAccessor].tagName]);
1751
+ if (childScope["EventAttributes:" + nodeAccessor] || childScope["ControlledHandler:" + nodeAccessor]) queueEffect(childScope, dynamicTagScript);
1729
1752
  } else {
1730
1753
  for (const accessor in normalizedRenderer[LocalClosures]) normalizedRenderer[LocalClosures][accessor](childScope, normalizedRenderer[LocalClosureValues][accessor]);
1731
1754
  if (normalizedRenderer["params"]) if (inputIsArgs) normalizedRenderer[Params](childScope, normalizedRenderer._ ? args[0] : args);
@@ -2055,8 +2078,9 @@ function _enable_catch() {
2055
2078
  function $signalReset(scope, id) {
2056
2079
  const ctrl = scope[AbortControllers]?.[id];
2057
2080
  if (ctrl) {
2058
- queueEffect(ctrl, abort);
2059
2081
  scope[AbortControllers][id] = void 0;
2082
+ if (rendering) queueEffect(ctrl, abort);
2083
+ else abort(ctrl);
2060
2084
  }
2061
2085
  }
2062
2086
  function $signal(scope, id) {
@@ -2219,10 +2243,13 @@ function mount(input = {}, reference, position) {
2219
2243
  set value(newValue) {
2220
2244
  _var_change(branch, newValue);
2221
2245
  },
2222
- update(newInput) {
2223
- if (args) runEffects(prepareEffects(() => {
2224
- args(branch, newInput);
2225
- }));
2246
+ update(newInput = {}) {
2247
+ if (args) {
2248
+ if (newInput.$global) ({$global, ...newInput} = newInput);
2249
+ runEffects(prepareEffects(() => {
2250
+ args(branch, newInput);
2251
+ }));
2252
+ }
2226
2253
  },
2227
2254
  destroy() {
2228
2255
  removeAndDestroyBranch(branch);
@@ -2382,6 +2409,10 @@ exports._const = _const;
2382
2409
  exports._content = _content;
2383
2410
  exports._content_closures = _content_closures;
2384
2411
  exports._content_resume = _content_resume;
2412
+ exports._controllable_input = _controllable_input;
2413
+ exports._controllable_open = _controllable_open;
2414
+ exports._controllable_select = _controllable_select;
2415
+ exports._controllable_textarea = _controllable_textarea;
2385
2416
  Object.defineProperty(exports, "_dynamic_tag", {
2386
2417
  enumerable: true,
2387
2418
  get: function() {
@@ -2392,6 +2423,11 @@ exports._dynamic_tag_content = _dynamic_tag_content;
2392
2423
  exports._el = _el;
2393
2424
  exports._el_read = _el_read;
2394
2425
  exports._enable_catch = _enable_catch;
2426
+ exports._enable_controllable = _enable_controllable;
2427
+ exports._enable_controllable_input = _enable_controllable_input;
2428
+ exports._enable_controllable_open = _enable_controllable_open;
2429
+ exports._enable_controllable_select = _enable_controllable_select;
2430
+ exports._enable_controllable_textarea = _enable_controllable_textarea;
2395
2431
  exports._for_closure = _for_closure;
2396
2432
  exports._for_in = _for_in;
2397
2433
  exports._for_of = _for_of;