marko 6.3.16 → 6.3.18

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright 2024 eBay Inc. and contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -30,6 +30,7 @@ export declare enum AccessorProp {
30
30
  Id = "L",
31
31
  Load = "X",
32
32
  LoopKey = "M",
33
+ LoopIndex = "I",
33
34
  ParentBranch = "N",
34
35
  PendingEffects = "J",
35
36
  PendingRenders = "W",
@@ -30,6 +30,7 @@ export declare enum AccessorProp {
30
30
  Id = "#Id",
31
31
  Load = "#Load",
32
32
  LoopKey = "#LoopKey",
33
+ LoopIndex = "#LoopIndex",
33
34
  ParentBranch = "#ParentBranch",
34
35
  PendingEffects = "#PendingEffects",
35
36
  PendingRenders = "#PendingRenders",
@@ -50,7 +50,6 @@ export declare enum NodeType {
50
50
  }
51
51
  export declare enum WalkCode {
52
52
  Get = 32,
53
- Inside = 36,
54
53
  Replace = 37,
55
54
  EndChild = 38,
56
55
  BeginChild = 47,
package/dist/debug/dom.js CHANGED
@@ -73,7 +73,12 @@ function stringifyStyleObject(name, value) {
73
73
  warnedStyleKeys.add(name);
74
74
  console.warn(`\`${name}\` is not a CSS property name; \`style\` object keys are written verbatim, so it renders as invalid CSS. Use \`${name.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()).replace(/^ms-/, "-ms-")}\`.`);
75
75
  }
76
- return value || value === 0 ? name + ":" + value : "";
76
+ return value || value === 0 ? escapeStyleAttr(name) + ":" + escapeStyleAttr(value + "") : "";
77
+ }
78
+ const unsafeStyleAttrReg = /[\\;]/g;
79
+ const replaceUnsafeStyleAttr = (c) => c === ";" ? "\\3B " : "\\\\";
80
+ function escapeStyleAttr(str) {
81
+ return unsafeStyleAttrReg.test(str) ? str.replace(unsafeStyleAttrReg, replaceUnsafeStyleAttr) : str;
77
82
  }
78
83
  function escapeStyleValue(str) {
79
84
  let closers = "";
@@ -991,9 +996,12 @@ function _attr_input_checkedValue_script(scope, nodeAccessor) {
991
996
  if (checkedValueChange) {
992
997
  const controlledValueKey = "ControlledValue:" + nodeAccessor;
993
998
  const oldValue = scope[controlledValueKey];
994
- const newValue = Array.isArray(oldValue) ? updateList(oldValue, el.value, el.checked) : el.checked ? el.value : void 0;
999
+ let newValue = Array.isArray(oldValue) ? updateList(oldValue, el.value, el.checked) : el.checked ? el.value : void 0;
995
1000
  if (el.name && el.type[0] === "r") {
996
- for (const radio of document.querySelectorAll(`[type=radio][name=${CSS.escape(el.name)}]`)) if (radio.form === el.form) radio.checked = Array.isArray(oldValue) ? oldValue.includes(radio.value) : controlledValueKey in scope ? oldValue === radio.value : radio.defaultChecked;
1001
+ for (const radio of document.querySelectorAll(`[type=radio][name=${CSS.escape(el.name)}]`)) if (radio.form === el.form) {
1002
+ if (newValue === void 0 && radio.defaultChecked) newValue = radio.value;
1003
+ radio.checked = Array.isArray(oldValue) ? oldValue.includes(radio.value) : controlledValueKey in scope ? oldValue === radio.value : radio.defaultChecked;
1004
+ }
997
1005
  } else el.checked = !el.checked;
998
1006
  checkedValueChange(newValue);
999
1007
  run();
@@ -1500,7 +1508,9 @@ function _await_promise(nodeAccessor, params) {
1500
1508
  }
1501
1509
  }, (error) => {
1502
1510
  if (thisPromise === scope[promiseAccessor]) {
1503
- awaitCounter.i = scope[promiseAccessor] = 0;
1511
+ scope[promiseAccessor] = 0;
1512
+ if (tryPlaceholder && !awaitCounter.m) awaitCounter.c();
1513
+ else awaitCounter.i = 0;
1504
1514
  queueAsyncRender(scope, renderCatch, error);
1505
1515
  }
1506
1516
  });
@@ -1733,12 +1743,17 @@ function loop(forEach) {
1733
1743
  const parentNode = referenceNode.nodeType > 1 ? referenceNode.parentNode || oldScopes[0]?.["#StartNode"].parentNode : referenceNode;
1734
1744
  let oldScopesByKey;
1735
1745
  let hasPotentialMoves;
1746
+ let start = 0;
1736
1747
  var seenKeys = /* @__PURE__ */ new Set();
1737
1748
  forEach(value, (key, args) => {
1738
1749
  assertValidLoopKey(key, seenKeys);
1739
- let branch = oldLen && (oldScopesByKey ||= oldScopes.reduce((map, scope, i) => map.set(scope["#LoopKey"] ?? i, scope), /* @__PURE__ */ new Map())).get(key);
1740
- if (branch) hasPotentialMoves = oldScopesByKey.delete(key);
1741
- else branch = createAndSetupBranch(scope["$global"], renderer, scope, parentNode);
1750
+ const i = newScopes.length;
1751
+ const oldScope = oldScopes[i];
1752
+ let branch = oldLen && (oldScopesByKey || key !== (oldScope?.["#LoopKey"] ?? i) ? (oldScopesByKey ||= oldScopes.reduce((map, scope, j) => j < i ? map : (scope["#LoopIndex"] = j, map.set(scope["#LoopKey"] ?? j, scope)), /* @__PURE__ */ new Map())).get(key) : oldScope && (start++, oldScope));
1753
+ if (branch) {
1754
+ hasPotentialMoves = true;
1755
+ oldScopesByKey?.delete(key);
1756
+ } else branch = createAndSetupBranch(scope["$global"], renderer, scope, parentNode);
1742
1757
  branch["#LoopKey"] = key;
1743
1758
  newScopes.push(branch);
1744
1759
  params?.(branch, args);
@@ -1748,7 +1763,6 @@ function loop(forEach) {
1748
1763
  let afterReference = null;
1749
1764
  let oldEnd = oldLen - 1;
1750
1765
  let newEnd = newLen - 1;
1751
- let start = 0;
1752
1766
  if (hasSiblings) {
1753
1767
  if (oldLen) {
1754
1768
  afterReference = oldScopes[oldEnd]["#EndNode"].nextSibling;
@@ -1766,19 +1780,18 @@ function loop(forEach) {
1766
1780
  for (const newScope of newScopes) insertBranchBefore(newScope, parentNode, afterReference);
1767
1781
  return;
1768
1782
  }
1769
- for (const branch of oldScopesByKey.values()) removeAndDestroyBranch(branch);
1770
- while (start < oldLen && start < newLen && oldScopes[start] === newScopes[start]) start++;
1783
+ if (oldScopesByKey) oldScopesByKey.forEach(removeAndDestroyBranch);
1784
+ else for (let i = newLen; i < oldLen; i++) removeAndDestroyBranch(oldScopes[i]);
1771
1785
  while (oldEnd >= start && newEnd >= start && oldScopes[oldEnd] === newScopes[newEnd]) {
1772
1786
  oldEnd--;
1773
1787
  newEnd--;
1774
1788
  }
1775
1789
  if (oldEnd + 1 < oldLen) afterReference = oldScopes[oldEnd + 1]["#StartNode"];
1776
- if (start > oldEnd) {
1777
- if (start <= newEnd) for (let i = start; i <= newEnd; i++) insertBranchBefore(newScopes[i], parentNode, afterReference);
1790
+ if (start > oldEnd || start > newEnd) {
1791
+ for (let i = start; i <= newEnd; i++) insertBranchBefore(newScopes[i], parentNode, afterReference);
1778
1792
  return;
1779
- } else if (start > newEnd) return;
1793
+ }
1780
1794
  const diffLen = newEnd - start + 1;
1781
- const oldPos = /* @__PURE__ */ new Map();
1782
1795
  const sources = new Array(diffLen);
1783
1796
  const pred = new Array(diffLen);
1784
1797
  const tails = [];
@@ -1786,8 +1799,7 @@ function loop(forEach) {
1786
1799
  let lo;
1787
1800
  let hi;
1788
1801
  let mid;
1789
- for (let i = start; i <= oldEnd; i++) oldPos.set(oldScopes[i], i);
1790
- for (let i = diffLen; i--;) sources[i] = oldPos.get(newScopes[start + i]) ?? -1;
1802
+ for (let i = diffLen; i--;) sources[i] = newScopes[start + i]["#LoopIndex"] ?? -1;
1791
1803
  for (let i = 0; i < diffLen; i++) if (~sources[i]) if (tail < 0 || sources[tails[tail]] < sources[i]) {
1792
1804
  if (~tail) pred[i] = tails[tail];
1793
1805
  tails[++tail] = i;
@@ -2217,7 +2229,8 @@ function insertLoaded(renderer, branch, marker, awaitCounter) {
2217
2229
  }
2218
2230
  function loadFailed(scope, awaitCounter) {
2219
2231
  return (error) => {
2220
- if (awaitCounter) awaitCounter.i = 0;
2232
+ if (awaitCounter) if (awaitCounter.m) awaitCounter.i = 0;
2233
+ else awaitCounter.c();
2221
2234
  queueAsyncRender(scope, renderCatch, error);
2222
2235
  };
2223
2236
  }
@@ -71,7 +71,12 @@ function stringifyStyleObject(name, value) {
71
71
  warnedStyleKeys.add(name);
72
72
  console.warn(`\`${name}\` is not a CSS property name; \`style\` object keys are written verbatim, so it renders as invalid CSS. Use \`${name.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()).replace(/^ms-/, "-ms-")}\`.`);
73
73
  }
74
- return value || value === 0 ? name + ":" + value : "";
74
+ return value || value === 0 ? escapeStyleAttr(name) + ":" + escapeStyleAttr(value + "") : "";
75
+ }
76
+ const unsafeStyleAttrReg = /[\\;]/g;
77
+ const replaceUnsafeStyleAttr = (c) => c === ";" ? "\\3B " : "\\\\";
78
+ function escapeStyleAttr(str) {
79
+ return unsafeStyleAttrReg.test(str) ? str.replace(unsafeStyleAttrReg, replaceUnsafeStyleAttr) : str;
75
80
  }
76
81
  function escapeStyleValue(str) {
77
82
  let closers = "";
@@ -989,9 +994,12 @@ function _attr_input_checkedValue_script(scope, nodeAccessor) {
989
994
  if (checkedValueChange) {
990
995
  const controlledValueKey = "ControlledValue:" + nodeAccessor;
991
996
  const oldValue = scope[controlledValueKey];
992
- const newValue = Array.isArray(oldValue) ? updateList(oldValue, el.value, el.checked) : el.checked ? el.value : void 0;
997
+ let newValue = Array.isArray(oldValue) ? updateList(oldValue, el.value, el.checked) : el.checked ? el.value : void 0;
993
998
  if (el.name && el.type[0] === "r") {
994
- for (const radio of document.querySelectorAll(`[type=radio][name=${CSS.escape(el.name)}]`)) if (radio.form === el.form) radio.checked = Array.isArray(oldValue) ? oldValue.includes(radio.value) : controlledValueKey in scope ? oldValue === radio.value : radio.defaultChecked;
999
+ for (const radio of document.querySelectorAll(`[type=radio][name=${CSS.escape(el.name)}]`)) if (radio.form === el.form) {
1000
+ if (newValue === void 0 && radio.defaultChecked) newValue = radio.value;
1001
+ radio.checked = Array.isArray(oldValue) ? oldValue.includes(radio.value) : controlledValueKey in scope ? oldValue === radio.value : radio.defaultChecked;
1002
+ }
995
1003
  } else el.checked = !el.checked;
996
1004
  checkedValueChange(newValue);
997
1005
  run();
@@ -1498,7 +1506,9 @@ function _await_promise(nodeAccessor, params) {
1498
1506
  }
1499
1507
  }, (error) => {
1500
1508
  if (thisPromise === scope[promiseAccessor]) {
1501
- awaitCounter.i = scope[promiseAccessor] = 0;
1509
+ scope[promiseAccessor] = 0;
1510
+ if (tryPlaceholder && !awaitCounter.m) awaitCounter.c();
1511
+ else awaitCounter.i = 0;
1502
1512
  queueAsyncRender(scope, renderCatch, error);
1503
1513
  }
1504
1514
  });
@@ -1731,12 +1741,17 @@ function loop(forEach) {
1731
1741
  const parentNode = referenceNode.nodeType > 1 ? referenceNode.parentNode || oldScopes[0]?.["#StartNode"].parentNode : referenceNode;
1732
1742
  let oldScopesByKey;
1733
1743
  let hasPotentialMoves;
1744
+ let start = 0;
1734
1745
  var seenKeys = /* @__PURE__ */ new Set();
1735
1746
  forEach(value, (key, args) => {
1736
1747
  assertValidLoopKey(key, seenKeys);
1737
- let branch = oldLen && (oldScopesByKey ||= oldScopes.reduce((map, scope, i) => map.set(scope["#LoopKey"] ?? i, scope), /* @__PURE__ */ new Map())).get(key);
1738
- if (branch) hasPotentialMoves = oldScopesByKey.delete(key);
1739
- else branch = createAndSetupBranch(scope["$global"], renderer, scope, parentNode);
1748
+ const i = newScopes.length;
1749
+ const oldScope = oldScopes[i];
1750
+ let branch = oldLen && (oldScopesByKey || key !== (oldScope?.["#LoopKey"] ?? i) ? (oldScopesByKey ||= oldScopes.reduce((map, scope, j) => j < i ? map : (scope["#LoopIndex"] = j, map.set(scope["#LoopKey"] ?? j, scope)), /* @__PURE__ */ new Map())).get(key) : oldScope && (start++, oldScope));
1751
+ if (branch) {
1752
+ hasPotentialMoves = true;
1753
+ oldScopesByKey?.delete(key);
1754
+ } else branch = createAndSetupBranch(scope["$global"], renderer, scope, parentNode);
1740
1755
  branch["#LoopKey"] = key;
1741
1756
  newScopes.push(branch);
1742
1757
  params?.(branch, args);
@@ -1746,7 +1761,6 @@ function loop(forEach) {
1746
1761
  let afterReference = null;
1747
1762
  let oldEnd = oldLen - 1;
1748
1763
  let newEnd = newLen - 1;
1749
- let start = 0;
1750
1764
  if (hasSiblings) {
1751
1765
  if (oldLen) {
1752
1766
  afterReference = oldScopes[oldEnd]["#EndNode"].nextSibling;
@@ -1764,19 +1778,18 @@ function loop(forEach) {
1764
1778
  for (const newScope of newScopes) insertBranchBefore(newScope, parentNode, afterReference);
1765
1779
  return;
1766
1780
  }
1767
- for (const branch of oldScopesByKey.values()) removeAndDestroyBranch(branch);
1768
- while (start < oldLen && start < newLen && oldScopes[start] === newScopes[start]) start++;
1781
+ if (oldScopesByKey) oldScopesByKey.forEach(removeAndDestroyBranch);
1782
+ else for (let i = newLen; i < oldLen; i++) removeAndDestroyBranch(oldScopes[i]);
1769
1783
  while (oldEnd >= start && newEnd >= start && oldScopes[oldEnd] === newScopes[newEnd]) {
1770
1784
  oldEnd--;
1771
1785
  newEnd--;
1772
1786
  }
1773
1787
  if (oldEnd + 1 < oldLen) afterReference = oldScopes[oldEnd + 1]["#StartNode"];
1774
- if (start > oldEnd) {
1775
- if (start <= newEnd) for (let i = start; i <= newEnd; i++) insertBranchBefore(newScopes[i], parentNode, afterReference);
1788
+ if (start > oldEnd || start > newEnd) {
1789
+ for (let i = start; i <= newEnd; i++) insertBranchBefore(newScopes[i], parentNode, afterReference);
1776
1790
  return;
1777
- } else if (start > newEnd) return;
1791
+ }
1778
1792
  const diffLen = newEnd - start + 1;
1779
- const oldPos = /* @__PURE__ */ new Map();
1780
1793
  const sources = new Array(diffLen);
1781
1794
  const pred = new Array(diffLen);
1782
1795
  const tails = [];
@@ -1784,8 +1797,7 @@ function loop(forEach) {
1784
1797
  let lo;
1785
1798
  let hi;
1786
1799
  let mid;
1787
- for (let i = start; i <= oldEnd; i++) oldPos.set(oldScopes[i], i);
1788
- for (let i = diffLen; i--;) sources[i] = oldPos.get(newScopes[start + i]) ?? -1;
1800
+ for (let i = diffLen; i--;) sources[i] = newScopes[start + i]["#LoopIndex"] ?? -1;
1789
1801
  for (let i = 0; i < diffLen; i++) if (~sources[i]) if (tail < 0 || sources[tails[tail]] < sources[i]) {
1790
1802
  if (~tail) pred[i] = tails[tail];
1791
1803
  tails[++tail] = i;
@@ -2215,7 +2227,8 @@ function insertLoaded(renderer, branch, marker, awaitCounter) {
2215
2227
  }
2216
2228
  function loadFailed(scope, awaitCounter) {
2217
2229
  return (error) => {
2218
- if (awaitCounter) awaitCounter.i = 0;
2230
+ if (awaitCounter) if (awaitCounter.m) awaitCounter.i = 0;
2231
+ else awaitCounter.c();
2219
2232
  queueAsyncRender(scope, renderCatch, error);
2220
2233
  };
2221
2234
  }
@@ -69,7 +69,12 @@ function stringifyStyleObject(name, value) {
69
69
  warnedStyleKeys.add(name);
70
70
  console.warn(`\`${name}\` is not a CSS property name; \`style\` object keys are written verbatim, so it renders as invalid CSS. Use \`${name.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()).replace(/^ms-/, "-ms-")}\`.`);
71
71
  }
72
- return value || value === 0 ? name + ":" + value : "";
72
+ return value || value === 0 ? escapeStyleAttr(name) + ":" + escapeStyleAttr(value + "") : "";
73
+ }
74
+ const unsafeStyleAttrReg = /[\\;]/g;
75
+ const replaceUnsafeStyleAttr = (c) => c === ";" ? "\\3B " : "\\\\";
76
+ function escapeStyleAttr(str) {
77
+ return unsafeStyleAttrReg.test(str) ? str.replace(unsafeStyleAttrReg, replaceUnsafeStyleAttr) : str;
73
78
  }
74
79
  function escapeStyleValue(str) {
75
80
  let closers = "";
@@ -239,8 +244,8 @@ function _escape_script(val) {
239
244
  assertValidTextValue(val);
240
245
  return val ? escapeScriptStr(val + "") : val === 0 ? "0" : "";
241
246
  }
242
- const unsafeStyleReg = /<\/style/gi;
243
- const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C/style") : str;
247
+ const unsafeStyleReg = /<(\/style)/gi;
248
+ const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C$1") : str;
244
249
  function _escape_style(val) {
245
250
  assertValidTextValue(val);
246
251
  return val ? escapeStyleStr(val + "") : val === 0 ? "0" : "";
@@ -906,11 +911,18 @@ function writeDate(state, val) {
906
911
  state.buf.push("new Date(" + +val + ")");
907
912
  return true;
908
913
  }
909
- const unsafeRegExpSourceReg = /\\[\s\S]|</g;
910
- const replaceUnsafeRegExpSourceChar = (match) => match === "<" || match === "\\<" ? "\\x3C" : match;
914
+ const unsafeRegExpSourceReg = /\\[\s\S]|[<\0\ud800-\udfff]/gu;
915
+ const unsafeRegExpSourceDetect = /[<\0\ud800-\udfff]/u;
916
+ const replaceUnsafeRegExpSourceChar = (match) => {
917
+ const ch = match.length === 3 ? "" : match[match.length - 1];
918
+ if (ch === "<") return "\\x3C";
919
+ if (ch === "\0") return "\\x00";
920
+ const code = ch.charCodeAt(0);
921
+ return code >= 55296 && code <= 57343 ? "\\u" + code.toString(16).padStart(4, "0") : match;
922
+ };
911
923
  function writeRegExp(state, val) {
912
924
  const { source } = val;
913
- state.buf.push("/" + (source.includes("<") ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags);
925
+ state.buf.push("/" + (unsafeRegExpSourceDetect.test(source) ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags);
914
926
  return true;
915
927
  }
916
928
  function writePromise(state, val, ref) {
@@ -1049,9 +1061,17 @@ function writeError(state, val, ref) {
1049
1061
  }
1050
1062
  function writeAggregateError(state, val, ref) {
1051
1063
  state.buf.push("new AggregateError(");
1052
- if (!writeProp(state, val.errors, ref, "errors")) state.buf.push("[]");
1064
+ const inlined = writeProp(state, val.errors, ref, "errors");
1065
+ if (!inlined) state.buf.push("[]");
1053
1066
  if (val.message) state.buf.push("," + quote(val.message + "", 0) + ")");
1054
1067
  else state.buf.push(")");
1068
+ if (inlined) {
1069
+ const errorsRef = state.refs.get(val.errors);
1070
+ if (errorsRef?.id) {
1071
+ state.assigned.add(errorsRef);
1072
+ addAssignment(errorsRef, accessId(state, ref) + toAccess("errors"));
1073
+ }
1074
+ }
1055
1075
  return true;
1056
1076
  }
1057
1077
  function writeURL(state, val) {
@@ -1106,11 +1126,17 @@ function writeRequest(state, val, ref) {
1106
1126
  options += sep + "credentials:" + quote(val.credentials, 0);
1107
1127
  sep = ",";
1108
1128
  }
1109
- const headers = stringEntriesToHeadersInit(val.headers);
1110
- state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null));
1111
- if (headers) {
1112
- options += sep + "headers:" + headers;
1129
+ const seenHeaders = state.refs.get(val.headers);
1130
+ if (seenHeaders) {
1131
+ options += sep + "headers:" + ensureId(state, seenHeaders);
1113
1132
  sep = ",";
1133
+ } else {
1134
+ state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null));
1135
+ const headers = stringEntriesToHeadersInit(val.headers);
1136
+ if (headers) {
1137
+ options += sep + "headers:" + headers;
1138
+ sep = ",";
1139
+ }
1114
1140
  }
1115
1141
  if (val.integrity) {
1116
1142
  options += sep + "integrity:" + quote(val.integrity, 0);
@@ -1151,9 +1177,13 @@ function writeResponse(state, val, ref) {
1151
1177
  options += sep + "statusText:" + quote(val.statusText, 0);
1152
1178
  sep = ",";
1153
1179
  }
1154
- const headers = stringEntriesToHeadersInit(val.headers);
1155
- state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null));
1156
- if (headers) options += sep + "headers:" + headers;
1180
+ const seenHeaders = state.refs.get(val.headers);
1181
+ if (seenHeaders) options += sep + "headers:" + ensureId(state, seenHeaders);
1182
+ else {
1183
+ state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null));
1184
+ const headers = stringEntriesToHeadersInit(val.headers);
1185
+ if (headers) options += sep + "headers:" + headers;
1186
+ }
1157
1187
  if (!val.body || val.bodyUsed) state.buf.push("new Response" + (options ? "(null,{" + options + "})" : ""));
1158
1188
  else {
1159
1189
  state.buf.push("new Response(");
@@ -2582,15 +2612,21 @@ const kSelectedValue = Symbol("selectedValue");
2582
2612
  const kSelectedValueMatched = Symbol("selectedValueMatched");
2583
2613
  function _attr_select_value(scopeId, nodeAccessor, value, valueChange, content, serializeType) {
2584
2614
  if (valueChange) writeControlledScope(3, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2585
- if (content) if (valueChange) {
2586
- const matched = { value: false };
2587
- withContext(kSelectedValue, value, () => withContext(kSelectedValueMatched, matched, content));
2588
- if (!matched.value && (Array.isArray(value) ? value.some((v) => normalizeStrAttrValue(v) !== "") : normalizeStrAttrValue(value) !== "")) console.error("A controlled `<select>`'s `value` has no matching `<option>`:", value);
2589
- } else withContext(kSelectedValue, value, content);
2615
+ if (content) {
2616
+ const selectedValue = value ?? "";
2617
+ if (valueChange) {
2618
+ const matched = { value: false };
2619
+ withContext(kSelectedValue, selectedValue, () => withContext(kSelectedValueMatched, matched, content));
2620
+ if (!matched.value && (Array.isArray(value) ? value.some((v) => normalizeStrAttrValue(v) !== "") : normalizeStrAttrValue(value) !== "")) console.error("A controlled `<select>`'s `value` has no matching `<option>`:", value);
2621
+ } else withContext(kSelectedValue, selectedValue, content);
2622
+ }
2590
2623
  }
2591
2624
  function _attr_textarea_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
2592
2625
  if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2593
- return _escape(value);
2626
+ return _textarea_value(value);
2627
+ }
2628
+ function _textarea_value(value) {
2629
+ return _escape(normalizeStrAttrValue(value));
2594
2630
  }
2595
2631
  function _attr_input_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
2596
2632
  if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
@@ -3147,7 +3183,7 @@ function writeTriggerScript(html, triggers) {
3147
3183
  default: return `(e=>e?.addEventListener("${trigger.type.slice(3)}",l,{once:1}))(document.querySelector(${JSON.stringify(trigger.selector)})||l())`;
3148
3184
  }
3149
3185
  });
3150
- writeScript(`((p,h,d,l=$=>d||p.after(new Range().createContextualFragment(d=h)))=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(document.currentScript,${htmlStr})`);
3186
+ writeScript(`((p,h,d,l=$=>{d||p.after(new Range().createContextualFragment(d=h))})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(document.currentScript,${htmlStr})`);
3151
3187
  }
3152
3188
  function toObjectExpression(options) {
3153
3189
  let result = "{";
@@ -3344,6 +3380,7 @@ exports._show_start = _show_start;
3344
3380
  exports._style_html = _style_html;
3345
3381
  exports._subscribe = _subscribe;
3346
3382
  exports._template = _template;
3383
+ exports._textarea_value = _textarea_value;
3347
3384
  exports._to_text = _to_text;
3348
3385
  exports._trailers = _trailers;
3349
3386
  exports._try = _try;
@@ -67,7 +67,12 @@ function stringifyStyleObject(name, value) {
67
67
  warnedStyleKeys.add(name);
68
68
  console.warn(`\`${name}\` is not a CSS property name; \`style\` object keys are written verbatim, so it renders as invalid CSS. Use \`${name.replace(/[A-Z]/g, (m) => "-" + m.toLowerCase()).replace(/^ms-/, "-ms-")}\`.`);
69
69
  }
70
- return value || value === 0 ? name + ":" + value : "";
70
+ return value || value === 0 ? escapeStyleAttr(name) + ":" + escapeStyleAttr(value + "") : "";
71
+ }
72
+ const unsafeStyleAttrReg = /[\\;]/g;
73
+ const replaceUnsafeStyleAttr = (c) => c === ";" ? "\\3B " : "\\\\";
74
+ function escapeStyleAttr(str) {
75
+ return unsafeStyleAttrReg.test(str) ? str.replace(unsafeStyleAttrReg, replaceUnsafeStyleAttr) : str;
71
76
  }
72
77
  function escapeStyleValue(str) {
73
78
  let closers = "";
@@ -237,8 +242,8 @@ function _escape_script(val) {
237
242
  assertValidTextValue(val);
238
243
  return val ? escapeScriptStr(val + "") : val === 0 ? "0" : "";
239
244
  }
240
- const unsafeStyleReg = /<\/style/gi;
241
- const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C/style") : str;
245
+ const unsafeStyleReg = /<(\/style)/gi;
246
+ const escapeStyleStr = (str) => unsafeStyleReg.test(str) ? str.replace(unsafeStyleReg, "\\3C$1") : str;
242
247
  function _escape_style(val) {
243
248
  assertValidTextValue(val);
244
249
  return val ? escapeStyleStr(val + "") : val === 0 ? "0" : "";
@@ -904,11 +909,18 @@ function writeDate(state, val) {
904
909
  state.buf.push("new Date(" + +val + ")");
905
910
  return true;
906
911
  }
907
- const unsafeRegExpSourceReg = /\\[\s\S]|</g;
908
- const replaceUnsafeRegExpSourceChar = (match) => match === "<" || match === "\\<" ? "\\x3C" : match;
912
+ const unsafeRegExpSourceReg = /\\[\s\S]|[<\0\ud800-\udfff]/gu;
913
+ const unsafeRegExpSourceDetect = /[<\0\ud800-\udfff]/u;
914
+ const replaceUnsafeRegExpSourceChar = (match) => {
915
+ const ch = match.length === 3 ? "" : match[match.length - 1];
916
+ if (ch === "<") return "\\x3C";
917
+ if (ch === "\0") return "\\x00";
918
+ const code = ch.charCodeAt(0);
919
+ return code >= 55296 && code <= 57343 ? "\\u" + code.toString(16).padStart(4, "0") : match;
920
+ };
909
921
  function writeRegExp(state, val) {
910
922
  const { source } = val;
911
- state.buf.push("/" + (source.includes("<") ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags);
923
+ state.buf.push("/" + (unsafeRegExpSourceDetect.test(source) ? source.replace(unsafeRegExpSourceReg, replaceUnsafeRegExpSourceChar) : source) + "/" + val.flags);
912
924
  return true;
913
925
  }
914
926
  function writePromise(state, val, ref) {
@@ -1047,9 +1059,17 @@ function writeError(state, val, ref) {
1047
1059
  }
1048
1060
  function writeAggregateError(state, val, ref) {
1049
1061
  state.buf.push("new AggregateError(");
1050
- if (!writeProp(state, val.errors, ref, "errors")) state.buf.push("[]");
1062
+ const inlined = writeProp(state, val.errors, ref, "errors");
1063
+ if (!inlined) state.buf.push("[]");
1051
1064
  if (val.message) state.buf.push("," + quote(val.message + "", 0) + ")");
1052
1065
  else state.buf.push(")");
1066
+ if (inlined) {
1067
+ const errorsRef = state.refs.get(val.errors);
1068
+ if (errorsRef?.id) {
1069
+ state.assigned.add(errorsRef);
1070
+ addAssignment(errorsRef, accessId(state, ref) + toAccess("errors"));
1071
+ }
1072
+ }
1053
1073
  return true;
1054
1074
  }
1055
1075
  function writeURL(state, val) {
@@ -1104,11 +1124,17 @@ function writeRequest(state, val, ref) {
1104
1124
  options += sep + "credentials:" + quote(val.credentials, 0);
1105
1125
  sep = ",";
1106
1126
  }
1107
- const headers = stringEntriesToHeadersInit(val.headers);
1108
- state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null));
1109
- if (headers) {
1110
- options += sep + "headers:" + headers;
1127
+ const seenHeaders = state.refs.get(val.headers);
1128
+ if (seenHeaders) {
1129
+ options += sep + "headers:" + ensureId(state, seenHeaders);
1111
1130
  sep = ",";
1131
+ } else {
1132
+ state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null));
1133
+ const headers = stringEntriesToHeadersInit(val.headers);
1134
+ if (headers) {
1135
+ options += sep + "headers:" + headers;
1136
+ sep = ",";
1137
+ }
1112
1138
  }
1113
1139
  if (val.integrity) {
1114
1140
  options += sep + "integrity:" + quote(val.integrity, 0);
@@ -1149,9 +1175,13 @@ function writeResponse(state, val, ref) {
1149
1175
  options += sep + "statusText:" + quote(val.statusText, 0);
1150
1176
  sep = ",";
1151
1177
  }
1152
- const headers = stringEntriesToHeadersInit(val.headers);
1153
- state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null));
1154
- if (headers) options += sep + "headers:" + headers;
1178
+ const seenHeaders = state.refs.get(val.headers);
1179
+ if (seenHeaders) options += sep + "headers:" + ensureId(state, seenHeaders);
1180
+ else {
1181
+ state.refs.set(val.headers, new Reference(ref, "headers", state.flush, null));
1182
+ const headers = stringEntriesToHeadersInit(val.headers);
1183
+ if (headers) options += sep + "headers:" + headers;
1184
+ }
1155
1185
  if (!val.body || val.bodyUsed) state.buf.push("new Response" + (options ? "(null,{" + options + "})" : ""));
1156
1186
  else {
1157
1187
  state.buf.push("new Response(");
@@ -2580,15 +2610,21 @@ const kSelectedValue = Symbol("selectedValue");
2580
2610
  const kSelectedValueMatched = Symbol("selectedValueMatched");
2581
2611
  function _attr_select_value(scopeId, nodeAccessor, value, valueChange, content, serializeType) {
2582
2612
  if (valueChange) writeControlledScope(3, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2583
- if (content) if (valueChange) {
2584
- const matched = { value: false };
2585
- withContext(kSelectedValue, value, () => withContext(kSelectedValueMatched, matched, content));
2586
- if (!matched.value && (Array.isArray(value) ? value.some((v) => normalizeStrAttrValue(v) !== "") : normalizeStrAttrValue(value) !== "")) console.error("A controlled `<select>`'s `value` has no matching `<option>`:", value);
2587
- } else withContext(kSelectedValue, value, content);
2613
+ if (content) {
2614
+ const selectedValue = value ?? "";
2615
+ if (valueChange) {
2616
+ const matched = { value: false };
2617
+ withContext(kSelectedValue, selectedValue, () => withContext(kSelectedValueMatched, matched, content));
2618
+ if (!matched.value && (Array.isArray(value) ? value.some((v) => normalizeStrAttrValue(v) !== "") : normalizeStrAttrValue(value) !== "")) console.error("A controlled `<select>`'s `value` has no matching `<option>`:", value);
2619
+ } else withContext(kSelectedValue, selectedValue, content);
2620
+ }
2588
2621
  }
2589
2622
  function _attr_textarea_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
2590
2623
  if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
2591
- return _escape(value);
2624
+ return _textarea_value(value);
2625
+ }
2626
+ function _textarea_value(value) {
2627
+ return _escape(normalizeStrAttrValue(value));
2592
2628
  }
2593
2629
  function _attr_input_value(scopeId, nodeAccessor, value, valueChange, serializeType) {
2594
2630
  if (valueChange) writeControlledScope(2, scopeId, nodeAccessor, void 0, valueChange, serializeType);
@@ -3145,7 +3181,7 @@ function writeTriggerScript(html, triggers) {
3145
3181
  default: return `(e=>e?.addEventListener("${trigger.type.slice(3)}",l,{once:1}))(document.querySelector(${JSON.stringify(trigger.selector)})||l())`;
3146
3182
  }
3147
3183
  });
3148
- writeScript(`((p,h,d,l=$=>d||p.after(new Range().createContextualFragment(d=h)))=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(document.currentScript,${htmlStr})`);
3184
+ writeScript(`((p,h,d,l=$=>{d||p.after(new Range().createContextualFragment(d=h))})=>${exprs.length > 1 ? `{${exprs.join(";")}}` : exprs[0]})(document.currentScript,${htmlStr})`);
3149
3185
  }
3150
3186
  function toObjectExpression(options) {
3151
3187
  let result = "{";
@@ -3270,4 +3306,4 @@ const compat = {
3270
3306
  };
3271
3307
  function NOOP() {}
3272
3308
  //#endregion
3273
- export { $global, _assert_hoist, _attr, _attr_and, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_nullish, _attr_option_value, _attr_or, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _escape_style_value, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _id, _if, _peek_scope_id, _resume, _resume_branch, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _sep, _serialize_guard, _serialize_if, _set_serialize_reason, _show_end, _show_start, _style_html, _subscribe, _template, _to_text, _trailers, _try, _unescaped, _var, attrTag, attrTags, compat, forIn, forInBy, forOf, forOfBy, forStepBy, forTo, forUntil, withLoadAssets, withPageAssets };
3309
+ export { $global, _assert_hoist, _attr, _attr_and, _attr_class, _attr_content, _attr_details_or_dialog_open as _attr_details_open, _attr_details_or_dialog_open as _attr_dialog_open, _attr_input_checked, _attr_input_checkedValue, _attr_input_value, _attr_nonce, _attr_nullish, _attr_option_value, _attr_or, _attr_select_value, _attr_style, _attr_textarea_value, _attrs, _attrs_content, _attrs_partial, _attrs_partial_content, _await, _content, _content_resume, _dynamic_tag, _el, _el_read_error, _el_resume, _escape, _escape_comment, _escape_script, _escape_style, _escape_style_value, _existing_scope, _flush_head, _for_in, _for_of, _for_to, _for_until, _hoist, _hoist_read_error, _html, _id, _if, _peek_scope_id, _resume, _resume_branch, writeScope as _scope, _scope_id, _scope_reason, _scope_with_id, _script, _sep, _serialize_guard, _serialize_if, _set_serialize_reason, _show_end, _show_start, _style_html, _subscribe, _template, _textarea_value, _to_text, _trailers, _try, _unescaped, _var, attrTag, attrTags, compat, forIn, forInBy, forOf, forOfBy, forStepBy, forTo, forUntil, withLoadAssets, withPageAssets };