marko 6.3.24 → 6.3.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,7 @@ export declare const BranchScopes = "A";
2
2
  export declare const ClosureScopes = "B";
3
3
  export declare const ClosureSignalIndex = "C";
4
4
  export declare const ConditionalRenderer = "D";
5
+ export declare const ControlledObserver = "N";
5
6
  export declare const ControlledHandler = "E";
6
7
  export declare const ControlledType = "F";
7
8
  export declare const ControlledValue = "G";
@@ -2,6 +2,7 @@ export declare const BranchScopes = "BranchScopes:";
2
2
  export declare const ClosureScopes = "ClosureScopes:";
3
3
  export declare const ClosureSignalIndex = "ClosureSignalIndex:";
4
4
  export declare const ConditionalRenderer = "ConditionalRenderer:";
5
+ export declare const ControlledObserver = "ControlledObserver:";
5
6
  export declare const ControlledHandler = "ControlledHandler:";
6
7
  export declare const ControlledType = "ControlledType:";
7
8
  export declare const ControlledValue = "ControlledValue:";
@@ -1,4 +1,4 @@
1
- export declare const Next = 20;
1
+ export declare const Next = 25;
2
2
  export declare const Over = 10;
3
3
  export declare const Out = 10;
4
4
  export declare const Multiplier = 10;
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:";
@@ -687,7 +688,7 @@ const walkInternal = function walkInternal(currentWalkIndex, walkCodes, scope) {
687
688
  currentWalkIndex = walkInternal(currentWalkIndex, walkCodes, scope[getDebugKey(currentScopeIndex++, "#childScope")] = createScope(scope[Global], scope[ClosestBranch]));
688
689
  if (value === 48) scope[getDebugKey(currentScopeIndex++, "#scopeOffset")] = skipScope();
689
690
  } else if (value < 92) {
690
- value = 20 * currentMultiplier + value - 67;
691
+ value = 25 * currentMultiplier + value - 67;
691
692
  while (value--) walker.nextNode();
692
693
  } else if (value < 107) {
693
694
  value = 10 * currentMultiplier + value - 97;
@@ -1011,6 +1012,36 @@ function _attr_input_checked_default(scope, nodeAccessor, checked) {
1011
1012
  if (restoreValue !== normalizedChecked) el.checked = restoreValue;
1012
1013
  }
1013
1014
  }
1015
+ /** Filled by the latches a compiled page emits, so a page carries only the
1016
+ * control kinds its tags can be (`_attrs_script` resolves the kind at run time). */
1017
+ const controllableScripts = {};
1018
+ /** The render pass equivalent, for a tag whose name is only known at run time;
1019
+ * a statically named tag passes its claim to `_attrs` instead. */
1020
+ const controllableRenders = {};
1021
+ function _enable_controllable_input() {
1022
+ controllableScripts[0] = _attr_input_checked_script;
1023
+ controllableScripts[1] = _attr_input_checkedValue_script;
1024
+ controllableScripts[2] = _attr_input_value_script;
1025
+ }
1026
+ function _enable_controllable_textarea() {
1027
+ controllableScripts[2] = _attr_input_value_script;
1028
+ }
1029
+ function _enable_controllable_select() {
1030
+ controllableScripts[3] = _attr_select_value_script;
1031
+ }
1032
+ function _enable_controllable_open() {
1033
+ controllableScripts[4] = _attr_details_or_dialog_open_script;
1034
+ }
1035
+ /** A run-time tag name can be any controllable, so its page enables them all. */
1036
+ function _enable_controllable() {
1037
+ _enable_controllable_input();
1038
+ _enable_controllable_select();
1039
+ _enable_controllable_open();
1040
+ controllableRenders.INPUT = _controllable_input;
1041
+ controllableRenders.TEXTAREA = _controllable_textarea;
1042
+ controllableRenders.SELECT = _controllable_select;
1043
+ controllableRenders.DETAILS = controllableRenders.DIALOG = _controllable_open;
1044
+ }
1014
1045
  function _attr_input_checked(scope, nodeAccessor, checked, checkedChange) {
1015
1046
  const el = scope[nodeAccessor];
1016
1047
  const normalizedChecked = isNotVoid(checked);
@@ -1172,12 +1203,12 @@ function _attr_select_value_script(scope, nodeAccessor) {
1172
1203
  }
1173
1204
  }
1174
1205
  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, {
1206
+ observeOnce(scope, nodeAccessor, {
1179
1207
  childList: true,
1180
1208
  subtree: true
1209
+ }, () => {
1210
+ const value = scope[ControlledValue + nodeAccessor];
1211
+ if (Array.isArray(value) ? value.length !== el.selectedOptions.length || value.some((_, i) => !value.includes(el.selectedOptions[i].value)) : el.value !== value) onChange();
1181
1212
  });
1182
1213
  }
