marko 6.1.11 → 6.1.13
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/common/accessor.d.ts +2 -2
- package/dist/common/accessor.debug.d.ts +2 -2
- package/dist/common/errors.d.ts +2 -2
- package/dist/common/types.d.ts +2 -2
- package/dist/debug/dom.js +72 -49
- package/dist/debug/dom.mjs +72 -49
- package/dist/debug/html.js +22 -4
- package/dist/debug/html.mjs +22 -4
- package/dist/dom/queue.d.ts +2 -2
- package/dist/dom/scope.d.ts +3 -0
- package/dist/dom.d.ts +2 -1
- package/dist/dom.js +51 -39
- package/dist/dom.mjs +51 -39
- package/dist/html/writer.d.ts +1 -1
- package/dist/translator/index.js +30 -9
- package/package.json +1 -1
package/dist/debug/dom.mjs
CHANGED
|
@@ -20,6 +20,7 @@ function* attrTagIterator() {
|
|
|
20
20
|
}
|
|
21
21
|
//#endregion
|
|
22
22
|
//#region src/common/errors.ts
|
|
23
|
+
const lowercaseEventHandlerReg = /^on[a-z]/;
|
|
23
24
|
function _el_read_error() {
|
|
24
25
|
throw new Error("Element references can only be read in scripts and event handlers.");
|
|
25
26
|
}
|
|
@@ -29,10 +30,6 @@ function _hoist_read_error() {
|
|
|
29
30
|
function _assert_hoist(value) {
|
|
30
31
|
if (typeof value !== "function") throw new Error(`Hoisted values must be functions, received type "${typeof value}".`);
|
|
31
32
|
}
|
|
32
|
-
function _assert_init(scope, accessor) {
|
|
33
|
-
if (scope["#Creating"] || !(accessor in scope)) throw new ReferenceError(`Cannot access '${accessor}' before initialization`);
|
|
34
|
-
return scope[accessor];
|
|
35
|
-
}
|
|
36
33
|
function assertExclusiveAttrs(attrs, onError = throwErr) {
|
|
37
34
|
if (attrs) {
|
|
38
35
|
let exclusiveAttrs;
|
|
@@ -48,6 +45,12 @@ function assertExclusiveAttrs(attrs, onError = throwErr) {
|
|
|
48
45
|
if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`);
|
|
49
46
|
}
|
|
50
47
|
}
|
|
48
|
+
function assertValidEventHandlerAttr(name, value) {
|
|
49
|
+
if (value && typeof value !== "string" && lowercaseEventHandlerReg.test(name)) throw new Error(`The \`${name}\` attribute must be a string or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}". To attach an event listener, use the \`on${name[2].toUpperCase()}${name.slice(3)}\` event handler instead.`);
|
|
50
|
+
}
|
|
51
|
+
function assertHandlerIsFunction(name, value) {
|
|
52
|
+
if (value && typeof value !== "function") throw new Error(`The \`${name}\` handler must be a function or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}".`);
|
|
53
|
+
}
|
|
51
54
|
function assertValidTagName(tagName) {
|
|
52
55
|
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.`);
|
|
53
56
|
}
|
|
@@ -148,6 +151,7 @@ function push(opt, item) {
|
|
|
148
151
|
//#region src/dom/event.ts
|
|
149
152
|
const defaultDelegator = /* @__PURE__ */ createDelegator();
|
|
150
153
|
function _on(element, type, handler) {
|
|
154
|
+
assertHandlerIsFunction("on" + type[0].toUpperCase() + type.slice(1), handler);
|
|
151
155
|
if (element["$" + type] === void 0) defaultDelegator(element, type, handleDelegated);
|
|
152
156
|
element["$" + type] = handler || null;
|
|
153
157
|
}
|
|
@@ -200,16 +204,34 @@ function parseHTML(html, ns) {
|
|
|
200
204
|
//#endregion
|
|
201
205
|
//#region src/dom/scope.ts
|
|
202
206
|
let nextScopeId = 1e6;
|
|
207
|
+
let collectingScopes;
|
|
203
208
|
function createScope($global, closestBranch) {
|
|
204
209
|
const scope = {
|
|
205
210
|
["#Id"]: nextScopeId++,
|
|
206
|
-
["#
|
|
211
|
+
["#Gen"]: runId,
|
|
207
212
|
["#ClosestBranch"]: closestBranch,
|
|
208
213
|
["$global"]: $global
|
|
209
214
|
};
|
|
210
|
-
|
|
215
|
+
collectingScopes?.push(scope);
|
|
211
216
|
return scope;
|
|
212
217
|
}
|
|
218
|
+
function syncGen(scope) {
|
|
219
|
+
scope["#Gen"] = runId;
|
|
220
|
+
}
|
|
221
|
+
function _assert_init(scope, accessor) {
|
|
222
|
+
if (scope["#Gen"] === runId || !(accessor in scope)) throw new ReferenceError(`Cannot access '${accessor}' before initialization`);
|
|
223
|
+
return scope[accessor];
|
|
224
|
+
}
|
|
225
|
+
function collectScopes(fn) {
|
|
226
|
+
const prev = collectingScopes;
|
|
227
|
+
collectingScopes = [];
|
|
228
|
+
try {
|
|
229
|
+
fn();
|
|
230
|
+
return collectingScopes;
|
|
231
|
+
} finally {
|
|
232
|
+
collectingScopes = prev;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
213
235
|
function skipScope() {
|
|
214
236
|
return nextScopeId++;
|
|
215
237
|
}
|
|
@@ -223,13 +245,13 @@ function destroyBranch(branch) {
|
|
|
223
245
|
destroyNestedScopes(branch);
|
|
224
246
|
}
|
|
225
247
|
function destroyScope(scope) {
|
|
226
|
-
if (
|
|
248
|
+
if (scope["#Gen"]) {
|
|
227
249
|
destroyNestedScopes(scope);
|
|
228
250
|
resetControllers(scope);
|
|
229
251
|
}
|
|
230
252
|
}
|
|
231
253
|
const destroyNestedScopes = function destroyNestedScopes(scope) {
|
|
232
|
-
scope["#
|
|
254
|
+
scope["#Gen"] = 0;
|
|
233
255
|
scope["#BranchScopes"]?.forEach(destroyNestedScopes);
|
|
234
256
|
scope["#AbortScopes"]?.forEach(resetControllers);
|
|
235
257
|
};
|
|
@@ -288,7 +310,7 @@ function _let(id, fn) {
|
|
|
288
310
|
id = +id.slice(id.lastIndexOf("/") + 1);
|
|
289
311
|
return (scope, value) => {
|
|
290
312
|
if (rendering) {
|
|
291
|
-
if (scope["#
|
|
313
|
+
if (scope["#Gen"] === runId) {
|
|
292
314
|
scope[valueAccessor] = value;
|
|
293
315
|
fn?.(scope);
|
|
294
316
|
}
|
|
@@ -323,7 +345,7 @@ function _const(valueAccessor, fn) {
|
|
|
323
345
|
}
|
|
324
346
|
function _or(id, fn, defaultPending = 1, scopeIdAccessor = "#Id") {
|
|
325
347
|
return (scope) => {
|
|
326
|
-
if (scope["#
|
|
348
|
+
if (scope["#Gen"] === runId) if (id in scope) {
|
|
327
349
|
if (!--scope[id]) fn(scope);
|
|
328
350
|
} else scope[id] = defaultPending;
|
|
329
351
|
else queueRender(scope, fn, id, 0, scope[scopeIdAccessor]);
|
|
@@ -334,7 +356,7 @@ function _for_closure(ownerLoopNodeAccessor, fn) {
|
|
|
334
356
|
const ownerSignal = (ownerScope) => {
|
|
335
357
|
const scopes = toArray(ownerScope[scopeAccessor]);
|
|
336
358
|
if (scopes.length) queueRender(ownerScope, () => {
|
|
337
|
-
for (const scope of scopes) if (
|
|
359
|
+
for (const scope of scopes) if (scope["#Gen"] > 0 && scope["#Gen"] < runId) fn(scope);
|
|
338
360
|
}, -1, 0, scopes[0]["#Id"]);
|
|
339
361
|
};
|
|
340
362
|
ownerSignal._ = fn;
|
|
@@ -345,7 +367,7 @@ function _if_closure(ownerConditionalNodeAccessor, branch, fn) {
|
|
|
345
367
|
const branchAccessor = "ConditionalRenderer:" + ownerConditionalNodeAccessor;
|
|
346
368
|
const ownerSignal = (scope) => {
|
|
347
369
|
const ifScope = scope[scopeAccessor];
|
|
348
|
-
if (ifScope &&
|
|
370
|
+
if (ifScope && ifScope["#Gen"] > 0 && ifScope["#Gen"] < runId && (scope[branchAccessor] || 0) === branch) queueRender(ifScope, fn, -1);
|
|
349
371
|
};
|
|
350
372
|
ownerSignal._ = fn;
|
|
351
373
|
return ownerSignal;
|
|
@@ -364,7 +386,7 @@ function _closure(...closureSignals) {
|
|
|
364
386
|
for (let i = closureSignals.length; i--;) closureSignals[i]["index"] = i;
|
|
365
387
|
return (scope) => {
|
|
366
388
|
if (scope[scopeInstances]) {
|
|
367
|
-
for (const childScope of scope[scopeInstances]) if (
|
|
389
|
+
for (const childScope of scope[scopeInstances]) if (childScope["#Gen"] > 0 && childScope["#Gen"] < runId) queueRender(childScope, closureSignals[childScope[signalIndex] || 0], -1);
|
|
368
390
|
}
|
|
369
391
|
};
|
|
370
392
|
}
|
|
@@ -604,6 +626,7 @@ function init(runtimeId = "M") {
|
|
|
604
626
|
renderId
|
|
605
627
|
};
|
|
606
628
|
const initScope = (scope) => {
|
|
629
|
+
scope["#Gen"] = 1;
|
|
607
630
|
scope["$global"] = initGlobal();
|
|
608
631
|
if (branchesEnabled && scope["#ClosestBranchId"]) scope["#ClosestBranch"] = getScope(scope["#ClosestBranchId"]);
|
|
609
632
|
return scope;
|
|
@@ -768,7 +791,7 @@ function _attr_input_checked_default(scope, nodeAccessor, checked) {
|
|
|
768
791
|
const el = scope[nodeAccessor];
|
|
769
792
|
const normalizedChecked = isNotVoid(checked);
|
|
770
793
|
if (el.defaultChecked !== normalizedChecked) {
|
|
771
|
-
const restoreValue = scope["#
|
|
794
|
+
const restoreValue = scope["#Gen"] < runId ? el.checked : normalizedChecked;
|
|
772
795
|
el.defaultChecked = normalizedChecked;
|
|
773
796
|
if (restoreValue !== normalizedChecked) el.checked = restoreValue;
|
|
774
797
|
}
|
|
@@ -776,9 +799,10 @@ function _attr_input_checked_default(scope, nodeAccessor, checked) {
|
|
|
776
799
|
function _attr_input_checked(scope, nodeAccessor, checked, checkedChange) {
|
|
777
800
|
const el = scope[nodeAccessor];
|
|
778
801
|
const normalizedChecked = isNotVoid(checked);
|
|
802
|
+
assertHandlerIsFunction("checkedChange", checkedChange);
|
|
779
803
|
scope["ControlledHandler:" + nodeAccessor] = checkedChange;
|
|
780
804
|
scope["ControlledType:" + nodeAccessor] = checkedChange ? 0 : 5;
|
|
781
|
-
if (checkedChange &&
|
|
805
|
+
if (checkedChange && scope["#Gen"] < runId) el.checked = normalizedChecked;
|
|
782
806
|
else _attr_input_checked_default(scope, nodeAccessor, normalizedChecked);
|
|
783
807
|
}
|
|
784
808
|
function _attr_input_checked_script(scope, nodeAccessor) {
|
|
@@ -804,9 +828,10 @@ function _attr_input_checkedValue(scope, nodeAccessor, checkedValue, checkedValu
|
|
|
804
828
|
const el = scope[nodeAccessor];
|
|
805
829
|
const multiple = Array.isArray(checkedValue);
|
|
806
830
|
const normalizedCheckedValue = scope["ControlledValue:" + nodeAccessor] = multiple ? checkedValue.map(normalizeStrProp) : normalizeStrProp(checkedValue);
|
|
831
|
+
assertHandlerIsFunction("checkedValueChange", checkedValueChange);
|
|
807
832
|
scope["ControlledHandler:" + nodeAccessor] = checkedValueChange;
|
|
808
833
|
scope["ControlledType:" + nodeAccessor] = checkedValueChange ? 1 : 5;
|
|
809
|
-
if (checkedValueChange &&
|
|
834
|
+
if (checkedValueChange && scope["#Gen"] < runId) {
|
|
810
835
|
el.checked = multiple ? normalizedCheckedValue.includes(normalizeStrProp(value)) : normalizeStrProp(value) === normalizedCheckedValue;
|
|
811
836
|
_attr(el, "value", value);
|
|
812
837
|
} else _attr_input_checkedValue_default(scope, nodeAccessor, checkedValue, value);
|
|
@@ -832,7 +857,7 @@ function _attr_input_value_default(scope, nodeAccessor, value) {
|
|
|
832
857
|
const el = scope[nodeAccessor];
|
|
833
858
|
const normalizedValue = normalizeAttrValue(value) || "";
|
|
834
859
|
if (el.defaultValue !== normalizedValue) {
|
|
835
|
-
const restoreValue = scope["#
|
|
860
|
+
const restoreValue = scope["#Gen"] < runId ? el.value : normalizedValue;
|
|
836
861
|
el.defaultValue = normalizedValue;
|
|
837
862
|
setInputValue(el, restoreValue);
|
|
838
863
|
}
|
|
@@ -840,10 +865,11 @@ function _attr_input_value_default(scope, nodeAccessor, value) {
|
|
|
840
865
|
function _attr_input_value(scope, nodeAccessor, value, valueChange) {
|
|
841
866
|
const el = scope[nodeAccessor];
|
|
842
867
|
const normalizedValue = normalizeAttrValue(value) || "";
|
|
868
|
+
assertHandlerIsFunction("valueChange", valueChange);
|
|
843
869
|
scope["ControlledHandler:" + nodeAccessor] = valueChange;
|
|
844
870
|
scope["ControlledValue:" + nodeAccessor] = normalizedValue;
|
|
845
871
|
scope["ControlledType:" + nodeAccessor] = valueChange ? 2 : 5;
|
|
846
|
-
if (valueChange &&
|
|
872
|
+
if (valueChange && scope["#Gen"] < runId) setInputValue(el, normalizedValue);
|
|
847
873
|
else _attr_input_value_default(scope, nodeAccessor, normalizedValue);
|
|
848
874
|
}
|
|
849
875
|
function _attr_input_value_script(scope, nodeAccessor) {
|
|
@@ -869,14 +895,14 @@ function setInputValue(el, value) {
|
|
|
869
895
|
function _attr_select_value_default(scope, nodeAccessor, value) {
|
|
870
896
|
let restoreValue;
|
|
871
897
|
const el = scope[nodeAccessor];
|
|
872
|
-
const
|
|
898
|
+
const live = scope["#Gen"] < runId;
|
|
873
899
|
const multiple = Array.isArray(value);
|
|
874
900
|
const normalizedValue = multiple ? value.map(normalizeStrProp) : normalizeStrProp(value);
|
|
875
901
|
pendingEffects.unshift(() => {
|
|
876
902
|
for (const opt of el.options) {
|
|
877
903
|
const selected = multiple ? normalizedValue.includes(opt.value) : opt.value === normalizedValue;
|
|
878
904
|
if (opt.defaultSelected !== selected) {
|
|
879
|
-
if (
|
|
905
|
+
if (live) restoreValue ??= getSelectValue(el, multiple);
|
|
880
906
|
opt.defaultSelected = selected;
|
|
881
907
|
}
|
|
882
908
|
}
|
|
@@ -885,9 +911,10 @@ function _attr_select_value_default(scope, nodeAccessor, value) {
|
|
|
885
911
|
}
|
|
886
912
|
function _attr_select_value(scope, nodeAccessor, value, valueChange) {
|
|
887
913
|
const el = scope[nodeAccessor];
|
|
888
|
-
const existing =
|
|
914
|
+
const existing = scope["#Gen"] < runId;
|
|
889
915
|
const multiple = Array.isArray(value);
|
|
890
916
|
const normalizedValue = scope["ControlledValue:" + nodeAccessor] = multiple ? value.map(normalizeStrProp) : normalizeStrProp(value);
|
|
917
|
+
assertHandlerIsFunction("valueChange", valueChange);
|
|
891
918
|
scope["ControlledHandler:" + nodeAccessor] = valueChange;
|
|
892
919
|
scope["ControlledType:" + nodeAccessor] = valueChange ? 3 : 5;
|
|
893
920
|
if (valueChange && existing) pendingEffects.unshift(() => setSelectValue(el, normalizedValue, multiple), scope);
|
|
@@ -933,13 +960,14 @@ function getSelectValue(el, multiple) {
|
|
|
933
960
|
return multiple ? Array.from(el.selectedOptions, (opt) => opt.value) : el.value;
|
|
934
961
|
}
|
|
935
962
|
function _attr_details_or_dialog_open_default(scope, nodeAccessor, open) {
|
|
936
|
-
if (scope["#
|
|
963
|
+
if (scope["#Gen"] === runId) scope[nodeAccessor].open = isNotVoid(open);
|
|
937
964
|
}
|
|
938
965
|
function _attr_details_or_dialog_open(scope, nodeAccessor, open, openChange) {
|
|
939
966
|
const normalizedOpen = scope["ControlledValue:" + nodeAccessor] = isNotVoid(open);
|
|
967
|
+
assertHandlerIsFunction("openChange", openChange);
|
|
940
968
|
scope["ControlledHandler:" + nodeAccessor] = openChange;
|
|
941
969
|
scope["ControlledType:" + nodeAccessor] = openChange ? 4 : 5;
|
|
942
|
-
if (openChange &&
|
|
970
|
+
if (openChange && scope["#Gen"] < runId) scope[nodeAccessor].open = normalizedOpen;
|
|
943
971
|
else _attr_details_or_dialog_open_default(scope, nodeAccessor, normalizedOpen);
|
|
944
972
|
}
|
|
945
973
|
function _attr_details_or_dialog_open_script(scope, nodeAccessor) {
|
|
@@ -998,6 +1026,7 @@ function _to_text(value) {
|
|
|
998
1026
|
return value || value === 0 ? value + "" : "";
|
|
999
1027
|
}
|
|
1000
1028
|
function _attr(element, name, value) {
|
|
1029
|
+
assertValidEventHandlerAttr(name, value);
|
|
1001
1030
|
setAttribute(element, name, normalizeAttrValue(value));
|
|
1002
1031
|
}
|
|
1003
1032
|
function setAttribute(element, name, value) {
|
|
@@ -1072,8 +1101,9 @@ function _attrs_partial_content(scope, nodeAccessor, nextAttrs, skip) {
|
|
|
1072
1101
|
}
|
|
1073
1102
|
function attrsInternal(scope, nodeAccessor, nextAttrs) {
|
|
1074
1103
|
const el = scope[nodeAccessor];
|
|
1075
|
-
let events;
|
|
1104
|
+
let events = scope["EventAttributes:" + nodeAccessor];
|
|
1076
1105
|
let skip;
|
|
1106
|
+
for (const name in events) events[name] = 0;
|
|
1077
1107
|
switch (el.tagName) {
|
|
1078
1108
|
case "INPUT":
|
|
1079
1109
|
if ("checked" in nextAttrs || "checkedChange" in nextAttrs) _attr_input_checked(scope, nodeAccessor, nextAttrs.checked, nextAttrs.checkedChange);
|
|
@@ -1243,7 +1273,7 @@ function _await_promise(nodeAccessor, params) {
|
|
|
1243
1273
|
scope[promiseAccessor] = 0;
|
|
1244
1274
|
queueAsyncRender(scope, () => {
|
|
1245
1275
|
if ((awaitBranch = scope[branchAccessor])["#DetachedAwait"]) {
|
|
1246
|
-
|
|
1276
|
+
awaitBranch["#PendingScopes"] = awaitBranch["#PendingScopes"]?.forEach(syncGen);
|
|
1247
1277
|
setupBranch(awaitBranch["#DetachedAwait"], awaitBranch);
|
|
1248
1278
|
awaitBranch["#DetachedAwait"] = 0;
|
|
1249
1279
|
insertBranchBefore(awaitBranch, scope[nodeAccessor].parentNode, scope[nodeAccessor]);
|
|
@@ -1284,8 +1314,8 @@ function _await_content(nodeAccessor, template, walks, setup) {
|
|
|
1284
1314
|
const branchAccessor = "BranchScopes:" + nodeAccessor;
|
|
1285
1315
|
const renderer = _content("", template, walks, setup)();
|
|
1286
1316
|
return (scope) => {
|
|
1287
|
-
(scope[branchAccessor] = createBranch(scope["$global"], renderer, scope, scope[nodeAccessor].parentNode))["#DetachedAwait"] = renderer;
|
|
1288
|
-
pendingScopes
|
|
1317
|
+
const pendingScopes = collectScopes(() => (scope[branchAccessor] = createBranch(scope["$global"], renderer, scope, scope[nodeAccessor].parentNode))["#DetachedAwait"] = renderer);
|
|
1318
|
+
scope[branchAccessor]["#PendingScopes"] = pendingScopes;
|
|
1289
1319
|
};
|
|
1290
1320
|
}
|
|
1291
1321
|
function addAwaitCounter(scope, tryBranch = findBranchWithKey(scope, "#PlaceholderContent")) {
|
|
@@ -1357,7 +1387,7 @@ function _if(nodeAccessor, ...branchesArgs) {
|
|
|
1357
1387
|
while (i < branchesArgs.length) branches.push(_content("", branchesArgs[i++], branchesArgs[i++], branchesArgs[i++])());
|
|
1358
1388
|
enableBranches();
|
|
1359
1389
|
return (scope, newBranch) => {
|
|
1360
|
-
if (newBranch !== scope[branchAccessor]) setConditionalRenderer(scope, nodeAccessor, branches[scope[branchAccessor] = newBranch], createAndSetupBranch);
|
|
1390
|
+
if (newBranch !== (scope[branchAccessor] ?? (scope["BranchScopes:" + nodeAccessor] && 0))) setConditionalRenderer(scope, nodeAccessor, branches[scope[branchAccessor] = newBranch], createAndSetupBranch);
|
|
1361
1391
|
};
|
|
1362
1392
|
}
|
|
1363
1393
|
function patchDynamicTag(fn) {
|
|
@@ -1449,7 +1479,8 @@ function loop(forEach) {
|
|
|
1449
1479
|
let hasPotentialMoves;
|
|
1450
1480
|
var seenKeys = /* @__PURE__ */ new Set();
|
|
1451
1481
|
forEach(value, (key, args) => {
|
|
1452
|
-
if (
|
|
1482
|
+
if (typeof key !== "string" && typeof key !== "number") console.error(`A <for> tag's \`by\` attribute must return a string or number, but it returned:`, key);
|
|
1483
|
+
else if (seenKeys.has(key)) console.error(`A <for> tag's \`by\` attribute must return a unique value for each item, but a duplicate was found matching:`, key);
|
|
1453
1484
|
else seenKeys.add(key);
|
|
1454
1485
|
let branch = oldLen && (oldScopesByKey ||= oldScopes.reduce((map, scope, i) => map.set(scope["#LoopKey"] ?? i, scope), /* @__PURE__ */ new Map())).get(key);
|
|
1455
1486
|
if (branch) hasPotentialMoves = oldScopesByKey.delete(key);
|
|
@@ -1548,13 +1579,12 @@ function byFirstArg(name) {
|
|
|
1548
1579
|
}
|
|
1549
1580
|
//#endregion
|
|
1550
1581
|
//#region src/dom/queue.ts
|
|
1551
|
-
let
|
|
1552
|
-
let
|
|
1582
|
+
let rendering;
|
|
1583
|
+
let runId = 2;
|
|
1553
1584
|
const caughtError = /* @__PURE__ */ new WeakSet();
|
|
1554
1585
|
const placeholderShown = /* @__PURE__ */ new WeakSet();
|
|
1555
1586
|
let pendingEffects = [];
|
|
1556
|
-
let
|
|
1557
|
-
let rendering;
|
|
1587
|
+
let pendingRenders = [];
|
|
1558
1588
|
const scopeKeyOffset = 1e3;
|
|
1559
1589
|
function queueRender(scope, signal, signalKey, value, scopeKey = scope["#Id"]) {
|
|
1560
1590
|
let render;
|
|
@@ -1647,13 +1677,11 @@ function runRenders() {
|
|
|
1647
1677
|
}
|
|
1648
1678
|
runRender(render);
|
|
1649
1679
|
}
|
|
1650
|
-
for (const scope of pendingScopes) scope["#Creating"] = 0;
|
|
1651
|
-
pendingScopes = [];
|
|
1652
1680
|
}
|
|
1653
1681
|
let runRender = (render) => render["signal"](render["scope"], render["value"]);
|
|
1654
1682
|
function skipDestroyedRenders() {
|
|
1655
1683
|
runRender = ((runRender) => (render) => {
|
|
1656
|
-
if (
|
|
1684
|
+
if (render["scope"]["#ClosestBranch"]?.["#Gen"] !== 0) runRender(render);
|
|
1657
1685
|
})(runRender);
|
|
1658
1686
|
}
|
|
1659
1687
|
let catchEnabled;
|
|
@@ -1676,8 +1704,7 @@ function _enable_catch() {
|
|
|
1676
1704
|
for (; i < effects.length;) {
|
|
1677
1705
|
fn = effects[i++];
|
|
1678
1706
|
scope = effects[i++];
|
|
1679
|
-
branch = scope["#ClosestBranch"];
|
|
1680
|
-
if (!branch?.["#Destroyed"] && !(checkPending && handlePendingTry(fn, scope, branch))) fn(scope);
|
|
1707
|
+
if ((branch = scope["#ClosestBranch"])?.["#Gen"] !== 0 && !(checkPending && handlePendingTry(fn, scope, branch))) fn(scope);
|
|
1681
1708
|
}
|
|
1682
1709
|
} else runEffects(effects);
|
|
1683
1710
|
})(runEffects);
|
|
@@ -1901,13 +1928,12 @@ function _load_setup(nodeAccessor, childScopeAccessor, load) {
|
|
|
1901
1928
|
}
|
|
1902
1929
|
function insertLoaded(renderer, branch, marker, awaitCounter) {
|
|
1903
1930
|
const parent = marker.parentNode;
|
|
1904
|
-
branch
|
|
1931
|
+
syncGen(branch);
|
|
1905
1932
|
renderer["clone"](branch, parent.namespaceURI);
|
|
1906
1933
|
setupBranch(renderer, branch);
|
|
1907
1934
|
applyLoad(branch, () => {
|
|
1908
1935
|
insertBranchBefore(branch, parent, marker);
|
|
1909
1936
|
marker.remove();
|
|
1910
|
-
pendingScopes.push(branch);
|
|
1911
1937
|
awaitCounter?.c();
|
|
1912
1938
|
});
|
|
1913
1939
|
}
|
|
@@ -1923,14 +1949,11 @@ function applyLoad(scope, insert) {
|
|
|
1923
1949
|
scope["#Load"] = 0;
|
|
1924
1950
|
if (remaining = values?.size) for (const [promise, entry] of values) promise.then((signal) => {
|
|
1925
1951
|
entry["signal"] = signal;
|
|
1926
|
-
if (!--remaining) {
|
|
1927
|
-
scope
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
insert();
|
|
1932
|
-
});
|
|
1933
|
-
}
|
|
1952
|
+
if (!--remaining) queueAsyncRender(scope, (scope) => {
|
|
1953
|
+
syncGen(scope);
|
|
1954
|
+
values.forEach((e) => e["signal"]._(scope, e["value"]));
|
|
1955
|
+
insert();
|
|
1956
|
+
});
|
|
1934
1957
|
}, () => 0);
|
|
1935
1958
|
else insert();
|
|
1936
1959
|
}
|
|
@@ -1939,7 +1962,7 @@ function _load_signal(load) {
|
|
|
1939
1962
|
let signal;
|
|
1940
1963
|
return (scope, value) => {
|
|
1941
1964
|
pending ||= load();
|
|
1942
|
-
if (scope["#Load"] || !("#Load" in scope) && scope["#
|
|
1965
|
+
if (scope["#Load"] || !("#Load" in scope) && scope["#Gen"] === runId) (scope["#Load"] ||= /* @__PURE__ */ new Map()).set(pending, { ["value"]: value });
|
|
1943
1966
|
else if (signal) signal(scope, value);
|
|
1944
1967
|
else pending.then((mod) => queueAsyncRender(scope, signal = mod._, value), () => 0);
|
|
1945
1968
|
};
|
package/dist/debug/html.js
CHANGED
|
@@ -22,6 +22,7 @@ function* attrTagIterator() {
|
|
|
22
22
|
}
|
|
23
23
|
//#endregion
|
|
24
24
|
//#region src/common/errors.ts
|
|
25
|
+
const lowercaseEventHandlerReg = /^on[a-z]/;
|
|
25
26
|
function _el_read_error() {
|
|
26
27
|
throw new Error("Element references can only be read in scripts and event handlers.");
|
|
27
28
|
}
|
|
@@ -46,6 +47,12 @@ function assertExclusiveAttrs(attrs, onError = throwErr) {
|
|
|
46
47
|
if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`);
|
|
47
48
|
}
|
|
48
49
|
}
|
|
50
|
+
function assertValidEventHandlerAttr(name, value) {
|
|
51
|
+
if (value && typeof value !== "string" && lowercaseEventHandlerReg.test(name)) throw new Error(`The \`${name}\` attribute must be a string or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}". To attach an event listener, use the \`on${name[2].toUpperCase()}${name.slice(3)}\` event handler instead.`);
|
|
52
|
+
}
|
|
53
|
+
function assertHandlerIsFunction(name, value) {
|
|
54
|
+
if (value && typeof value !== "function") throw new Error(`The \`${name}\` handler must be a function or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}".`);
|
|
55
|
+
}
|
|
49
56
|
function assertValidTagName(tagName) {
|
|
50
57
|
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.`);
|
|
51
58
|
}
|
|
@@ -1398,17 +1405,26 @@ function concat(opt, other) {
|
|
|
1398
1405
|
//#region src/html/for.ts
|
|
1399
1406
|
function forOfBy(by, item, index) {
|
|
1400
1407
|
if (by) {
|
|
1401
|
-
|
|
1402
|
-
return
|
|
1408
|
+
const key = typeof by === "string" ? item[by] : by(item, index);
|
|
1409
|
+
if (typeof key !== "string" && typeof key !== "number") console.error(`A <for> tag's \`by\` attribute must return a string or number, but it returned:`, key);
|
|
1410
|
+
return key;
|
|
1403
1411
|
}
|
|
1404
1412
|
return index;
|
|
1405
1413
|
}
|
|
1406
1414
|
function forInBy(by, name, value) {
|
|
1407
|
-
if (by)
|
|
1415
|
+
if (by) {
|
|
1416
|
+
const key = by(name, value);
|
|
1417
|
+
if (typeof key !== "string" && typeof key !== "number") console.error(`A <for> tag's \`by\` attribute must return a string or number, but it returned:`, key);
|
|
1418
|
+
return key;
|
|
1419
|
+
}
|
|
1408
1420
|
return name;
|
|
1409
1421
|
}
|
|
1410
1422
|
function forStepBy(by, index) {
|
|
1411
|
-
if (by)
|
|
1423
|
+
if (by) {
|
|
1424
|
+
const key = by(index);
|
|
1425
|
+
if (typeof key !== "string" && typeof key !== "number") console.error(`A <for> tag's \`by\` attribute must return a string or number, but it returned:`, key);
|
|
1426
|
+
return key;
|
|
1427
|
+
}
|
|
1412
1428
|
return index;
|
|
1413
1429
|
}
|
|
1414
1430
|
//#endregion
|
|
@@ -2414,6 +2430,7 @@ function _attr_nonce() {
|
|
|
2414
2430
|
return getChunk().boundary.state.nonceAttr;
|
|
2415
2431
|
}
|
|
2416
2432
|
function _attr(name, value) {
|
|
2433
|
+
assertValidEventHandlerAttr(name, value);
|
|
2417
2434
|
return isVoid(value) ? "" : nonVoidAttr(name, value);
|
|
2418
2435
|
}
|
|
2419
2436
|
function _attrs(data, nodeAccessor, scopeId, tagName) {
|
|
@@ -2489,6 +2506,7 @@ function _attrs_partial_content(data, skip, nodeAccessor, scopeId, tagName, seri
|
|
|
2489
2506
|
_attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
|
|
2490
2507
|
}
|
|
2491
2508
|
function writeControlledScope(type, scopeId, nodeAccessor, value, valueChange) {
|
|
2509
|
+
assertHandlerIsFunction("valueChange", valueChange);
|
|
2492
2510
|
writeScope(scopeId, {
|
|
2493
2511
|
["ControlledType:" + nodeAccessor]: type,
|
|
2494
2512
|
["ControlledValue:" + nodeAccessor]: value,
|
package/dist/debug/html.mjs
CHANGED
|
@@ -20,6 +20,7 @@ function* attrTagIterator() {
|
|
|
20
20
|
}
|
|
21
21
|
//#endregion
|
|
22
22
|
//#region src/common/errors.ts
|
|
23
|
+
const lowercaseEventHandlerReg = /^on[a-z]/;
|
|
23
24
|
function _el_read_error() {
|
|
24
25
|
throw new Error("Element references can only be read in scripts and event handlers.");
|
|
25
26
|
}
|
|
@@ -44,6 +45,12 @@ function assertExclusiveAttrs(attrs, onError = throwErr) {
|
|
|
44
45
|
if (exclusiveAttrs && exclusiveAttrs.length > 1) onError(`The attributes ${joinWithAnd(exclusiveAttrs)} are mutually exclusive.`);
|
|
45
46
|
}
|
|
46
47
|
}
|
|
48
|
+
function assertValidEventHandlerAttr(name, value) {
|
|
49
|
+
if (value && typeof value !== "string" && lowercaseEventHandlerReg.test(name)) throw new Error(`The \`${name}\` attribute must be a string or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}". To attach an event listener, use the \`on${name[2].toUpperCase()}${name.slice(3)}\` event handler instead.`);
|
|
50
|
+
}
|
|
51
|
+
function assertHandlerIsFunction(name, value) {
|
|
52
|
+
if (value && typeof value !== "function") throw new Error(`The \`${name}\` handler must be a function or a falsey value (\`null\`, \`undefined\`, \`false\`, \`0\`, …), but received type "${typeof value}".`);
|
|
53
|
+
}
|
|
47
54
|
function assertValidTagName(tagName) {
|
|
48
55
|
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.`);
|
|
49
56
|
}
|
|
@@ -1396,17 +1403,26 @@ function concat(opt, other) {
|
|
|
1396
1403
|
//#region src/html/for.ts
|
|
1397
1404
|
function forOfBy(by, item, index) {
|
|
1398
1405
|
if (by) {
|
|
1399
|
-
|
|
1400
|
-
return
|
|
1406
|
+
const key = typeof by === "string" ? item[by] : by(item, index);
|
|
1407
|
+
if (typeof key !== "string" && typeof key !== "number") console.error(`A <for> tag's \`by\` attribute must return a string or number, but it returned:`, key);
|
|
1408
|
+
return key;
|
|
1401
1409
|
}
|
|
1402
1410
|
return index;
|
|
1403
1411
|
}
|
|
1404
1412
|
function forInBy(by, name, value) {
|
|
1405
|
-
if (by)
|
|
1413
|
+
if (by) {
|
|
1414
|
+
const key = by(name, value);
|
|
1415
|
+
if (typeof key !== "string" && typeof key !== "number") console.error(`A <for> tag's \`by\` attribute must return a string or number, but it returned:`, key);
|
|
1416
|
+
return key;
|
|
1417
|
+
}
|
|
1406
1418
|
return name;
|
|
1407
1419
|
}
|
|
1408
1420
|
function forStepBy(by, index) {
|
|
1409
|
-
if (by)
|
|
1421
|
+
if (by) {
|
|
1422
|
+
const key = by(index);
|
|
1423
|
+
if (typeof key !== "string" && typeof key !== "number") console.error(`A <for> tag's \`by\` attribute must return a string or number, but it returned:`, key);
|
|
1424
|
+
return key;
|
|
1425
|
+
}
|
|
1410
1426
|
return index;
|
|
1411
1427
|
}
|
|
1412
1428
|
//#endregion
|
|
@@ -2412,6 +2428,7 @@ function _attr_nonce() {
|
|
|
2412
2428
|
return getChunk().boundary.state.nonceAttr;
|
|
2413
2429
|
}
|
|
2414
2430
|
function _attr(name, value) {
|
|
2431
|
+
assertValidEventHandlerAttr(name, value);
|
|
2415
2432
|
return isVoid(value) ? "" : nonVoidAttr(name, value);
|
|
2416
2433
|
}
|
|
2417
2434
|
function _attrs(data, nodeAccessor, scopeId, tagName) {
|
|
@@ -2487,6 +2504,7 @@ function _attrs_partial_content(data, skip, nodeAccessor, scopeId, tagName, seri
|
|
|
2487
2504
|
_attr_content(nodeAccessor, scopeId, data?.content, serializeReason);
|
|
2488
2505
|
}
|
|
2489
2506
|
function writeControlledScope(type, scopeId, nodeAccessor, value, valueChange) {
|
|
2507
|
+
assertHandlerIsFunction("valueChange", valueChange);
|
|
2490
2508
|
writeScope(scopeId, {
|
|
2491
2509
|
["ControlledType:" + nodeAccessor]: type,
|
|
2492
2510
|
["ControlledValue:" + nodeAccessor]: value,
|
package/dist/dom/queue.d.ts
CHANGED
|
@@ -9,11 +9,11 @@ export type PendingRender = {
|
|
|
9
9
|
[PendingRenderProp.Gen]: number;
|
|
10
10
|
[PendingRenderProp.Pending]?: 0 | 1;
|
|
11
11
|
};
|
|
12
|
+
export declare let rendering: undefined | 0 | 1;
|
|
13
|
+
export declare let runId: number;
|
|
12
14
|
export declare const caughtError: WeakSet<unknown[]>;
|
|
13
15
|
export declare const placeholderShown: WeakSet<unknown[]>;
|
|
14
16
|
export declare let pendingEffects: unknown[];
|
|
15
|
-
export declare let pendingScopes: Scope[];
|
|
16
|
-
export declare let rendering: undefined | 0 | 1;
|
|
17
17
|
export declare function queueRender<T, U extends Scope = Scope>(scope: U, signal: Signal<T, U>, signalKey: number, value?: T, scopeKey?: number): void;
|
|
18
18
|
export declare function queuePendingRender(render: PendingRender): void;
|
|
19
19
|
export declare function queueEffect<S extends Scope, T extends ExecFn<S>>(scope: S, fn: T): void;
|
package/dist/dom/scope.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { AccessorProp, type BranchScope, type Scope } from "../common/types";
|
|
2
2
|
export declare function createScope($global: Scope[AccessorProp.Global], closestBranch?: BranchScope): Scope;
|
|
3
|
+
export declare function syncGen(scope: Scope): void;
|
|
4
|
+
export declare function _assert_init(scope: Scope, accessor: string): any;
|
|
5
|
+
export declare function collectScopes(fn: () => void): Scope[];
|
|
3
6
|
export declare function skipScope(): number;
|
|
4
7
|
export declare function findBranchWithKey(scope: Scope, key: string): BranchScope | undefined;
|
|
5
8
|
export declare function destroyBranch(branch: BranchScope): void;
|
package/dist/dom.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { attrTag, attrTags } from "./common/attr-tag";
|
|
2
|
-
export { _assert_hoist
|
|
2
|
+
export { _assert_hoist } from "./common/errors";
|
|
3
3
|
export { forIn, forOf, forTo, forUntil } from "./common/for";
|
|
4
4
|
export { _call } from "./common/helpers";
|
|
5
5
|
export { $signal, $signalReset } from "./dom/abort-signal";
|
|
@@ -12,5 +12,6 @@ export { _load_event_trigger, _load_idle_trigger, _load_media_trigger, _load_rac
|
|
|
12
12
|
export { _enable_catch, run } from "./dom/queue";
|
|
13
13
|
export { _content, _content_closures, _content_resume } from "./dom/renderer";
|
|
14
14
|
export { _el, _resume, _var_resume, init, initEmbedded, ready, } from "./dom/resume";
|
|
15
|
+
export { _assert_init } from "./dom/scope";
|
|
15
16
|
export { _child_setup, _closure, _closure_get, _const, _el_read, _for_closure, _hoist, _hoist_resume, _id, _if_closure, _let, _let_change, _or, _return, _return_change, _script, _var, _var_change, } from "./dom/signals";
|
|
16
17
|
export { _template } from "./dom/template";
|