unpoly-rails 3.10.2 → 3.11.0.rc1

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.
@@ -5,7 +5,7 @@
5
5
  /***/ (() => {
6
6
 
7
7
  window.up = {
8
- version: '3.10.2'
8
+ version: '3.11.0-rc1'
9
9
  };
10
10
 
11
11
 
@@ -116,7 +116,7 @@ up.util = (function () {
116
116
  }
117
117
  function iteratee(block) {
118
118
  if (isString(block)) {
119
- return item => item[block];
119
+ return (item) => item[block];
120
120
  }
121
121
  else {
122
122
  return block;
@@ -135,11 +135,7 @@ up.util = (function () {
135
135
  return mapped;
136
136
  }
137
137
  function mapObject(array, pairer) {
138
- const merger = function (object, pair) {
139
- object[pair[0]] = pair[1];
140
- return object;
141
- };
142
- return map(array, pairer).reduce(merger, {});
138
+ return Object.fromEntries(array.map(pairer));
143
139
  }
144
140
  function each(array, block) {
145
141
  let i = 0;
@@ -147,15 +143,15 @@ up.util = (function () {
147
143
  block(item, i++);
148
144
  }
149
145
  }
150
- function isNull(object) {
151
- return object === null;
146
+ function isNull(value) {
147
+ return value === null;
152
148
  }
153
- function isUndefined(object) {
154
- return object === undefined;
149
+ function isUndefined(value) {
150
+ return value === undefined;
155
151
  }
156
152
  const isDefined = negate(isUndefined);
157
- function isMissing(object) {
158
- return isUndefined(object) || isNull(object);
153
+ function isMissing(value) {
154
+ return isUndefined(value) || isNull(value);
159
155
  }
160
156
  const isGiven = negate(isMissing);
161
157
  function isBlank(value) {
@@ -180,49 +176,49 @@ up.util = (function () {
180
176
  }
181
177
  }
182
178
  const isPresent = negate(isBlank);
183
- function isFunction(object) {
184
- return typeof (object) === 'function';
179
+ function isFunction(value) {
180
+ return typeof (value) === 'function';
185
181
  }
186
- function isString(object) {
187
- return (typeof (object) === 'string') || object instanceof String;
182
+ function isString(value) {
183
+ return (typeof (value) === 'string') || value instanceof String;
188
184
  }
189
- function isBoolean(object) {
190
- return (typeof (object) === 'boolean') || object instanceof Boolean;
185
+ function isBoolean(value) {
186
+ return (typeof (value) === 'boolean') || value instanceof Boolean;
191
187
  }
192
- function isNumber(object) {
193
- return (typeof (object) === 'number') || object instanceof Number;
188
+ function isNumber(value) {
189
+ return (typeof (value) === 'number') || value instanceof Number;
194
190
  }
195
- function isOptions(object) {
196
- return (typeof (object) === 'object') && !isNull(object) && (isUndefined(object.constructor) || (object.constructor === Object));
191
+ function isOptions(value) {
192
+ return (typeof (value) === 'object') && !isNull(value) && (isUndefined(value.constructor) || (value.constructor === Object));
197
193
  }
198
- function isObject(object) {
199
- const typeOfResult = typeof (object);
200
- return ((typeOfResult === 'object') && !isNull(object)) || (typeOfResult === 'function');
194
+ function isObject(value) {
195
+ const typeOfResult = typeof (value);
196
+ return ((typeOfResult === 'object') && !isNull(value)) || (typeOfResult === 'function');
201
197
  }
202
- function isElement(object) {
203
- return object instanceof Element;
198
+ function isElement(value) {
199
+ return value instanceof Element;
204
200
  }
205
- function isTextNode(object) {
206
- return object instanceof Text;
201
+ function isTextNode(value) {
202
+ return value instanceof Text;
207
203
  }
208
- function isRegExp(object) {
209
- return object instanceof RegExp;
204
+ function isRegExp(value) {
205
+ return value instanceof RegExp;
210
206
  }
211
- function isError(object) {
212
- return object instanceof Error;
207
+ function isError(value) {
208
+ return value instanceof Error;
213
209
  }
214
- function isJQuery(object) {
215
- return up.browser.canJQuery() && object instanceof jQuery;
210
+ function isJQuery(value) {
211
+ return up.browser.canJQuery() && value instanceof jQuery;
216
212
  }
217
- function isElementLike(object) {
218
- return !!(object && (object.addEventListener || (isJQuery(object) && object[0]?.addEventListener)));
213
+ function isElementLike(value) {
214
+ return !!(value && (value.addEventListener || (isJQuery(value) && value[0]?.addEventListener)));
219
215
  }
220
- function isPromise(object) {
221
- return isObject(object) && isFunction(object.then);
216
+ function isPromise(value) {
217
+ return isObject(value) && isFunction(value.then);
222
218
  }
223
219
  const { isArray } = Array;
224
- function isFormData(object) {
225
- return object instanceof FormData;
220
+ function isFormData(value) {
221
+ return value instanceof FormData;
226
222
  }
227
223
  function toArray(value) {
228
224
  return isArray(value) ? value : copyArrayLike(value);
@@ -389,13 +385,15 @@ up.util = (function () {
389
385
  return filterList(list, tester);
390
386
  }
391
387
  function intersect(array1, array2) {
392
- return filterList(array1, element => contains(array2, element));
388
+ return filterList(array1, (element) => contains(array2, element));
393
389
  }
394
390
  function scheduleTimer(millis, callback) {
395
391
  return setTimeout(callback, millis);
396
392
  }
397
393
  function queueTask(task) {
398
- return setTimeout(task);
394
+ const channel = new MessageChannel();
395
+ channel.port1.onmessage = () => task();
396
+ channel.port2.postMessage(0);
399
397
  }
400
398
  function last(value) {
401
399
  return value[value.length - 1];
@@ -462,7 +460,7 @@ up.util = (function () {
462
460
  "'": '''
463
461
  };
464
462
  function escapeHTML(string) {
465
- return string.replace(/[&<>"']/g, char => ESCAPE_HTML_ENTITY_MAP[char]);
463
+ return string.replace(/[&<>"']/g, (char) => ESCAPE_HTML_ENTITY_MAP[char]);
466
464
  }
467
465
  function escapeRegExp(string) {
468
466
  return string.replace(/[\\^$*+?.()|[\]{}]/g, '\\$&');
@@ -491,9 +489,9 @@ up.util = (function () {
491
489
  function identity(arg) {
492
490
  return arg;
493
491
  }
494
- function sequence(functions) {
495
- functions = compact(functions);
496
- return (...args) => map(functions, fn => fn(...args));
492
+ function sequence(...args) {
493
+ let functions = scanFunctions(...args);
494
+ return (...args) => map(functions, (fn) => fn(...args));
497
495
  }
498
496
  function flatten(array) {
499
497
  const flattened = [];
@@ -547,7 +545,7 @@ up.util = (function () {
547
545
  const aKeys = Object.keys(a);
548
546
  const bKeys = Object.keys(b);
549
547
  if (isEqualList(aKeys, bKeys)) {
550
- return every(aKeys, aKey => isEqual(a[aKey], b[aKey]));
548
+ return every(aKeys, (aKey) => isEqual(a[aKey], b[aKey]));
551
549
  }
552
550
  else {
553
551
  return false;
@@ -611,7 +609,7 @@ up.util = (function () {
611
609
  return renamed;
612
610
  }
613
611
  function camelToKebabCase(str) {
614
- return str.replace(/[A-Z]/g, char => '-' + char.toLowerCase());
612
+ return str.replace(/[A-Z]/g, (char) => '-' + char.toLowerCase());
615
613
  }
616
614
  function lowerCaseFirst(str) {
617
615
  return str[0].toLowerCase() + str.slice(1);
@@ -865,6 +863,9 @@ up.util = (function () {
865
863
  ];
866
864
  });
867
865
  }
866
+ function spanObject(keys, value) {
867
+ return mapObject(keys, (key) => [key, value]);
868
+ }
868
869
  return {
869
870
  parseURL,
870
871
  normalizeURL,
@@ -882,6 +883,7 @@ up.util = (function () {
882
883
  map,
883
884
  flatMap,
884
885
  mapObject,
886
+ spanObject,
885
887
  findResult,
886
888
  some,
887
889
  every,
@@ -1085,12 +1087,13 @@ up.element = (function () {
1085
1087
  return root.querySelector(selector);
1086
1088
  }
1087
1089
  function subtree(root, selector) {
1088
- const results = [];
1090
+ const descendantMatches = root.querySelectorAll(selector);
1089
1091
  if (elementLikeMatches(root, selector)) {
1090
- results.push(root);
1092
+ return [root, ...descendantMatches];
1093
+ }
1094
+ else {
1095
+ return descendantMatches;
1091
1096
  }
1092
- results.push(...root.querySelectorAll(selector));
1093
- return results;
1094
1097
  }
1095
1098
  function subtreeFirst(root, selector) {
1096
1099
  return elementLikeMatches(root, selector) ? root : root.querySelector(selector);
@@ -1196,7 +1199,7 @@ up.element = (function () {
1196
1199
  }
1197
1200
  function metaContent(name) {
1198
1201
  const selector = "meta" + attrSelector('name', name);
1199
- return first(selector)?.getAttribute('content');
1202
+ return document.head.querySelector(selector)?.getAttribute('content');
1200
1203
  }
1201
1204
  function insertBefore(existingNode, newNode) {
1202
1205
  existingNode.parentNode.insertBefore(newNode, existingNode);
@@ -1306,7 +1309,7 @@ up.element = (function () {
1306
1309
  return element;
1307
1310
  }
1308
1311
  const SINGLETON_TAG_NAMES = ['HTML', 'BODY', 'HEAD', 'TITLE'];
1309
- const isSingleton = up.mockable(element => element.matches(SINGLETON_TAG_NAMES.join()));
1312
+ const isSingleton = up.mockable((element) => element.matches(SINGLETON_TAG_NAMES.join()));
1310
1313
  function elementTagName(element) {
1311
1314
  return element.tagName.toLowerCase();
1312
1315
  }
@@ -1334,9 +1337,11 @@ up.element = (function () {
1334
1337
  function createBrokenDocumentFromHTML(html) {
1335
1338
  return new DOMParser().parseFromString(html, 'text/html');
1336
1339
  }
1337
- function fixParserDamage(scriptish) {
1338
- let clone = createFromHTML(scriptish.outerHTML);
1339
- scriptish.replaceWith(clone);
1340
+ function revivedClone(element) {
1341
+ let clone = createFromHTML(element.outerHTML);
1342
+ if ('nonce' in element)
1343
+ clone.nonce = element.nonce;
1344
+ return clone;
1340
1345
  }
1341
1346
  function createFromHTML(html) {
1342
1347
  return extractSingular(createNodesFromHTML(html));
@@ -1618,6 +1623,18 @@ up.element = (function () {
1618
1623
  return [element.parentElement, 'beforeend'];
1619
1624
  }
1620
1625
  }
1626
+ function moveBefore(parent, movedElement, referenceElement) {
1627
+ let fn = parent.moveBefore || parent.insertBefore;
1628
+ fn.call(parent, movedElement, referenceElement);
1629
+ }
1630
+ function preservingAppend(parent, newNode) {
1631
+ moveBefore(parent, newNode, null);
1632
+ }
1633
+ function preservingReplace(oldElement, newElement) {
1634
+ let parent = oldElement.parentElement;
1635
+ moveBefore(parent, newElement, oldElement);
1636
+ oldElement.remove();
1637
+ }
1621
1638
  return {
1622
1639
  subtree,
1623
1640
  subtreeFirst,
@@ -1644,7 +1661,7 @@ up.element = (function () {
1644
1661
  attrSelector,
1645
1662
  tagName: elementTagName,
1646
1663
  createBrokenDocumentFromHTML,
1647
- fixParserDamage,
1664
+ revivedClone,
1648
1665
  createNodesFromHTML,
1649
1666
  createFromHTML,
1650
1667
  extractSingular,
@@ -1686,6 +1703,8 @@ up.element = (function () {
1686
1703
  matchSelectorMap,
1687
1704
  elementLikeMatches,
1688
1705
  documentPosition,
1706
+ preservingAppend,
1707
+ preservingReplace,
1689
1708
  };
1690
1709
  })();
1691
1710
 
@@ -1779,7 +1798,7 @@ up.Record = class Record {
1779
1798
  return {};
1780
1799
  }
1781
1800
  constructor(options) {
1782
- Object.assign(this, this.defaults(options), this.attributes(options));
1801
+ Object.assign(this, u.mergeDefined(this.defaults(options), this.attributes(options)));
1783
1802
  }
1784
1803
  attributes(source = this) {
1785
1804
  return u.pick(source, this.keys());
@@ -1858,13 +1877,39 @@ up.LogConfig = class LogConfig extends up.Config {
1858
1877
  /* 19 */
1859
1878
  /***/ (() => {
1860
1879
 
1880
+ const u = up.util;
1881
+ up.Registry = class Registry {
1882
+ constructor(valueDescription, normalize = u.identity) {
1883
+ this._data = {};
1884
+ this._normalize = normalize;
1885
+ this._valueDescription = valueDescription;
1886
+ this.put = this.put.bind(this);
1887
+ document.addEventListener('up:framework:reset', () => this.reset());
1888
+ }
1889
+ put(key, object) {
1890
+ object = this._normalize(object);
1891
+ object.isDefault = up.framework.evaling;
1892
+ this._data[key] = object;
1893
+ }
1894
+ get(name) {
1895
+ return this._data[name] || up.fail("Unknown %s %o", this._valueDescription, name);
1896
+ }
1897
+ reset() {
1898
+ this._data = u.pickBy(this._data, 'isDefault');
1899
+ }
1900
+ };
1901
+
1902
+
1903
+ /***/ }),
1904
+ /* 20 */
1905
+ /***/ (() => {
1906
+
1861
1907
  const u = up.util;
1862
1908
  const e = up.element;
1863
1909
  up.OptionsParser = class OptionsParser {
1864
1910
  constructor(element, options, parserOptions = {}) {
1865
1911
  this._options = options;
1866
1912
  this._element = element;
1867
- this._parserOptions = parserOptions;
1868
1913
  this._fail = parserOptions.fail;
1869
1914
  this._closest = parserOptions.closest;
1870
1915
  this._attrPrefix = parserOptions.attrPrefix || 'up-';
@@ -1899,11 +1944,11 @@ up.OptionsParser = class OptionsParser {
1899
1944
  value ??= this._parseFromAttr(attrValueFn, this._element, attrName);
1900
1945
  }
1901
1946
  value ??= keyOptions.default ?? this._defaults[key];
1902
- let normalizeFn = keyOptions.normalize;
1903
- if (normalizeFn) {
1904
- value = normalizeFn(value);
1905
- }
1906
1947
  if (u.isDefined(value)) {
1948
+ let normalizeFn = keyOptions.normalize;
1949
+ if (normalizeFn) {
1950
+ value = normalizeFn(value);
1951
+ }
1907
1952
  this._options[key] = value;
1908
1953
  }
1909
1954
  let failKey;
@@ -1912,8 +1957,8 @@ up.OptionsParser = class OptionsParser {
1912
1957
  this.parse(attrValueFn, failKey, { ...keyOptions, attr: failAttrNames });
1913
1958
  }
1914
1959
  }
1915
- include(optionsFn) {
1916
- let fnResult = optionsFn(this._element, this._options, this._parserOptions);
1960
+ include(optionsFn, parserOptions) {
1961
+ let fnResult = optionsFn(this._element, this._options, { defaults: this._defaults, ...parserOptions });
1917
1962
  Object.assign(this._options, fnResult);
1918
1963
  }
1919
1964
  _parseFromAttr(attrValueFn, element, attrName) {
@@ -1940,7 +1985,7 @@ up.OptionsParser = class OptionsParser {
1940
1985
 
1941
1986
 
1942
1987
  /***/ }),
1943
- /* 20 */
1988
+ /* 21 */
1944
1989
  /***/ (() => {
1945
1990
 
1946
1991
  const u = up.util;
@@ -1969,7 +2014,7 @@ up.FIFOCache = class FIFOCache {
1969
2014
 
1970
2015
 
1971
2016
  /***/ }),
1972
- /* 21 */
2017
+ /* 22 */
1973
2018
  /***/ (() => {
1974
2019
 
1975
2020
  up.Rect = class Rect extends up.Record {
@@ -2000,7 +2045,7 @@ up.Rect = class Rect extends up.Record {
2000
2045
 
2001
2046
 
2002
2047
  /***/ }),
2003
- /* 22 */
2048
+ /* 23 */
2004
2049
  /***/ (() => {
2005
2050
 
2006
2051
  const e = up.element;
@@ -2048,7 +2093,7 @@ up.BodyShifter = class BodyShifter {
2048
2093
 
2049
2094
 
2050
2095
  /***/ }),
2051
- /* 23 */
2096
+ /* 24 */
2052
2097
  /***/ (() => {
2053
2098
 
2054
2099
  const u = up.util;
@@ -2074,7 +2119,7 @@ up.Change = class Change {
2074
2119
 
2075
2120
 
2076
2121
  /***/ }),
2077
- /* 24 */
2122
+ /* 25 */
2078
2123
  /***/ (() => {
2079
2124
 
2080
2125
  const u = up.util;
@@ -2149,7 +2194,7 @@ up.Change.Addition = class Addition extends up.Change {
2149
2194
 
2150
2195
 
2151
2196
  /***/ }),
2152
- /* 25 */
2197
+ /* 26 */
2153
2198
  /***/ (() => {
2154
2199
 
2155
2200
  var _a;
@@ -2272,7 +2317,7 @@ up.RenderJob = (_a = class RenderJob {
2272
2317
 
2273
2318
 
2274
2319
  /***/ }),
2275
- /* 26 */
2320
+ /* 27 */
2276
2321
  /***/ (() => {
2277
2322
 
2278
2323
  up.Change.DestroyFragment = class DestroyFragment extends up.Change {
@@ -2297,18 +2342,18 @@ up.Change.DestroyFragment = class DestroyFragment extends up.Change {
2297
2342
  async _destroyAfterAnimation() {
2298
2343
  this._emitDestroyed();
2299
2344
  await this._animate();
2300
- this._wipe();
2345
+ this._erase();
2301
2346
  this._onFinished?.();
2302
2347
  }
2303
2348
  _destroyNow() {
2304
- this._wipe();
2349
+ this._erase();
2305
2350
  this._emitDestroyed();
2306
2351
  this._onFinished?.();
2307
2352
  }
2308
2353
  _animate() {
2309
2354
  return up.motion.animate(this._element, this._animation, this.options);
2310
2355
  }
2311
- _wipe() {
2356
+ _erase() {
2312
2357
  this._layer.asCurrent(() => {
2313
2358
  up.fragment.abort(this._element);
2314
2359
  up.script.clean(this._element, { layer: this._layer });
@@ -2323,7 +2368,7 @@ up.Change.DestroyFragment = class DestroyFragment extends up.Change {
2323
2368
 
2324
2369
 
2325
2370
  /***/ }),
2326
- /* 27 */
2371
+ /* 28 */
2327
2372
  /***/ (() => {
2328
2373
 
2329
2374
  let u = up.util;
@@ -2414,7 +2459,7 @@ up.Change.OpenLayer = class OpenLayer extends up.Change.Addition {
2414
2459
  }
2415
2460
  _buildLayer() {
2416
2461
  const buildOptions = { ...this.options, opening: true };
2417
- const beforeNew = optionsWithLayerDefaults => {
2462
+ const beforeNew = (optionsWithLayerDefaults) => {
2418
2463
  return this.options = up.RenderOptions.finalize(optionsWithLayerDefaults);
2419
2464
  };
2420
2465
  return up.layer.build(buildOptions, beforeNew);
@@ -2478,7 +2523,7 @@ up.Change.OpenLayer = class OpenLayer extends up.Change.Addition {
2478
2523
 
2479
2524
 
2480
2525
  /***/ }),
2481
- /* 28 */
2526
+ /* 29 */
2482
2527
  /***/ (() => {
2483
2528
 
2484
2529
  var _a;
@@ -2629,7 +2674,7 @@ up.Change.UpdateLayer = (_a = class UpdateLayer extends up.Change.Addition {
2629
2674
 
2630
2675
 
2631
2676
  /***/ }),
2632
- /* 29 */
2677
+ /* 30 */
2633
2678
  /***/ (() => {
2634
2679
 
2635
2680
  const u = up.util;
@@ -2652,7 +2697,7 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2652
2697
  target: up.fragment.targetForSteps(this._steps),
2653
2698
  });
2654
2699
  this._steps.reverse();
2655
- const motionEndPromises = this._steps.map(step => this._executeStep(step));
2700
+ const motionEndPromises = this._steps.map((step) => this._executeStep(step));
2656
2701
  this.renderResult.finished = this._finish(motionEndPromises);
2657
2702
  return this.renderResult;
2658
2703
  }
@@ -2683,7 +2728,7 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2683
2728
  return Promise.resolve();
2684
2729
  }
2685
2730
  else {
2686
- this._preserveKeepables(step);
2731
+ this._preserveDescendantKeepables(step);
2687
2732
  const parent = step.oldElement.parentNode;
2688
2733
  const morphOptions = {
2689
2734
  ...step,
@@ -2691,9 +2736,9 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2691
2736
  up.fragment.markAsDestroying(step.oldElement);
2692
2737
  },
2693
2738
  afterInsert: () => {
2694
- this._restoreKeepables(step);
2739
+ this._restoreDescendantKeepables(step);
2695
2740
  this.responseDoc.finalizeElement(step.newElement);
2696
- this._unmarkKeepables(step);
2741
+ this._finalizeDescendantKeepables(step);
2697
2742
  up.hello(step.newElement, step);
2698
2743
  this._addToResult(step.newElement);
2699
2744
  },
@@ -2774,8 +2819,8 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2774
2819
  }
2775
2820
  }
2776
2821
  }
2777
- _preserveKeepables(step) {
2778
- const keepPlans = [];
2822
+ _preserveDescendantKeepables(step) {
2823
+ const descendantKeepPlans = [];
2779
2824
  if (step.keep) {
2780
2825
  for (let keepable of step.oldElement.querySelectorAll('[up-keep]')) {
2781
2826
  let keepPlan = this._findKeepPlan({ ...step, oldElement: keepable, descendantsOnly: true });
@@ -2785,37 +2830,42 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2785
2830
  keepable.classList.add('up-keeping');
2786
2831
  up.script.disableSubtree(keepPlan.newElement);
2787
2832
  let viewports = up.viewport.subtree(keepPlan.oldElement);
2788
- keepPlan.revivers = viewports.map(function (viewport) {
2833
+ keepPlan.revivers = u.map(viewports, function (viewport) {
2789
2834
  let cursorProps = up.viewport.copyCursorProps(viewport);
2790
2835
  return () => up.viewport.copyCursorProps(cursorProps, viewport);
2791
2836
  });
2792
- if (this._willChangeElement(document.body)) {
2837
+ if (this._willChangeBody()) {
2793
2838
  keepPlan.newElement.replaceWith(keepable);
2794
2839
  }
2795
2840
  else {
2796
- document.body.append(keepable);
2841
+ e.preservingAppend(document.body, keepable);
2797
2842
  }
2798
- keepPlans.push(keepPlan);
2843
+ descendantKeepPlans.push(keepPlan);
2799
2844
  }
2800
2845
  }
2801
2846
  }
2802
- step.keepPlans = keepPlans;
2847
+ step.descendantKeepPlans = descendantKeepPlans;
2803
2848
  }
2804
- _restoreKeepables(step) {
2805
- for (let keepPlan of step.keepPlans) {
2806
- keepPlan.newElement.replaceWith(keepPlan.oldElement);
2849
+ _restoreDescendantKeepables(step) {
2850
+ for (let keepPlan of step.descendantKeepPlans) {
2851
+ if (this._willChangeBody()) {
2852
+ keepPlan.newElement.replaceWith(keepPlan.oldElement);
2853
+ }
2854
+ else {
2855
+ e.preservingReplace(keepPlan.newElement, keepPlan.oldElement);
2856
+ }
2807
2857
  for (let reviver of keepPlan.revivers) {
2808
2858
  reviver();
2809
2859
  }
2810
2860
  }
2811
2861
  }
2812
- _unmarkKeepables(step) {
2813
- for (let keepPlan of step.keepPlans) {
2862
+ _finalizeDescendantKeepables(step) {
2863
+ for (let keepPlan of step.descendantKeepPlans) {
2814
2864
  keepPlan.oldElement.classList.remove('up-keeping');
2815
2865
  }
2816
2866
  }
2817
- _willChangeElement(element) {
2818
- return u.some(this._steps, (step) => step.oldElement.contains(element));
2867
+ _willChangeBody() {
2868
+ return u.some(this._steps, (step) => step.oldElement.matches('body'));
2819
2869
  }
2820
2870
  _handleFocus(fragment, options) {
2821
2871
  const fragmentFocus = new up.FragmentFocus({
@@ -2837,7 +2887,7 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2837
2887
 
2838
2888
 
2839
2889
  /***/ }),
2840
- /* 30 */
2890
+ /* 31 */
2841
2891
  /***/ (() => {
2842
2892
 
2843
2893
  const u = up.util;
@@ -2915,7 +2965,7 @@ up.Change.CloseLayer = class CloseLayer extends up.Change {
2915
2965
 
2916
2966
 
2917
2967
  /***/ }),
2918
- /* 31 */
2968
+ /* 32 */
2919
2969
  /***/ (() => {
2920
2970
 
2921
2971
  var _a;
@@ -2934,7 +2984,7 @@ up.Change.FromURL = (_a = class FromURL extends up.Change {
2934
2984
  return request;
2935
2985
  this.options.handleAbort?.(request);
2936
2986
  request.runPreviews(this.options);
2937
- return await u.always(request, responseOrError => this._onRequestSettled(responseOrError));
2987
+ return await u.always(request, (responseOrError) => this._onRequestSettled(responseOrError));
2938
2988
  }
2939
2989
  _newPageReason() {
2940
2990
  if (u.isCrossOrigin(this.options.url)) {
@@ -2992,7 +3042,7 @@ up.Change.FromURL = (_a = class FromURL extends up.Change {
2992
3042
 
2993
3043
 
2994
3044
  /***/ }),
2995
- /* 32 */
3045
+ /* 33 */
2996
3046
  /***/ (() => {
2997
3047
 
2998
3048
  var _a;
@@ -3110,6 +3160,17 @@ up.Change.FromResponse = (_a = class FromResponse extends up.Change {
3110
3160
  renderOptions.source = this.improveHistoryValue(renderOptions.source, 'keep');
3111
3161
  renderOptions.history = !!renderOptions.location;
3112
3162
  }
3163
+ let openLayerOptions = this._response.openLayer;
3164
+ if (openLayerOptions) {
3165
+ Object.assign(renderOptions, {
3166
+ ...up.Layer.Overlay.UNSET_VISUALS,
3167
+ target: undefined,
3168
+ ...up.fragment.config.navigateOptions,
3169
+ ...openLayerOptions,
3170
+ layer: 'new',
3171
+ });
3172
+ Object.assign(renderOptions, openLayerOptions);
3173
+ }
3113
3174
  renderOptions.location = this.improveHistoryValue(renderOptions.location, serverLocation);
3114
3175
  renderOptions.title = this.improveHistoryValue(renderOptions.title, this._response.title);
3115
3176
  renderOptions.eventPlans = this._response.eventPlans;
@@ -3124,7 +3185,7 @@ up.Change.FromResponse = (_a = class FromResponse extends up.Change {
3124
3185
  renderOptions.target = ':none';
3125
3186
  }
3126
3187
  renderOptions.context = u.merge(renderOptions.context, this._response.context);
3127
- renderOptions.cspNonces = this._response.cspNonces;
3188
+ renderOptions.cspInfo = this._response.cspInfo;
3128
3189
  renderOptions.time ??= this._response.lastModified;
3129
3190
  renderOptions.etag ??= this._response.etag;
3130
3191
  }
@@ -3138,7 +3199,7 @@ up.Change.FromResponse = (_a = class FromResponse extends up.Change {
3138
3199
 
3139
3200
 
3140
3201
  /***/ }),
3141
- /* 33 */
3202
+ /* 34 */
3142
3203
  /***/ (() => {
3143
3204
 
3144
3205
  var _a;
@@ -3210,7 +3271,7 @@ up.Change.FromContent = (_a = class FromContent extends up.Change {
3210
3271
  'fragment',
3211
3272
  'document',
3212
3273
  'html',
3213
- 'cspNonces',
3274
+ 'cspInfo',
3214
3275
  'origin',
3215
3276
  'data',
3216
3277
  ]);
@@ -3241,7 +3302,7 @@ up.Change.FromContent = (_a = class FromContent extends up.Change {
3241
3302
  return this._expandTargets(target || ':main', layer)[0];
3242
3303
  }
3243
3304
  getPreflightProps(opts = {}) {
3244
- const getPlanProps = plan => plan.getPreflightProps();
3305
+ const getPlanProps = (plan) => plan.getPreflightProps();
3245
3306
  return this._seekPlan(getPlanProps) || opts.optional || this._cannotMatchPreflightTarget();
3246
3307
  }
3247
3308
  _cannotMatchPreflightTarget() {
@@ -3293,7 +3354,7 @@ up.Change.FromContent = (_a = class FromContent extends up.Change {
3293
3354
 
3294
3355
 
3295
3356
  /***/ }),
3296
- /* 34 */
3357
+ /* 35 */
3297
3358
  /***/ (() => {
3298
3359
 
3299
3360
  const u = up.util;
@@ -3388,7 +3449,7 @@ up.CompilerPass = class CompilerPass {
3388
3449
 
3389
3450
 
3390
3451
  /***/ }),
3391
- /* 35 */
3452
+ /* 36 */
3392
3453
  /***/ (() => {
3393
3454
 
3394
3455
  const u = up.util;
@@ -3493,7 +3554,7 @@ up.CSSTransition = class CSSTransition {
3493
3554
 
3494
3555
 
3495
3556
  /***/ }),
3496
- /* 36 */
3557
+ /* 37 */
3497
3558
  /***/ (() => {
3498
3559
 
3499
3560
  const u = up.util;
@@ -3516,7 +3577,7 @@ up.DestructorPass = class DestructorPass {
3516
3577
 
3517
3578
 
3518
3579
  /***/ }),
3519
- /* 37 */
3580
+ /* 38 */
3520
3581
  /***/ (() => {
3521
3582
 
3522
3583
  const u = up.util;
@@ -3615,7 +3676,7 @@ up.EventEmitter = class EventEmitter extends up.Record {
3615
3676
 
3616
3677
 
3617
3678
  /***/ }),
3618
- /* 38 */
3679
+ /* 39 */
3619
3680
  /***/ (() => {
3620
3681
 
3621
3682
  const u = up.util;
@@ -3666,7 +3727,8 @@ up.EventListener = class EventListener extends up.Record {
3666
3727
  }
3667
3728
  let element = event.target;
3668
3729
  if (this.selector) {
3669
- element = element.closest(u.evalOption(this.selector));
3730
+ let selector = u.evalOption(this.selector);
3731
+ element = element.closest(selector);
3670
3732
  }
3671
3733
  if (this.guard && !this.guard(event)) {
3672
3734
  return;
@@ -3719,7 +3781,7 @@ up.EventListener = class EventListener extends up.Record {
3719
3781
 
3720
3782
 
3721
3783
  /***/ }),
3722
- /* 39 */
3784
+ /* 40 */
3723
3785
  /***/ (() => {
3724
3786
 
3725
3787
  const u = up.util;
@@ -3765,7 +3827,7 @@ up.EventListenerGroup = class EventListenerGroup extends up.Record {
3765
3827
  }
3766
3828
  });
3767
3829
  }
3768
- static fromBindArgs(args, defaults) {
3830
+ static fromBindArgs(args, overrides) {
3769
3831
  args = u.copy(args);
3770
3832
  const callback = args.pop();
3771
3833
  let elements;
@@ -3785,14 +3847,63 @@ up.EventListenerGroup = class EventListenerGroup extends up.Record {
3785
3847
  }
3786
3848
  const options = u.extractOptions(args);
3787
3849
  const selector = args[0];
3788
- const attributes = { elements, eventTypes, selector, callback, ...options, ...defaults };
3850
+ const attributes = { elements, eventTypes, selector, callback, ...options, ...overrides };
3789
3851
  return new (this)(attributes);
3790
3852
  }
3791
3853
  };
3792
3854
 
3793
3855
 
3794
3856
  /***/ }),
3795
- /* 40 */
3857
+ /* 41 */
3858
+ /***/ (() => {
3859
+
3860
+ const u = up.util;
3861
+ up.SelectorTracker = class SelectorTracker {
3862
+ constructor(selector, options, addCallback) {
3863
+ this._selector = selector;
3864
+ this._addCallback = addCallback;
3865
+ this._layer = options.layer || 'any';
3866
+ this._filter = options.filter || u.identity;
3867
+ this._live = options.live ?? true;
3868
+ this._knownMatches = new Map();
3869
+ }
3870
+ start() {
3871
+ this._sync();
3872
+ return u.sequence(this._trackFragments(), () => this._removeAllMatches());
3873
+ }
3874
+ _trackFragments() {
3875
+ if (this._live) {
3876
+ return up.on('up:fragment:inserted up:fragment:destroyed', () => this._sync());
3877
+ }
3878
+ }
3879
+ _sync() {
3880
+ let removeMap = new Map(this._knownMatches);
3881
+ this._knownMatches.clear();
3882
+ for (let newMatch of this._currentMatches) {
3883
+ let knownRemoveCallback = removeMap.get(newMatch);
3884
+ removeMap.delete(newMatch);
3885
+ let removeCallback = knownRemoveCallback || this._addCallback(newMatch) || u.noop;
3886
+ this._knownMatches.set(newMatch, removeCallback);
3887
+ }
3888
+ this._runRemoveCallbacks(removeMap);
3889
+ }
3890
+ get _currentMatches() {
3891
+ let allMatches = up.fragment.all(this._selector, { layer: this._layer });
3892
+ return this._filter(allMatches);
3893
+ }
3894
+ _removeAllMatches() {
3895
+ this._runRemoveCallbacks(this._knownMatches);
3896
+ }
3897
+ _runRemoveCallbacks(map) {
3898
+ for (let [element, removeCallback] of map) {
3899
+ removeCallback(element);
3900
+ }
3901
+ }
3902
+ };
3903
+
3904
+
3905
+ /***/ }),
3906
+ /* 42 */
3796
3907
  /***/ (() => {
3797
3908
 
3798
3909
  const u = up.util;
@@ -3800,40 +3911,46 @@ up.FieldWatcher = class FieldWatcher {
3800
3911
  constructor(root, options, callback) {
3801
3912
  this._options = options;
3802
3913
  this._root = root;
3803
- this._scope = up.form.getScope(root);
3804
3914
  this._callback = callback;
3805
3915
  this._batch = options.batch;
3916
+ this._logPrefix = options.logPrefix ?? 'up.watch()';
3917
+ this._ensureWatchable();
3806
3918
  }
3807
3919
  start() {
3808
3920
  this._scheduledValues = null;
3809
3921
  this._processedValues = this._readFieldValues();
3810
3922
  this._currentTimer = null;
3811
3923
  this._callbackRunning = false;
3812
- this._cleaner = u.cleaner();
3813
- this._watchFieldsWithin(this._root);
3814
- this._root.addEventListener('up:fragment:inserted', ({ target }) => {
3815
- if (target !== this._root)
3816
- this._watchFieldsWithin(target);
3817
- });
3818
- this._cleaner(up.fragment.onAborted(this._scope, () => this._abort()));
3819
- this._cleaner(up.on(this._scope, 'reset', () => this._onFormReset()));
3924
+ return u.sequence(up.form.trackFields(this._root, (field) => this._watchField(field)), this._trackAbort(), this._trackReset(), () => this._abort());
3820
3925
  }
3821
- stop() {
3822
- this._abort();
3823
- this._cleaner.clean();
3926
+ _ensureWatchable() {
3927
+ const fail = (message) => up.fail(message, this._logPrefix, this._root);
3928
+ if (!this._callback) {
3929
+ fail('No callback provided for %s (%o)');
3930
+ }
3931
+ if (this._root.matches('input[type=radio]')) {
3932
+ fail('Use %s with the container of a radio group, not with an individual radio button (%o)');
3933
+ }
3934
+ }
3935
+ _trackAbort() {
3936
+ let guard = ({ target }) => target.contains(this._region);
3937
+ return up.on('up:fragment:aborted', { guard }, () => this._abort());
3938
+ }
3939
+ _trackReset() {
3940
+ let guard = ({ target }) => target === this._region;
3941
+ return up.on('reset', { guard }, (event) => this._onFormReset(event));
3942
+ }
3943
+ get _region() {
3944
+ return up.form.getRegion(this._root);
3824
3945
  }
3825
3946
  _fieldOptions(field) {
3826
3947
  let rootOptions = u.copy(this._options);
3827
3948
  return up.form.watchOptions(field, rootOptions, { defaults: { event: 'input' } });
3828
3949
  }
3829
- _watchFieldsWithin(container) {
3830
- for (let field of up.form.fields(container)) {
3831
- this._watchField(field);
3832
- }
3833
- }
3834
3950
  _watchField(field) {
3835
3951
  let fieldOptions = this._fieldOptions(field);
3836
- this._cleaner(up.on(field, fieldOptions.event, () => this._check(fieldOptions)));
3952
+ let eventType = fieldOptions.event;
3953
+ return up.on(field, eventType, (event) => this._check(event, fieldOptions));
3837
3954
  }
3838
3955
  _abort() {
3839
3956
  this._scheduledValues = null;
@@ -3858,7 +3975,7 @@ up.FieldWatcher = class FieldWatcher {
3858
3975
  return;
3859
3976
  if (this._currentTimer)
3860
3977
  return;
3861
- if (!this._scope.isConnected)
3978
+ if (!up.fragment.isAlive(this._region))
3862
3979
  return;
3863
3980
  let callbackOptions = u.omit(this._scheduledFieldOptions, ['event', 'delay']);
3864
3981
  const diff = this._changedValues(this._processedValues, this._scheduledValues);
@@ -3903,20 +4020,141 @@ up.FieldWatcher = class FieldWatcher {
3903
4020
  _readFieldValues() {
3904
4021
  return up.Params.fromContainer(this._root).toObject();
3905
4022
  }
3906
- _check(fieldOptions = {}) {
4023
+ _check(event, fieldOptions = {}) {
4024
+ up.log.putsEvent(event);
3907
4025
  const values = this._readFieldValues();
3908
4026
  if (this._isNewValues(values)) {
3909
4027
  this._scheduleValues(values, fieldOptions);
3910
4028
  }
3911
4029
  }
3912
- _onFormReset() {
3913
- u.task(() => this._check());
4030
+ _onFormReset(event) {
4031
+ u.task(() => this._check(event));
3914
4032
  }
3915
4033
  };
3916
4034
 
3917
4035
 
3918
4036
  /***/ }),
3919
- /* 41 */
4037
+ /* 43 */
4038
+ /***/ (() => {
4039
+
4040
+ const u = up.util;
4041
+ const e = up.element;
4042
+ const BUILTIN_SWITCH_EFFECTS = [
4043
+ { attr: 'up-hide-for', toggle(target, active) { e.toggle(target, !active); } },
4044
+ { attr: 'up-show-for', toggle(target, active) { e.toggle(target, active); } },
4045
+ { attr: 'up-disable-for', toggle(target, active) { up.form.setDisabled(target, active); } },
4046
+ { attr: 'up-enable-for', toggle(target, active) { up.form.setDisabled(target, !active); } },
4047
+ ];
4048
+ up.Switcher = class Switcher {
4049
+ constructor(root) {
4050
+ this._root = root;
4051
+ this._switcheeSelector = root.getAttribute('up-switch') || up.fail("No switch target given for %o", root);
4052
+ this._regionSelector = root.getAttribute('up-switch-region');
4053
+ }
4054
+ start() {
4055
+ this._switchRegion();
4056
+ return u.sequence(this._trackFieldChanges(), this._trackNewSwitchees());
4057
+ }
4058
+ _trackFieldChanges() {
4059
+ let callback = () => this._onFieldChanged();
4060
+ return up.migrate.watchForSwitch?.(this._root, callback)
4061
+ || up.watch(this._root, { logPrefix: '[up-switch]' }, callback);
4062
+ }
4063
+ _trackNewSwitchees() {
4064
+ let filter = (matches) => {
4065
+ let scope = this._scope;
4066
+ return u.filter(matches, (match) => scope.contains(match));
4067
+ };
4068
+ let onSwitcheeAdded = (switchee) => this._switchSwitchee(switchee);
4069
+ return up.fragment.trackSelector(this._switcheeSelector, { filter }, onSwitcheeAdded);
4070
+ }
4071
+ _onFieldChanged() {
4072
+ this._switchRegion();
4073
+ }
4074
+ _switchRegion() {
4075
+ const fieldTokens = this._buildFieldTokens();
4076
+ for (let switchee of this._findSwitchees()) {
4077
+ this._switchSwitchee(switchee, fieldTokens);
4078
+ }
4079
+ }
4080
+ _switchSwitchee(switchee, fieldTokens = this._buildFieldTokens()) {
4081
+ let previousValues = switchee.upSwitchValues;
4082
+ if (!u.isEqual(previousValues, fieldTokens)) {
4083
+ switchee.upSwitchValues = fieldTokens;
4084
+ this._switchSwitcheeNow(switchee, fieldTokens);
4085
+ }
4086
+ }
4087
+ _switchSwitcheeNow(switchee, fieldTokens) {
4088
+ for (let { attr, toggle } of BUILTIN_SWITCH_EFFECTS) {
4089
+ let attrValue = switchee.getAttribute(attr);
4090
+ if (attrValue) {
4091
+ let activeTokens = this._parseSwitcheeTokens(attrValue);
4092
+ let isActive = u.intersect(fieldTokens, activeTokens).length > 0;
4093
+ toggle(switchee, isActive);
4094
+ }
4095
+ }
4096
+ let log = ['Switching %o', switchee];
4097
+ up.emit(switchee, 'up:form:switch', { field: this._root, tokens: fieldTokens, log });
4098
+ }
4099
+ _findSwitchees() {
4100
+ return up.fragment.subtree(this._scope, this._switcheeSelector);
4101
+ }
4102
+ get _scope() {
4103
+ if (this._regionSelector) {
4104
+ return up.fragment.get(this._regionSelector, { origin: this._root });
4105
+ }
4106
+ else {
4107
+ return up.form.getRegion(this._root);
4108
+ }
4109
+ }
4110
+ _parseSwitcheeTokens(str) {
4111
+ return u.getSimpleTokens(str, { json: true });
4112
+ }
4113
+ _buildFieldTokens() {
4114
+ let fields = up.form.fields(this._root);
4115
+ let field = fields[0];
4116
+ let value;
4117
+ let meta;
4118
+ if (field.matches('input[type=checkbox]')) {
4119
+ if (field.checked) {
4120
+ value = field.value;
4121
+ meta = ':checked';
4122
+ }
4123
+ else {
4124
+ meta = ':unchecked';
4125
+ }
4126
+ }
4127
+ else if (field.matches('input[type=radio]')) {
4128
+ let checkedButton = up.migrate.checkedRadioButtonForSwitch?.(field) || u.find(fields, 'checked');
4129
+ if (checkedButton) {
4130
+ meta = ':checked';
4131
+ value = checkedButton.value;
4132
+ }
4133
+ else {
4134
+ meta = ':unchecked';
4135
+ }
4136
+ }
4137
+ else {
4138
+ value = field.value;
4139
+ }
4140
+ const values = [];
4141
+ if (u.isPresent(value)) {
4142
+ values.push(value);
4143
+ values.push(':present');
4144
+ }
4145
+ else {
4146
+ values.push(':blank');
4147
+ }
4148
+ if (u.isPresent(meta)) {
4149
+ values.push(meta);
4150
+ }
4151
+ return values;
4152
+ }
4153
+ };
4154
+
4155
+
4156
+ /***/ }),
4157
+ /* 44 */
3920
4158
  /***/ (() => {
3921
4159
 
3922
4160
  const u = up.util;
@@ -3927,41 +4165,51 @@ up.FormValidator = class FormValidator {
3927
4165
  this._dirtySolutions = [];
3928
4166
  this._nextRenderTimer = null;
3929
4167
  this._rendering = false;
3930
- this._resetNextRenderPromise();
3931
4168
  this._honorAbort();
3932
4169
  }
4170
+ start() {
4171
+ let guard = (field) => this._isValidatingField(field);
4172
+ let callback = (field) => this._onFieldAdded(field);
4173
+ return up.form.trackFields(this._form, { guard }, callback);
4174
+ }
4175
+ _isValidatingField(field) {
4176
+ return field.closest('[up-validate]:not([up-validate=false])');
4177
+ }
4178
+ _onFieldAdded(field) {
4179
+ let eventType = up.form.validateOptions(field).event;
4180
+ return up.on(field, eventType, (event) => {
4181
+ up.log.putsEvent(event);
4182
+ up.error.muteUncriticalRejection(this.validate({ origin: field }));
4183
+ });
4184
+ }
3933
4185
  _honorAbort() {
3934
4186
  up.fragment.onAborted(this._form, (event) => this._onAborted(event));
3935
4187
  }
3936
4188
  _onAborted(event) {
3937
- if (this._dirtySolutions.length) {
3938
- this._dirtySolutions = [];
3939
- this._nextRenderPromise.reject(new up.Aborted(event.reason));
3940
- this._resetNextRenderPromise();
4189
+ let abortedError = new up.Aborted(event.reason);
4190
+ let solution;
4191
+ while (solution = this._dirtySolutions.shift()) {
4192
+ solution.deferred.reject(abortedError);
3941
4193
  }
3942
4194
  }
3943
- _resetNextRenderPromise() {
3944
- this._nextRenderPromise = u.newDeferred();
3945
- }
3946
- watchContainer(fieldOrForm) {
3947
- let { event } = this._originOptions(fieldOrForm);
3948
- let guard = () => up.fragment.isAlive(fieldOrForm);
3949
- let callback = () => up.error.muteUncriticalRejection(this.validate({ origin: fieldOrForm }));
3950
- up.on(fieldOrForm, event, { guard }, callback);
3951
- }
3952
4195
  validate(options = {}) {
3953
- let solutions = this._getSolutions(options);
3954
- this._dirtySolutions.push(...solutions);
4196
+ let newSolutions = this._getSolutions(options);
4197
+ this._dirtySolutions.push(...newSolutions);
3955
4198
  this._scheduleNextRender();
3956
- return this._nextRenderPromise;
4199
+ return newSolutions[0]?.deferred;
3957
4200
  }
3958
4201
  _getSolutions(options) {
3959
4202
  let solutions = this._getTargetSelectorSolutions(options)
3960
4203
  || this._getFieldSolutions(options)
3961
4204
  || this._getElementSolutions(options.origin);
4205
+ let deferred = u.newDeferred();
3962
4206
  for (let solution of solutions) {
3963
- solution.renderOptions = this._originOptions(solution.origin, options);
4207
+ let renderOptions = up.form.validateOptions(solution.origin, options);
4208
+ solution.batch = u.pluckKey(renderOptions, 'batch');
4209
+ solution.renderOptions = renderOptions;
4210
+ solution.destination = `${renderOptions.method} ${renderOptions.url}`;
3964
4211
  solution.target = up.fragment.resolveOrigin(solution.target, solution);
4212
+ solution.deferred = deferred;
3965
4213
  }
3966
4214
  return solutions;
3967
4215
  }
@@ -4013,9 +4261,6 @@ up.FormValidator = class FormValidator {
4013
4261
  return this._getTargetSelectorSolutions({ target, origin: field });
4014
4262
  }
4015
4263
  }
4016
- _originOptions(element, overrideOptions) {
4017
- return up.form.watchOptions(element, overrideOptions, { defaults: { event: 'change' } });
4018
- }
4019
4264
  _scheduleNextRender() {
4020
4265
  let solutionDelays = this._dirtySolutions.map((solution) => solution.renderOptions.delay);
4021
4266
  let shortestDelay = Math.min(...solutionDelays) || 0;
@@ -4035,33 +4280,53 @@ up.FormValidator = class FormValidator {
4035
4280
  return;
4036
4281
  if (this._nextRenderTimer)
4037
4282
  return;
4038
- let options = this._mergeRenderOptions(this._dirtySolutions);
4039
- this._dirtySolutions = [];
4283
+ let solutionsBatch = this._selectDirtySolutionsBatch();
4284
+ let renderOptions = this._mergeRenderOptions(solutionsBatch);
4040
4285
  this._rendering = true;
4041
- let renderingPromise = this._nextRenderPromise;
4042
- this._resetNextRenderPromise();
4043
4286
  try {
4044
- renderingPromise.resolve(up.render(options));
4045
- await renderingPromise;
4287
+ let renderPromise = up.render(renderOptions);
4288
+ for (let solution of solutionsBatch) {
4289
+ solution.deferred.resolve(renderPromise);
4290
+ }
4291
+ await renderPromise;
4046
4292
  }
4047
4293
  finally {
4048
4294
  this._rendering = false;
4049
4295
  this._renderDirtySolutions();
4050
4296
  }
4051
4297
  }
4298
+ _selectDirtySolutionsBatch() {
4299
+ let batch = [];
4300
+ let i = 0;
4301
+ while (i < this._dirtySolutions.length) {
4302
+ let solution = this._dirtySolutions[i];
4303
+ if (batch.length === 0 || this._canBatchSolutions(batch[0], solution)) {
4304
+ batch.push(solution);
4305
+ this._dirtySolutions.splice(i, 1);
4306
+ }
4307
+ else {
4308
+ i++;
4309
+ }
4310
+ }
4311
+ return batch;
4312
+ }
4313
+ _canBatchSolutions(s1, s2) {
4314
+ return s1.destination === s2.destination && s1.batch && s2.batch;
4315
+ }
4052
4316
  _mergeRenderOptions(dirtySolutions) {
4053
4317
  let dirtyOrigins = u.map(dirtySolutions, 'origin');
4054
4318
  let dirtyFields = u.flatMap(dirtyOrigins, up.form.fields);
4055
4319
  let dirtyNames = u.uniq(u.map(dirtyFields, 'name'));
4056
4320
  let dirtyRenderOptionsList = u.map(dirtySolutions, 'renderOptions');
4057
- let options = u.mergeDefined(...dirtyRenderOptionsList, up.form.destinationOptions(this._form));
4321
+ let formDestinationOptions = up.form.destinationOptions(this._form);
4322
+ let options = u.mergeDefined(formDestinationOptions, ...dirtyRenderOptionsList);
4058
4323
  options.target = u.map(dirtySolutions, 'target').join(', ');
4059
4324
  options.origin = this._form;
4060
4325
  options.focus ??= 'keep';
4061
4326
  options.failOptions = false;
4062
4327
  options.defaultMaybe = true;
4063
- options.params = up.Params.merge(options.params, ...u.map(dirtyRenderOptionsList, 'params'));
4064
- options.headers = u.merge(options.headers, ...u.map(dirtyRenderOptionsList, 'headers'));
4328
+ options.params = up.Params.merge(formDestinationOptions.params, ...u.map(dirtyRenderOptionsList, 'params'));
4329
+ options.headers = u.merge(formDestinationOptions.headers, ...u.map(dirtyRenderOptionsList, 'headers'));
4065
4330
  this._addValidateHeader(options.headers, dirtyNames);
4066
4331
  options.feedback = u.some(dirtyRenderOptionsList, 'feedback');
4067
4332
  options.data = undefined;
@@ -4089,15 +4354,11 @@ up.FormValidator = class FormValidator {
4089
4354
  value = ':unknown';
4090
4355
  headers[key] = value;
4091
4356
  }
4092
- static forElement(element) {
4093
- let form = up.form.get(element);
4094
- return form.upFormValidator ||= new this(form);
4095
- }
4096
4357
  };
4097
4358
 
4098
4359
 
4099
4360
  /***/ }),
4100
- /* 42 */
4361
+ /* 45 */
4101
4362
  /***/ (() => {
4102
4363
 
4103
4364
  up.FocusCapsule = class FocusCapsule {
@@ -4136,7 +4397,7 @@ up.FocusCapsule = class FocusCapsule {
4136
4397
 
4137
4398
 
4138
4399
  /***/ }),
4139
- /* 43 */
4400
+ /* 46 */
4140
4401
  /***/ (() => {
4141
4402
 
4142
4403
  const u = up.util;
@@ -4179,7 +4440,7 @@ up.FragmentProcessor = class FragmentProcessor extends up.Record {
4179
4440
  return this.processPrimitive(opt);
4180
4441
  }
4181
4442
  processArray(array) {
4182
- return u.find(array, opt => this.tryProcess(opt));
4443
+ return u.find(array, (opt) => this.tryProcess(opt));
4183
4444
  }
4184
4445
  resolveCondition(condition) {
4185
4446
  if (condition === 'main') {
@@ -4201,7 +4462,7 @@ up.FragmentProcessor = class FragmentProcessor extends up.Record {
4201
4462
 
4202
4463
 
4203
4464
  /***/ }),
4204
- /* 44 */
4465
+ /* 47 */
4205
4466
  /***/ (() => {
4206
4467
 
4207
4468
  const u = up.util;
@@ -4250,7 +4511,7 @@ up.FragmentFinder = class FragmentFinder {
4250
4511
 
4251
4512
 
4252
4513
  /***/ }),
4253
- /* 45 */
4514
+ /* 48 */
4254
4515
  /***/ (() => {
4255
4516
 
4256
4517
  const u = up.util;
@@ -4260,6 +4521,7 @@ up.FragmentFocus = class FragmentFocus extends up.FragmentProcessor {
4260
4521
  keys() {
4261
4522
  return super.keys().concat([
4262
4523
  'hash',
4524
+ 'focusVisible',
4263
4525
  'focusCapsule',
4264
4526
  'inputDevice',
4265
4527
  ]);
@@ -4316,7 +4578,12 @@ up.FragmentFocus = class FragmentFocus extends up.FragmentProcessor {
4316
4578
  }
4317
4579
  _focusElement(element) {
4318
4580
  if (element) {
4319
- up.focus(element, { force: true, ...PREVENT_SCROLL_OPTIONS, inputDevice: this.inputDevice });
4581
+ up.focus(element, {
4582
+ force: true,
4583
+ ...PREVENT_SCROLL_OPTIONS,
4584
+ inputDevice: this.inputDevice,
4585
+ focusVisible: this.focusVisible,
4586
+ });
4320
4587
  return true;
4321
4588
  }
4322
4589
  }
@@ -4333,7 +4600,7 @@ up.FragmentFocus = class FragmentFocus extends up.FragmentProcessor {
4333
4600
 
4334
4601
 
4335
4602
  /***/ }),
4336
- /* 46 */
4603
+ /* 49 */
4337
4604
  /***/ (() => {
4338
4605
 
4339
4606
  const e = up.element;
@@ -4419,6 +4686,11 @@ up.FragmentPolling = class FragmentPolling {
4419
4686
  if (this._state !== 'started') {
4420
4687
  return;
4421
4688
  }
4689
+ if (!up.fragment.isAlive(this._fragment)) {
4690
+ this._stop();
4691
+ up.puts('[up-poll]', 'Stopped polling a detached fragment');
4692
+ return;
4693
+ }
4422
4694
  if (!this._isFragmentVisible()) {
4423
4695
  up.puts('[up-poll]', 'Will not poll hidden fragment');
4424
4696
  return;
@@ -4488,7 +4760,7 @@ up.FragmentPolling = class FragmentPolling {
4488
4760
 
4489
4761
 
4490
4762
  /***/ }),
4491
- /* 47 */
4763
+ /* 50 */
4492
4764
  /***/ (() => {
4493
4765
 
4494
4766
  const u = up.util;
@@ -4505,8 +4777,10 @@ up.FragmentScrolling = class FragmentScrolling extends up.FragmentProcessor {
4505
4777
  }
4506
4778
  processPrimitive(opt) {
4507
4779
  switch (opt) {
4508
- case 'reset':
4509
- return this._reset();
4780
+ case 'top':
4781
+ return this._scrollTo(0);
4782
+ case 'bottom':
4783
+ return this._scrollTo(99999999);
4510
4784
  case 'layer':
4511
4785
  return this._revealLayer();
4512
4786
  case 'main':
@@ -4541,9 +4815,8 @@ up.FragmentScrolling = class FragmentScrolling extends up.FragmentProcessor {
4541
4815
  _revealLayer() {
4542
4816
  return this._revealElement(this.layer.getBoxElement());
4543
4817
  }
4544
- _reset() {
4545
- up.viewport.resetScroll({ ...this.attributes(), around: this.fragment });
4546
- return true;
4818
+ _scrollTo(position) {
4819
+ return up.viewport.scrollTo(position, { ...this.attributes(), around: this.fragment });
4547
4820
  }
4548
4821
  _restore() {
4549
4822
  return up.viewport.restoreScroll({ ...this.attributes(), around: this.fragment });
@@ -4552,7 +4825,7 @@ up.FragmentScrolling = class FragmentScrolling extends up.FragmentProcessor {
4552
4825
 
4553
4826
 
4554
4827
  /***/ }),
4555
- /* 48 */
4828
+ /* 51 */
4556
4829
  /***/ (() => {
4557
4830
 
4558
4831
  const e = up.element;
@@ -4788,7 +5061,7 @@ up.Layer = class Layer extends up.Record {
4788
5061
  up.history.push(location);
4789
5062
  }
4790
5063
  if (!this.opening) {
4791
- this.emit('up:layer:location:changed', { location });
5064
+ this.emit('up:layer:location:changed', { location, log: false });
4792
5065
  }
4793
5066
  }
4794
5067
  }
@@ -4818,7 +5091,7 @@ up.Layer = class Layer extends up.Record {
4818
5091
 
4819
5092
 
4820
5093
  /***/ }),
4821
- /* 49 */
5094
+ /* 52 */
4822
5095
  /***/ (() => {
4823
5096
 
4824
5097
  var _a;
@@ -4918,7 +5191,7 @@ up.Layer.Overlay = (_a = class Overlay extends up.Layer {
4918
5191
  }
4919
5192
  if (this._supportsDismissMethod('outside')) {
4920
5193
  if (this.viewportElement) {
4921
- up.on(this.viewportElement, 'up:click', event => {
5194
+ up.on(this.viewportElement, 'up:click', (event) => {
4922
5195
  if (event.target === this.viewportElement) {
4923
5196
  this._onOutsideClicked(event, true);
4924
5197
  }
@@ -4934,17 +5207,17 @@ up.Layer.Overlay = (_a = class Overlay extends up.Layer {
4934
5207
  }
4935
5208
  }
4936
5209
  if (this._supportsDismissMethod('key')) {
4937
- this.unbindEscapePressed = up.event.onEscape(event => this.onEscapePressed(event));
5210
+ this.unbindEscapePressed = up.event.onEscape((event) => this.onEscapePressed(event));
4938
5211
  }
4939
- this.registerClickCloser('up-accept', (value, closeOptions) => {
5212
+ this.registerAttrCloser('up-accept', (value, closeOptions) => {
4940
5213
  this.accept(value, closeOptions);
4941
5214
  });
4942
- this.registerClickCloser('up-dismiss', (value, closeOptions) => {
5215
+ this.registerAttrCloser('up-dismiss', (value, closeOptions) => {
4943
5216
  this.dismiss(value, closeOptions);
4944
5217
  });
4945
5218
  up.migrate.registerLayerCloser?.(this);
4946
- this._registerEventCloser(this.acceptEvent, this.accept);
4947
- this._registerEventCloser(this.dismissEvent, this.dismiss);
5219
+ this._registerExternalEventCloser(this.acceptEvent, this.accept);
5220
+ this._registerExternalEventCloser(this.dismissEvent, this.dismiss);
4948
5221
  this.on('up:click', 'label[for]', (event, label) => this._onLabelClicked(event, label));
4949
5222
  }
4950
5223
  _onLabelClicked(event, label) {
@@ -4979,26 +5252,38 @@ up.Layer.Overlay = (_a = class Overlay extends up.Layer {
4979
5252
  }
4980
5253
  }
4981
5254
  }
4982
- registerClickCloser(attribute, closeFn) {
4983
- let selector = `[${attribute}]`;
4984
- this.on('up:click', selector, function (event) {
5255
+ registerAttrCloser(attribute, closeFn) {
5256
+ this._registerClickCloser(attribute, closeFn);
5257
+ this._registerSubmitCloser(attribute, closeFn);
5258
+ }
5259
+ _registerClickCloser(attribute, closeFn) {
5260
+ this.on('up:click', `[${attribute}]:not(form)`, (event, link) => {
5261
+ up.event.halt(event, { log: true });
5262
+ const value = e.jsonAttr(link, attribute);
5263
+ this._onAttrCloserActivated(link, value, closeFn);
5264
+ });
5265
+ }
5266
+ _registerSubmitCloser(attribute, closeFn) {
5267
+ this.on('submit', `[${attribute}]`, (event, form) => {
4985
5268
  up.event.halt(event, { log: true });
4986
- const origin = event.target.closest(selector);
4987
- const value = e.jsonAttr(origin, attribute);
4988
- const closeOptions = { origin };
4989
- const parser = new up.OptionsParser(origin, closeOptions);
4990
- parser.booleanOrString('animation');
4991
- parser.string('easing');
4992
- parser.number('duration');
4993
- parser.string('confirm');
4994
- up.error.muteUncriticalSync(() => closeFn(value, closeOptions));
5269
+ const value = up.Params.fromForm(form);
5270
+ this._onAttrCloserActivated(form, value, closeFn);
4995
5271
  });
4996
5272
  }
4997
- _registerEventCloser(eventTypes, closeFn) {
5273
+ _onAttrCloserActivated(origin, value, closeFn) {
5274
+ const closeOptions = { origin };
5275
+ const parser = new up.OptionsParser(origin, closeOptions);
5276
+ parser.booleanOrString('animation');
5277
+ parser.string('easing');
5278
+ parser.number('duration');
5279
+ parser.string('confirm');
5280
+ up.error.muteUncriticalSync(() => closeFn(value, closeOptions));
5281
+ }
5282
+ _registerExternalEventCloser(eventTypes, closeFn) {
4998
5283
  if (!eventTypes) {
4999
5284
  return;
5000
5285
  }
5001
- return this.on(eventTypes, event => {
5286
+ return this.on(eventTypes, (event) => {
5002
5287
  event.preventDefault();
5003
5288
  up.error.muteUncriticalSync(() => closeFn.call(this, event, { response: event.response }));
5004
5289
  });
@@ -5101,11 +5386,12 @@ up.Layer.Overlay = (_a = class Overlay extends up.Layer {
5101
5386
  'closeEasing',
5102
5387
  'trapFocus',
5103
5388
  ],
5389
+ _a.UNSET_VISUALS = u.spanObject(_a.VISUAL_KEYS, undefined),
5104
5390
  _a);
5105
5391
 
5106
5392
 
5107
5393
  /***/ }),
5108
- /* 50 */
5394
+ /* 53 */
5109
5395
  /***/ (() => {
5110
5396
 
5111
5397
  up.Layer.OverlayWithTether = class OverlayWithTether extends up.Layer.Overlay {
@@ -5144,7 +5430,7 @@ up.Layer.OverlayWithTether = class OverlayWithTether extends up.Layer.Overlay {
5144
5430
 
5145
5431
 
5146
5432
  /***/ }),
5147
- /* 51 */
5433
+ /* 54 */
5148
5434
  /***/ (() => {
5149
5435
 
5150
5436
  up.Layer.OverlayWithViewport = class OverlayWithViewport extends up.Layer.Overlay {
@@ -5173,7 +5459,7 @@ up.Layer.OverlayWithViewport = class OverlayWithViewport extends up.Layer.Overla
5173
5459
 
5174
5460
 
5175
5461
  /***/ }),
5176
- /* 52 */
5462
+ /* 55 */
5177
5463
  /***/ (() => {
5178
5464
 
5179
5465
  var _a;
@@ -5219,7 +5505,7 @@ up.Layer.Root = (_a = class Root extends up.Layer {
5219
5505
 
5220
5506
 
5221
5507
  /***/ }),
5222
- /* 53 */
5508
+ /* 56 */
5223
5509
  /***/ (() => {
5224
5510
 
5225
5511
  var _a;
@@ -5230,7 +5516,7 @@ up.Layer.Modal = (_a = class Modal extends up.Layer.OverlayWithViewport {
5230
5516
 
5231
5517
 
5232
5518
  /***/ }),
5233
- /* 54 */
5519
+ /* 57 */
5234
5520
  /***/ (() => {
5235
5521
 
5236
5522
  var _a;
@@ -5241,7 +5527,7 @@ up.Layer.Popup = (_a = class Popup extends up.Layer.OverlayWithTether {
5241
5527
 
5242
5528
 
5243
5529
  /***/ }),
5244
- /* 55 */
5530
+ /* 58 */
5245
5531
  /***/ (() => {
5246
5532
 
5247
5533
  var _a;
@@ -5252,7 +5538,7 @@ up.Layer.Drawer = (_a = class Drawer extends up.Layer.OverlayWithViewport {
5252
5538
 
5253
5539
 
5254
5540
  /***/ }),
5255
- /* 56 */
5541
+ /* 59 */
5256
5542
  /***/ (() => {
5257
5543
 
5258
5544
  var _a;
@@ -5263,7 +5549,7 @@ up.Layer.Cover = (_a = class Cover extends up.Layer.OverlayWithViewport {
5263
5549
 
5264
5550
 
5265
5551
  /***/ }),
5266
- /* 57 */
5552
+ /* 60 */
5267
5553
  /***/ (() => {
5268
5554
 
5269
5555
  var _a;
@@ -5279,7 +5565,7 @@ up.LayerLookup = (_a = class LayerLookup {
5279
5565
  this._values = u.getSimpleTokens(options.layer);
5280
5566
  }
5281
5567
  all() {
5282
- let results = u.flatMap(this._values, value => this._resolveValue(value));
5568
+ let results = u.flatMap(this._values, (value) => this._resolveValue(value));
5283
5569
  results = u.compact(results);
5284
5570
  results = u.uniq(results);
5285
5571
  return results;
@@ -5294,7 +5580,7 @@ up.LayerLookup = (_a = class LayerLookup {
5294
5580
  }
5295
5581
  _forElement(element) {
5296
5582
  element = e.get(element);
5297
- return u.find(this._stack.reversed(), layer => layer.contains(element));
5583
+ return u.find(this._stack.reversed(), (layer) => layer.contains(element));
5298
5584
  }
5299
5585
  _forIndex(value) {
5300
5586
  return this._stack.at(value);
@@ -5376,7 +5662,7 @@ up.LayerLookup = (_a = class LayerLookup {
5376
5662
 
5377
5663
 
5378
5664
  /***/ }),
5379
- /* 58 */
5665
+ /* 61 */
5380
5666
  /***/ (() => {
5381
5667
 
5382
5668
  const u = up.util;
@@ -5490,7 +5776,7 @@ up.LayerStack = class LayerStack {
5490
5776
 
5491
5777
 
5492
5778
  /***/ }),
5493
- /* 59 */
5779
+ /* 62 */
5494
5780
  /***/ (() => {
5495
5781
 
5496
5782
  const u = up.util;
@@ -5524,7 +5810,7 @@ up.LinkCurrentURLs = class LinkCurrentURLs {
5524
5810
 
5525
5811
 
5526
5812
  /***/ }),
5527
- /* 60 */
5813
+ /* 63 */
5528
5814
  /***/ (() => {
5529
5815
 
5530
5816
  const u = up.util;
@@ -5565,13 +5851,15 @@ up.LinkFollowIntent = class LinkFollowIntent {
5565
5851
  }
5566
5852
  _runCallback(event) {
5567
5853
  up.log.putsEvent(event);
5854
+ if (!up.fragment.isAlive(this._link))
5855
+ return;
5568
5856
  this._callback({ onRequestKnown: (request) => this._lastRequest = request });
5569
5857
  }
5570
5858
  };
5571
5859
 
5572
5860
 
5573
5861
  /***/ }),
5574
- /* 61 */
5862
+ /* 64 */
5575
5863
  /***/ (() => {
5576
5864
 
5577
5865
  const u = up.util;
@@ -5613,7 +5901,7 @@ up.MotionController = class MotionController {
5613
5901
  }
5614
5902
  _expandFinishRequest(elements) {
5615
5903
  if (elements) {
5616
- return u.flatMap(elements, el => e.list(el.closest(this._selector), el.querySelectorAll(this._selector)));
5904
+ return u.flatMap(elements, (el) => e.list(el.closest(this._selector), el.querySelectorAll(this._selector)));
5617
5905
  }
5618
5906
  else {
5619
5907
  return document.querySelectorAll(this._selector);
@@ -5667,10 +5955,9 @@ up.MotionController = class MotionController {
5667
5955
 
5668
5956
 
5669
5957
  /***/ }),
5670
- /* 62 */
5958
+ /* 65 */
5671
5959
  /***/ (() => {
5672
5960
 
5673
- const u = up.util;
5674
5961
  const e = up.element;
5675
5962
  up.NonceableCallback = class NonceableCallback {
5676
5963
  constructor(script, nonce) {
@@ -5724,37 +6011,11 @@ up.NonceableCallback = class NonceableCallback {
5724
6011
  }
5725
6012
  }
5726
6013
  }
5727
- _allowedBy(allowedNonces) {
5728
- return this.nonce && u.contains(allowedNonces, this.nonce);
5729
- }
5730
- static adoptNonces(element, allowedNonces) {
5731
- if (!allowedNonces?.length) {
5732
- return;
5733
- }
5734
- const getPageNonce = u.memoize(up.protocol.cspNonce);
5735
- u.each(up.script.config.nonceableAttributes, (attribute) => {
5736
- let matches = e.subtree(element, `[${attribute}^="nonce-"]`);
5737
- u.each(matches, (match) => {
5738
- let attributeValue = match.getAttribute(attribute);
5739
- let callback = this.fromString(attributeValue);
5740
- let warn = (message, ...args) => up.log.warn('up.render()', `Cannot use callback [${attribute}="${attributeValue}"]: ${message}`, ...args);
5741
- if (!callback._allowedBy(allowedNonces)) {
5742
- return warn("Callback's CSP nonce (%o) does not match response header (%o)", callback.nonce, allowedNonces);
5743
- }
5744
- let pageNonce = getPageNonce();
5745
- if (!pageNonce) {
5746
- return warn("Current page's CSP nonce is unknown");
5747
- }
5748
- callback.nonce = pageNonce;
5749
- match.setAttribute(attribute, callback.toString());
5750
- });
5751
- });
5752
- }
5753
6014
  };
5754
6015
 
5755
6016
 
5756
6017
  /***/ }),
5757
- /* 63 */
6018
+ /* 66 */
5758
6019
  /***/ (() => {
5759
6020
 
5760
6021
  const e = up.element;
@@ -5776,7 +6037,7 @@ up.OverlayFocus = class OverlayFocus {
5776
6037
  'aria-modal': this._trapFocus.toString()
5777
6038
  });
5778
6039
  if (this._trapFocus) {
5779
- this._untrapFocus = up.on('focusin', event => this._onFocus(event));
6040
+ this._untrapFocus = up.on('focusin', (event) => this._onFocus(event));
5780
6041
  this._focusTrapBefore = e.affix(this._focusElement, 'beforebegin', 'up-focus-trap[tabindex=0]');
5781
6042
  this._focusTrapAfter = e.affix(this._focusElement, 'afterend', 'up-focus-trap[tabindex=0]');
5782
6043
  }
@@ -5827,7 +6088,7 @@ up.OverlayFocus = class OverlayFocus {
5827
6088
 
5828
6089
 
5829
6090
  /***/ }),
5830
- /* 64 */
6091
+ /* 67 */
5831
6092
  /***/ (() => {
5832
6093
 
5833
6094
  const u = up.util;
@@ -5964,7 +6225,7 @@ up.Params = class Params {
5964
6225
  this.entries = u.reject(this.entries, this._matchEntryFn(name));
5965
6226
  }
5966
6227
  _matchEntryFn(name) {
5967
- return entry => entry.name === name;
6228
+ return (entry) => entry.name === name;
5968
6229
  }
5969
6230
  get(name) {
5970
6231
  if (this._isArrayKey(name)) {
@@ -6061,7 +6322,7 @@ up.Params = class Params {
6061
6322
 
6062
6323
 
6063
6324
  /***/ }),
6064
- /* 65 */
6325
+ /* 68 */
6065
6326
  /***/ (() => {
6066
6327
 
6067
6328
  const u = up.util;
@@ -6132,7 +6393,7 @@ up.Preview = class Preview {
6132
6393
  }
6133
6394
  disable(...args) {
6134
6395
  let [element] = this._parseMutatorArgs(args, 'val');
6135
- this.undo(up.form.disable(element));
6396
+ this.undo(up.form.disableTemp(element));
6136
6397
  }
6137
6398
  insert(...args) {
6138
6399
  let [reference, position = 'beforeend', tempValue] = this._parseMutatorArgs(args, 'val', u.isAdjacentPosition, 'val');
@@ -6195,7 +6456,7 @@ up.Preview = class Preview {
6195
6456
 
6196
6457
 
6197
6458
  /***/ }),
6198
- /* 66 */
6459
+ /* 69 */
6199
6460
  /***/ (() => {
6200
6461
 
6201
6462
  const e = up.element;
@@ -6245,7 +6506,7 @@ up.ProgressBar = class ProgressBar {
6245
6506
 
6246
6507
 
6247
6508
  /***/ }),
6248
- /* 67 */
6509
+ /* 70 */
6249
6510
  /***/ (() => {
6250
6511
 
6251
6512
  const u = up.util;
@@ -6341,7 +6602,7 @@ up.RenderOptions = (function () {
6341
6602
  return u.merge(preprocessedOptions.defaults, lateDefaults, preprocessedOptions);
6342
6603
  }
6343
6604
  function assertContentGiven(options) {
6344
- if (!u.some(CONTENT_KEYS, contentKey => u.isGiven(options[contentKey]))) {
6605
+ if (!u.some(CONTENT_KEYS, (contentKey) => u.isGiven(options[contentKey]))) {
6345
6606
  if (options.defaultToEmptyContent) {
6346
6607
  options.content = '';
6347
6608
  }
@@ -6391,7 +6652,7 @@ up.RenderOptions = (function () {
6391
6652
 
6392
6653
 
6393
6654
  /***/ }),
6394
- /* 68 */
6655
+ /* 71 */
6395
6656
  /***/ (() => {
6396
6657
 
6397
6658
  up.RenderResult = class RenderResult extends up.Record {
@@ -6439,7 +6700,7 @@ up.RenderResult = class RenderResult extends up.Record {
6439
6700
 
6440
6701
 
6441
6702
  /***/ }),
6442
- /* 69 */
6703
+ /* 72 */
6443
6704
  /***/ (() => {
6444
6705
 
6445
6706
  var _a;
@@ -6466,6 +6727,8 @@ up.Request = (_a = class Request extends up.Record {
6466
6727
  'failMode',
6467
6728
  'failContext',
6468
6729
  'origin',
6730
+ 'originLayer',
6731
+ 'originMode',
6469
6732
  'builtAt',
6470
6733
  'wrapMethod',
6471
6734
  'contentType',
@@ -6478,30 +6741,31 @@ up.Request = (_a = class Request extends up.Record {
6478
6741
  ];
6479
6742
  }
6480
6743
  defaults() {
6744
+ let config = up.network.config;
6481
6745
  return {
6482
6746
  state: 'new',
6483
6747
  abortable: true,
6484
6748
  headers: {},
6485
- timeout: up.network.config.timeout,
6749
+ timeout: config.timeout,
6486
6750
  builtAt: new Date(),
6487
6751
  previews: [],
6752
+ wrapMethod: config.wrapMethod,
6488
6753
  };
6489
6754
  }
6490
6755
  constructor(options) {
6491
6756
  super(options);
6492
6757
  this.params = new up.Params(this.params);
6493
- if (this.wrapMethod == null) {
6494
- this.wrapMethod = up.network.config.wrapMethod;
6495
- }
6496
6758
  this._normalize();
6497
6759
  if ((this.target || this.layer || this.origin) && !options.basic) {
6498
6760
  const layerLookupOptions = { origin: this.origin };
6499
6761
  this.layer = up.layer.get(this.layer, layerLookupOptions);
6500
- this.failLayer = up.layer.get(this.failLayer, layerLookupOptions);
6501
6762
  this.context ||= this.layer.context || {};
6502
- this.failContext ||= this.failLayer?.context || {};
6503
6763
  this.mode ||= this.layer.mode;
6764
+ this.failLayer = up.layer.get(this.failLayer, layerLookupOptions);
6765
+ this.failContext ||= this.failLayer?.context || {};
6504
6766
  this.failMode ||= this.failLayer?.mode;
6767
+ this.originLayer ||= up.layer.get(this.origin) || up.layer.current;
6768
+ this.originMode ||= this.originLayer?.mode;
6505
6769
  }
6506
6770
  this.bindLayer = options.bindLayer || this.layer;
6507
6771
  this._fragments = options.fragments;
@@ -6548,8 +6812,9 @@ up.Request = (_a = class Request extends up.Record {
6548
6812
  u.task(() => {
6549
6813
  this.layer = undefined;
6550
6814
  this.failLayer = undefined;
6551
- this._bindLayer = undefined;
6815
+ this.bindLayer = undefined;
6552
6816
  this.origin = undefined;
6817
+ this.originLayer = undefined;
6553
6818
  this._fragments = undefined;
6554
6819
  this._bindFragments = undefined;
6555
6820
  });
@@ -6703,6 +6968,7 @@ up.Request = (_a = class Request extends up.Record {
6703
6968
  status: this.xhr.status,
6704
6969
  title: up.protocol.titleFromXHR(this.xhr),
6705
6970
  target: up.protocol.targetFromXHR(this.xhr),
6971
+ openLayer: up.protocol.openLayerFromXHR(this.xhr),
6706
6972
  acceptLayer: up.protocol.acceptLayerFromXHR(this.xhr),
6707
6973
  dismissLayer: up.protocol.dismissLayerFromXHR(this.xhr),
6708
6974
  eventPlans: up.protocol.eventPlansFromXHR(this.xhr),
@@ -6756,7 +7022,7 @@ up.Request = (_a = class Request extends up.Record {
6756
7022
  return this.headers[name];
6757
7023
  }
6758
7024
  _setAutoHeaders() {
6759
- for (let key of ['target', 'failTarget', 'mode', 'failMode', 'context', 'failContext']) {
7025
+ for (let key of ['target', 'failTarget', 'mode', 'failMode', 'context', 'failContext', 'originMode']) {
6760
7026
  this._setPropertyHeader(key);
6761
7027
  }
6762
7028
  let csrfHeader, csrfToken;
@@ -6817,7 +7083,7 @@ up.Request = (_a = class Request extends up.Record {
6817
7083
 
6818
7084
 
6819
7085
  /***/ }),
6820
- /* 70 */
7086
+ /* 73 */
6821
7087
  /***/ (() => {
6822
7088
 
6823
7089
  const u = up.util;
@@ -6982,7 +7248,7 @@ up.Request.Cache = class Cache {
6982
7248
 
6983
7249
 
6984
7250
  /***/ }),
6985
- /* 71 */
7251
+ /* 74 */
6986
7252
  /***/ (() => {
6987
7253
 
6988
7254
  const u = up.util;
@@ -7000,7 +7266,7 @@ up.Request.Queue = class Queue {
7000
7266
  }
7001
7267
  asap(request) {
7002
7268
  request.runQueuedCallbacks();
7003
- u.always(request, responseOrError => this._onRequestSettled(request, responseOrError));
7269
+ u.always(request, (responseOrError) => this._onRequestSettled(request, responseOrError));
7004
7270
  this._scheduleSlowTimer(request);
7005
7271
  this._queueRequest(request);
7006
7272
  queueMicrotask(() => this._poke());
@@ -7031,7 +7297,7 @@ up.Request.Queue = class Queue {
7031
7297
  this._queuedRequests.push(request);
7032
7298
  }
7033
7299
  _pluckNextRequest() {
7034
- let request = u.find(this._queuedRequests, request => !request.background);
7300
+ let request = u.find(this._queuedRequests, (request) => !request.background);
7035
7301
  request ||= this._queuedRequests[0];
7036
7302
  return u.remove(this._queuedRequests, request);
7037
7303
  }
@@ -7093,7 +7359,7 @@ up.Request.Queue = class Queue {
7093
7359
 
7094
7360
 
7095
7361
  /***/ }),
7096
- /* 72 */
7362
+ /* 75 */
7097
7363
  /***/ (() => {
7098
7364
 
7099
7365
  const u = up.util;
@@ -7132,7 +7398,7 @@ up.Request.FormRenderer = class FormRenderer {
7132
7398
 
7133
7399
 
7134
7400
  /***/ }),
7135
- /* 73 */
7401
+ /* 76 */
7136
7402
  /***/ (() => {
7137
7403
 
7138
7404
  var _a;
@@ -7203,7 +7469,7 @@ up.Request.XHRRenderer = (_a = class XHRRenderer {
7203
7469
 
7204
7470
 
7205
7471
  /***/ }),
7206
- /* 74 */
7472
+ /* 77 */
7207
7473
  /***/ (() => {
7208
7474
 
7209
7475
  const u = up.util;
@@ -7218,6 +7484,7 @@ up.Response = class Response extends up.Record {
7218
7484
  'xhr',
7219
7485
  'target',
7220
7486
  'title',
7487
+ 'openLayer',
7221
7488
  'acceptLayer',
7222
7489
  'dismissLayer',
7223
7490
  'eventPlans',
@@ -7232,7 +7499,7 @@ up.Response = class Response extends up.Record {
7232
7499
  defaults() {
7233
7500
  return {
7234
7501
  headers: {},
7235
- loadedAt: new Date()
7502
+ loadedAt: new Date(),
7236
7503
  };
7237
7504
  }
7238
7505
  get ok() {
@@ -7251,8 +7518,9 @@ up.Response = class Response extends up.Record {
7251
7518
  get contentType() {
7252
7519
  return this.header('Content-Type');
7253
7520
  }
7254
- get cspNonces() {
7255
- return up.protocol.cspNoncesFromHeader(this.header('Content-Security-Policy') || this.header('Content-Security-Policy-Report-Only'));
7521
+ get cspInfo() {
7522
+ let policy = this.header('Content-Security-Policy') || this.header('Content-Security-Policy-Report-Only');
7523
+ return up.protocol.cspInfoFromHeader(policy);
7256
7524
  }
7257
7525
  get lastModified() {
7258
7526
  let header = this.header('Last-Modified');
@@ -7281,15 +7549,15 @@ up.Response = class Response extends up.Record {
7281
7549
 
7282
7550
 
7283
7551
  /***/ }),
7284
- /* 75 */
7552
+ /* 78 */
7285
7553
  /***/ (() => {
7286
7554
 
7287
7555
  var _a;
7288
7556
  const u = up.util;
7289
7557
  const e = up.element;
7290
- const FULL_DOCUMENT_PATTERN = /^\s*<(html|!DOCTYPE)\b/i;
7558
+ const FULL_DOCUMENT_PATTERN = /^\s*(<!--[^-]*.*?-->\s*)*<(html|!DOCTYPE)\b/i;
7291
7559
  up.ResponseDoc = (_a = class ResponseDoc {
7292
- constructor({ document, fragment, content, target, origin, data, cspNonces, match }) {
7560
+ constructor({ document, fragment, content, target, origin, data, cspInfo, match }) {
7293
7561
  if (document) {
7294
7562
  this._parseDocument(document, origin, data);
7295
7563
  }
@@ -7299,7 +7567,7 @@ up.ResponseDoc = (_a = class ResponseDoc {
7299
7567
  else {
7300
7568
  this._parseContent(content || '', origin, target, data);
7301
7569
  }
7302
- this._cspNonces = cspNonces;
7570
+ this._cspInfo = cspInfo || {};
7303
7571
  if (origin) {
7304
7572
  let originSelector = up.fragment.tryToTarget(origin);
7305
7573
  if (originSelector) {
@@ -7328,9 +7596,6 @@ up.ResponseDoc = (_a = class ResponseDoc {
7328
7596
  this._document = this._buildFauxDocument(value);
7329
7597
  }
7330
7598
  }
7331
- _parseDocumentFromHTML(html) {
7332
- return e.createBrokenDocumentFromHTML(html);
7333
- }
7334
7599
  _parseFragment(value, origin, data) {
7335
7600
  let element = e.extractSingular(up.fragment.provideNodes(value, { origin, data }));
7336
7601
  this._document = this._buildFauxDocument(element);
@@ -7368,7 +7633,14 @@ up.ResponseDoc = (_a = class ResponseDoc {
7368
7633
  return this._fromHead(up.history.findMetaTags);
7369
7634
  }
7370
7635
  get assets() {
7371
- return this._fromHead(up.script.findAssets);
7636
+ return this._fromHead((head) => {
7637
+ let assets = up.script.findAssets(head);
7638
+ return u.map(assets, (asset) => {
7639
+ this._adoptNoncesInSubtree(asset);
7640
+ let clone = this._reviveElementAsClone(asset);
7641
+ return clone;
7642
+ });
7643
+ });
7372
7644
  }
7373
7645
  get lang() {
7374
7646
  if (this._isFullDocument) {
@@ -7420,21 +7692,43 @@ up.ResponseDoc = (_a = class ResponseDoc {
7420
7692
  throw new up.CannotMatch();
7421
7693
  }
7422
7694
  }
7695
+ _disableScriptsInSubtree(element) {
7696
+ let pageNonce = up.protocol.cspNonce();
7697
+ up.script.disableSubtree(element, (script) => !this._isScriptAllowed(script, pageNonce));
7698
+ }
7699
+ _isScriptAllowed(scriptElement, pageNonce) {
7700
+ let strategy = up.fragment.config.runScripts;
7701
+ if (strategy === true && this._cspInfo.declaration?.includes("'strict-dynamic'")) {
7702
+ return pageNonce && (pageNonce === scriptElement.nonce);
7703
+ }
7704
+ else {
7705
+ return u.evalOption(strategy, scriptElement);
7706
+ }
7707
+ }
7708
+ _reviveElementAsClone(element) {
7709
+ return e.revivedClone(element);
7710
+ }
7711
+ _reviveSubtreeInPlace(element) {
7712
+ if (this._document instanceof Document) {
7713
+ for (let brokenElement of e.subtree(element, ':is(noscript, script, audio, video):not(.up-keeping, .up-keeping *)')) {
7714
+ let clone = this._reviveElementAsClone(brokenElement);
7715
+ brokenElement.replaceWith(clone);
7716
+ }
7717
+ }
7718
+ }
7719
+ _adoptNoncesInSubtree(element) {
7720
+ up.script.adoptNoncesInSubtree(element, this._cspInfo.nonces);
7721
+ }
7423
7722
  commitElement(element) {
7424
7723
  if (this._document.contains(element)) {
7425
- if (!up.fragment.config.runScripts) {
7426
- up.script.disableSubtree(element);
7427
- }
7724
+ this._adoptNoncesInSubtree(element);
7725
+ this._disableScriptsInSubtree(element);
7428
7726
  element.remove();
7429
7727
  return true;
7430
7728
  }
7431
7729
  }
7432
7730
  finalizeElement(element) {
7433
- up.NonceableCallback.adoptNonces(element, this._cspNonces);
7434
- if (this._document instanceof Document) {
7435
- let brokenElements = e.subtree(element, ':is(noscript,script,audio,video):not(.up-keeping, .up-keeping *)');
7436
- u.each(brokenElements, e.fixParserDamage);
7437
- }
7731
+ this._reviveSubtreeInPlace(element);
7438
7732
  }
7439
7733
  },
7440
7734
  (() => {
@@ -7446,7 +7740,7 @@ up.ResponseDoc = (_a = class ResponseDoc {
7446
7740
 
7447
7741
 
7448
7742
  /***/ }),
7449
- /* 76 */
7743
+ /* 79 */
7450
7744
  /***/ (() => {
7451
7745
 
7452
7746
  const e = up.element;
@@ -7536,7 +7830,7 @@ up.RevealMotion = class RevealMotion {
7536
7830
 
7537
7831
 
7538
7832
  /***/ }),
7539
- /* 77 */
7833
+ /* 80 */
7540
7834
  /***/ (() => {
7541
7835
 
7542
7836
  const u = up.util;
@@ -7558,7 +7852,7 @@ up.Selector = class Selector {
7558
7852
  this._layers = up.layer.getAll(options);
7559
7853
  if (!this._layers.length)
7560
7854
  throw new up.CannotMatch(["Unknown layer: %o", options.layer]);
7561
- this._filters.push(match => u.some(this._layers, layer => layer.contains(match)));
7855
+ this._filters.push((match) => u.some(this._layers, (layer) => layer.contains(match)));
7562
7856
  expandTargetLayer = this._layers[0];
7563
7857
  }
7564
7858
  this._selectors = up.fragment.expandTargets(selector, { ...options, layer: expandTargetLayer });
@@ -7593,7 +7887,7 @@ up.Selector = class Selector {
7593
7887
  });
7594
7888
  }
7595
7889
  _passesFilter(element) {
7596
- return element && u.every(this._filters, filter => filter(element));
7890
+ return element && u.every(this._filters, (filter) => filter(element));
7597
7891
  }
7598
7892
  _filterOne(element) {
7599
7893
  return u.presence(element, this._passesFilter.bind(this));
@@ -7605,7 +7899,7 @@ up.Selector = class Selector {
7605
7899
 
7606
7900
 
7607
7901
  /***/ }),
7608
- /* 78 */
7902
+ /* 81 */
7609
7903
  /***/ (() => {
7610
7904
 
7611
7905
  const u = up.util;
@@ -7725,7 +8019,7 @@ up.Tether = class Tether {
7725
8019
 
7726
8020
 
7727
8021
  /***/ }),
7728
- /* 79 */
8022
+ /* 82 */
7729
8023
  /***/ (() => {
7730
8024
 
7731
8025
  const u = up.util;
@@ -7798,7 +8092,7 @@ up.URLPattern = class URLPattern {
7798
8092
 
7799
8093
 
7800
8094
  /***/ }),
7801
- /* 80 */
8095
+ /* 83 */
7802
8096
  /***/ (() => {
7803
8097
 
7804
8098
  up.framework = (function () {
@@ -7887,7 +8181,7 @@ up.boot = up.framework.boot;
7887
8181
 
7888
8182
 
7889
8183
  /***/ }),
7890
- /* 81 */
8184
+ /* 84 */
7891
8185
  /***/ (() => {
7892
8186
 
7893
8187
  up.event = (function () {
@@ -7939,9 +8233,8 @@ up.event = (function () {
7939
8233
  event.preventDefault();
7940
8234
  }
7941
8235
  const keyModifiers = ['metaKey', 'shiftKey', 'ctrlKey', 'altKey'];
7942
- function isUnmodified(event) {
7943
- return (u.isUndefined(event.button) || (event.button === 0)) &&
7944
- !u.some(keyModifiers, modifier => event[modifier]);
8236
+ function isModified(event) {
8237
+ return (event.button > 0) || u.some(keyModifiers, (modifier) => event[modifier]);
7945
8238
  }
7946
8239
  function isSyntheticClick(event) {
7947
8240
  return u.isMissing(event.clientX);
@@ -7962,7 +8255,7 @@ up.event = (function () {
7962
8255
  return newEvent;
7963
8256
  }
7964
8257
  function executeEmitAttr(event, element) {
7965
- if (!isUnmodified(event)) {
8258
+ if (isModified(event)) {
7966
8259
  return;
7967
8260
  }
7968
8261
  const eventType = e.attr(element, 'up-emit');
@@ -7991,7 +8284,7 @@ up.event = (function () {
7991
8284
  assertEmitted,
7992
8285
  onEscape,
7993
8286
  halt,
7994
- isUnmodified,
8287
+ isModified,
7995
8288
  isSyntheticClick,
7996
8289
  fork,
7997
8290
  keyModifiers,
@@ -8004,14 +8297,14 @@ up.emit = up.event.emit;
8004
8297
 
8005
8298
 
8006
8299
  /***/ }),
8007
- /* 82 */
8300
+ /* 85 */
8008
8301
  /***/ (() => {
8009
8302
 
8010
8303
  up.protocol = (function () {
8011
8304
  const u = up.util;
8012
8305
  const e = up.element;
8013
8306
  const headerize = function (camel) {
8014
- const header = camel.replace(/(^.|[A-Z])/g, char => '-' + char.toUpperCase());
8307
+ const header = camel.replace(/(^.|[A-Z])/g, (char) => '-' + char.toUpperCase());
8015
8308
  return 'X-Up' + header;
8016
8309
  };
8017
8310
  const extractHeader = function (xhr, shortHeader, parseFn = u.identity) {
@@ -8049,6 +8342,9 @@ up.protocol = (function () {
8049
8342
  function eventPlansFromXHR(xhr) {
8050
8343
  return extractHeader(xhr, 'events', u.parseRelaxedJSON);
8051
8344
  }
8345
+ function openLayerFromXHR(xhr) {
8346
+ return extractHeader(xhr, 'openLayer', u.parseRelaxedJSON);
8347
+ }
8052
8348
  function acceptLayerFromXHR(xhr) {
8053
8349
  return extractHeader(xhr, 'acceptLayer', u.parseRelaxedJSON);
8054
8350
  }
@@ -8084,21 +8380,26 @@ up.protocol = (function () {
8084
8380
  function cspNonce() {
8085
8381
  return u.evalOption(config.cspNonce);
8086
8382
  }
8087
- function cspNoncesFromHeader(cspHeader) {
8088
- let nonces = [];
8383
+ const NONCE_PATTERN = /'nonce-([^']+)'/g;
8384
+ function findNonces(cspPart) {
8385
+ let matches = cspPart.matchAll(NONCE_PATTERN);
8386
+ return u.map(matches, '1');
8387
+ }
8388
+ function cspInfoFromHeader(cspHeader) {
8389
+ let results = {};
8089
8390
  if (cspHeader) {
8090
- let parts = cspHeader.split(/\s*;\s*/);
8091
- for (let part of parts) {
8092
- if (part.indexOf('script-src') === 0) {
8093
- let noncePattern = /'nonce-([^']+)'/g;
8094
- let match;
8095
- while (match = noncePattern.exec(part)) {
8096
- nonces.push(match[1]);
8097
- }
8391
+ let declarations = cspHeader.split(/\s*;\s*/);
8392
+ for (let declaration of declarations) {
8393
+ let directive = declaration.match(/^(script|default)-src:/)?.[1];
8394
+ if (directive) {
8395
+ results[directive] = {
8396
+ declaration: declaration,
8397
+ nonces: findNonces(declaration)
8398
+ };
8098
8399
  }
8099
8400
  }
8100
8401
  }
8101
- return nonces;
8402
+ return results.script || results.default || {};
8102
8403
  }
8103
8404
  function wrapMethod(method, params) {
8104
8405
  params.add(config.methodParam, method);
@@ -8110,6 +8411,7 @@ up.protocol = (function () {
8110
8411
  titleFromXHR,
8111
8412
  targetFromXHR,
8112
8413
  methodFromXHR,
8414
+ openLayerFromXHR,
8113
8415
  acceptLayerFromXHR,
8114
8416
  contextFromXHR,
8115
8417
  dismissLayerFromXHR,
@@ -8123,13 +8425,13 @@ up.protocol = (function () {
8123
8425
  initialRequestMethod,
8124
8426
  headerize,
8125
8427
  wrapMethod,
8126
- cspNoncesFromHeader,
8428
+ cspInfoFromHeader,
8127
8429
  };
8128
8430
  })();
8129
8431
 
8130
8432
 
8131
8433
  /***/ }),
8132
- /* 83 */
8434
+ /* 86 */
8133
8435
  /***/ (() => {
8134
8436
 
8135
8437
  up.log = (function () {
@@ -8142,24 +8444,26 @@ up.log = (function () {
8142
8444
  }
8143
8445
  const printToWarn = (...args) => printToStream('warn', ...args);
8144
8446
  const printToError = (...args) => printToStream('error', ...args);
8145
- function printToStream(stream, trace, message, ...args) {
8146
- printToStreamStyled(stream, trace, '', message, ...args);
8447
+ function printToStream(stream, prefix, message, ...args) {
8448
+ printToStreamStyled(stream, prefix, '', message, ...args);
8147
8449
  }
8148
- function printToStreamStyled(stream, trace, customStyles, message, ...args) {
8450
+ function printToStreamStyled(stream, prefix, customStyles, message, ...args) {
8149
8451
  if (message) {
8150
8452
  if (config.format) {
8151
- console[stream](`%c${trace}%c ${message}`, 'color: #666666; padding: 1px 3px; border: 1px solid #bbbbbb; border-radius: 2px; font-size: 90%; display: inline-block;' + customStyles, '', ...args);
8453
+ console[stream](`%c${prefix}%c ${message}`, 'color: #666666; padding: 1px 3px; border: 1px solid #bbbbbb; border-radius: 2px; font-size: 90%; display: inline-block;' + customStyles, '', ...args);
8152
8454
  }
8153
8455
  else {
8154
- console[stream](`[${trace}] ${u.sprintf(message, ...args)}`);
8456
+ console[stream](`[${prefix}] ${u.sprintf(message, ...args)}`);
8155
8457
  }
8156
8458
  }
8157
8459
  }
8460
+ let lastPrintedUserEvent;
8158
8461
  function printUserEvent(event) {
8159
- if (config.enabled) {
8160
- event = event.originalEvent || event;
8462
+ if (config.enabled && lastPrintedUserEvent !== event) {
8463
+ lastPrintedUserEvent = event;
8464
+ let originalEvent = event.originalEvent || event;
8161
8465
  let color = '#5566cc';
8162
- printToStreamStyled('log', event.type, `color: white; border-color: ${color}; background-color: ${color}`, 'Interaction on %o', event.target);
8466
+ printToStreamStyled('log', originalEvent.type, `color: white; border-color: ${color}; background-color: ${color}`, 'Interaction on %o', originalEvent.target);
8163
8467
  }
8164
8468
  }
8165
8469
  function printBanner() {
@@ -8210,7 +8514,7 @@ up.warn = up.log.warn;
8210
8514
 
8211
8515
 
8212
8516
  /***/ }),
8213
- /* 84 */
8517
+ /* 87 */
8214
8518
  /***/ (() => {
8215
8519
 
8216
8520
  up.script = (function () {
@@ -8392,16 +8696,41 @@ up.script = (function () {
8392
8696
  up.event.assertEmitted('up:assets:changed', { oldAssets, newAssets, renderOptions });
8393
8697
  }
8394
8698
  }
8395
- function disableScript(scriptElement) {
8396
- scriptElement.type = 'up-disabled-script';
8699
+ function disableScriptsInSubtree(root, guard = () => true) {
8700
+ for (let script of findScripts(root)) {
8701
+ if (guard(script)) {
8702
+ script.type = 'up-disabled-script';
8703
+ }
8704
+ }
8397
8705
  }
8398
- function disableScriptsInSubtree(root) {
8399
- let selector = config.selector('scriptSelectors');
8400
- u.each(e.subtree(root, selector), disableScript);
8706
+ function findScripts(root, selectorSuffix = '') {
8707
+ let selector = config.selector('scriptSelectors') + selectorSuffix;
8708
+ return e.subtree(root, selector);
8401
8709
  }
8402
8710
  function isScript(value) {
8403
8711
  return config.matches(value, 'scriptSelectors');
8404
8712
  }
8713
+ function adoptNoncesInSubtree(root, responseNonces) {
8714
+ let pageNonce = up.protocol.cspNonce();
8715
+ if (!responseNonces?.length || !pageNonce)
8716
+ return;
8717
+ for (let script of findScripts(root, '[nonce]')) {
8718
+ if (responseNonces.includes(script.nonce)) {
8719
+ script.nonce = pageNonce;
8720
+ }
8721
+ }
8722
+ for (let attribute of config.nonceableAttributes) {
8723
+ let matches = e.subtree(root, `[${attribute}^="nonce-"]`);
8724
+ for (let match of matches) {
8725
+ let attributeValue = match.getAttribute(attribute);
8726
+ let callback = up.NonceableCallback.fromString(attributeValue);
8727
+ if (responseNonces.includes(callback.nonce)) {
8728
+ callback.nonce = pageNonce;
8729
+ match.setAttribute(attribute, callback.toString());
8730
+ }
8731
+ }
8732
+ }
8733
+ }
8405
8734
  function reset() {
8406
8735
  registeredCompilers = u.filter(registeredCompilers, 'isDefault');
8407
8736
  registeredMacros = u.filter(registeredMacros, 'isDefault');
@@ -8419,6 +8748,7 @@ up.script = (function () {
8419
8748
  findAssets,
8420
8749
  assertAssetsOK,
8421
8750
  disableSubtree: disableScriptsInSubtree,
8751
+ adoptNoncesInSubtree,
8422
8752
  isScript,
8423
8753
  };
8424
8754
  })();
@@ -8431,7 +8761,7 @@ up.attribute = up.script.attrCompiler;
8431
8761
 
8432
8762
 
8433
8763
  /***/ }),
8434
- /* 85 */
8764
+ /* 88 */
8435
8765
  /***/ (() => {
8436
8766
 
8437
8767
  up.history = (function () {
@@ -8457,59 +8787,75 @@ up.history = (function () {
8457
8787
  }));
8458
8788
  let previousLocation;
8459
8789
  let nextPreviousLocation;
8790
+ let nextTrackOptions;
8791
+ let adoptedBases = new up.FIFOCache({ capacity: 100, normalizeKey: getBase });
8792
+ function isAdopted(location) {
8793
+ return !!adoptedBases.get(location);
8794
+ }
8460
8795
  function reset() {
8461
8796
  previousLocation = undefined;
8462
8797
  nextPreviousLocation = undefined;
8463
- trackCurrentLocation();
8798
+ nextTrackOptions = undefined;
8799
+ adoptedBases.clear();
8800
+ trackCurrentLocation({ reason: null, alreadyHandled: true });
8801
+ adopt();
8464
8802
  }
8465
8803
  function currentLocation() {
8466
8804
  return u.normalizeURL(location.href);
8467
8805
  }
8468
- function trackCurrentLocation() {
8469
- const url = currentLocation();
8470
- if (nextPreviousLocation !== url) {
8806
+ function trackCurrentLocation(trackOptions) {
8807
+ let { reason, alreadyHandled } = nextTrackOptions || trackOptions;
8808
+ let location = currentLocation();
8809
+ if (nextPreviousLocation !== location) {
8471
8810
  previousLocation = nextPreviousLocation;
8472
- nextPreviousLocation = url;
8811
+ nextPreviousLocation = location;
8812
+ if (reason === 'detect') {
8813
+ reason = (getBase(location) === getBase(previousLocation)) ? 'hash' : 'pop';
8814
+ }
8815
+ let willHandle = !alreadyHandled && isAdopted(location);
8816
+ let locationChangedEvent = up.event.build('up:location:changed', {
8817
+ reason,
8818
+ location,
8819
+ previousLocation,
8820
+ alreadyHandled,
8821
+ willHandle,
8822
+ log: `New location is ${location}`
8823
+ });
8824
+ up.migrate.prepareLocationChangedEvent?.(locationChangedEvent);
8825
+ if (reason) {
8826
+ up.emit(locationChangedEvent);
8827
+ reactToChange(locationChangedEvent);
8828
+ }
8473
8829
  }
8474
8830
  }
8475
- trackCurrentLocation();
8831
+ function splitLocation(location) {
8832
+ return location?.split(/(?=#)/) || [];
8833
+ }
8834
+ function getBase(location) {
8835
+ return splitLocation(location)[0];
8836
+ }
8476
8837
  function isLocation(url, options) {
8477
8838
  return u.matchURLs(url, location.href, { hash: true, ...options });
8478
8839
  }
8479
- function replace(location, options = {}) {
8480
- location = u.normalizeURL(location);
8481
- if (manipulate('replaceState', location) && (options.event !== false)) {
8482
- emitLocationChanged({ location, reason: 'replace', log: `Replaced state for ${location}` });
8483
- }
8840
+ function replace(location, trackOptions) {
8841
+ placeAdoptedHistoryEntry('replaceState', location, trackOptions);
8484
8842
  }
8485
- function push(location) {
8486
- location = u.normalizeURL(location);
8487
- if (!isLocation(location) && manipulate('pushState', location)) {
8488
- emitLocationChanged({ location, reason: 'push', log: `Advanced to location ${location}` });
8489
- }
8490
- }
8491
- function emitLocationChanged(props) {
8492
- let event = up.event.build('up:location:changed', props);
8493
- up.migrate?.renamedProperty?.(event, 'url', 'location');
8494
- up.emit(event);
8843
+ function push(location, trackOptions) {
8844
+ placeAdoptedHistoryEntry('pushState', location, trackOptions);
8495
8845
  }
8496
- function manipulate(method, url) {
8846
+ function placeAdoptedHistoryEntry(method, location, trackOptions) {
8847
+ adopt(location);
8497
8848
  if (config.enabled) {
8498
- const state = buildState();
8499
- window.history[method](state, '', url);
8500
- trackCurrentLocation();
8501
- return true;
8849
+ nextTrackOptions = trackOptions;
8850
+ history[method](null, '', location);
8851
+ nextTrackOptions = undefined;
8502
8852
  }
8503
8853
  }
8504
- function buildState() {
8505
- return { up: {} };
8854
+ function adopt(location = currentLocation()) {
8855
+ location = u.normalizeURL(location);
8856
+ adoptedBases.set(location, true);
8506
8857
  }
8507
- function restoreStateOnPop(state) {
8508
- if (!state?.up) {
8509
- up.puts('popstate', 'Ignoring a history state not owned by Unpoly');
8510
- return;
8511
- }
8512
- let location = currentLocation();
8858
+ function restoreLocation(location) {
8513
8859
  up.error.muteUncriticalRejection(up.render({
8514
8860
  guardEvent: up.event.build('up:location:restore', { location, log: `Restoring location ${location}` }),
8515
8861
  url: location,
@@ -8527,28 +8873,23 @@ up.history = (function () {
8527
8873
  focus: ['restore', 'auto'],
8528
8874
  }));
8529
8875
  }
8530
- function onPop(event) {
8531
- trackCurrentLocation();
8532
- let location = currentLocation();
8533
- emitLocationChanged({ location, reason: 'pop', log: `Navigated to history entry ${location}` });
8534
- up.viewport.saveFocus({ location: previousLocation });
8535
- up.viewport.saveScroll({ location: previousLocation });
8536
- restoreStateOnPop(event.state);
8537
- }
8538
- function register() {
8539
- window.addEventListener('popstate', onPop);
8540
- if (up.protocol.initialRequestMethod() === 'GET') {
8541
- replace(currentLocation(), { event: false });
8876
+ function reactToChange(event) {
8877
+ if (event.alreadyHandled) {
8878
+ return;
8542
8879
  }
8543
- }
8544
- up.on('up:framework:boot', function () {
8545
- if ('jasmine' in window) {
8546
- register();
8880
+ if (!event.willHandle) {
8881
+ up.puts('up.history', 'Ignoring history entry owned by foreign script');
8882
+ return;
8547
8883
  }
8548
- else {
8549
- setTimeout(register, 100);
8884
+ if (event.reason === 'pop') {
8885
+ up.viewport.saveFocus({ location: event.previousLocation });
8886
+ up.viewport.saveScroll({ location: event.previousLocation });
8887
+ restoreLocation(event.location);
8550
8888
  }
8551
- });
8889
+ else if (event.reason === 'hash') {
8890
+ up.viewport.revealHash(event.hash, { strong: true });
8891
+ }
8892
+ }
8552
8893
  function findMetaTags(head = document.head) {
8553
8894
  return head.querySelectorAll(config.selector('metaTagSelectors'));
8554
8895
  }
@@ -8570,6 +8911,62 @@ up.history = (function () {
8570
8911
  function updateLang(newLang) {
8571
8912
  e.setAttrPresence(e.root, 'lang', newLang, !!newLang);
8572
8913
  }
8914
+ function patchHistoryAPI() {
8915
+ const originalPushState = history.pushState;
8916
+ history.pushState = function (...args) {
8917
+ originalPushState.apply(this, args);
8918
+ trackCurrentLocation({ reason: 'push', alreadyHandled: true });
8919
+ };
8920
+ const originalReplaceState = history.replaceState;
8921
+ history.replaceState = function (...args) {
8922
+ originalReplaceState.apply(this, args);
8923
+ trackCurrentLocation({ reason: 'replace', alreadyHandled: true });
8924
+ };
8925
+ }
8926
+ function adoptInitialHistoryEntry() {
8927
+ if (up.protocol.initialRequestMethod() === 'GET') {
8928
+ adopt();
8929
+ }
8930
+ }
8931
+ up.on('up:framework:boot', function () {
8932
+ trackCurrentLocation({ reason: null, alreadyHandled: true });
8933
+ patchHistoryAPI();
8934
+ adoptInitialHistoryEntry();
8935
+ });
8936
+ up.on('DOMContentLoaded', function () {
8937
+ up.viewport.revealHash({ strong: true });
8938
+ u.task(up.viewport.revealHash);
8939
+ });
8940
+ up.on(window, 'hashchange, popstate', () => {
8941
+ trackCurrentLocation({ reason: 'detect', alreadyHandled: false });
8942
+ });
8943
+ function onJumpLinkClicked(event, link) {
8944
+ if (event.defaultPrevented)
8945
+ return;
8946
+ if (up.event.isModified(event))
8947
+ return;
8948
+ let [currentBase, currentHash] = splitLocation(up.layer.current.location);
8949
+ let [linkBase, linkHash] = splitLocation(u.normalizeURL(link));
8950
+ let verbatimHREF = link.getAttribute('href');
8951
+ let isJumpLink = (currentBase === linkBase) || verbatimHREF.startsWith('#');
8952
+ if (!isJumpLink)
8953
+ return;
8954
+ let behavior = link.getAttribute('up-scroll-behavior') ?? 'auto';
8955
+ let layer = up.layer.get(link);
8956
+ let revealFn = up.viewport.revealHashFn(linkHash, { layer, behavior });
8957
+ if (revealFn) {
8958
+ up.event.halt(event);
8959
+ up.log.putsEvent(event);
8960
+ if (linkHash !== currentHash && layer.showsLiveHistory()) {
8961
+ let newHREF = currentBase + linkHash;
8962
+ push(newHREF, { reason: 'hash', alreadyHandled: true });
8963
+ }
8964
+ revealFn();
8965
+ }
8966
+ else {
8967
+ }
8968
+ }
8969
+ up.on('up:click', 'a[href*="#"]', onJumpLinkClicked);
8573
8970
  up.macro('[up-back]', function (link) {
8574
8971
  if (previousLocation) {
8575
8972
  e.setMissingAttrs(link, {
@@ -8597,10 +8994,10 @@ up.history = (function () {
8597
8994
 
8598
8995
 
8599
8996
  /***/ }),
8600
- /* 86 */
8997
+ /* 89 */
8601
8998
  /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
8602
8999
 
8603
- __webpack_require__(87);
9000
+ __webpack_require__(90);
8604
9001
  const u = up.util;
8605
9002
  const e = up.element;
8606
9003
  up.fragment = (function () {
@@ -8645,6 +9042,7 @@ up.fragment = (function () {
8645
9042
  saveScroll: true,
8646
9043
  saveFocus: true,
8647
9044
  focus: 'keep',
9045
+ focusVisible: 'auto',
8648
9046
  abort: 'target',
8649
9047
  failOptions: true,
8650
9048
  feedback: true,
@@ -8659,7 +9057,7 @@ up.fragment = (function () {
8659
9057
  peel: true,
8660
9058
  },
8661
9059
  match: 'region',
8662
- runScripts: true,
9060
+ runScripts: false,
8663
9061
  autoHistoryTargets: [':main'],
8664
9062
  autoFocus: ['hash', 'autofocus', 'main-if-main', 'keep', 'target-if-lost'],
8665
9063
  autoScroll: ['hash', 'layer-if-main'],
@@ -8701,6 +9099,9 @@ up.fragment = (function () {
8701
9099
  return render({ ...options, navigate: true });
8702
9100
  });
8703
9101
  function emitFragmentInserted(element) {
9102
+ if (element.upInserted)
9103
+ return;
9104
+ element.upInserted = true;
8704
9105
  return up.emit(element, 'up:fragment:inserted', {
8705
9106
  log: ['Inserted fragment %o', element],
8706
9107
  });
@@ -8708,8 +9109,9 @@ up.fragment = (function () {
8708
9109
  function emitFragmentKeep(keepPlan) {
8709
9110
  let { oldElement, newElement: newFragment, newData, renderOptions } = keepPlan;
8710
9111
  const log = ['Keeping fragment %o', oldElement];
8711
- const callback = e.callbackAttr(oldElement, 'up-on-keep', { exposedKeys: ['newFragment', 'newData'] });
8712
- return up.emit(oldElement, 'up:fragment:keep', { newFragment, newData, renderOptions, log, callback });
9112
+ const callback = e.callbackAttr(keepPlan.oldElement, 'up-on-keep', { exposedKeys: ['newFragment', 'newData'] });
9113
+ const event = up.event.build('up:fragment:keep', { newFragment, newData, renderOptions });
9114
+ return up.emit(oldElement, event, { log, callback });
8713
9115
  }
8714
9116
  function emitFragmentDestroyed(fragment, options) {
8715
9117
  const log = options.log ?? ['Destroyed fragment %o', fragment];
@@ -8786,7 +9188,7 @@ up.fragment = (function () {
8786
9188
  }
8787
9189
  function markFragmentAsDestroying(element) {
8788
9190
  element.classList.add('up-destroying');
8789
- element.setAttribute('aria-hidden', 'true');
9191
+ element.setAttribute('inert', '');
8790
9192
  }
8791
9193
  function reload(...args) {
8792
9194
  const options = parseTargetAndOptions(args);
@@ -8843,8 +9245,8 @@ up.fragment = (function () {
8843
9245
  function toTarget(element, options) {
8844
9246
  return u.presence(element, u.isString) || tryToTarget(element, options) || cannotTarget(element);
8845
9247
  }
8846
- function isTargetable(element) {
8847
- return !!tryToTarget(element);
9248
+ function isTargetable(element, options) {
9249
+ return !!tryToTarget(element, options);
8848
9250
  }
8849
9251
  function untargetableMessage(element) {
8850
9252
  return `Cannot derive good target selector from a <${e.tagName(element)}> element without identifying attributes. Try setting an [id] or configure up.fragment.config.targetDerivers.`;
@@ -9064,7 +9466,7 @@ up.fragment = (function () {
9064
9466
  if (steps.length < 2)
9065
9467
  return steps;
9066
9468
  let compressed = u.uniqBy(steps, 'oldElement');
9067
- compressed = u.reject(compressed, step => isContainedByRivalStep(compressed, step));
9469
+ compressed = u.reject(compressed, (step) => isContainedByRivalStep(compressed, step));
9068
9470
  return compressed;
9069
9471
  }
9070
9472
  function abort(...args) {
@@ -9161,6 +9563,11 @@ up.fragment = (function () {
9161
9563
  return () => up.destroy(tempElement);
9162
9564
  }
9163
9565
  }
9566
+ function trackSelector(...args) {
9567
+ let parsedArgs = u.args(args, 'val', 'options', 'callback');
9568
+ let tracker = new up.SelectorTracker(...parsedArgs);
9569
+ return tracker.start();
9570
+ }
9164
9571
  up.on('up:framework:boot', function () {
9165
9572
  const { documentElement } = document;
9166
9573
  documentElement.setAttribute('up-source', normalizeSource(location.href));
@@ -9213,6 +9620,7 @@ up.fragment = (function () {
9213
9620
  insertTemp,
9214
9621
  provideNodes,
9215
9622
  cloneTemplate,
9623
+ trackSelector,
9216
9624
  };
9217
9625
  })();
9218
9626
  up.reload = up.fragment.reload;
@@ -9225,7 +9633,7 @@ u.delegate(up, ['context'], () => up.layer.current);
9225
9633
 
9226
9634
 
9227
9635
  /***/ }),
9228
- /* 87 */
9636
+ /* 90 */
9229
9637
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9230
9638
 
9231
9639
  "use strict";
@@ -9234,10 +9642,10 @@ __webpack_require__.r(__webpack_exports__);
9234
9642
 
9235
9643
 
9236
9644
  /***/ }),
9237
- /* 88 */
9645
+ /* 91 */
9238
9646
  /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
9239
9647
 
9240
- __webpack_require__(89);
9648
+ __webpack_require__(92);
9241
9649
  up.viewport = (function () {
9242
9650
  const u = up.util;
9243
9651
  const e = up.element;
@@ -9299,10 +9707,25 @@ up.viewport = (function () {
9299
9707
  doFocus(element, options);
9300
9708
  return element === document.activeElement;
9301
9709
  }
9302
- function revealHash(hash = location.hash, options) {
9303
- let match = firstHashTarget(hash, options);
9710
+ function revealHash(...args) {
9711
+ return revealHashFn(...args)?.();
9712
+ }
9713
+ function revealHashFn(hash = location.hash, { strong, layer, origin, behavior = 'instant' } = {}) {
9714
+ if (!hash)
9715
+ return;
9716
+ let match = firstHashTarget(hash, { layer, origin });
9304
9717
  if (match) {
9305
- return reveal(match, { top: true });
9718
+ return () => {
9719
+ let doReveal = () => reveal(match, { top: true, behavior });
9720
+ if (strong)
9721
+ u.task(doReveal);
9722
+ return doReveal();
9723
+ };
9724
+ }
9725
+ else if (hash === '#top') {
9726
+ return () => {
9727
+ return scrollTo(0, { behavior });
9728
+ };
9306
9729
  }
9307
9730
  }
9308
9731
  function allSelector() {
@@ -9374,7 +9797,7 @@ up.viewport = (function () {
9374
9797
  const { location } = options.layer;
9375
9798
  const locationScrollTops = options.layer.lastScrollTops.get(location);
9376
9799
  if (locationScrollTops) {
9377
- setScrollTops(viewports, locationScrollTops);
9800
+ setScrollPositions(viewports, locationScrollTops, 0);
9378
9801
  up.puts('up.viewport.restoreScroll()', 'Restored scroll positions to %o', locationScrollTops);
9379
9802
  return true;
9380
9803
  }
@@ -9420,14 +9843,16 @@ up.viewport = (function () {
9420
9843
  }
9421
9844
  return [viewports, options];
9422
9845
  }
9423
- function resetScroll(...args) {
9424
- const [viewports, _options] = parseOptions(args);
9425
- setScrollTops(viewports, {});
9846
+ function scrollTo(position, ...args) {
9847
+ const [viewports, options] = parseOptions(args);
9848
+ setScrollPositions(viewports, {}, position, options.behavior);
9849
+ return true;
9426
9850
  }
9427
- function setScrollTops(viewports, tops) {
9851
+ function setScrollPositions(viewports, tops, defaultTop, behavior = 'instant') {
9428
9852
  for (let viewport of viewports) {
9429
9853
  const key = scrollTopKey(viewport);
9430
- viewport.scrollTop = tops[key] || 0;
9854
+ const top = tops[key] || defaultTop;
9855
+ viewport.scrollTo({ top, behavior });
9431
9856
  }
9432
9857
  }
9433
9858
  function absolutize(element, options = {}) {
@@ -9468,7 +9893,8 @@ up.viewport = (function () {
9468
9893
  };
9469
9894
  }
9470
9895
  function firstHashTarget(hash, options = {}) {
9471
- if (hash = pureHash(hash)) {
9896
+ hash = pureHash(hash);
9897
+ if (hash) {
9472
9898
  const selector = [
9473
9899
  e.idSelector(hash),
9474
9900
  'a' + e.attrSelector('name', hash)
@@ -9496,22 +9922,10 @@ up.viewport = (function () {
9496
9922
  }
9497
9923
  return to;
9498
9924
  }
9499
- document.addEventListener('DOMContentLoaded', function () {
9500
- revealHash();
9501
- u.task(revealHash);
9502
- });
9503
- up.on(window, 'hashchange', () => revealHash());
9504
- up.on('up:click', 'a[href^="#"]', function (event, link) {
9505
- if (link.hash !== location.hash)
9506
- return;
9507
- if (up.link.isFollowable(link))
9508
- return;
9509
- if (revealHash(link.hash))
9510
- up.event.halt(event);
9511
- });
9512
9925
  return {
9513
9926
  reveal,
9514
9927
  revealHash,
9928
+ revealHashFn,
9515
9929
  firstHashTarget,
9516
9930
  config,
9517
9931
  get: closest,
@@ -9524,7 +9938,7 @@ up.viewport = (function () {
9524
9938
  rootScrollbarWidth,
9525
9939
  saveScroll,
9526
9940
  restoreScroll,
9527
- resetScroll,
9941
+ scrollTo,
9528
9942
  saveFocus,
9529
9943
  restoreFocus,
9530
9944
  absolutize,
@@ -9541,7 +9955,7 @@ up.reveal = up.viewport.reveal;
9541
9955
 
9542
9956
 
9543
9957
  /***/ }),
9544
- /* 89 */
9958
+ /* 92 */
9545
9959
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9546
9960
 
9547
9961
  "use strict";
@@ -9550,27 +9964,22 @@ __webpack_require__.r(__webpack_exports__);
9550
9964
 
9551
9965
 
9552
9966
  /***/ }),
9553
- /* 90 */
9967
+ /* 93 */
9554
9968
  /***/ (() => {
9555
9969
 
9556
9970
  up.motion = (function () {
9557
9971
  const u = up.util;
9558
9972
  const e = up.element;
9559
- let namedAnimations = {};
9560
- let namedTransitions = {};
9561
9973
  const motionController = new up.MotionController('motion');
9562
9974
  const config = new up.Config(() => ({
9563
9975
  duration: 175,
9564
9976
  easing: 'ease',
9565
9977
  enabled: !matchMedia('(prefers-reduced-motion: reduce)').matches
9566
9978
  }));
9567
- function pickDefault(registry) {
9568
- return u.pickBy(registry, 'isDefault');
9569
- }
9979
+ let namedAnimations = new up.Registry('animation', findAnimationFn);
9980
+ let namedTransitions = new up.Registry('transition', findTransitionFn);
9570
9981
  function reset() {
9571
9982
  motionController.reset();
9572
- namedAnimations = pickDefault(namedAnimations);
9573
- namedTransitions = pickDefault(namedTransitions);
9574
9983
  }
9575
9984
  function isEnabled() {
9576
9985
  return config.enabled;
@@ -9610,9 +10019,6 @@ up.motion = (function () {
9610
10019
  options.easing ??= config.easing;
9611
10020
  options.duration ??= config.duration;
9612
10021
  }
9613
- function findNamedAnimation(name) {
9614
- return namedAnimations[name] || up.fail("Unknown animation %o", name);
9615
- }
9616
10022
  function finish(element) {
9617
10023
  return motionController.finish(element);
9618
10024
  }
@@ -9663,27 +10069,21 @@ up.motion = (function () {
9663
10069
  return Promise.resolve();
9664
10070
  }
9665
10071
  }
9666
- function findTransitionFn(object) {
9667
- if (isNone(object)) {
10072
+ function findTransitionFn(value) {
10073
+ if (isNone(value)) {
9668
10074
  return undefined;
9669
10075
  }
9670
- else if (u.isFunction(object)) {
9671
- return object;
10076
+ else if (u.isFunction(value)) {
10077
+ return value;
9672
10078
  }
9673
- else if (u.isArray(object)) {
9674
- return composeTransitionFn(...object);
10079
+ else if (u.isArray(value)) {
10080
+ return composeTransitionFn(...value);
9675
10081
  }
9676
- else if (u.isString(object)) {
9677
- let namedTransition;
9678
- if (object.indexOf('/') >= 0) {
9679
- return composeTransitionFn(...object.split('/'));
9680
- }
9681
- else if (namedTransition = namedTransitions[object]) {
9682
- return findTransitionFn(namedTransition);
9683
- }
10082
+ else if (u.isString(value) && value.includes('/')) {
10083
+ return composeTransitionFn(...value.split('/'));
9684
10084
  }
9685
10085
  else {
9686
- up.fail("Unknown transition %o", object);
10086
+ return namedTransitions.get(value);
9687
10087
  }
9688
10088
  }
9689
10089
  function composeTransitionFn(oldAnimation, newAnimation) {
@@ -9696,21 +10096,18 @@ up.motion = (function () {
9696
10096
  ]);
9697
10097
  }
9698
10098
  }
9699
- function findAnimationFn(object) {
9700
- if (isNone(object)) {
10099
+ function findAnimationFn(value) {
10100
+ if (isNone(value)) {
9701
10101
  return undefined;
9702
10102
  }
9703
- else if (u.isFunction(object)) {
9704
- return object;
9705
- }
9706
- else if (u.isString(object)) {
9707
- return findNamedAnimation(object);
10103
+ else if (u.isFunction(value)) {
10104
+ return value;
9708
10105
  }
9709
- else if (u.isOptions(object)) {
9710
- return (element, options) => animateNow(element, object, options);
10106
+ else if (u.isOptions(value)) {
10107
+ return (element, options) => animateNow(element, value, options);
9711
10108
  }
9712
10109
  else {
9713
- up.fail('Unknown animation %o', object);
10110
+ return namedAnimations.get(value);
9714
10111
  }
9715
10112
  }
9716
10113
  const swapElementsDirectly = up.mockable(function (oldElement, newElement) {
@@ -9725,16 +10122,6 @@ up.motion = (function () {
9725
10122
  parser.number('duration');
9726
10123
  return options;
9727
10124
  }
9728
- function registerTransition(name, transition) {
9729
- const fn = findTransitionFn(transition);
9730
- fn.isDefault = up.framework.evaling;
9731
- namedTransitions[name] = fn;
9732
- }
9733
- function registerAnimation(name, animation) {
9734
- const fn = findAnimationFn(animation);
9735
- fn.isDefault = up.framework.evaling;
9736
- namedAnimations[name] = fn;
9737
- }
9738
10125
  up.on('up:framework:boot', function () {
9739
10126
  if (!isEnabled()) {
9740
10127
  up.puts('up.motion', 'Animations are disabled');
@@ -9744,7 +10131,7 @@ up.motion = (function () {
9744
10131
  return !animationOrTransition || animationOrTransition === 'none';
9745
10132
  }
9746
10133
  function registerOpacityAnimation(name, from, to) {
9747
- registerAnimation(name, function (element, options) {
10134
+ namedAnimations.put(name, function (element, options) {
9748
10135
  element.style.opacity = 0;
9749
10136
  e.setStyle(element, { opacity: from });
9750
10137
  return animateNow(element, { opacity: to }, options);
@@ -9765,12 +10152,12 @@ up.motion = (function () {
9765
10152
  function registerMoveAnimations(direction, boxToTransform) {
9766
10153
  const animationToName = `move-to-${direction}`;
9767
10154
  const animationFromName = `move-from-${direction}`;
9768
- registerAnimation(animationToName, function (element, options) {
10155
+ namedAnimations.put(animationToName, function (element, options) {
9769
10156
  const box = untranslatedBox(element);
9770
10157
  const transform = boxToTransform(box);
9771
10158
  return animateNow(element, transform, options);
9772
10159
  });
9773
- registerAnimation(animationFromName, function (element, options) {
10160
+ namedAnimations.put(animationFromName, function (element, options) {
9774
10161
  const box = untranslatedBox(element);
9775
10162
  const transform = boxToTransform(box);
9776
10163
  e.setStyle(element, transform);
@@ -9793,19 +10180,19 @@ up.motion = (function () {
9793
10180
  const travelDistance = up.viewport.rootWidth() - box.left;
9794
10181
  return translateCSS(travelDistance, 0);
9795
10182
  });
9796
- registerTransition('cross-fade', ['fade-out', 'fade-in']);
9797
- registerTransition('move-left', ['move-to-left', 'move-from-right']);
9798
- registerTransition('move-right', ['move-to-right', 'move-from-left']);
9799
- registerTransition('move-up', ['move-to-top', 'move-from-bottom']);
9800
- registerTransition('move-down', ['move-to-bottom', 'move-from-top']);
10183
+ namedTransitions.put('cross-fade', ['fade-out', 'fade-in']);
10184
+ namedTransitions.put('move-left', ['move-to-left', 'move-from-right']);
10185
+ namedTransitions.put('move-right', ['move-to-right', 'move-from-left']);
10186
+ namedTransitions.put('move-up', ['move-to-top', 'move-from-bottom']);
10187
+ namedTransitions.put('move-down', ['move-to-bottom', 'move-from-top']);
9801
10188
  up.on('up:framework:reset', reset);
9802
10189
  return {
9803
10190
  morph,
9804
10191
  animate,
9805
10192
  finish,
9806
10193
  finishCount() { return motionController.finishCount; },
9807
- transition: registerTransition,
9808
- animation: registerAnimation,
10194
+ transition: namedTransitions.put,
10195
+ animation: namedAnimations.put,
9809
10196
  config,
9810
10197
  isEnabled,
9811
10198
  isNone,
@@ -9821,10 +10208,10 @@ up.animate = up.motion.animate;
9821
10208
 
9822
10209
 
9823
10210
  /***/ }),
9824
- /* 91 */
10211
+ /* 94 */
9825
10212
  /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
9826
10213
 
9827
- __webpack_require__(92);
10214
+ __webpack_require__(95);
9828
10215
  const u = up.util;
9829
10216
  up.network = (function () {
9830
10217
  const config = new up.Config(() => ({
@@ -9836,7 +10223,7 @@ up.network = (function () {
9836
10223
  lateDelay: 400,
9837
10224
  fail(response) { return (response.status < 200 || response.status > 299) && response.status !== 304; },
9838
10225
  autoCache(request) { return request.isSafe(); },
9839
- expireCache(request, _response) { return !request.isSafe(); },
10226
+ expireCache(request) { return !request.isSafe(); },
9840
10227
  evictCache: false,
9841
10228
  progressBar: true,
9842
10229
  timeout: 90000,
@@ -9863,6 +10250,8 @@ up.network = (function () {
9863
10250
  return options;
9864
10251
  }
9865
10252
  function processRequest(request) {
10253
+ cache.expire(request.expireCache ?? u.evalOption(config.expireCache, request) ?? false);
10254
+ cache.evict(request.evictCache ?? u.evalOption(config.evictCache, request) ?? false);
9866
10255
  useCachedRequest(request) || queueRequest(request);
9867
10256
  }
9868
10257
  function useCachedRequest(newRequest) {
@@ -9888,14 +10277,8 @@ up.network = (function () {
9888
10277
  request.onLoading = () => cache.reindex(request);
9889
10278
  }
9890
10279
  u.always(request, function (responseOrError) {
9891
- let expireCache = responseOrError.expireCache ?? request.expireCache ?? u.evalOption(config.expireCache, request, responseOrError);
9892
- if (expireCache) {
9893
- cache.expire(expireCache, { except: request });
9894
- }
9895
- let evictCache = responseOrError.evictCache ?? request.evictCache ?? u.evalOption(config.evictCache, request, responseOrError);
9896
- if (evictCache) {
9897
- cache.evict(evictCache, { except: request });
9898
- }
10280
+ cache.expire(responseOrError.expireCache ?? false, { except: request });
10281
+ cache.evict(responseOrError.evictCache ?? false, { except: request });
9899
10282
  let hasCacheEntry = cache.get(request);
9900
10283
  let isResponse = responseOrError instanceof up.Response;
9901
10284
  let isNetworkError = !isResponse;
@@ -9964,7 +10347,7 @@ up.cache = up.network.cache;
9964
10347
 
9965
10348
 
9966
10349
  /***/ }),
9967
- /* 92 */
10350
+ /* 95 */
9968
10351
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9969
10352
 
9970
10353
  "use strict";
@@ -9973,10 +10356,10 @@ __webpack_require__.r(__webpack_exports__);
9973
10356
 
9974
10357
 
9975
10358
  /***/ }),
9976
- /* 93 */
10359
+ /* 96 */
9977
10360
  /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
9978
10361
 
9979
- __webpack_require__(94);
10362
+ __webpack_require__(97);
9980
10363
  const u = up.util;
9981
10364
  const e = up.element;
9982
10365
  up.layer = (function () {
@@ -10151,7 +10534,7 @@ up.layer = (function () {
10151
10534
  });
10152
10535
  }
10153
10536
  function anySelector() {
10154
- return u.map(LAYER_CLASSES, Class => Class.selector()).join();
10537
+ return u.map(LAYER_CLASSES, (Class) => Class.selector()).join();
10155
10538
  }
10156
10539
  function optionToString(option) {
10157
10540
  if (u.isString(option)) {
@@ -10221,7 +10604,7 @@ up.layer = (function () {
10221
10604
 
10222
10605
 
10223
10606
  /***/ }),
10224
- /* 94 */
10607
+ /* 97 */
10225
10608
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
10226
10609
 
10227
10610
  "use strict";
@@ -10230,14 +10613,16 @@ __webpack_require__.r(__webpack_exports__);
10230
10613
 
10231
10614
 
10232
10615
  /***/ }),
10233
- /* 95 */
10616
+ /* 98 */
10234
10617
  /***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {
10235
10618
 
10236
- __webpack_require__(96);
10619
+ __webpack_require__(99);
10237
10620
  up.link = (function () {
10238
10621
  const u = up.util;
10239
10622
  const e = up.element;
10623
+ let lastTouchstartTarget = null;
10240
10624
  let lastMousedownTarget = null;
10625
+ let lastInstantTarget = null;
10241
10626
  const ATTRS_WITH_LOCAL_HTML = '[up-content], [up-fragment], [up-document]';
10242
10627
  const ATTRS_SUGGESTING_FOLLOW = `${ATTRS_WITH_LOCAL_HTML}, [up-target], [up-layer], [up-transition], [up-preload]`;
10243
10628
  const DEFAULT_INTERACTIVE_ELEMENT = 'a[href], button';
@@ -10267,7 +10652,9 @@ up.link = (function () {
10267
10652
  }
10268
10653
  }
10269
10654
  function reset() {
10655
+ lastTouchstartTarget = null;
10270
10656
  lastMousedownTarget = null;
10657
+ lastInstantTarget = null;
10271
10658
  }
10272
10659
  const follow = up.mockable(function (link, options, parserOptions) {
10273
10660
  return up.render(followOptions(link, options, parserOptions));
@@ -10289,6 +10676,7 @@ up.link = (function () {
10289
10676
  parser.string('contentType');
10290
10677
  parser.booleanOrNumber('lateDelay');
10291
10678
  parser.number('timeout');
10679
+ parser.booleanOrString('fail');
10292
10680
  return options;
10293
10681
  }
10294
10682
  function followOptions(link, options, parserOptions) {
@@ -10297,7 +10685,6 @@ up.link = (function () {
10297
10685
  const parser = new up.OptionsParser(link, options, { fail: true, ...parserOptions });
10298
10686
  parser.include(parseRequestOptions);
10299
10687
  options.origin ||= link;
10300
- parser.boolean('fail');
10301
10688
  parser.boolean('navigate', { default: true });
10302
10689
  parser.string('confirm', { attr: ['up-confirm', 'data-confirm'] });
10303
10690
  parser.string('target');
@@ -10331,9 +10718,12 @@ up.link = (function () {
10331
10718
  parser.string('dismissEvent');
10332
10719
  parser.string('acceptLocation');
10333
10720
  parser.string('dismissLocation');
10334
- parser.booleanOrString('history');
10721
+ parser.booleanOrString('closeAnimation');
10722
+ parser.string('closeEasing');
10723
+ parser.number('closeDuration');
10335
10724
  parser.include(up.status.statusOptions);
10336
10725
  parser.booleanOrString('focus');
10726
+ parser.booleanOrString('focusVisible');
10337
10727
  parser.boolean('saveScroll');
10338
10728
  parser.boolean('saveFocus');
10339
10729
  parser.booleanOrString('scroll');
@@ -10363,9 +10753,9 @@ up.link = (function () {
10363
10753
  abortable: false,
10364
10754
  background: true,
10365
10755
  cache: true,
10756
+ ...options,
10366
10757
  ...up.RenderOptions.NO_INPUT_INTERFERENCE,
10367
10758
  ...up.RenderOptions.NO_PREVIEWS,
10368
- ...options,
10369
10759
  guardEvent,
10370
10760
  preload: true,
10371
10761
  });
@@ -10424,27 +10814,37 @@ up.link = (function () {
10424
10814
  }
10425
10815
  function convertClicks(layer) {
10426
10816
  layer.on('click', function (event, element) {
10427
- if (!up.event.isUnmodified(event)) {
10817
+ if (up.event.isModified(event)) {
10428
10818
  return;
10429
10819
  }
10430
- if (isInstant(element) && lastMousedownTarget) {
10820
+ if (isInstant(element) && lastInstantTarget === element) {
10431
10821
  up.event.halt(event);
10432
10822
  }
10433
10823
  else if (up.event.inputDevice === 'key' || up.event.isSyntheticClick(event) || (layer.wasHitByMouseEvent(event) && !didUserDragAway(event))) {
10434
10824
  forkEventAsUpClick(event);
10435
10825
  }
10436
- return lastMousedownTarget = null;
10826
+ lastMousedownTarget = null;
10827
+ lastInstantTarget = null;
10828
+ });
10829
+ layer.on('touchstart', { passive: true }, function (event, element) {
10830
+ lastTouchstartTarget = element;
10437
10831
  });
10438
10832
  layer.on('mousedown', function (event, element) {
10439
- if (!up.event.isUnmodified(event)) {
10833
+ if (up.event.isModified(event)) {
10440
10834
  return;
10441
10835
  }
10442
- lastMousedownTarget = event.target;
10443
- if (isInstant(element)) {
10836
+ lastMousedownTarget = element;
10837
+ if (isInstant(element) && !isLongPressPossible(event)) {
10838
+ lastInstantTarget = element;
10444
10839
  forkEventAsUpClick(event);
10445
10840
  }
10841
+ lastTouchstartTarget = null;
10446
10842
  });
10447
10843
  }
10844
+ function isLongPressPossible(mousedownEvent) {
10845
+ let mousedownTarget = mousedownEvent.target;
10846
+ return (lastTouchstartTarget === mousedownTarget) && mousedownTarget.closest('[href]');
10847
+ }
10448
10848
  function didUserDragAway(clickEvent) {
10449
10849
  return lastMousedownTarget && (lastMousedownTarget !== clickEvent.target);
10450
10850
  }
@@ -10540,7 +10940,7 @@ up.deferred = { load: up.link.loadDeferred };
10540
10940
 
10541
10941
 
10542
10942
  /***/ }),
10543
- /* 96 */
10943
+ /* 99 */
10544
10944
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
10545
10945
 
10546
10946
  "use strict";
@@ -10549,7 +10949,7 @@ __webpack_require__.r(__webpack_exports__);
10549
10949
 
10550
10950
 
10551
10951
  /***/ }),
10552
- /* 97 */
10952
+ /* 100 */
10553
10953
  /***/ (() => {
10554
10954
 
10555
10955
  up.form = (function () {
@@ -10562,12 +10962,14 @@ up.form = (function () {
10562
10962
  noSubmitSelectors: ['[up-submit=false]', '[target]', e.crossOriginSelector('action')],
10563
10963
  submitButtonSelectors: ['input[type=submit]', 'input[type=image]', 'button[type=submit]', 'button:not([type])'],
10564
10964
  genericButtonSelectors: ['input[type=button]', 'button[type=button]'],
10965
+ validateBatch: true,
10565
10966
  watchInputEvents: ['input', 'change'],
10566
10967
  watchInputDelay: 0,
10567
10968
  watchChangeEvents: ['change'],
10969
+ watchableEvents: ['input', 'change'],
10568
10970
  }));
10569
10971
  function fieldSelector(suffix = '') {
10570
- return config.fieldSelectors.map(field => field + suffix).join();
10972
+ return config.fieldSelectors.map((field) => field + suffix).join();
10571
10973
  }
10572
10974
  function isField(element) {
10573
10975
  return element.matches(fieldSelector());
@@ -10578,11 +10980,17 @@ up.form = (function () {
10578
10980
  if (root.matches('form[id]')) {
10579
10981
  const outsideFieldSelector = fieldSelector(e.attrSelector('form', root.getAttribute('id')));
10580
10982
  const outsideFields = up.fragment.all(outsideFieldSelector, { layer: root });
10581
- fields.push(...outsideFields);
10582
- fields = u.uniq(fields);
10983
+ fields = u.uniq([...fields, ...outsideFields]);
10583
10984
  }
10584
10985
  return fields;
10585
10986
  }
10987
+ function findFieldsAndButtons(container) {
10988
+ return [
10989
+ ...findFields(container),
10990
+ ...findSubmitButtons(container),
10991
+ ...findGenericButtons(container),
10992
+ ];
10993
+ }
10586
10994
  function findSubmitButtons(root) {
10587
10995
  return e.subtree(root, submitButtonSelector());
10588
10996
  }
@@ -10617,8 +11025,10 @@ up.form = (function () {
10617
11025
  }
10618
11026
  function watchOptions(field, options, parserOptions = {}) {
10619
11027
  options = u.options(options);
10620
- let parser = new up.OptionsParser(field, options, { ...parserOptions, closest: true, attrPrefix: 'up-watch-' });
10621
- parser.include(up.status.statusOptions);
11028
+ parserOptions.closest ??= true;
11029
+ parserOptions.attrPrefix ??= 'up-watch-';
11030
+ let parser = new up.OptionsParser(field, options, parserOptions);
11031
+ parser.include(up.status.statusOptions, parserOptions);
10622
11032
  parser.string('event');
10623
11033
  parser.number('delay');
10624
11034
  let config = up.form.config;
@@ -10632,15 +11042,20 @@ up.form = (function () {
10632
11042
  options.origin ||= field;
10633
11043
  return options;
10634
11044
  }
10635
- function disableContainer(container) {
10636
- let controls = [
10637
- ...findFields(container),
10638
- ...findSubmitButtons(container),
10639
- ...findGenericButtons(container),
10640
- ];
10641
- return u.sequence(u.map(controls, disableControl));
11045
+ function validateOptions(field, options, parserOptions = {}) {
11046
+ options = u.options(options);
11047
+ let parser = new up.OptionsParser(field, options, { ...parserOptions, closest: true, attrPrefix: 'up-validate-' });
11048
+ parser.string('url');
11049
+ parser.string('method', { normalize: u.normalizeMethod });
11050
+ parser.boolean('batch', { default: config.validateBatch });
11051
+ parser.include(watchOptions, { defaults: { event: 'change' } });
11052
+ return options;
11053
+ }
11054
+ function disableContainerTemp(container) {
11055
+ let controls = findFieldsAndButtons(container);
11056
+ return u.sequence(u.map(controls, disableControlTemp));
10642
11057
  }
10643
- function disableControl(control) {
11058
+ function disableControlTemp(control) {
10644
11059
  if (control.disabled)
10645
11060
  return;
10646
11061
  let focusFallback;
@@ -10655,7 +11070,7 @@ up.form = (function () {
10655
11070
  return () => { control.disabled = false; };
10656
11071
  }
10657
11072
  function getDisableContainers(disable, origin) {
10658
- let originScope = () => getScope(origin);
11073
+ let originScope = () => getRegion(origin);
10659
11074
  if (disable === true) {
10660
11075
  return [originScope()];
10661
11076
  }
@@ -10680,6 +11095,11 @@ up.form = (function () {
10680
11095
  }
10681
11096
  };
10682
11097
  }
11098
+ function setContainerDisabled(container, disabled) {
11099
+ for (let control of findFieldsAndButtons(container)) {
11100
+ control.disabled = disabled;
11101
+ }
11102
+ }
10683
11103
  function destinationOptions(form, options, parserOptions) {
10684
11104
  options = u.options(options);
10685
11105
  form = getForm(form);
@@ -10711,8 +11131,7 @@ up.form = (function () {
10711
11131
  root = up.element.get(root);
10712
11132
  callback ||= watchCallbackFromElement(root) || up.fail('No callback given for up.watch()');
10713
11133
  const watcher = new up.FieldWatcher(root, options, callback);
10714
- watcher.start();
10715
- return () => watcher.stop();
11134
+ return watcher.start();
10716
11135
  }
10717
11136
  function watchCallbackFromElement(element) {
10718
11137
  let rawCallback = element.getAttribute('up-watch');
@@ -10722,7 +11141,7 @@ up.form = (function () {
10722
11141
  }
10723
11142
  function autosubmit(target, options = {}) {
10724
11143
  const onChange = (_diff, renderOptions) => submit(target, renderOptions);
10725
- return watch(target, { ...options, batch: true }, onChange);
11144
+ return watch(target, { logPrefix: 'up.autosubmit()', ...options, batch: true }, onChange);
10726
11145
  }
10727
11146
  function getGroupSelectors() {
10728
11147
  return up.migrate.migratedFormGroupSelectors?.() || config.groupSelectors;
@@ -10750,7 +11169,8 @@ up.form = (function () {
10750
11169
  }
10751
11170
  function validate(...args) {
10752
11171
  let options = parseValidateArgs(...args);
10753
- let validator = up.FormValidator.forElement(options.origin);
11172
+ let form = getForm(options.origin);
11173
+ let validator = getFormValidator(form);
10754
11174
  return validator.validate(options);
10755
11175
  }
10756
11176
  function parseValidateArgs(originOrTarget, ...args) {
@@ -10763,88 +11183,20 @@ up.form = (function () {
10763
11183
  }
10764
11184
  return options;
10765
11185
  }
10766
- function switcherValues(field) {
10767
- let value;
10768
- let meta;
10769
- if (field.matches('input[type=checkbox]')) {
10770
- if (field.checked) {
10771
- value = field.value;
10772
- meta = ':checked';
10773
- }
10774
- else {
10775
- meta = ':unchecked';
10776
- }
10777
- }
10778
- else if (field.matches('input[type=radio]')) {
10779
- const form = getScope(field);
10780
- const groupName = field.getAttribute('name');
10781
- const checkedButton = form.querySelector(`input[type=radio]${e.attrSelector('name', groupName)}:checked`);
10782
- if (checkedButton) {
10783
- meta = ':checked';
10784
- value = checkedButton.value;
10785
- }
10786
- else {
10787
- meta = ':unchecked';
10788
- }
10789
- }
10790
- else {
10791
- value = field.value;
10792
- }
10793
- const values = [];
10794
- if (u.isPresent(value)) {
10795
- values.push(value);
10796
- values.push(':present');
10797
- }
10798
- else {
10799
- values.push(':blank');
10800
- }
10801
- if (u.isPresent(meta)) {
10802
- values.push(meta);
10803
- }
10804
- return values;
10805
- }
10806
- function switchTargets(switcher, options = {}) {
10807
- const targetSelector = options.target || options.target || switcher.getAttribute('up-switch');
10808
- const form = getScope(switcher);
10809
- targetSelector || up.fail("No switch target given for %o", switcher);
10810
- const fieldValues = switcherValues(switcher);
10811
- for (let target of up.fragment.all(form, targetSelector)) {
10812
- switchTarget(target, fieldValues);
10813
- }
10814
- }
10815
- const switchTarget = up.mockable(function (target, fieldValues) {
10816
- let show;
10817
- fieldValues ||= switcherValues(findSwitcherForTarget(target));
10818
- let hideValues = target.getAttribute('up-hide-for');
10819
- if (hideValues) {
10820
- hideValues = parseSwitchTokens(hideValues);
10821
- show = u.intersect(fieldValues, hideValues).length === 0;
10822
- }
10823
- else {
10824
- let showValues = target.getAttribute('up-show-for');
10825
- showValues = showValues ? parseSwitchTokens(showValues) : [':present', ':checked'];
10826
- show = u.intersect(fieldValues, showValues).length > 0;
10827
- }
10828
- e.toggle(target, show);
10829
- target.classList.add('up-switched');
10830
- });
10831
- function parseSwitchTokens(str) {
10832
- return u.getSimpleTokens(str, { json: true });
10833
- }
10834
- function findSwitcherForTarget(target) {
10835
- const form = getScope(target);
10836
- const switchers = form.querySelectorAll('[up-switch]');
10837
- const switcher = u.find(switchers, function (switcher) {
10838
- const targetSelector = switcher.getAttribute('up-switch');
10839
- return target.matches(targetSelector);
10840
- });
10841
- return switcher || up.fail('Could not find [up-switch] field for %o', target);
10842
- }
10843
11186
  function getForm(elementOrSelector, options = {}) {
10844
11187
  const element = up.fragment.get(elementOrSelector, options);
10845
11188
  return element.form || element.closest('form');
10846
11189
  }
10847
- function getScope(origin, options) {
11190
+ function getFormValidator(form) {
11191
+ return form.upFormValidator ||= setupFormValidator(form);
11192
+ }
11193
+ function setupFormValidator(form) {
11194
+ const validator = new up.FormValidator(form);
11195
+ const stop = validator.start();
11196
+ up.destructor(form, stop);
11197
+ return validator;
11198
+ }
11199
+ function getRegion(origin, options) {
10848
11200
  if (origin) {
10849
11201
  return getForm(origin, options) || up.layer.get(origin).element;
10850
11202
  }
@@ -10852,6 +11204,19 @@ up.form = (function () {
10852
11204
  return up.layer.current.element;
10853
11205
  }
10854
11206
  }
11207
+ function trackFields(...args) {
11208
+ let [root, { guard }, callback] = u.args(args, 'val', 'options', 'callback');
11209
+ let filter = function (fields) {
11210
+ let scope = getRegion(root);
11211
+ return u.filter(fields, function (field) {
11212
+ return (root === scope || root.contains(field))
11213
+ && (getForm(field) === scope)
11214
+ && (!guard || guard(field));
11215
+ });
11216
+ };
11217
+ const live = true;
11218
+ return up.fragment.trackSelector(fieldSelector(), { filter, live }, callback);
11219
+ }
10855
11220
  function focusedField() {
10856
11221
  return u.presence(document.activeElement, isField);
10857
11222
  }
@@ -10866,49 +11231,39 @@ up.form = (function () {
10866
11231
  up.event.halt(event, { log: true });
10867
11232
  up.error.muteUncriticalRejection(submit(form, { submitButton }));
10868
11233
  });
10869
- up.compiler(validatingFieldSelector, function (fieldOrForm) {
10870
- let validator = up.FormValidator.forElement(fieldOrForm);
10871
- validator.watchContainer(fieldOrForm);
11234
+ up.compiler('form', function (form) {
11235
+ getFormValidator(form);
10872
11236
  });
10873
- function validatingFieldSelector() {
10874
- let includes = config.fieldSelectors.map((selector) => `${selector}[up-validate], [up-validate] ${selector}`);
10875
- let excludes = ['[up-validate=false]'];
10876
- return e.unionSelector(includes, excludes);
10877
- }
10878
11237
  up.compiler('[up-switch]', (switcher) => {
10879
- switchTargets(switcher);
10880
- });
10881
- up.on('change', '[up-switch]', (_event, switcher) => {
10882
- switchTargets(switcher);
10883
- });
10884
- up.compiler('[up-show-for]:not(.up-switched), [up-hide-for]:not(.up-switched)', (element) => {
10885
- switchTarget(element);
11238
+ return new up.Switcher(switcher).start();
10886
11239
  });
10887
11240
  up.attribute('up-watch', (formOrField) => watch(formOrField));
10888
- up.attribute('up-autosubmit', (formOrField) => autosubmit(formOrField));
11241
+ up.attribute('up-autosubmit', (formOrField) => autosubmit(formOrField, { logPrefix: '[up-autosubmit]' }));
10889
11242
  return {
10890
11243
  config,
10891
11244
  submit,
10892
11245
  submitOptions,
10893
11246
  destinationOptions,
10894
11247
  watchOptions,
11248
+ validateOptions,
10895
11249
  isSubmittable,
10896
11250
  watch,
10897
11251
  validate,
10898
11252
  autosubmit,
10899
11253
  fieldSelector,
10900
11254
  fields: findFields,
11255
+ trackFields,
10901
11256
  isField,
10902
11257
  submitButtons: findSubmitButtons,
10903
11258
  focusedField,
10904
- switchTarget,
10905
- disable: disableContainer,
11259
+ disableTemp: disableContainerTemp,
11260
+ setDisabled: setContainerDisabled,
10906
11261
  getDisablePreviewFn,
10907
11262
  group: findGroup,
10908
11263
  groupSolution: findGroupSolution,
10909
11264
  groupSelectors: getGroupSelectors,
10910
11265
  get: getForm,
10911
- getScope,
11266
+ getRegion,
10912
11267
  };
10913
11268
  })();
10914
11269
  up.submit = up.form.submit;
@@ -10918,13 +11273,12 @@ up.validate = up.form.validate;
10918
11273
 
10919
11274
 
10920
11275
  /***/ }),
10921
- /* 98 */
11276
+ /* 101 */
10922
11277
  /***/ (() => {
10923
11278
 
10924
11279
  up.status = (function () {
10925
11280
  const u = up.util;
10926
11281
  const e = up.element;
10927
- let namedPreviewFns = {};
10928
11282
  const config = new up.Config(() => ({
10929
11283
  currentClasses: ['up-current'],
10930
11284
  activeClasses: ['up-active'],
@@ -10932,9 +11286,9 @@ up.status = (function () {
10932
11286
  navSelectors: ['[up-nav]', 'nav'],
10933
11287
  noNavSelectors: ['[up-nav=false]'],
10934
11288
  }));
11289
+ let namedPreviewFns = new up.Registry('preview');
10935
11290
  function reset() {
10936
11291
  up.layer.root.feedbackLocation = null;
10937
- namedPreviewFns = u.pickBy(namedPreviewFns, 'isDefault');
10938
11292
  }
10939
11293
  const SELECTOR_LINK = 'a, [up-href]';
10940
11294
  function linkCurrentURLs(link) {
@@ -11010,7 +11364,7 @@ up.status = (function () {
11010
11364
  }
11011
11365
  function resolvePreviewString(str) {
11012
11366
  return u.map(u.parseScalarJSONPairs(str), ([name, parsedOptions]) => {
11013
- let previewFn = namedPreviewFns[name] || up.fail('Unknown preview "%s"', name);
11367
+ let previewFn = namedPreviewFns.get(name);
11014
11368
  return function (preview, runOptions) {
11015
11369
  up.puts('[up-preview]', 'Showing preview %o', name);
11016
11370
  return previewFn(preview, parsedOptions || runOptions);
@@ -11021,10 +11375,6 @@ up.status = (function () {
11021
11375
  activeElements ||= u.wrapList(origin);
11022
11376
  return activeElements.map(findActivatableArea);
11023
11377
  }
11024
- function registerPreview(name, previewFn) {
11025
- previewFn.isDefault = up.framework.evaling;
11026
- namedPreviewFns[name] = previewFn;
11027
- }
11028
11378
  function getFeedbackClassesPreviewFn(feedbackOption, fragments) {
11029
11379
  if (!feedbackOption)
11030
11380
  return;
@@ -11069,7 +11419,7 @@ up.status = (function () {
11069
11419
  up.on('up:framework:reset', reset);
11070
11420
  return {
11071
11421
  config,
11072
- preview: registerPreview,
11422
+ preview: namedPreviewFns.put,
11073
11423
  resolvePreviewFns,
11074
11424
  runPreviews,
11075
11425
  statusOptions,
@@ -11079,7 +11429,7 @@ up.preview = up.status.preview;
11079
11429
 
11080
11430
 
11081
11431
  /***/ }),
11082
- /* 99 */
11432
+ /* 102 */
11083
11433
  /***/ (() => {
11084
11434
 
11085
11435
  up.radio = (function () {
@@ -11173,7 +11523,7 @@ up.radio = (function () {
11173
11523
 
11174
11524
 
11175
11525
  /***/ }),
11176
- /* 100 */
11526
+ /* 103 */
11177
11527
  /***/ (() => {
11178
11528
 
11179
11529
  (function () {
@@ -11323,15 +11673,18 @@ __webpack_require__(83);
11323
11673
  __webpack_require__(84);
11324
11674
  __webpack_require__(85);
11325
11675
  __webpack_require__(86);
11676
+ __webpack_require__(87);
11326
11677
  __webpack_require__(88);
11327
- __webpack_require__(90);
11678
+ __webpack_require__(89);
11328
11679
  __webpack_require__(91);
11329
11680
  __webpack_require__(93);
11330
- __webpack_require__(95);
11331
- __webpack_require__(97);
11681
+ __webpack_require__(94);
11682
+ __webpack_require__(96);
11332
11683
  __webpack_require__(98);
11333
- __webpack_require__(99);
11334
11684
  __webpack_require__(100);
11685
+ __webpack_require__(101);
11686
+ __webpack_require__(102);
11687
+ __webpack_require__(103);
11335
11688
  up.framework.onEvaled();
11336
11689
 
11337
11690
  })();