1183
1214
  function setSelectValue(el, value, multiple) {
@@ -1207,7 +1238,10 @@ function _attr_details_or_dialog_open(scope, nodeAccessor, open, openChange) {
1207
1238
  }
1208
1239
  function _attr_details_or_dialog_open_script(scope, nodeAccessor) {
1209
1240
  const el = scope[nodeAccessor];
1210
- new MutationObserver(() => {
1241
+ observeOnce(scope, nodeAccessor, {
1242
+ attributes: true,
1243
+ attributeFilter: ["open"]
1244
+ }, () => {
1211
1245
  const openChange = scope[ControlledHandler + nodeAccessor];
1212
1246
  if (openChange && el.open === !scope["ControlledValue:" + nodeAccessor]) {
1213
1247
  const newValue = el.open;
@@ -1215,11 +1249,11 @@ function _attr_details_or_dialog_open_script(scope, nodeAccessor) {
1215
1249
  openChange(newValue);
1216
1250
  run();
1217
1251
  }
1218
- }).observe(el, {
1219
- attributes: true,
1220
- attributeFilter: ["open"]
1221
1252
  });
1222
1253
  }
1254
+ function observeOnce(scope, nodeAccessor, init, callback) {
1255
+ (scope[ControlledObserver + nodeAccessor] ||= new MutationObserver(callback)).observe(scope[nodeAccessor], init);
1256
+ }
1223
1257
  function syncControllableFormInput(el, hasChanged, onChange) {
1224
1258
  el._ = onChange;
1225
1259
  delegate("input", handleChange);
@@ -1255,6 +1289,35 @@ function updateList(arr, val, push) {
1255
1289
  const index = arr.indexOf(val);
1256
1290
  return (push ? !~index && [...arr, val] : ~index && arr.slice(0, index).concat(arr.slice(index + 1))) || arr;
1257
1291
  }
1292
+ function _controllable_input(scope, nodeAccessor, nextAttrs) {
1293
+ if ("checked" in nextAttrs || "checkedChange" in nextAttrs) {
1294
+ _attr_input_checked(scope, nodeAccessor, nextAttrs.checked, nextAttrs.checkedChange);
1295
+ return /^checked(?:Value)?(?:Change)?$/;
1296
+ }
1297
+ if ("checkedValue" in nextAttrs || "checkedValueChange" in nextAttrs) {
1298
+ _attr_input_checkedValue(scope, nodeAccessor, nextAttrs.checkedValue, nextAttrs.checkedValueChange, nextAttrs.value);
1299
+ return /^(?:value|checked(?:Value)?)(?:Change)?$/;
1300
+ }
1301
+ return _controllable_textarea(scope, nodeAccessor, nextAttrs, _attr_input_value_dynamic_default);
1302
+ }
1303
+ function _controllable_textarea(scope, nodeAccessor, nextAttrs, dynamicDefault) {
1304
+ if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1305
+ _attr_input_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange, dynamicDefault);
1306
+ return /^value(?:Change)?$/;
1307
+ }
1308
+ }
1309
+ function _controllable_select(scope, nodeAccessor, nextAttrs) {
1310
+ if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1311
+ _attr_select_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
1312
+ return /^value(?:Change)?$/;
1313
+ }
1314
+ }
1315
+ function _controllable_open(scope, nodeAccessor, nextAttrs) {
1316
+ if ("open" in nextAttrs || "openChange" in nextAttrs) {
1317
+ _attr_details_or_dialog_open(scope, nodeAccessor, nextAttrs.open, nextAttrs.openChange);
1318
+ return /^open(?:Change)?$/;
1319
+ }
1320
+ }
1258
1321
  //#endregion
1259
1322
  //#region src/dom/dom.ts
1260
1323
  function _to_text(value) {
@@ -1312,23 +1375,23 @@ function _text_content(node, value) {
1312
1375
  const normalizedValue = _to_text(value);
1313
1376
  if (node.textContent !== normalizedValue) node.textContent = normalizedValue;
1314
1377
  }
1315
- function _attrs(scope, nodeAccessor, nextAttrs) {
1378
+ function _attrs(scope, nodeAccessor, nextAttrs, controllable) {
1316
1379
  const el = scope[nodeAccessor];
1317
1380
  for (let i = el.attributes.length; i--;) {
1318
1381
  const { name } = el.attributes.item(i);
1319
1382
  if (!(nextAttrs && (name in nextAttrs || hasAttrAlias(el, name, nextAttrs)))) el.removeAttribute(name);
1320
1383
  }
1321
1384
  assertExclusiveAttrs(nextAttrs);
1322
- attrsInternal(scope, nodeAccessor, nextAttrs);
1385
+ attrsInternal(scope, nodeAccessor, nextAttrs, controllable);
1323
1386
  }
1324
- function _attrs_content(scope, nodeAccessor, nextAttrs) {
1325
- _attrs(scope, nodeAccessor, nextAttrs);
1387
+ function _attrs_content(scope, nodeAccessor, nextAttrs, controllable) {
1388
+ _attrs(scope, nodeAccessor, nextAttrs, controllable);
1326
1389
  _attr_content(scope, nodeAccessor, nextAttrs?.content);
1327
1390
  }
1328
1391
  function hasAttrAlias(element, attr, nextAttrs) {
1329
1392
  return attr === "checked" && element.tagName === "INPUT" && "checkedValue" in nextAttrs;
1330
1393
  }
1331
- function _attrs_partial(scope, nodeAccessor, nextAttrs, skip) {
1394
+ function _attrs_partial(scope, nodeAccessor, nextAttrs, skip, controllable) {
1332
1395
  const el = scope[nodeAccessor];
1333
1396
  const partial = {};
1334
1397
  for (let i = el.attributes.length; i--;) {
@@ -1343,52 +1406,19 @@ function _attrs_partial(scope, nodeAccessor, nextAttrs, skip) {
1343
1406
  ...nextAttrs,
1344
1407
  ...skip
1345
1408
  });
1346
- attrsInternal(scope, nodeAccessor, partial);
1409
+ attrsInternal(scope, nodeAccessor, partial, controllable);
1347
1410
  }
1348
- function _attrs_partial_content(scope, nodeAccessor, nextAttrs, skip) {
1349
- _attrs_partial(scope, nodeAccessor, nextAttrs, skip);
1411
+ function _attrs_partial_content(scope, nodeAccessor, nextAttrs, skip, controllable) {
1412
+ _attrs_partial(scope, nodeAccessor, nextAttrs, skip, controllable);
1350
1413
  _attr_content(scope, nodeAccessor, nextAttrs?.content);
1351
1414
  }
1352
- function attrsInternal(scope, nodeAccessor, nextAttrs) {
1415
+ function attrsInternal(scope, nodeAccessor, nextAttrs, controllable) {
1353
1416
  const el = scope[nodeAccessor];
1354
1417
  let events = scope[EventAttributes + nodeAccessor];
1355
- let skip;
1356
1418
  for (const name in events) events[name] = 0;
1357
1419
  scope[ControlledType + nodeAccessor] = 5;
1358
1420
  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
- }
1421
+ const skip = nextAttrs && (controllable || controllableRenders[el.tagName])?.(scope, nodeAccessor, nextAttrs);
1392
1422
  for (const name in nextAttrs) {
1393
1423
  const value = nextAttrs[name];
1394
1424
  switch (name) {
@@ -1417,23 +1447,7 @@ function _attr_content(scope, nodeAccessor, value) {
1417
1447
  function _attrs_script(scope, nodeAccessor) {
1418
1448
  const el = scope[nodeAccessor];
1419
1449
  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;
1436
- }
1450
+ controllableScripts[scope[ControlledType + nodeAccessor]]?.(scope, nodeAccessor);
1437
1451
  for (const name in events) _on(el, name, events[name]);
1438
1452
  }
1439
1453
  function _html(scope, value, accessor) {
@@ -1547,6 +1561,11 @@ function _await_promise(nodeAccessor, params) {
1547
1561
  if (thisPromise === scope[promiseAccessor]) {
1548
1562
  const referenceNode = scope[nodeAccessor];
1549
1563
  scope[promiseAccessor] = 0;
1564
+ if (scope["#ClosestBranch"]?.["#Gen"] === 0) {
1565
+ awaitCounter.c();
1566
+ run();
1567
+ return;
1568
+ }
1550
1569
  queueAsyncRender(scope, () => {
1551
1570
  awaitBranch = resolveAwait(scope, referenceNode, data);
1552
1571
  const pendingRenders = awaitBranch[PendingRenders];
@@ -2382,6 +2401,10 @@ exports._const = _const;
2382
2401
  exports._content = _content;
2383
2402
  exports._content_closures = _content_closures;
2384
2403
  exports._content_resume = _content_resume;
2404
+ exports._controllable_input = _controllable_input;
2405
+ exports._controllable_open = _controllable_open;
2406
+ exports._controllable_select = _controllable_select;
2407
+ exports._controllable_textarea = _controllable_textarea;
2385
2408
  Object.defineProperty(exports, "_dynamic_tag", {
2386
2409
  enumerable: true,
2387
2410
  get: function() {
@@ -2392,6 +2415,11 @@ exports._dynamic_tag_content = _dynamic_tag_content;
2392
2415
  exports._el = _el;
2393
2416
  exports._el_read = _el_read;
2394
2417
  exports._enable_catch = _enable_catch;
2418
+ exports._enable_controllable = _enable_controllable;
2419
+ exports._enable_controllable_input = _enable_controllable_input;
2420
+ exports._enable_controllable_open = _enable_controllable_open;
2421
+ exports._enable_controllable_select = _enable_controllable_select;
2422
+ exports._enable_controllable_textarea = _enable_controllable_textarea;
2395
2423
  exports._for_closure = _for_closure;
2396
2424
  exports._for_in = _for_in;
2397
2425
  exports._for_of = _for_of;
@@ -24,6 +24,7 @@ const BranchScopes$1 = "BranchScopes:";
24
24
  const ClosureScopes = "ClosureScopes:";
25
25
  const ClosureSignalIndex = "ClosureSignalIndex:";
26
26
  const ConditionalRenderer = "ConditionalRenderer:";
27
+ const ControlledObserver = "ControlledObserver:";
27
28
  const ControlledHandler = "ControlledHandler:";
28
29
  const ControlledType = "ControlledType:";
29
30
  const ControlledValue = "ControlledValue:";
@@ -685,7 +686,7 @@ const walkInternal = function walkInternal(currentWalkIndex, walkCodes, scope) {
685
686
  currentWalkIndex = walkInternal(currentWalkIndex, walkCodes, scope[getDebugKey(currentScopeIndex++, "#childScope")] = createScope(scope[Global], scope[ClosestBranch]));
686
687
  if (value === 48) scope[getDebugKey(currentScopeIndex++, "#scopeOffset")] = skipScope();
687
688
  } else if (value < 92) {
688
- value = 20 * currentMultiplier + value - 67;
689
+ value = 25 * currentMultiplier + value - 67;
689
690
  while (value--) walker.nextNode();
690
691
  } else if (value < 107) {
691
692
  value = 10 * currentMultiplier + value - 97;
@@ -1009,6 +1010,36 @@ function _attr_input_checked_default(scope, nodeAccessor, checked) {
1009
1010
  if (restoreValue !== normalizedChecked) el.checked = restoreValue;
1010
1011
  }
1011
1012
  }
1013
+ /** Filled by the latches a compiled page emits, so a page carries only the
1014
+ * control kinds its tags can be (`_attrs_script` resolves the kind at run time). */
1015
+ const controllableScripts = {};
1016
+ /** The render pass equivalent, for a tag whose name is only known at run time;
1017
+ * a statically named tag passes its claim to `_attrs` instead. */
1018
+ const controllableRenders = {};
1019
+ function _enable_controllable_input() {
1020
+ controllableScripts[0] = _attr_input_checked_script;
1021
+ controllableScripts[1] = _attr_input_checkedValue_script;
1022
+ controllableScripts[2] = _attr_input_value_script;
1023
+ }
1024
+ function _enable_controllable_textarea() {
1025
+ controllableScripts[2] = _attr_input_value_script;
1026
+ }
1027
+ function _enable_controllable_select() {
1028
+ controllableScripts[3] = _attr_select_value_script;
1029
+ }
1030
+ function _enable_controllable_open() {
1031
+ controllableScripts[4] = _attr_details_or_dialog_open_script;
1032
+ }
1033
+ /** A run-time tag name can be any controllable, so its page enables them all. */
1034
+ function _enable_controllable() {
1035
+ _enable_controllable_input();
1036
+ _enable_controllable_select();
1037
+ _enable_controllable_open();
1038
+ controllableRenders.INPUT = _controllable_input;
1039
+ controllableRenders.TEXTAREA = _controllable_textarea;
1040
+ controllableRenders.SELECT = _controllable_select;
1041
+ controllableRenders.DETAILS = controllableRenders.DIALOG = _controllable_open;
1042
+ }
1012
1043
  function _attr_input_checked(scope, nodeAccessor, checked, checkedChange) {
1013
1044
  const el = scope[nodeAccessor];
1014
1045
  const normalizedChecked = isNotVoid(checked);
@@ -1170,12 +1201,12 @@ function _attr_select_value_script(scope, nodeAccessor) {
1170
1201
  }
1171
1202
  }
1172
1203
  syncControllableFormInput(el, hasSelectChanged, onChange);
1173
- new MutationObserver(() => {
1174
- const value = scope[ControlledValue + nodeAccessor];
1175
- if (Array.isArray(value) ? value.length !== el.selectedOptions.length || value.some((_, i) => !value.includes(el.selectedOptions[i].value)) : el.value !== value) onChange();
1176
- }).observe(el, {
1204
+ observeOnce(scope, nodeAccessor, {
1177
1205
  childList: true,
1178
1206
  subtree: true
1207
+ }, () => {
1208
+ const value = scope[ControlledValue + nodeAccessor];
1209
+ if (Array.isArray(value) ? value.length !== el.selectedOptions.length || value.some((_, i) => !value.includes(el.selectedOptions[i].value)) : el.value !== value) onChange();
1179
1210
  });
1180
1211
  }
1181
1212
  function setSelectValue(el, value, multiple) {
@@ -1205,7 +1236,10 @@ function _attr_details_or_dialog_open(scope, nodeAccessor, open, openChange) {
1205
1236
  }
1206
1237
  function _attr_details_or_dialog_open_script(scope, nodeAccessor) {
1207
1238
  const el = scope[nodeAccessor];
1208
- new MutationObserver(() => {
1239
+ observeOnce(scope, nodeAccessor, {
1240
+ attributes: true,
1241
+ attributeFilter: ["open"]
1242
+ }, () => {
1209
1243
  const openChange = scope[ControlledHandler + nodeAccessor];
1210
1244
  if (openChange && el.open === !scope["ControlledValue:" + nodeAccessor]) {
1211
1245
  const newValue = el.open;
@@ -1213,11 +1247,11 @@ function _attr_details_or_dialog_open_script(scope, nodeAccessor) {
1213
1247
  openChange(newValue);
1214
1248
  run();
1215
1249
  }
1216
- }).observe(el, {
1217
- attributes: true,
1218
- attributeFilter: ["open"]
1219
1250
  });
1220
1251
  }
1252
+ function observeOnce(scope, nodeAccessor, init, callback) {
1253
+ (scope[ControlledObserver + nodeAccessor] ||= new MutationObserver(callback)).observe(scope[nodeAccessor], init);
1254
+ }
1221
1255
  function syncControllableFormInput(el, hasChanged, onChange) {
1222
1256
  el._ = onChange;
1223
1257
  delegate("input", handleChange);
@@ -1253,6 +1287,35 @@ function updateList(arr, val, push) {
1253
1287
  const index = arr.indexOf(val);
1254
1288
  return (push ? !~index && [...arr, val] : ~index && arr.slice(0, index).concat(arr.slice(index + 1))) || arr;
1255
1289
  }
1290
+ function _controllable_input(scope, nodeAccessor, nextAttrs) {
1291
+ if ("checked" in nextAttrs || "checkedChange" in nextAttrs) {
1292
+ _attr_input_checked(scope, nodeAccessor, nextAttrs.checked, nextAttrs.checkedChange);
1293
+ return /^checked(?:Value)?(?:Change)?$/;
1294
+ }
1295
+ if ("checkedValue" in nextAttrs || "checkedValueChange" in nextAttrs) {
1296
+ _attr_input_checkedValue(scope, nodeAccessor, nextAttrs.checkedValue, nextAttrs.checkedValueChange, nextAttrs.value);
1297
+ return /^(?:value|checked(?:Value)?)(?:Change)?$/;
1298
+ }
1299
+ return _controllable_textarea(scope, nodeAccessor, nextAttrs, _attr_input_value_dynamic_default);
1300
+ }
1301
+ function _controllable_textarea(scope, nodeAccessor, nextAttrs, dynamicDefault) {
1302
+ if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1303
+ _attr_input_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange, dynamicDefault);
1304
+ return /^value(?:Change)?$/;
1305
+ }
1306
+ }
1307
+ function _controllable_select(scope, nodeAccessor, nextAttrs) {
1308
+ if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1309
+ _attr_select_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
1310
+ return /^value(?:Change)?$/;
1311
+ }
1312
+ }
1313
+ function _controllable_open(scope, nodeAccessor, nextAttrs) {
1314
+ if ("open" in nextAttrs || "openChange" in nextAttrs) {
1315
+ _attr_details_or_dialog_open(scope, nodeAccessor, nextAttrs.open, nextAttrs.openChange);
1316
+ return /^open(?:Change)?$/;
1317
+ }
1318
+ }
1256
1319
  //#endregion
1257
1320
  //#region src/dom/dom.ts
1258
1321
  function _to_text(value) {
@@ -1310,23 +1373,23 @@ function _text_content(node, value) {
1310
1373
  const normalizedValue = _to_text(value);
1311
1374
  if (node.textContent !== normalizedValue) node.textContent = normalizedValue;
1312
1375
  }
1313
- function _attrs(scope, nodeAccessor, nextAttrs) {
1376
+ function _attrs(scope, nodeAccessor, nextAttrs, controllable) {
1314
1377
  const el = scope[nodeAccessor];
1315
1378
  for (let i = el.attributes.length; i--;) {
1316
1379
  const { name } = el.attributes.item(i);
1317
1380
  if (!(nextAttrs && (name in nextAttrs || hasAttrAlias(el, name, nextAttrs)))) el.removeAttribute(name);
1318
1381
  }
1319
1382
  assertExclusiveAttrs(nextAttrs);
1320
- attrsInternal(scope, nodeAccessor, nextAttrs);
1383
+ attrsInternal(scope, nodeAccessor, nextAttrs, controllable);
1321
1384
  }
1322
- function _attrs_content(scope, nodeAccessor, nextAttrs) {
1323
- _attrs(scope, nodeAccessor, nextAttrs);
1385
+ function _attrs_content(scope, nodeAccessor, nextAttrs, controllable) {
1386
+ _attrs(scope, nodeAccessor, nextAttrs, controllable);
1324
1387
  _attr_content(scope, nodeAccessor, nextAttrs?.content);
1325
1388
  }
1326
1389
  function hasAttrAlias(element, attr, nextAttrs) {
1327
1390
  return attr === "checked" && element.tagName === "INPUT" && "checkedValue" in nextAttrs;
1328
1391
  }
1329
- function _attrs_partial(scope, nodeAccessor, nextAttrs, skip) {
1392
+ function _attrs_partial(scope, nodeAccessor, nextAttrs, skip, controllable) {
1330
1393
  const el = scope[nodeAccessor];
1331
1394
  const partial = {};
1332
1395
  for (let i = el.attributes.length; i--;) {
@@ -1341,52 +1404,19 @@ function _attrs_partial(scope, nodeAccessor, nextAttrs, skip) {
1341
1404
  ...nextAttrs,
1342
1405
  ...skip
1343
1406
  });
1344
- attrsInternal(scope, nodeAccessor, partial);
1407
+ attrsInternal(scope, nodeAccessor, partial, controllable);
1345
1408
  }
1346
- function _attrs_partial_content(scope, nodeAccessor, nextAttrs, skip) {
1347
- _attrs_partial(scope, nodeAccessor, nextAttrs, skip);
1409
+ function _attrs_partial_content(scope, nodeAccessor, nextAttrs, skip, controllable) {
1410
+ _attrs_partial(scope, nodeAccessor, nextAttrs, skip, controllable);
1348
1411
  _attr_content(scope, nodeAccessor, nextAttrs?.content);
1349
1412
  }
1350
- function attrsInternal(scope, nodeAccessor, nextAttrs) {
1413
+ function attrsInternal(scope, nodeAccessor, nextAttrs, controllable) {
1351
1414
  const el = scope[nodeAccessor];
1352
1415
  let events = scope[EventAttributes + nodeAccessor];
1353
- let skip;
1354
1416
  for (const name in events) events[name] = 0;
1355
1417
  scope[ControlledType + nodeAccessor] = 5;
1356
1418
  scope[ControlledHandler + nodeAccessor] = 0;
1357
- switch (nextAttrs && el.tagName) {
1358
- case "INPUT":
1359
- if ("checked" in nextAttrs || "checkedChange" in nextAttrs) {
1360
- _attr_input_checked(scope, nodeAccessor, nextAttrs.checked, nextAttrs.checkedChange);
1361
- skip = /^checked(?:Value)?(?:Change)?$/;
1362
- } else if ("checkedValue" in nextAttrs || "checkedValueChange" in nextAttrs) {
1363
- _attr_input_checkedValue(scope, nodeAccessor, nextAttrs.checkedValue, nextAttrs.checkedValueChange, nextAttrs.value);
1364
- skip = /^(?:value|checked(?:Value)?)(?:Change)?$/;
1365
- } else if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1366
- _attr_input_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange, _attr_input_value_dynamic_default);
1367
- skip = /^value(?:Change)?$/;
1368
- }
1369
- break;
1370
- case "SELECT":
1371
- if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1372
- _attr_select_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
1373
- skip = /^value(?:Change)?$/;
1374
- }
1375
- break;
1376
- case "TEXTAREA":
1377
- if ("value" in nextAttrs || "valueChange" in nextAttrs) {
1378
- _attr_input_value(scope, nodeAccessor, nextAttrs.value, nextAttrs.valueChange);
1379
- skip = /^value(?:Change)?$/;
1380
- }
1381
- break;
1382
- case "DETAILS":
1383
- case "DIALOG":
1384
- if ("open" in nextAttrs || "openChange" in nextAttrs) {
1385
- _attr_details_or_dialog_open(scope, nodeAccessor, nextAttrs.open, nextAttrs.openChange);
1386
- skip = /^open(?:Change)?$/;
1387
- }
1388
- break;
1389
- }
1419
+ const skip = nextAttrs && (controllable || controllableRenders[el.tagName])?.(scope, nodeAccessor, nextAttrs);
1390
1420
  for (const name in nextAttrs) {
1391
1421
  const value = nextAttrs[name];
1392
1422
  switch (name) {
@@ -1415,23 +1445,7 @@ function _attr_content(scope, nodeAccessor, value) {
1415
1445
  function _attrs_script(scope, nodeAccessor) {
1416
1446
  const el = scope[nodeAccessor];
1417
1447
  const events = scope[EventAttributes + nodeAccessor];
1418
- switch (scope[ControlledType + nodeAccessor]) {
1419
- case 0:
1420
- _attr_input_checked_script(scope, nodeAccessor);
1421
- break;
1422
- case 1:
1423
- _attr_input_checkedValue_script(scope, nodeAccessor);
1424
- break;
1425
- case 2:
1426
- _attr_input_value_script(scope, nodeAccessor);
1427
- break;
1428
- case 3:
1429
- _attr_select_value_script(scope, nodeAccessor);
1430
- break;
1431
- case 4:
1432
- _attr_details_or_dialog_open_script(scope, nodeAccessor);
1433
- break;
1434
- }
1448
+ controllableScripts[scope[ControlledType + nodeAccessor]]?.(scope, nodeAccessor);
1435
1449
  for (const name in events) _on(el, name, events[name]);
1436
1450
  }
1437
1451
  function _html(scope, value, accessor) {
@@ -1545,6 +1559,11 @@ function _await_promise(nodeAccessor, params) {
1545
1559
  if (thisPromise === scope[promiseAccessor]) {
1546
1560
  const referenceNode = scope[nodeAccessor];
1547
1561
  scope[promiseAccessor] = 0;
1562
+ if (scope["#ClosestBranch"]?.["#Gen"] === 0) {
1563
+ awaitCounter.c();
1564
+ run();
1565
+ return;
1566
+ }
1548
1567
  queueAsyncRender(scope, () => {
1549
1568
  awaitBranch = resolveAwait(scope, referenceNode, data);
1550
1569
  const pendingRenders = awaitBranch[PendingRenders];
@@ -2329,4 +2348,4 @@ function getSelectorOrResolve(selector, resolve) {
2329
2348
  return document.querySelector(selector) || (console.warn(`A lazy load trigger could not find an element matching "${selector}". The module was loaded immediately.`), resolve());
2330
2349
  }
2331
2350
  //#endregion
2332
- export { $signal, $signalReset, _assert_hoist, _assert_init, _attr, _attr_class, _attr_class_item, _attr_class_items, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_details_or_dialog_open_default as _attr_details_open_default, _attr_details_or_dialog_open_default as _attr_dialog_open_default, _attr_details_or_dialog_open_script as _attr_details_open_script, _attr_details_or_dialog_open_script as _attr_dialog_open_script, _attr_input_checked, _attr_input_checkedValue, _attr_input_checkedValue_default, _attr_input_checkedValue_script, _attr_input_checked_default, _attr_input_checked_script, _attr_input_value, _attr_input_value as _attr_textarea_value, _attr_input_value_attribute_default, _attr_input_value_default, _attr_input_value_default as _attr_textarea_value_default, _attr_input_value_dynamic_default, _attr_input_value_script, _attr_input_value_script as _attr_textarea_value_script, _attr_nonce, _attr_select_value, _attr_select_value_default, _attr_select_value_script, _attr_style, _attr_style_item, _attr_style_items, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _attrs_script, _await_content, _await_promise, _call, _child_setup, _closure, _closure_get, _const, _content, _content_closures, _content_resume, _dynamic_tag, _dynamic_tag_content, _el, _el_read, _enable_catch, _for_closure, _for_in, _for_of, _for_selector, _for_to, _for_until, _hoist, _hoist_resume, _html, _id, _if, _if_closure, _let, _let_change, _lifecycle, _load_event_trigger, _load_idle_trigger, _load_media_trigger, _load_race_trigger, _load_setup, _load_signal, _load_template, _load_visible_trigger, _on, _or, _resume, _resume_dynamic_tag, _return, _return_change, _script, _show, _style_rule_item, _style_shell, _template, _text, _text_content, _to_text, _try, _var, _var_change, _var_resume, attrTag, attrTags, compat, forIn, forOf, forTo, forUntil, init, initEmbedded, ready, run };
2351
+ export { $signal, $signalReset, _assert_hoist, _assert_init, _attr, _attr_class, _attr_class_item, _attr_class_items, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_details_or_dialog_open_default as _attr_details_open_default, _attr_details_or_dialog_open_default as _attr_dialog_open_default, _attr_details_or_dialog_open_script as _attr_details_open_script, _attr_details_or_dialog_open_script as _attr_dialog_open_script, _attr_input_checked, _attr_input_checkedValue, _attr_input_checkedValue_default, _attr_input_checkedValue_script, _attr_input_checked_default, _attr_input_checked_script, _attr_input_value, _attr_input_value as _attr_textarea_value, _attr_input_value_attribute_default, _attr_input_value_default, _attr_input_value_default as _attr_textarea_value_default, _attr_input_value_dynamic_default, _attr_input_value_script, _attr_input_value_script as _attr_textarea_value_script, _attr_nonce, _attr_select_value, _attr_select_value_default, _attr_select_value_script, _attr_style, _attr_style_item, _attr_style_items, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _attrs_script, _await_content, _await_promise, _call, _child_setup, _closure, _closure_get, _const, _content, _content_closures, _content_resume, _controllable_input, _controllable_open, _controllable_select, _controllable_textarea, _dynamic_tag, _dynamic_tag_content, _el, _el_read, _enable_catch, _enable_controllable, _enable_controllable_input, _enable_controllable_open, _enable_controllable_select, _enable_controllable_textarea, _for_closure, _for_in, _for_of, _for_selector, _for_to, _for_until, _hoist, _hoist_resume, _html, _id, _if, _if_closure, _let, _let_change, _lifecycle, _load_event_trigger, _load_idle_trigger, _load_media_trigger, _load_race_trigger, _load_setup, _load_signal, _load_template, _load_visible_trigger, _on, _or, _resume, _resume_dynamic_tag, _return, _return_change, _script, _show, _style_rule_item, _style_shell, _template, _text, _text_content, _to_text, _try, _var, _var_change, _var_resume, attrTag, attrTags, compat, forIn, forOf, forTo, forUntil, init, initEmbedded, ready, run };
@@ -1,5 +1,22 @@
1
- import { type Accessor, type Scope } from "../common/types";
1
+ import { type Accessor, ControlledType, type Scope } from "../common/types";
2
2
  export declare function _attr_input_checked_default(scope: Scope, nodeAccessor: Accessor, checked: boolean): void;
3
+ /** Filled by the latches a compiled page emits, so a page carries only the
4
+ * control kinds its tags can be (`_attrs_script` resolves the kind at run time). */
5
+ export declare const controllableScripts: {
6
+ [T in ControlledType]?: (scope: Scope, nodeAccessor: Accessor) => void;
7
+ };
8
+ /** The render pass equivalent, for a tag whose name is only known at run time;
9
+ * a statically named tag passes its claim to `_attrs` instead. */
10
+ export declare const controllableRenders: {
11
+ [tagName: string]: ControllableAttrs;
12
+ };
13
+ export type ControllableAttrs = (scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>) => RegExp | void;
14
+ export declare function _enable_controllable_input(): void;
15
+ export declare function _enable_controllable_textarea(): void;
16
+ export declare function _enable_controllable_select(): void;
17
+ export declare function _enable_controllable_open(): void;
18
+ /** A run-time tag name can be any controllable, so its page enables them all. */
19
+ export declare function _enable_controllable(): void;
3
20
  export declare function _attr_input_checked(scope: Scope, nodeAccessor: Accessor, checked: unknown, checkedChange: unknown): void;
4
21
  export declare function _attr_input_checked_script(scope: Scope, nodeAccessor: Accessor): void;
5
22
  export declare function _attr_input_checkedValue_default(scope: Scope, nodeAccessor: Accessor, checkedValue: unknown, value: unknown): void;
@@ -16,3 +33,7 @@ export declare function _attr_select_value_script(scope: Scope, nodeAccessor: Ac
16
33
  export declare function _attr_details_or_dialog_open_default(scope: Scope, nodeAccessor: Accessor, open: unknown): void;
17
34
  export declare function _attr_details_or_dialog_open(scope: Scope, nodeAccessor: Accessor, open: unknown, openChange: unknown): void;
18
35
  export declare function _attr_details_or_dialog_open_script(scope: Scope, nodeAccessor: Accessor): void;
36
+ export declare function _controllable_input(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>): RegExp | undefined;
37
+ export declare function _controllable_textarea(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>, dynamicDefault?: typeof _attr_input_value_dynamic_default): RegExp | undefined;
38
+ export declare function _controllable_select(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>): RegExp | undefined;
39
+ export declare function _controllable_open(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>): RegExp | undefined;
package/dist/dom/dom.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type Accessor, type Scope } from "../common/types";
2
+ import { type ControllableAttrs } from "./controllable";
2
3
  export declare function _to_text(value: unknown): string;
3
4
  export declare function _attr(element: Element, name: string, value: unknown): void;
4
5
  export declare function _attr_class(element: Element, value: unknown): void;
@@ -12,10 +13,10 @@ export declare function _style_rule_item(element: HTMLStyleElement, name: string
12
13
  export declare function _attr_nonce(scope: Scope, nodeAccessor: Accessor): void;
13
14
  export declare function _text(node: Text | Comment, value: unknown): void;
14
15
  export declare function _text_content(node: ParentNode, value: unknown): void;
15
- export declare function _attrs(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>): void;
16
- export declare function _attrs_content(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>): void;
17
- export declare function _attrs_partial(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>, skip: Record<string, 1>): void;
18
- export declare function _attrs_partial_content(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>, skip: Record<string, 1>): void;
16
+ export declare function _attrs(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>, controllable?: ControllableAttrs): void;
17
+ export declare function _attrs_content(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>, controllable?: ControllableAttrs): void;
18
+ export declare function _attrs_partial(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>, skip: Record<string, 1>, controllable?: ControllableAttrs): void;
19
+ export declare function _attrs_partial_content(scope: Scope, nodeAccessor: Accessor, nextAttrs: Record<string, unknown>, skip: Record<string, 1>, controllable?: ControllableAttrs): void;
19
20
  export declare function _attr_content(scope: Scope, nodeAccessor: Accessor, value: unknown): void;
20
21
  export declare function _attrs_script(scope: Scope, nodeAccessor: Accessor): void;
21
22
  export declare function _html(scope: Scope, value: unknown, accessor: Accessor): void;
package/dist/dom.d.ts CHANGED
@@ -5,7 +5,7 @@ export { _call } from "./common/helpers";
5
5
  export { $signal, $signalReset } from "./dom/abort-signal";
6
6
  export { compat } from "./dom/compat";
7
7
  export { _await_content, _await_promise, _dynamic_tag, _dynamic_tag_content, _for_in, _for_of, _for_to, _for_until, _if, _resume_dynamic_tag, _show, _try, } from "./dom/control-flow";
8
- export { _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open_default as _attr_details_open_default, _attr_details_or_dialog_open_script as _attr_details_open_script, _attr_details_or_dialog_open as _attr_dialog_open, _attr_details_or_dialog_open_default as _attr_dialog_open_default, _attr_details_or_dialog_open_script as _attr_dialog_open_script, _attr_input_checked, _attr_input_checked_default, _attr_input_checked_script, _attr_input_checkedValue, _attr_input_checkedValue_default, _attr_input_checkedValue_script, _attr_input_value, _attr_input_value_attribute_default, _attr_input_value_default, _attr_input_value_dynamic_default, _attr_input_value_script, _attr_select_value, _attr_select_value_default, _attr_select_value_script, _attr_input_value as _attr_textarea_value, _attr_input_value_default as _attr_textarea_value_default, _attr_input_value_script as _attr_textarea_value_script, } from "./dom/controllable";
8
+ export { _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open_default as _attr_details_open_default, _attr_details_or_dialog_open_script as _attr_details_open_script, _attr_details_or_dialog_open as _attr_dialog_open, _attr_details_or_dialog_open_default as _attr_dialog_open_default, _attr_details_or_dialog_open_script as _attr_dialog_open_script, _attr_input_checked, _attr_input_checked_default, _attr_input_checked_script, _attr_input_checkedValue, _attr_input_checkedValue_default, _attr_input_checkedValue_script, _attr_input_value, _attr_input_value_attribute_default, _attr_input_value_default, _attr_input_value_dynamic_default, _attr_input_value_script, _attr_select_value, _attr_select_value_default, _attr_select_value_script, _attr_input_value as _attr_textarea_value, _attr_input_value_default as _attr_textarea_value_default, _attr_input_value_script as _attr_textarea_value_script, _controllable_input, _controllable_open, _controllable_select, _controllable_textarea, _enable_controllable, _enable_controllable_input, _enable_controllable_open, _enable_controllable_select, _enable_controllable_textarea, } from "./dom/controllable";
9
9
  export { _attr, _attr_class, _attr_class_item, _attr_class_items, _attr_content, _attr_nonce, _attr_style, _attr_style_item, _attr_style_items, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _attrs_script, _html, _lifecycle, _style_rule_item, _style_shell, _text, _text_content, _to_text, } from "./dom/dom";
10
10
  export { _on } from "./dom/event";
11
11
  export { _load_event_trigger, _load_idle_trigger, _load_media_trigger, _load_race_trigger, _load_setup, _load_signal, _load_template, _load_visible_trigger, } from "./dom/load";