unpoly-rails 3.11.0 → 3.12.0

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.11.0'
8
+ version: '3.12.0'
9
9
  };
10
10
 
11
11
 
@@ -395,6 +395,9 @@ up.util = (function () {
395
395
  return setTimeout(callback, millis);
396
396
  }
397
397
  function queueTask(task) {
398
+ setTimeout(task);
399
+ }
400
+ function queueFastTask(task) {
398
401
  const channel = new MessageChannel();
399
402
  channel.port1.onmessage = () => task();
400
403
  channel.port2.postMessage(0);
@@ -778,7 +781,7 @@ up.util = (function () {
778
781
  function scanFunctions(...values) {
779
782
  return values.flat().filter(isFunction);
780
783
  }
781
- function cleaner() {
784
+ function cleaner(order = 'lifo') {
782
785
  let fns = [];
783
786
  let track = function (values, transform) {
784
787
  values = scanFunctions(...values).map(transform);
@@ -791,9 +794,9 @@ up.util = (function () {
791
794
  track(values, up.error.guardFn);
792
795
  };
793
796
  api.clean = function (...args) {
794
- let { length } = fns;
795
- for (let i = length - 1; i >= 0; i--)
796
- fns[i](...args);
797
+ if (order === 'lifo')
798
+ fns.reverse();
799
+ fns.forEach((fn) => fn(...args));
797
800
  fns = [];
798
801
  };
799
802
  return api;
@@ -969,6 +972,7 @@ up.util = (function () {
969
972
  isBasicObjectProperty,
970
973
  isCrossOrigin,
971
974
  task: queueTask,
975
+ fastTask: queueFastTask,
972
976
  isEqual,
973
977
  getSimpleTokens,
974
978
  getComplexTokens,
@@ -1034,6 +1038,9 @@ up.error = (function () {
1034
1038
  reportError(error);
1035
1039
  }
1036
1040
  }
1041
+ function guardPromise(promise) {
1042
+ return promise.catch(reportError);
1043
+ }
1037
1044
  function guardFn(fn) {
1038
1045
  return (...args) => guard(() => fn(...args));
1039
1046
  }
@@ -1043,6 +1050,7 @@ up.error = (function () {
1043
1050
  muteUncriticalRejection,
1044
1051
  muteUncriticalSync,
1045
1052
  guard,
1053
+ guardPromise,
1046
1054
  guardFn,
1047
1055
  };
1048
1056
  })();
@@ -1359,6 +1367,10 @@ up.element = (function () {
1359
1367
  return `.${klass}`;
1360
1368
  }
1361
1369
  function createBrokenDocumentFromHTML(html) {
1370
+ const firstTag = firstTagNameInHTML(html);
1371
+ if (['TR', 'TD', 'TH', 'THEAD', 'TBODY'].includes(firstTag)) {
1372
+ html = `<table>${html}</table>`;
1373
+ }
1362
1374
  return new DOMParser().parseFromString(html, 'text/html');
1363
1375
  }
1364
1376
  function revivedClone(element) {
@@ -1648,6 +1660,15 @@ up.element = (function () {
1648
1660
  return [element.parentElement, 'beforeend'];
1649
1661
  }
1650
1662
  }
1663
+ const FIRST_TAG_NAME_PATTERN = /^\s*(<!--[^-]*.*?-->\s*)*<([a-z-!]+)\b/i;
1664
+ function firstTagNameInHTML(html) {
1665
+ var _a;
1666
+ return (_a = FIRST_TAG_NAME_PATTERN.exec(html)) === null || _a === void 0 ? void 0 : _a[2].toUpperCase();
1667
+ }
1668
+ function isFullDocumentHTML(html) {
1669
+ let firstTag = firstTagNameInHTML(html);
1670
+ return firstTag === 'HTML' || firstTag === '!DOCTYPE';
1671
+ }
1651
1672
  return {
1652
1673
  subtree,
1653
1674
  subtreeFirst,
@@ -1716,6 +1737,8 @@ up.element = (function () {
1716
1737
  matchSelectorMap,
1717
1738
  elementLikeMatches,
1718
1739
  documentPosition,
1740
+ firstTagNameInHTML,
1741
+ isFullDocumentHTML,
1719
1742
  };
1720
1743
  })();
1721
1744
 
@@ -1916,12 +1939,13 @@ const u = up.util;
1916
1939
  const e = up.element;
1917
1940
  up.OptionsParser = class OptionsParser {
1918
1941
  constructor(element, options, parserOptions = {}) {
1942
+ var _a;
1919
1943
  this._options = options;
1920
1944
  this._element = element;
1921
1945
  this._fail = parserOptions.fail;
1922
1946
  this._closest = parserOptions.closest;
1923
1947
  this._attrPrefix = parserOptions.attrPrefix || 'up-';
1924
- this._defaults = parserOptions.defaults || {};
1948
+ this._defaults = (_a = parserOptions.defaults) !== null && _a !== void 0 ? _a : {};
1925
1949
  }
1926
1950
  string(key, keyOptions) {
1927
1951
  this.parse(e.attr, key, keyOptions);
@@ -1952,7 +1976,9 @@ up.OptionsParser = class OptionsParser {
1952
1976
  for (let attrName of attrNames) {
1953
1977
  value !== null && value !== void 0 ? value : (value = this._parseFromAttr(attrValueFn, this._element, attrName));
1954
1978
  }
1955
- value !== null && value !== void 0 ? value : (value = (_b = keyOptions.default) !== null && _b !== void 0 ? _b : this._defaults[key]);
1979
+ if (this._defaults !== false) {
1980
+ value !== null && value !== void 0 ? value : (value = (_b = keyOptions.default) !== null && _b !== void 0 ? _b : this._defaults[key]);
1981
+ }
1956
1982
  if (u.isDefined(value)) {
1957
1983
  let normalizeFn = keyOptions.normalize;
1958
1984
  if (normalizeFn) {
@@ -2050,6 +2076,14 @@ up.Rect = class Rect extends up.Record {
2050
2076
  static fromElement(element) {
2051
2077
  return new (this)(element.getBoundingClientRect());
2052
2078
  }
2079
+ static fromElementAsFixed(element) {
2080
+ let fixedClone = element.cloneNode(true);
2081
+ element.after(fixedClone);
2082
+ fixedClone.style.position = 'fixed';
2083
+ let rect = this.fromElement(fixedClone);
2084
+ fixedClone.remove();
2085
+ return rect;
2086
+ }
2053
2087
  };
2054
2088
 
2055
2089
 
@@ -2124,6 +2158,11 @@ up.Change = class Change {
2124
2158
  deriveFailOptions() {
2125
2159
  return up.RenderOptions.deriveFailOptions(this.options);
2126
2160
  }
2161
+ ensureLayerAlive(layer = this.layer) {
2162
+ if (!layer.isAlive()) {
2163
+ throw new up.Aborted("Layer is already " + layer.state);
2164
+ }
2165
+ }
2127
2166
  };
2128
2167
 
2129
2168
 
@@ -2144,18 +2183,18 @@ up.Change.Addition = class Addition extends up.Change {
2144
2183
  handleLayerChangeRequests() {
2145
2184
  if (this.layer.isOverlay()) {
2146
2185
  this._tryAcceptLayerFromServer();
2147
- this.abortWhenLayerClosed();
2186
+ this.ensureLayerAlive();
2148
2187
  this.layer.tryAcceptForLocation(this._responseOptions());
2149
- this.abortWhenLayerClosed();
2188
+ this.ensureLayerAlive();
2150
2189
  this._tryDismissLayerFromServer();
2151
- this.abortWhenLayerClosed();
2190
+ this.ensureLayerAlive();
2152
2191
  this.layer.tryDismissForLocation(this._responseOptions());
2153
- this.abortWhenLayerClosed();
2192
+ this.ensureLayerAlive();
2154
2193
  }
2155
2194
  this.layer.asCurrent(() => {
2156
2195
  for (let eventPlan of this._eventPlans) {
2157
2196
  up.emit(Object.assign(Object.assign({}, eventPlan), this._responseOptions()));
2158
- this.abortWhenLayerClosed();
2197
+ this.ensureLayerAlive();
2159
2198
  }
2160
2199
  });
2161
2200
  }
@@ -2169,11 +2208,6 @@ up.Change.Addition = class Addition extends up.Change {
2169
2208
  this.layer.dismiss(this._dismissLayer, this._responseOptions());
2170
2209
  }
2171
2210
  }
2172
- abortWhenLayerClosed(layer = this.layer) {
2173
- if (layer.isClosed()) {
2174
- throw new up.Aborted('Layer was closed');
2175
- }
2176
- }
2177
2211
  _setSource({ oldElement, newElement, source }) {
2178
2212
  if (source === 'keep') {
2179
2213
  source = (oldElement && up.fragment.source(oldElement));
@@ -2300,16 +2334,16 @@ up.RenderJob = (_a = class RenderJob {
2300
2334
  }
2301
2335
  }
2302
2336
  }
2303
- _handleAbortOption(request) {
2337
+ _handleAbortOption({ bindFragments, bindLayer, origin, layer, request }) {
2304
2338
  let { abort } = this.renderOptions;
2305
- if (!abort || !up.network.isBusy())
2339
+ if (!abort)
2306
2340
  return;
2307
- let { bindFragments, bindLayer, origin, layer } = this._getChange().getPreflightProps();
2308
2341
  let abortOptions = {
2309
2342
  except: request,
2310
2343
  logOnce: ['up.render()', 'Change with { abort } option will abort other requests'],
2311
2344
  newLayer: (layer === 'new'),
2312
2345
  origin,
2346
+ jid: this.renderOptions.jid,
2313
2347
  };
2314
2348
  if (abort === 'target') {
2315
2349
  up.fragment.abort(bindFragments, Object.assign({}, abortOptions));
@@ -2457,7 +2491,7 @@ up.Change.OpenLayer = class OpenLayer extends up.Change.Addition {
2457
2491
  else {
2458
2492
  this._content = this.responseDoc.select(this.target);
2459
2493
  }
2460
- if (!this._content || this._baseLayer.isClosed()) {
2494
+ if (!this._content || !this._baseLayer.isAlive()) {
2461
2495
  throw new up.CannotMatch();
2462
2496
  }
2463
2497
  }
@@ -2478,7 +2512,7 @@ up.Change.OpenLayer = class OpenLayer extends up.Change.Addition {
2478
2512
  this.layer.setContent(this._content);
2479
2513
  this.responseDoc.finalizeElement(this._content);
2480
2514
  this.setReloadAttrs({ newElement: this._content, source: this.options.source });
2481
- up.hello(this.layer.element, Object.assign(Object.assign({}, this.options), { layer: this.layer, dataRoot: this._content }));
2515
+ this._helloPromise = up.hello(this.layer.element, Object.assign(Object.assign({}, this.options), { layer: this.layer, dataRoot: this._content }));
2482
2516
  this._newOverlayResult = new up.RenderResult({
2483
2517
  layer: this.layer,
2484
2518
  fragments: [this._content],
@@ -2487,9 +2521,9 @@ up.Change.OpenLayer = class OpenLayer extends up.Change.Addition {
2487
2521
  });
2488
2522
  this._handleScroll();
2489
2523
  this._newOverlayResult.finished = this._finish();
2490
- this.layer.opening = false;
2524
+ this.layer.state = 'opened';
2491
2525
  this._emitOpenedEvent();
2492
- this.abortWhenLayerClosed();
2526
+ this.ensureLayerAlive();
2493
2527
  }
2494
2528
  _renderOtherLayers() {
2495
2529
  if (this._otherLayersResult)
@@ -2503,17 +2537,17 @@ up.Change.OpenLayer = class OpenLayer extends up.Change.Addition {
2503
2537
  _finish() {
2504
2538
  return __awaiter(this, void 0, void 0, function* () {
2505
2539
  yield this.layer.startOpenAnimation();
2506
- this.abortWhenLayerClosed();
2540
+ this.ensureLayerAlive();
2507
2541
  this._handleFocus();
2542
+ yield this._helloPromise;
2508
2543
  return this._newOverlayResult;
2509
2544
  });
2510
2545
  }
2511
2546
  _buildLayer() {
2512
- const buildOptions = Object.assign(Object.assign({}, this.options), { opening: true });
2513
2547
  const beforeNew = (optionsWithLayerDefaults) => {
2514
2548
  return this.options = up.RenderOptions.finalize(optionsWithLayerDefaults);
2515
2549
  };
2516
- return up.layer.build(buildOptions, beforeNew);
2550
+ return up.layer.build(this.options, beforeNew);
2517
2551
  }
2518
2552
  _handleHistory() {
2519
2553
  var _a;
@@ -2630,7 +2664,10 @@ up.Change.UpdateLayer = (_a = class UpdateLayer extends up.Change.Addition {
2630
2664
  this.layer.peel({ history: !this._hasHistory() });
2631
2665
  }
2632
2666
  if (this.options.abort !== false) {
2633
- up.fragment.abort(this._getFragments(), { reason: 'Fragment is being replaced' });
2667
+ up.fragment.abort(this._getFragments(), {
2668
+ reason: 'Fragment is being replaced',
2669
+ jid: this.options.jid,
2670
+ });
2634
2671
  }
2635
2672
  Object.assign(this.layer.context, this._context);
2636
2673
  if (this._hasHistory()) {
@@ -2739,6 +2776,7 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2739
2776
  this._steps = u.copy(u.assert(options.steps));
2740
2777
  this._passRenderOptions = u.assert(options.passRenderOptions);
2741
2778
  this._noneOptions = options.noneOptions || {};
2779
+ this._finishDelays = [];
2742
2780
  }
2743
2781
  execute(responseDoc) {
2744
2782
  this.responseDoc = responseDoc;
@@ -2755,16 +2793,21 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2755
2793
  }
2756
2794
  else {
2757
2795
  this._steps.reverse();
2758
- const motionEndPromises = this._steps.map((step) => this._executeStep(step));
2759
- this.renderResult.finished = this._finish(motionEndPromises);
2796
+ up.fragment.mutate(() => {
2797
+ const motionEndPromises = this._steps.map((step) => this._executeStep(step));
2798
+ this.renderResult.finished = this._finish(motionEndPromises);
2799
+ });
2760
2800
  }
2761
2801
  return this.renderResult;
2762
2802
  }
2763
- _finish(motionEndPromises) {
2803
+ _delayFinish(delay) {
2804
+ this._finishDelays.push(delay);
2805
+ }
2806
+ _finish() {
2764
2807
  return __awaiter(this, void 0, void 0, function* () {
2765
- yield Promise.all(motionEndPromises);
2808
+ yield Promise.all(this._finishDelays);
2766
2809
  for (let step of this._steps) {
2767
- this.abortWhenLayerClosed(step.layer);
2810
+ this.ensureLayerAlive(step.layer);
2768
2811
  }
2769
2812
  return this.renderResult;
2770
2813
  });
@@ -2780,7 +2823,8 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2780
2823
  if (keepPlan) {
2781
2824
  this._handleFocus(step.oldElement, step);
2782
2825
  this._handleScroll(step.oldElement, step);
2783
- return Promise.resolve();
2826
+ up.fragment.emitKept(keepPlan);
2827
+ break;
2784
2828
  }
2785
2829
  else {
2786
2830
  this._preserveDescendantKeepables(step);
@@ -2794,23 +2838,27 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2794
2838
  }, beforeDetach: () => {
2795
2839
  up.script.clean(step.oldElement, { layer: step.layer });
2796
2840
  }, afterDetach() {
2841
+ var _a;
2797
2842
  e.cleanJQuery();
2798
2843
  up.fragment.emitDestroyed(step.oldElement, { parent, log: false });
2844
+ (_a = step.afterDetach) === null || _a === void 0 ? void 0 : _a.call(step);
2799
2845
  }, scrollNew: () => {
2800
2846
  this._handleFocus(step.newElement, step);
2801
2847
  this._handleScroll(step.newElement, step);
2802
2848
  } });
2803
- return up.morph(step.oldElement, step.newElement, step.transition, morphOptions);
2849
+ this._delayFinish(up.morph(step.oldElement, step.newElement, step.transition, morphOptions));
2850
+ break;
2804
2851
  }
2805
2852
  }
2806
2853
  case 'content': {
2807
2854
  let oldWrapper = e.wrapChildren(step.oldElement);
2808
2855
  let newWrapper = e.wrapChildren(step.newElement);
2809
- let wrapperStep = Object.assign(Object.assign({}, step), { placement: 'swap', oldElement: oldWrapper, newElement: newWrapper, focus: false });
2810
- return this._executeStep(wrapperStep).then(() => {
2811
- e.unwrap(newWrapper);
2812
- this._handleFocus(step.oldElement, step);
2813
- });
2856
+ let wrapperStep = Object.assign(Object.assign({}, step), { placement: 'swap', oldElement: oldWrapper, newElement: newWrapper, focus: false, afterDetach: () => {
2857
+ e.unwrap(newWrapper);
2858
+ this._handleFocus(step.oldElement, step);
2859
+ } });
2860
+ this._executeStep(wrapperStep);
2861
+ break;
2814
2862
  }
2815
2863
  case 'before':
2816
2864
  case 'after': {
@@ -2820,7 +2868,8 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2820
2868
  this._welcomeElement(wrapper, step);
2821
2869
  this._handleFocus(wrapper, step);
2822
2870
  this._handleScroll(wrapper, step);
2823
- return up.animate(wrapper, step.animation, step).then(() => e.unwrap(wrapper));
2871
+ this._delayFinish(up.animate(wrapper, step.animation, step).then(() => e.unwrap(wrapper)));
2872
+ break;
2824
2873
  }
2825
2874
  default: {
2826
2875
  up.fail('Unknown placement: %o', step.placement);
@@ -2830,7 +2879,7 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2830
2879
  _welcomeElement(element, step) {
2831
2880
  this.responseDoc.finalizeElement(element);
2832
2881
  this.setReloadAttrs(step);
2833
- up.hello(element, step);
2882
+ this._delayFinish(up.hello(element, step));
2834
2883
  this._addToResult(element);
2835
2884
  }
2836
2885
  _preserveDescendantKeepables(step) {
@@ -2871,6 +2920,7 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2871
2920
  _finalizeDescendantKeepables(step) {
2872
2921
  for (let keepPlan of step.descendantKeepPlans) {
2873
2922
  keepPlan.oldElement.classList.remove('up-keeping');
2923
+ up.fragment.emitKept(keepPlan);
2874
2924
  }
2875
2925
  }
2876
2926
  _willChangeBody() {
@@ -2897,7 +2947,7 @@ up.Change.CloseLayer = class CloseLayer extends up.Change {
2897
2947
  var _a, _b;
2898
2948
  super(options);
2899
2949
  this._verb = options.verb;
2900
- this._layer = up.layer.get(options);
2950
+ this.layer = up.layer.get(options);
2901
2951
  this._origin = options.origin;
2902
2952
  this._value = options.value;
2903
2953
  this._preventable = (_a = options.preventable) !== null && _a !== void 0 ? _a : true;
@@ -2905,50 +2955,51 @@ up.Change.CloseLayer = class CloseLayer extends up.Change {
2905
2955
  this._history = (_b = options.history) !== null && _b !== void 0 ? _b : true;
2906
2956
  }
2907
2957
  execute() {
2908
- if (!this._layer.isOpen())
2909
- return;
2958
+ this.ensureLayerAlive();
2910
2959
  up.browser.assertConfirmed(this.options);
2911
2960
  if (this._emitCloseEvent().defaultPrevented && this._preventable) {
2912
2961
  throw new up.Aborted('Close event was prevented');
2913
2962
  }
2914
2963
  this._emitClosingEvent();
2915
- up.fragment.abort({ reason: 'Layer is closing', layer: this._layer });
2916
- const { parent } = this._layer;
2917
- this._layer.peel();
2918
- this._layer.stack.remove(this._layer);
2964
+ up.fragment.abort({ reason: 'Layer is closing', layer: this.layer });
2965
+ this.layer.state = 'closing';
2966
+ const { parent } = this.layer;
2967
+ this.layer.peel();
2968
+ this._handleFocus(parent);
2969
+ this.layer.teardownHandlers();
2970
+ this.layer.destroyElements(this.options);
2971
+ this.layer.stack.remove(this.layer);
2919
2972
  if (this._history) {
2920
2973
  parent.restoreHistory();
2921
2974
  }
2922
- this._handleFocus(parent);
2923
- this._layer.teardownHandlers();
2924
- this._layer.destroyElements(this.options);
2975
+ this.layer.state = 'closed';
2925
2976
  this._emitClosedEvent(parent);
2926
2977
  }
2927
2978
  _emitCloseEvent() {
2928
- let event = this._layer.emit(this._buildEvent(`up:layer:${this._verb}`), {
2929
- callback: this._layer.callback(`on${u.upperCaseFirst(this._verb)}`),
2930
- log: [`Will ${this._verb} ${this._layer} with value %o`, this._value]
2979
+ let event = this.layer.emit(this._buildEvent(`up:layer:${this._verb}`), {
2980
+ callback: this.layer.callback(`on${u.upperCaseFirst(this._verb)}`),
2981
+ log: [`Will ${this._verb} ${this.layer} with value %o`, this._value]
2931
2982
  });
2932
2983
  this._value = event.value;
2933
2984
  return event;
2934
2985
  }
2935
2986
  _emitClosingEvent() {
2936
2987
  let event = this._buildEvent(`up:layer:${this._verb}ing`);
2937
- this._layer.emit(event, { log: false });
2988
+ this.layer.emit(event, { log: false });
2938
2989
  }
2939
2990
  _emitClosedEvent(formerParent) {
2940
2991
  const verbPast = `${this._verb}ed`;
2941
2992
  const verbPastUpperCaseFirst = u.upperCaseFirst(verbPast);
2942
- return this._layer.emit(this._buildEvent(`up:layer:${verbPast}`), {
2993
+ return this.layer.emit(this._buildEvent(`up:layer:${verbPast}`), {
2943
2994
  baseLayer: formerParent,
2944
- callback: this._layer.callback(`on${verbPastUpperCaseFirst}`),
2995
+ callback: this.layer.callback(`on${verbPastUpperCaseFirst}`),
2945
2996
  ensureBubbles: true,
2946
- log: [`${verbPastUpperCaseFirst} ${this._layer} with value %o`, this._value]
2997
+ log: [`${verbPastUpperCaseFirst} ${this.layer} with value %o`, this._value]
2947
2998
  });
2948
2999
  }
2949
3000
  _buildEvent(name) {
2950
3001
  return up.event.build(name, {
2951
- layer: this._layer,
3002
+ layer: this.layer,
2952
3003
  value: this._value,
2953
3004
  origin: this._origin,
2954
3005
  response: this._response,
@@ -2956,11 +3007,11 @@ up.Change.CloseLayer = class CloseLayer extends up.Change {
2956
3007
  }
2957
3008
  _handleFocus(formerParent) {
2958
3009
  var _a;
2959
- let hadFocus = this._layer.hasFocus();
2960
- this._layer.overlayFocus.teardown();
3010
+ let hadFocus = this.layer.hasFocus();
3011
+ this.layer.overlayFocus.teardown();
2961
3012
  (_a = formerParent.overlayFocus) === null || _a === void 0 ? void 0 : _a.moveToFront();
2962
3013
  if (hadFocus) {
2963
- let newFocusElement = this._layer.origin || formerParent.element;
3014
+ let newFocusElement = this.layer.origin || formerParent.element;
2964
3015
  up.focus(newFocusElement, { preventScroll: true });
2965
3016
  }
2966
3017
  }
@@ -2984,7 +3035,7 @@ var _a;
2984
3035
  const u = up.util;
2985
3036
  up.Change.FromURL = (_a = class FromURL extends up.Change {
2986
3037
  execute() {
2987
- var _b, _c, _d, _e;
3038
+ var _b, _c;
2988
3039
  return __awaiter(this, void 0, void 0, function* () {
2989
3040
  let newPageReason = this._newPageReason();
2990
3041
  if (newPageReason) {
@@ -2992,11 +3043,12 @@ up.Change.FromURL = (_a = class FromURL extends up.Change {
2992
3043
  up.network.loadPage(this.options);
2993
3044
  return u.unresolvablePromise();
2994
3045
  }
2995
- let request = this.request = up.request(this._getRequestAttrs());
3046
+ let requestAttrs = this._getRequestAttrs();
3047
+ let request = this.request = up.request(requestAttrs);
2996
3048
  (_c = (_b = this.options).onRequestKnown) === null || _c === void 0 ? void 0 : _c.call(_b, request);
2997
3049
  if (this.options.preload)
2998
3050
  return request;
2999
- (_e = (_d = this.options).handleAbort) === null || _e === void 0 ? void 0 : _e.call(_d, request);
3051
+ this.options.handleAbort(Object.assign({ request }, requestAttrs));
3000
3052
  request.runPreviews(this.options);
3001
3053
  return yield u.always(request, (responseOrError) => this._onRequestSettled(responseOrError));
3002
3054
  });
@@ -3080,6 +3132,7 @@ up.Change.FromResponse = (_a = class FromResponse extends up.Change {
3080
3132
  }
3081
3133
  else {
3082
3134
  this._request.assertEmitted('up:fragment:loaded', Object.assign(Object.assign({}, this._loadedEventProps()), { callback: this.options.onLoaded, log: ['Loaded fragment from %s', this._response.description], skip: () => this._skip() }));
3135
+ this._assetRenderableResponse();
3083
3136
  }
3084
3137
  let fail = (_b = u.evalOption(this.options.fail, this._response)) !== null && _b !== void 0 ? _b : !this._response.ok;
3085
3138
  if (fail) {
@@ -3087,6 +3140,11 @@ up.Change.FromResponse = (_a = class FromResponse extends up.Change {
3087
3140
  }
3088
3141
  return this._updateContentFromResponse(this.options);
3089
3142
  }
3143
+ _assetRenderableResponse() {
3144
+ if (!up.fragment.config.renderableResponse(this._response)) {
3145
+ throw new up.CannotParse(['Cannot render response with content-type "%s" (configure with up.fragment.config.renderableResponse)', this._response.contentType]);
3146
+ }
3147
+ }
3090
3148
  _skip() {
3091
3149
  up.puts('up.render()', 'Skipping ' + this._response.description);
3092
3150
  this.options.target = ':none';
@@ -3223,7 +3281,7 @@ up.Change.FromContent = (_a = class FromContent extends up.Change {
3223
3281
  return plans;
3224
3282
  }
3225
3283
  _isRenderableLayer(layer) {
3226
- return (layer === 'new') || layer.isOpen();
3284
+ return (layer === 'new') || layer.isAlive();
3227
3285
  }
3228
3286
  _filterLayers() {
3229
3287
  this._layers = u.filter(this._layers, this._isRenderableLayer);
@@ -3253,7 +3311,6 @@ up.Change.FromContent = (_a = class FromContent extends up.Change {
3253
3311
  return !(error instanceof up.CannotMatch);
3254
3312
  }
3255
3313
  _onPlanApplicable(plan) {
3256
- var _b, _c;
3257
3314
  let primaryPlan = this._getPlans()[0];
3258
3315
  if (plan !== primaryPlan) {
3259
3316
  up.puts('up.render()', 'Could not match primary target "%s". Updating a fallback target "%s".', primaryPlan.target, plan.target);
@@ -3262,7 +3319,7 @@ up.Change.FromContent = (_a = class FromContent extends up.Change {
3262
3319
  if (assets) {
3263
3320
  up.script.assertAssetsOK(assets, plan.options);
3264
3321
  }
3265
- (_c = (_b = this.options).handleAbort) === null || _c === void 0 ? void 0 : _c.call(_b, null);
3322
+ this.options.handleAbort(this.getPreflightProps());
3266
3323
  }
3267
3324
  _getResponseDoc() {
3268
3325
  var _b, _c;
@@ -3359,8 +3416,17 @@ up.Change.FromContent = (_a = class FromContent extends up.Change {
3359
3416
 
3360
3417
  /***/ }),
3361
3418
  /* 35 */
3362
- /***/ (() => {
3419
+ /***/ (function() {
3363
3420
 
3421
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3422
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3423
+ return new (P || (P = Promise))(function (resolve, reject) {
3424
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
3425
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
3426
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
3427
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
3428
+ });
3429
+ };
3364
3430
  const u = up.util;
3365
3431
  up.CompilerPass = class CompilerPass {
3366
3432
  constructor(root, compilers, { layer, data, dataRoot, dataMap, meta }) {
@@ -3371,6 +3437,7 @@ up.CompilerPass = class CompilerPass {
3371
3437
  this._data = data;
3372
3438
  this._dataRoot = dataRoot || root;
3373
3439
  this._dataMap = dataMap;
3440
+ this._compilePromises = [];
3374
3441
  meta || (meta = {});
3375
3442
  meta.layer = layer;
3376
3443
  this._meta = meta;
@@ -3382,6 +3449,7 @@ up.CompilerPass = class CompilerPass {
3382
3449
  this._runCompiler(compiler);
3383
3450
  }
3384
3451
  });
3452
+ return Promise.all(this._compilePromises);
3385
3453
  }
3386
3454
  setCompileData() {
3387
3455
  if (this._data) {
@@ -3412,7 +3480,7 @@ up.CompilerPass = class CompilerPass {
3412
3480
  this._compileOneElement(compiler, match);
3413
3481
  }
3414
3482
  }
3415
- return (_b = (_a = up.migrate).postCompile) === null || _b === void 0 ? void 0 : _b.call(_a, matches, compiler);
3483
+ (_b = (_a = up.migrate).postCompile) === null || _b === void 0 ? void 0 : _b.call(_a, matches, compiler);
3416
3484
  }
3417
3485
  _compileOneElement(compiler, element) {
3418
3486
  const compileArgs = [element];
@@ -3420,8 +3488,8 @@ up.CompilerPass = class CompilerPass {
3420
3488
  const data = up.script.data(element);
3421
3489
  compileArgs.push(data, this._meta);
3422
3490
  }
3423
- const result = this._applyCompilerFunction(compiler, element, compileArgs);
3424
- up.destructor(element, result);
3491
+ let onDestructor = (destructor) => up.destructor(element, destructor);
3492
+ this._applyCompilerFunction(compiler, element, compileArgs, onDestructor);
3425
3493
  }
3426
3494
  _compileBatch(compiler, elements) {
3427
3495
  const compileArgs = [elements];
@@ -3429,26 +3497,40 @@ up.CompilerPass = class CompilerPass {
3429
3497
  const dataList = u.map(elements, up.script.data);
3430
3498
  compileArgs.push(dataList, this._meta);
3431
3499
  }
3432
- const result = this._applyCompilerFunction(compiler, elements, compileArgs);
3433
- if (result) {
3434
- up.fail('Compilers with { batch: true } cannot return destructors');
3435
- }
3500
+ let onDestructor = () => this._reportBatchCompilerWithDestructor(compiler);
3501
+ this._applyCompilerFunction(compiler, elements, compileArgs, onDestructor);
3436
3502
  }
3437
- _applyCompilerFunction(compiler, elementOrElements, compileArgs) {
3438
- return up.error.guard(() => compiler.apply(elementOrElements, compileArgs));
3503
+ _applyCompilerFunction(compiler, elementOrElements, compileArgs, onDestructor) {
3504
+ return __awaiter(this, void 0, void 0, function* () {
3505
+ let maybeDestructor = up.error.guard(() => compiler.apply(elementOrElements, compileArgs));
3506
+ if (u.isPromise(maybeDestructor)) {
3507
+ let guardedPromise = up.error.guardPromise(maybeDestructor);
3508
+ this._compilePromises.push(guardedPromise);
3509
+ maybeDestructor = yield guardedPromise;
3510
+ }
3511
+ if (maybeDestructor)
3512
+ onDestructor(maybeDestructor);
3513
+ });
3514
+ }
3515
+ _reportBatchCompilerWithDestructor(compiler) {
3516
+ let error = new up.Error(['Batch compiler (%s) cannot return a destructor', compiler.selector]);
3517
+ reportError(error);
3439
3518
  }
3440
3519
  _select(selector) {
3441
3520
  return up.fragment.subtree(this._root, u.evalOption(selector), { layer: this._layer });
3442
3521
  }
3443
3522
  _selectOnce(compiler) {
3444
3523
  let matches = this._select(compiler.selector);
3445
- return u.filter(matches, (element) => {
3446
- let appliedCompilers = (element.upAppliedCompilers || (element.upAppliedCompilers = new Set()));
3447
- if (!appliedCompilers.has(compiler)) {
3448
- appliedCompilers.add(compiler);
3449
- return true;
3450
- }
3451
- });
3524
+ if (!compiler.rerun) {
3525
+ matches = u.filter(matches, (element) => {
3526
+ let appliedCompilers = (element.upAppliedCompilers || (element.upAppliedCompilers = new Set()));
3527
+ if (!appliedCompilers.has(compiler)) {
3528
+ appliedCompilers.add(compiler);
3529
+ return true;
3530
+ }
3531
+ });
3532
+ }
3533
+ return matches;
3452
3534
  }
3453
3535
  };
3454
3536
 
@@ -3871,24 +3953,28 @@ up.EventListenerGroup = class EventListenerGroup extends up.Record {
3871
3953
  const u = up.util;
3872
3954
  up.SelectorTracker = class SelectorTracker {
3873
3955
  constructor(selector, options, addCallback) {
3874
- var _a;
3875
3956
  this._selector = selector;
3876
3957
  this._addCallback = addCallback;
3877
3958
  this._layer = options.layer || 'any';
3878
3959
  this._filter = options.filter || u.identity;
3879
- this._live = (_a = options.live) !== null && _a !== void 0 ? _a : true;
3880
3960
  this._knownMatches = new Map();
3961
+ this._syncScheduled = false;
3881
3962
  }
3882
3963
  start() {
3883
- this._sync();
3964
+ this._scheduleSync();
3884
3965
  return u.sequence(this._trackFragments(), () => this._removeAllMatches());
3885
3966
  }
3886
3967
  _trackFragments() {
3887
- if (this._live) {
3888
- return up.on('up:fragment:inserted up:fragment:destroyed', () => this._sync());
3968
+ return up.on('up:fragment:inserted up:fragment:destroyed', () => this._scheduleSync());
3969
+ }
3970
+ _scheduleSync() {
3971
+ if (!this._syncScheduled) {
3972
+ this._syncScheduled = true;
3973
+ up.fragment.afterMutate(() => this._sync());
3889
3974
  }
3890
3975
  }
3891
3976
  _sync() {
3977
+ this._syncScheduled = false;
3892
3978
  let removeMap = new Map(this._knownMatches);
3893
3979
  this._knownMatches.clear();
3894
3980
  for (let newMatch of this._currentMatches) {
@@ -3943,7 +4029,7 @@ up.FieldWatcher = class FieldWatcher {
3943
4029
  this._processedValues = this._readFieldValues();
3944
4030
  this._currentTimer = null;
3945
4031
  this._callbackRunning = false;
3946
- return u.sequence(up.form.trackFields(this._root, (field) => this._watchField(field)), this._trackAbort(), this._trackReset(), () => this._abort());
4032
+ return u.sequence(this._trackFields(), this._trackAbort(), this._trackReset(), () => this._abort());
3947
4033
  }
3948
4034
  _ensureWatchable() {
3949
4035
  const fail = (message) => up.fail(message, this._logPrefix, this._root);
@@ -3957,6 +4043,14 @@ up.FieldWatcher = class FieldWatcher {
3957
4043
  fail('%s can only watch fields with a name (%o)');
3958
4044
  }
3959
4045
  }
4046
+ _trackFields() {
4047
+ if (up.form.isField(this._root)) {
4048
+ return this._watchField(this._root);
4049
+ }
4050
+ else {
4051
+ return up.form.trackFields(this._root, (field) => this._watchField(field));
4052
+ }
4053
+ }
3960
4054
  _trackAbort() {
3961
4055
  let guard = ({ target }) => target.contains(this._region);
3962
4056
  return up.on('up:fragment:aborted', { guard }, () => this._abort());
@@ -4630,65 +4724,79 @@ up.FragmentFocus = class FragmentFocus extends up.FragmentProcessor {
4630
4724
  /***/ (() => {
4631
4725
 
4632
4726
  const e = up.element;
4727
+ const u = up.util;
4633
4728
  up.FragmentPolling = class FragmentPolling {
4729
+ static forFragment(fragment) {
4730
+ return fragment.upPolling || (fragment.upPolling = new this(fragment));
4731
+ }
4634
4732
  constructor(fragment) {
4635
4733
  this._options = up.radio.pollOptions(fragment);
4636
4734
  this._fragment = fragment;
4637
4735
  up.destructor(fragment, this._onFragmentDestroyed.bind(this));
4638
- up.fragment.onAborted(fragment, this._onFragmentAborted.bind(this));
4639
- this._state = 'initialized';
4640
- this._abortable = true;
4736
+ this._state = 'stopped';
4737
+ this._forceIntent = null;
4738
+ this._reloadJID = u.uid();
4641
4739
  this._loading = false;
4642
4740
  this._satisfyInterval();
4643
4741
  }
4644
- static forFragment(fragment) {
4645
- return fragment.upPolling || (fragment.upPolling = new this(fragment));
4646
- }
4647
4742
  onPollAttributeObserved() {
4648
4743
  this._start();
4649
4744
  }
4745
+ _onFragmentAborted({ newLayer, jid }) {
4746
+ const isOurAbort = (jid === this._reloadJID);
4747
+ if (isOurAbort || newLayer)
4748
+ return;
4749
+ this._stop();
4750
+ }
4751
+ _onFragmentKept() {
4752
+ if (this._forceIntent !== 'stop') {
4753
+ this._start();
4754
+ }
4755
+ }
4650
4756
  _onFragmentDestroyed() {
4651
4757
  this._stop();
4652
4758
  }
4653
4759
  _start(options) {
4654
4760
  Object.assign(this._options, options);
4655
- if (this._state !== 'started') {
4761
+ if (this._state === 'stopped') {
4656
4762
  if (!up.fragment.isTargetable(this._fragment)) {
4657
4763
  up.warn('[up-poll]', 'Cannot poll untargetable fragment %o', this._fragment);
4658
4764
  return;
4659
4765
  }
4660
4766
  this._state = 'started';
4661
- this._ensureEventsBound();
4767
+ this._bindEvents();
4662
4768
  this._scheduleRemainingTime();
4663
4769
  }
4664
4770
  }
4665
4771
  _stop() {
4666
- var _a;
4667
4772
  if (this._state === 'started') {
4668
4773
  this._clearReloadTimer();
4669
4774
  this._state = 'stopped';
4670
- (_a = this._unbindEvents) === null || _a === void 0 ? void 0 : _a.call(this);
4671
4775
  }
4672
4776
  }
4673
4777
  forceStart(options) {
4674
4778
  Object.assign(this._options, options);
4675
- this.forceStarted = true;
4779
+ this._forceIntent = 'start';
4676
4780
  this._start();
4677
4781
  }
4678
4782
  forceStop() {
4783
+ this._forceIntent = 'stop';
4679
4784
  this._stop();
4680
- this.forceStarted = false;
4681
4785
  }
4682
- _ensureEventsBound() {
4683
- if (!this._unbindEvents) {
4684
- this._unbindEvents = up.on('visibilitychange up:layer:opened up:layer:dismissed up:layer:accepted', this._onVisibilityChange.bind(this));
4685
- }
4786
+ _bindEvents() {
4787
+ if (this._eventsBound)
4788
+ return;
4789
+ this._eventsBound = true;
4790
+ up.destructor(this._fragment, up.on('visibilitychange up:layer:opened up:layer:dismissed up:layer:accepted', this._onVisibilityChange.bind(this)));
4791
+ up.fragment.onAborted(this._fragment, this._onFragmentAborted.bind(this));
4792
+ up.fragment.onKept(this._fragment, this._onFragmentKept.bind(this));
4686
4793
  }
4687
4794
  _onVisibilityChange() {
4688
4795
  if (this._isFragmentVisible()) {
4689
4796
  this._scheduleRemainingTime();
4690
4797
  }
4691
4798
  else {
4799
+ this._clearReloadTimer();
4692
4800
  }
4693
4801
  }
4694
4802
  _isFragmentVisible() {
@@ -4700,17 +4808,17 @@ up.FragmentPolling = class FragmentPolling {
4700
4808
  this._reloadTimer = null;
4701
4809
  }
4702
4810
  _scheduleRemainingTime() {
4703
- if (!this._reloadTimer && !this._loading) {
4704
- this._clearReloadTimer();
4705
- this._reloadTimer = setTimeout(this._onTimerReached.bind(this), this._getRemainingDelay());
4706
- }
4811
+ if (this._reloadTimer || this._loading || this._state === 'stopped')
4812
+ return;
4813
+ this._clearReloadTimer();
4814
+ this._reloadTimer = setTimeout(this._onTimerReached.bind(this), this._getRemainingDelay());
4707
4815
  }
4708
4816
  _onTimerReached() {
4709
4817
  this._reloadTimer = null;
4710
4818
  this._tryReload();
4711
4819
  }
4712
4820
  _tryReload() {
4713
- if (this._state !== 'started') {
4821
+ if (this._state === 'stopped') {
4714
4822
  return;
4715
4823
  }
4716
4824
  if (!up.fragment.isAlive(this._fragment)) {
@@ -4741,24 +4849,10 @@ up.FragmentPolling = class FragmentPolling {
4741
4849
  }
4742
4850
  _reloadNow() {
4743
4851
  this._clearReloadTimer();
4744
- let oldAbortable = this._abortable;
4745
- try {
4746
- this._abortable = false;
4747
- this._loading = true;
4748
- up.reload(this._fragment, this._reloadOptions()).then(this._onReloadSuccess.bind(this), this._onReloadFailure.bind(this));
4749
- }
4750
- finally {
4751
- this._abortable = oldAbortable;
4752
- }
4753
- }
4754
- _reloadOptions() {
4852
+ this._loading = true;
4755
4853
  let guardEvent = up.event.build('up:fragment:poll', { log: ['Polling fragment', this._fragment] });
4756
- return Object.assign(Object.assign({}, this._options), { guardEvent });
4757
- }
4758
- _onFragmentAborted({ newLayer }) {
4759
- if (this._abortable && !newLayer) {
4760
- this._stop();
4761
- }
4854
+ let reloadOptions = Object.assign(Object.assign({}, this._options), { guardEvent, jid: this._reloadJID });
4855
+ up.reload(this._fragment, reloadOptions).then(this._onReloadSuccess.bind(this), this._onReloadFailure.bind(this));
4762
4856
  }
4763
4857
  _onReloadSuccess({ fragment }) {
4764
4858
  this._loading = false;
@@ -4771,8 +4865,7 @@ up.FragmentPolling = class FragmentPolling {
4771
4865
  }
4772
4866
  }
4773
4867
  _onFragmentSwapped(newFragment) {
4774
- this._stop();
4775
- if (this.forceStarted && up.fragment.matches(this._fragment, newFragment)) {
4868
+ if (this._forceIntent === 'start' && up.fragment.matches(this._fragment, newFragment)) {
4776
4869
  this.constructor.forFragment(newFragment).forceStart(this._options);
4777
4870
  }
4778
4871
  }
@@ -4919,11 +5012,8 @@ up.Layer = class Layer extends up.Record {
4919
5012
  isOverlay() {
4920
5013
  return this.stack.isOverlay(this);
4921
5014
  }
4922
- isOpen() {
4923
- return this.stack.isOpen(this);
4924
- }
4925
- isClosed() {
4926
- return this.stack.isClosed(this);
5015
+ isAlive() {
5016
+ throw new up.NotImplemented();
4927
5017
  }
4928
5018
  get parent() {
4929
5019
  return this.stack.parentOf(this);
@@ -5097,7 +5187,7 @@ up.Layer = class Layer extends up.Record {
5097
5187
  if (newLocation !== liveLocation && this.showsLiveHistory() && push) {
5098
5188
  up.history.push(newLocation);
5099
5189
  }
5100
- if (newLocation !== prevSavedLocation && !this.opening) {
5190
+ if (newLocation !== prevSavedLocation && this.state !== 'opening') {
5101
5191
  this.emit('up:layer:location:changed', { location: newLocation, previousLocation: prevSavedLocation, log: false });
5102
5192
  }
5103
5193
  }
@@ -5156,11 +5246,11 @@ up.Layer.Overlay = (_a = class Overlay extends up.Layer {
5156
5246
  'dismissEvent',
5157
5247
  'acceptLocation',
5158
5248
  'dismissLocation',
5159
- 'opening'
5160
5249
  ];
5161
5250
  }
5162
5251
  constructor(options) {
5163
5252
  super(options);
5253
+ this.state = 'opening';
5164
5254
  if (this.dismissable === true) {
5165
5255
  this.dismissable = ['button', 'key', 'outside'];
5166
5256
  }
@@ -5352,7 +5442,6 @@ up.Layer.Overlay = (_a = class Overlay extends up.Layer {
5352
5442
  super.teardownHandlers();
5353
5443
  (_b = this._unbindParentClicked) === null || _b === void 0 ? void 0 : _b.call(this);
5354
5444
  (_c = this._unbindEscapePressed) === null || _c === void 0 ? void 0 : _c.call(this);
5355
- this.overlayFocus.teardown();
5356
5445
  }
5357
5446
  destroyElements(options) {
5358
5447
  const animation = () => this.startCloseAnimation(options);
@@ -5396,9 +5485,12 @@ up.Layer.Overlay = (_a = class Overlay extends up.Layer {
5396
5485
  boxAnimation,
5397
5486
  backdropAnimation,
5398
5487
  easing: options.easing || this.closeEasing,
5399
- duration: options.duration || this.closeDuration
5488
+ duration: options.duration || this.closeDuration,
5400
5489
  });
5401
5490
  }
5491
+ isAlive() {
5492
+ return ['opening', 'opened'].includes(this.state);
5493
+ }
5402
5494
  accept(value = null, options = {}) {
5403
5495
  return this._executeCloseChange('accept', value, options);
5404
5496
  }
@@ -5466,7 +5558,7 @@ up.Layer.OverlayWithTether = class OverlayWithTether extends up.Layer.Overlay {
5466
5558
  this._tether.stop();
5467
5559
  }
5468
5560
  sync() {
5469
- if (this.isOpen()) {
5561
+ if (this.isAlive()) {
5470
5562
  if (this.isDetached() || this._tether.isDetached()) {
5471
5563
  this.dismiss(':detached', {
5472
5564
  animation: false,
@@ -5503,7 +5595,7 @@ up.Layer.OverlayWithViewport = class OverlayWithViewport extends up.Layer.Overla
5503
5595
  up.viewport.bodyShifter.lowerStack();
5504
5596
  }
5505
5597
  sync() {
5506
- if (this.isDetached() && this.isOpen()) {
5598
+ if (this.isDetached() && this.isAlive()) {
5507
5599
  this.constructor.getParentElement().appendChild(this.element);
5508
5600
  }
5509
5601
  }
@@ -5539,6 +5631,9 @@ up.Layer.Root = (_a = class Root extends up.Layer {
5539
5631
  sync() {
5540
5632
  this.setupHandlers();
5541
5633
  }
5634
+ isAlive() {
5635
+ return true;
5636
+ }
5542
5637
  accept() {
5543
5638
  this._cannotCloseRoot();
5544
5639
  }
@@ -5741,12 +5836,6 @@ up.LayerStack = class LayerStack {
5741
5836
  this._currentOverrides = [];
5742
5837
  this.root.reset();
5743
5838
  }
5744
- isOpen(layer) {
5745
- return u.contains(this.layers, layer);
5746
- }
5747
- isClosed(layer) {
5748
- return !this.isOpen(layer);
5749
- }
5750
5839
  parentOf(layer) {
5751
5840
  return this.layers[layer.index - 1];
5752
5841
  }
@@ -6613,6 +6702,7 @@ up.RenderOptions = (function () {
6613
6702
  'fallback',
6614
6703
  'abort',
6615
6704
  'abortable',
6705
+ 'handleAbort',
6616
6706
  'confirm',
6617
6707
  'feedback',
6618
6708
  'disable',
@@ -7557,6 +7647,7 @@ up.Request.XHRRenderer = (_a = class XHRRenderer {
7557
7647
  /***/ (() => {
7558
7648
 
7559
7649
  const u = up.util;
7650
+ const HTML_CONTENT_TYPE = /^(text\/html|application\/xhtml\+xml) *(;|$)/i;
7560
7651
  up.Response = class Response extends up.Record {
7561
7652
  keys() {
7562
7653
  return [
@@ -7604,6 +7695,9 @@ up.Response = class Response extends up.Record {
7604
7695
  get contentType() {
7605
7696
  return this.header('Content-Type');
7606
7697
  }
7698
+ isHTML() {
7699
+ return HTML_CONTENT_TYPE.test(this.contentType);
7700
+ }
7607
7701
  get cspInfo() {
7608
7702
  let policy = this.header('Content-Security-Policy') || this.header('Content-Security-Policy-Report-Only');
7609
7703
  return up.protocol.cspInfoFromHeader(policy);
@@ -7655,7 +7749,6 @@ up.Response = class Response extends up.Record {
7655
7749
  var _a;
7656
7750
  const u = up.util;
7657
7751
  const e = up.element;
7658
- const FULL_DOCUMENT_PATTERN = /^\s*(<!--[^-]*.*?-->\s*)*<(html|!DOCTYPE)\b/i;
7659
7752
  up.ResponseDoc = (_a = class ResponseDoc {
7660
7753
  constructor({ document, fragment, content, target, origin, data, cspInfo, match }) {
7661
7754
  if (document) {
@@ -7682,7 +7775,7 @@ up.ResponseDoc = (_a = class ResponseDoc {
7682
7775
  this._isFullDocument = true;
7683
7776
  }
7684
7777
  else if (u.isString(value)) {
7685
- this._isFullDocument = FULL_DOCUMENT_PATTERN.test(value);
7778
+ this._isFullDocument = e.isFullDocumentHTML(value);
7686
7779
  let htmlParser = (html) => [e.createBrokenDocumentFromHTML(html)];
7687
7780
  let nodes = up.fragment.provideNodes(value, { origin, data, htmlParser });
7688
7781
  if (nodes[0] instanceof Document) {
@@ -7908,21 +8001,27 @@ up.RevealMotion = class RevealMotion {
7908
8001
  return up.Rect.fromElement(this._viewport);
7909
8002
  }
7910
8003
  }
7911
- _selectObstructions(selector) {
8004
+ _computeObstructionRects(selector) {
7912
8005
  let elements = up.fragment.all(selector, { layer: this._obstructionsLayer });
7913
- return u.filter(elements, e.isVisible);
8006
+ elements = u.filter(elements, e.isVisible);
8007
+ return u.map(elements, (element) => {
8008
+ if (e.style(element, 'position') === 'sticky') {
8009
+ return up.Rect.fromElementAsFixed(element);
8010
+ }
8011
+ else {
8012
+ return up.Rect.fromElement(element);
8013
+ }
8014
+ });
7914
8015
  }
7915
8016
  _substractObstructions(viewportRect) {
7916
- for (let obstruction of this._selectObstructions(this._topObstructionSelector)) {
7917
- let obstructionRect = up.Rect.fromElement(obstruction);
8017
+ for (let obstructionRect of this._computeObstructionRects(this._topObstructionSelector)) {
7918
8018
  let diff = obstructionRect.bottom - viewportRect.top;
7919
8019
  if (diff > 0) {
7920
8020
  viewportRect.top += diff;
7921
8021
  viewportRect.height -= diff;
7922
8022
  }
7923
8023
  }
7924
- for (let obstruction of this._selectObstructions(this._bottomObstructionSelector)) {
7925
- let obstructionRect = up.Rect.fromElement(obstruction);
8024
+ for (let obstructionRect of this._computeObstructionRects(this._bottomObstructionSelector)) {
7926
8025
  let diff = viewportRect.bottom - obstructionRect.top;
7927
8026
  if (diff > 0) {
7928
8027
  viewportRect.height -= diff;
@@ -8222,12 +8321,12 @@ up.framework = (function () {
8222
8321
  console.error("Unpoly cannot boot: %s", issue);
8223
8322
  }
8224
8323
  }
8225
- function mustBootManually() {
8226
- let unpolyScript = document.currentScript;
8227
- if (unpolyScript === null || unpolyScript === void 0 ? void 0 : unpolyScript.async) {
8324
+ function mustManualBoot() {
8325
+ var _a;
8326
+ if ((_a = document.currentScript) === null || _a === void 0 ? void 0 : _a.async) {
8228
8327
  return true;
8229
8328
  }
8230
- if ((unpolyScript === null || unpolyScript === void 0 ? void 0 : unpolyScript.getAttribute('up-boot')) === 'manual') {
8329
+ if (document.querySelector('[up-boot=manual]:is(html, script)')) {
8231
8330
  return true;
8232
8331
  }
8233
8332
  if (document.readyState === 'complete') {
@@ -8236,7 +8335,7 @@ up.framework = (function () {
8236
8335
  }
8237
8336
  function onEvaled() {
8238
8337
  up.emit('up:framework:evaled', { log: false });
8239
- if (mustBootManually()) {
8338
+ if (mustManualBoot()) {
8240
8339
  console.debug('Call up.boot() after you have configured Unpoly');
8241
8340
  }
8242
8341
  else {
@@ -8303,6 +8402,12 @@ up.event = (function () {
8303
8402
  function on(...args) {
8304
8403
  return buildListenerGroup(args).bind();
8305
8404
  }
8405
+ function onAncestor(fragment, eventType, callback) {
8406
+ let guard = (event) => event.target.contains(fragment);
8407
+ let unsubscribe = up.on(eventType, { guard }, callback);
8408
+ up.destructor(fragment, unsubscribe);
8409
+ return unsubscribe;
8410
+ }
8306
8411
  function off(...args) {
8307
8412
  return buildListenerGroup(args).unbind();
8308
8413
  }
@@ -8384,6 +8489,7 @@ up.event = (function () {
8384
8489
  on('up:framework:reset', reset);
8385
8490
  return {
8386
8491
  on,
8492
+ onAncestor,
8387
8493
  off,
8388
8494
  build,
8389
8495
  emit,
@@ -8624,8 +8730,17 @@ up.warn = up.log.warn;
8624
8730
 
8625
8731
  /***/ }),
8626
8732
  /* 87 */
8627
- /***/ (() => {
8733
+ /***/ (function() {
8628
8734
 
8735
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8736
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
8737
+ return new (P || (P = Promise))(function (resolve, reject) {
8738
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
8739
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
8740
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8741
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8742
+ });
8743
+ };
8629
8744
  up.script = (function () {
8630
8745
  const u = up.util;
8631
8746
  const e = up.element;
@@ -8729,6 +8844,7 @@ up.script = (function () {
8729
8844
  isDefault: up.framework.evaling,
8730
8845
  priority: 0,
8731
8846
  batch: false,
8847
+ rerun: false,
8732
8848
  });
8733
8849
  return Object.assign(callback, options, overrides);
8734
8850
  }
@@ -8755,14 +8871,21 @@ up.script = (function () {
8755
8871
  up.emit(fragment, 'up:fragment:compile', { log: false });
8756
8872
  let compilers = options.compilers || registeredMacros.concat(registeredCompilers);
8757
8873
  const pass = new up.CompilerPass(fragment, compilers, options);
8758
- pass.run();
8874
+ return pass.run();
8759
8875
  }
8760
- function registerDestructor(element, destructor) {
8761
- let fns = u.scanFunctions(destructor);
8876
+ function registerDestructor(element, value) {
8877
+ let fns = u.scanFunctions(value);
8762
8878
  if (!fns.length)
8763
8879
  return;
8764
- let registry = (element.upDestructors || (element.upDestructors = buildDestructorRegistry(element)));
8765
- registry.guard(fns);
8880
+ if (element.isConnected) {
8881
+ let registry = (element.upDestructors || (element.upDestructors = buildDestructorRegistry(element)));
8882
+ registry.guard(fns);
8883
+ }
8884
+ else {
8885
+ up.puts('up.destructor()', 'Immediately calling destructor for detached element (%o)', element);
8886
+ for (let fn of fns)
8887
+ up.error.guard(fn, element);
8888
+ }
8766
8889
  }
8767
8890
  function buildDestructorRegistry(element) {
8768
8891
  let registry = u.cleaner();
@@ -8770,11 +8893,16 @@ up.script = (function () {
8770
8893
  return registry;
8771
8894
  }
8772
8895
  function hello(element, options = {}) {
8773
- element = up.fragment.get(element, options);
8774
- up.puts('up.hello()', "Compiling fragment %o", element);
8775
- compile(element, options);
8776
- up.fragment.emitInserted(element);
8777
- return element;
8896
+ return __awaiter(this, void 0, void 0, function* () {
8897
+ element = up.fragment.get(element, options);
8898
+ up.puts('up.hello()', "Compiling fragment %o", element);
8899
+ yield up.fragment.mutate(() => __awaiter(this, void 0, void 0, function* () {
8900
+ let compilePromise = compile(element, options);
8901
+ up.fragment.emitInserted(element);
8902
+ yield compilePromise;
8903
+ }));
8904
+ return element;
8905
+ });
8778
8906
  }
8779
8907
  function clean(fragment, options = {}) {
8780
8908
  new up.DestructorPass(fragment, options).run();
@@ -8895,31 +9023,45 @@ up.history = (function () {
8895
9023
  let nextPreviousLocation;
8896
9024
  let nextTrackOptions;
8897
9025
  let adoptedBases = new up.FIFOCache({ capacity: 100, normalizeKey: getBase });
8898
- function isAdopted(location) {
8899
- return !!adoptedBases.get(location);
8900
- }
8901
9026
  function reset() {
8902
9027
  previousLocation = undefined;
8903
9028
  nextPreviousLocation = undefined;
8904
9029
  nextTrackOptions = undefined;
8905
9030
  adoptedBases.clear();
8906
9031
  trackCurrentLocation({ reason: null, alreadyHandled: true });
8907
- adopt();
9032
+ adoptBase();
8908
9033
  }
8909
9034
  function currentLocation() {
8910
9035
  return u.normalizeURL(location.href);
8911
9036
  }
9037
+ function withTrackOptions(trackOptions, fn) {
9038
+ try {
9039
+ nextTrackOptions = trackOptions;
9040
+ fn();
9041
+ }
9042
+ finally {
9043
+ nextTrackOptions = undefined;
9044
+ }
9045
+ }
8912
9046
  function trackCurrentLocation(trackOptions) {
8913
9047
  var _a, _b;
8914
- let { reason, alreadyHandled } = nextTrackOptions || trackOptions;
9048
+ let { reason, alreadyHandled, pauseTracking } = nextTrackOptions || trackOptions;
9049
+ if (pauseTracking)
9050
+ return;
8915
9051
  let location = currentLocation();
9052
+ if (isAdoptedState()) {
9053
+ adoptBase(location);
9054
+ }
9055
+ else if (isAdoptedBase(location)) {
9056
+ adoptState();
9057
+ }
8916
9058
  if (nextPreviousLocation !== location) {
8917
9059
  previousLocation = nextPreviousLocation;
8918
9060
  nextPreviousLocation = location;
8919
9061
  if (reason === 'detect') {
8920
9062
  reason = (getBase(location) === getBase(previousLocation)) ? 'hash' : 'pop';
8921
9063
  }
8922
- let willHandle = !alreadyHandled && isAdopted(location);
9064
+ let willHandle = !alreadyHandled && isAdoptedBase(location);
8923
9065
  let locationChangedEvent = up.event.build('up:location:changed', {
8924
9066
  reason,
8925
9067
  location,
@@ -8953,17 +9095,34 @@ up.history = (function () {
8953
9095
  placeAdoptedHistoryEntry('pushState', location, trackOptions);
8954
9096
  }
8955
9097
  function placeAdoptedHistoryEntry(method, location, trackOptions) {
8956
- adopt(location);
9098
+ adoptBase(location);
8957
9099
  if (config.enabled) {
8958
- nextTrackOptions = trackOptions;
8959
- history[method](null, '', location);
8960
- nextTrackOptions = undefined;
9100
+ withTrackOptions(trackOptions, function () {
9101
+ history[method](null, { up: true }, location);
9102
+ });
8961
9103
  }
8962
9104
  }
8963
- function adopt(location = currentLocation()) {
9105
+ function isAdoptedBase(location) {
9106
+ return !!adoptedBases.get(location);
9107
+ }
9108
+ function adoptBase(location = currentLocation()) {
8964
9109
  location = u.normalizeURL(location);
8965
9110
  adoptedBases.set(location, true);
8966
9111
  }
9112
+ function isAdoptedState() {
9113
+ var _a;
9114
+ return (_a = history.state) === null || _a === void 0 ? void 0 : _a.up;
9115
+ }
9116
+ function adoptState() {
9117
+ let { state } = history;
9118
+ if (isAdoptedState())
9119
+ return;
9120
+ if (u.isBlank(state) || u.isObject(state)) {
9121
+ withTrackOptions({ pauseTracking: true }, function () {
9122
+ history.replaceState(Object.assign(Object.assign({}, state), { up: true }), '');
9123
+ });
9124
+ }
9125
+ }
8967
9126
  function restoreLocation(location) {
8968
9127
  up.error.muteUncriticalRejection(up.render({
8969
9128
  guardEvent: up.event.build('up:location:restore', { location, log: `Restoring location ${location}` }),
@@ -9034,7 +9193,8 @@ up.history = (function () {
9034
9193
  }
9035
9194
  function adoptInitialHistoryEntry() {
9036
9195
  if (up.protocol.initialRequestMethod() === 'GET') {
9037
- adopt();
9196
+ adoptState();
9197
+ adoptBase();
9038
9198
  }
9039
9199
  }
9040
9200
  up.on('up:framework:boot', function ({ mode }) {
@@ -9172,6 +9332,7 @@ up.fragment = (function () {
9172
9332
  autoScroll: ['hash', 'layer-if-main'],
9173
9333
  autoRevalidate: (response) => response.expired,
9174
9334
  skipResponse: defaultSkipResponse,
9335
+ renderableResponse: (response) => response.isHTML(),
9175
9336
  normalizeKeepHTML: defaultNormalizeKeepHTML
9176
9337
  }));
9177
9338
  u.delegate(config, ['mainTargets'], () => up.layer.config.any);
@@ -9208,12 +9369,13 @@ up.fragment = (function () {
9208
9369
  const options = parseTargetAndOptions(args);
9209
9370
  return render(Object.assign(Object.assign({}, options), { navigate: true }));
9210
9371
  });
9211
- function emitFragmentKeep(keepPlan) {
9212
- let { oldElement, newElement: newFragment, newData, renderOptions } = keepPlan;
9372
+ function emitFragmentKeep({ oldElement, newElement: newFragment, newData, renderOptions }) {
9213
9373
  const log = ['Keeping fragment %o', oldElement];
9214
- const callback = e.callbackAttr(keepPlan.oldElement, 'up-on-keep', { exposedKeys: ['newFragment', 'newData'] });
9215
- const event = up.event.build('up:fragment:keep', { newFragment, newData, renderOptions });
9216
- return up.emit(oldElement, event, { log, callback });
9374
+ const callback = e.callbackAttr(oldElement, 'up-on-keep', { exposedKeys: ['newFragment', 'newData'] });
9375
+ return up.emit(oldElement, 'up:fragment:keep', { log, callback, newFragment, newData, renderOptions });
9376
+ }
9377
+ function emitFragmentKept({ oldElement, newElement: newFragment, newData }) {
9378
+ return up.emit(oldElement, 'up:fragment:kept', { log: true, newFragment, newData });
9217
9379
  }
9218
9380
  function findKeepPlan(options) {
9219
9381
  if (options.keep === false)
@@ -9307,12 +9469,7 @@ up.fragment = (function () {
9307
9469
  if (root) {
9308
9470
  return getFirstDescendant(root, selector, options);
9309
9471
  }
9310
- return new up.FragmentFinder({
9311
- selector,
9312
- origin: options.origin,
9313
- layer: options.layer,
9314
- match: options.match,
9315
- }).find();
9472
+ return new up.FragmentFinder(Object.assign({ selector }, u.pick(options, ['layer', 'match', 'origin', 'destroying']))).find();
9316
9473
  }
9317
9474
  function getFirstDescendant(...args) {
9318
9475
  let [root, selectorString, options] = parseGetArgs(args);
@@ -9350,8 +9507,9 @@ up.fragment = (function () {
9350
9507
  function destroy(...args) {
9351
9508
  var _a, _b;
9352
9509
  const options = parseTargetAndOptions(args);
9353
- if (options.element = getSmart(options.target, options)) {
9354
- new up.Change.DestroyFragment(options).execute();
9510
+ const element = getSmart(options.target, options);
9511
+ if (element) {
9512
+ new up.Change.DestroyFragment(Object.assign(Object.assign({}, options), { element })).execute();
9355
9513
  }
9356
9514
  return (_b = (_a = up.migrate).formerlyAsync) === null || _b === void 0 ? void 0 : _b.call(_a, 'up.destroy()');
9357
9515
  }
@@ -9536,7 +9694,7 @@ up.fragment = (function () {
9536
9694
  targets.unshift(...replaced);
9537
9695
  }
9538
9696
  else if (LAYER_PSEUDO.test(target)) {
9539
- if (layer === 'new' || layer.opening)
9697
+ if (layer === 'new' || layer.state === 'opening')
9540
9698
  continue;
9541
9699
  let firstSwappableTarget = toTarget(layer.getFirstSwappableElement(), options);
9542
9700
  targets.unshift(target.replace(LAYER_PSEUDO, firstSwappableTarget));
@@ -9647,7 +9805,7 @@ up.fragment = (function () {
9647
9805
  function abort(...args) {
9648
9806
  let options = parseTargetAndOptions(args);
9649
9807
  let testFn;
9650
- let { reason, newLayer } = options;
9808
+ let { reason, newLayer, jid } = options;
9651
9809
  let elements;
9652
9810
  if (options.target) {
9653
9811
  elements = getAll(options.target, options);
@@ -9663,14 +9821,14 @@ up.fragment = (function () {
9663
9821
  let testFnWithAbortable = (request) => request.abortable && testFn(request);
9664
9822
  up.network.abort(testFnWithAbortable, Object.assign(Object.assign({}, options), { reason }));
9665
9823
  for (let element of elements) {
9666
- up.emit(element, 'up:fragment:aborted', { reason, newLayer, log: false });
9824
+ up.emit(element, 'up:fragment:aborted', { reason, newLayer, jid, log: reason });
9667
9825
  }
9668
9826
  }
9669
9827
  function onAborted(fragment, callback) {
9670
- let guard = (event) => event.target.contains(fragment);
9671
- let unsubscribe = up.on('up:fragment:aborted', { guard }, callback);
9672
- up.destructor(fragment, unsubscribe);
9673
- return unsubscribe;
9828
+ return up.event.onAncestor(fragment, 'up:fragment:aborted', callback);
9829
+ }
9830
+ function onKept(fragment, callback) {
9831
+ return up.event.onAncestor(fragment, 'up:fragment:kept', callback);
9674
9832
  }
9675
9833
  function onFirstIntersect(element, callback, { margin = 0 } = {}) {
9676
9834
  if (e.isIntersectingWindow(element, { margin })) {
@@ -9744,6 +9902,26 @@ up.fragment = (function () {
9744
9902
  let tracker = new up.SelectorTracker(...parsedArgs);
9745
9903
  return tracker.start();
9746
9904
  }
9905
+ let mutateLevel = 0;
9906
+ let afterMutateCleaner = u.cleaner('fifo');
9907
+ function mutate(callback) {
9908
+ try {
9909
+ mutateLevel++;
9910
+ return callback();
9911
+ }
9912
+ finally {
9913
+ if (--mutateLevel === 0)
9914
+ afterMutateCleaner.clean();
9915
+ }
9916
+ }
9917
+ function afterMutate(callback) {
9918
+ if (mutateLevel === 0) {
9919
+ callback();
9920
+ }
9921
+ else {
9922
+ afterMutateCleaner(callback);
9923
+ }
9924
+ }
9747
9925
  up.on('up:framework:boot', function () {
9748
9926
  const { documentElement } = document;
9749
9927
  up.hello(documentElement);
@@ -9771,6 +9949,7 @@ up.fragment = (function () {
9771
9949
  emitInserted: emitFragmentInserted,
9772
9950
  emitDestroyed: emitFragmentDestroyed,
9773
9951
  emitKeep: emitFragmentKeep,
9952
+ emitKept: emitFragmentKept,
9774
9953
  keepPlan: findKeepPlan,
9775
9954
  defaultNormalizeKeepHTML,
9776
9955
  successKey,
@@ -9787,6 +9966,7 @@ up.fragment = (function () {
9787
9966
  shouldRevalidate,
9788
9967
  abort,
9789
9968
  onAborted,
9969
+ onKept,
9790
9970
  onFirstIntersect,
9791
9971
  splitTarget,
9792
9972
  parseTargetSteps,
@@ -9799,6 +9979,8 @@ up.fragment = (function () {
9799
9979
  provideNodes,
9800
9980
  cloneTemplate,
9801
9981
  trackSelector,
9982
+ mutate,
9983
+ afterMutate,
9802
9984
  };
9803
9985
  })();
9804
9986
  up.reload = up.fragment.reload;
@@ -9895,7 +10077,7 @@ up.viewport = (function () {
9895
10077
  return () => {
9896
10078
  let doReveal = () => reveal(match, { top: true, behavior });
9897
10079
  if (strong)
9898
- u.task(doReveal);
10080
+ u.fastTask(doReveal);
9899
10081
  return doReveal();
9900
10082
  };
9901
10083
  }
@@ -11079,6 +11261,7 @@ up.link = (function () {
11079
11261
  let childLink = e.get(area, childLinkSelector);
11080
11262
  if (childLink) {
11081
11263
  e.setMissingAttrs(area, Object.assign({ 'up-href': e.attr(childLink, 'href') }, e.upAttrs(childLink)));
11264
+ childLink.upExpandedPair = area.upExpandedPair = [area, childLink];
11082
11265
  e.addClasses(area, e.upClasses(childLink));
11083
11266
  makeFollowable(area);
11084
11267
  }
@@ -11177,6 +11360,7 @@ up.form = (function () {
11177
11360
  return up.render(submitOptions(form, options));
11178
11361
  });
11179
11362
  function submitOptions(form, options, parserOptions) {
11363
+ form = up.fragment.get(form);
11180
11364
  form = getForm(form);
11181
11365
  options = u.options(options);
11182
11366
  let parser = new up.OptionsParser(form, options, parserOptions);
@@ -11191,6 +11375,7 @@ up.form = (function () {
11191
11375
  options.origin || (options.origin = up.viewport.focusedElementWithin(form) || options.submitButton || form);
11192
11376
  options.activeElements = u.uniq([options.origin, options.submitButton, form].filter(u.isElement));
11193
11377
  parser.include(up.link.followOptions);
11378
+ Object.assign(options, submitButtonOverrides(options.submitButton));
11194
11379
  return options;
11195
11380
  }
11196
11381
  function watchOptions(field, options, parserOptions = {}) {
@@ -11280,14 +11465,22 @@ up.form = (function () {
11280
11465
  const parser = new up.OptionsParser(form, options, parserOptions);
11281
11466
  parser.string('contentType', { attr: 'enctype' });
11282
11467
  parser.json('headers');
11283
- const params = up.Params.fromForm(form);
11468
+ const paramParts = [
11469
+ up.Params.fromForm(form),
11470
+ e.jsonAttr(form, 'up-params'),
11471
+ ];
11472
+ const headerParts = [
11473
+ e.jsonAttr(form, 'up-headers'),
11474
+ ];
11284
11475
  const submitButton = ((_a = options.submitButton) !== null && _a !== void 0 ? _a : (options.submitButton = findSubmitButtons(form)[0]));
11285
11476
  if (submitButton) {
11286
- params.addField(submitButton);
11477
+ paramParts.push(up.Params.fromFields(submitButton), e.jsonAttr(submitButton, 'up-params'));
11478
+ headerParts.push(e.jsonAttr(submitButton, 'up-headers'));
11287
11479
  options.method || (options.method = submitButton.getAttribute('formmethod'));
11288
11480
  options.url || (options.url = submitButton.getAttribute('formaction'));
11289
11481
  }
11290
- options.params = up.Params.merge(params, options.params);
11482
+ options.params = up.Params.merge(...paramParts, options.params);
11483
+ options.headers = u.merge(...headerParts, options.headers);
11291
11484
  parser.string('url', { attr: 'action', default: up.fragment.source(form) });
11292
11485
  parser.string('method', {
11293
11486
  attr: ['up-method', 'data-method', 'method'],
@@ -11299,6 +11492,12 @@ up.form = (function () {
11299
11492
  }
11300
11493
  return options;
11301
11494
  }
11495
+ function submitButtonOverrides(submitButton) {
11496
+ if (!submitButton)
11497
+ return {};
11498
+ let followOptions = up.link.followOptions(submitButton, {}, { defaults: false });
11499
+ return u.omit(followOptions, ['method', 'url', 'guardEvent', 'origin', 'params', 'headers']);
11500
+ }
11302
11501
  function watch(...args) {
11303
11502
  let [root, options, callback] = u.args(args, 'val', 'options', 'callback');
11304
11503
  root = up.element.get(root);
@@ -11357,9 +11556,22 @@ up.form = (function () {
11357
11556
  }
11358
11557
  return options;
11359
11558
  }
11360
- function getForm(elementOrSelector, options = {}) {
11361
- const element = up.fragment.get(elementOrSelector, options);
11362
- return element.form || element.closest('form');
11559
+ function getForm(element) {
11560
+ return getLiteralForm(element) || getClosestForm(element) || getAssociatedForm(element);
11561
+ }
11562
+ function getLiteralForm(element) {
11563
+ if (element instanceof HTMLFormElement)
11564
+ return element;
11565
+ }
11566
+ function getClosestForm(element) {
11567
+ return element.closest('form');
11568
+ }
11569
+ function getAssociatedForm(element) {
11570
+ let formID = element.getAttribute('form');
11571
+ if (formID) {
11572
+ let selector = 'form' + e.idSelector(formID);
11573
+ return up.fragment.get(selector, { layer: element });
11574
+ }
11363
11575
  }
11364
11576
  function getFormValidator(form) {
11365
11577
  return form.upFormValidator || (form.upFormValidator = setupFormValidator(form));
@@ -11370,15 +11582,16 @@ up.form = (function () {
11370
11582
  up.destructor(form, stop);
11371
11583
  return validator;
11372
11584
  }
11373
- function getRegion(origin, options) {
11585
+ function getRegion(origin) {
11586
+ return getOriginRegion(origin) || up.layer.current.element;
11587
+ }
11588
+ function getOriginRegion(origin) {
11589
+ var _a;
11374
11590
  if (origin) {
11375
- return getForm(origin, options) || up.layer.get(origin).element;
11376
- }
11377
- else {
11378
- return up.layer.current.element;
11591
+ return getForm(origin) || ((_a = up.layer.get(origin)) === null || _a === void 0 ? void 0 : _a.element);
11379
11592
  }
11380
11593
  }
11381
- function trackFields(...args) {
11594
+ const trackFields = up.mockable(function (...args) {
11382
11595
  let [root, { guard }, callback] = u.args(args, 'val', 'options', 'callback');
11383
11596
  let filter = function (fields) {
11384
11597
  let region = getRegion(root);
@@ -11388,9 +11601,8 @@ up.form = (function () {
11388
11601
  && (!guard || guard(field));
11389
11602
  });
11390
11603
  };
11391
- const live = true;
11392
- return up.fragment.trackSelector(fieldSelector(), { filter, live }, callback);
11393
- }
11604
+ return up.fragment.trackSelector(fieldSelector(), { filter }, callback);
11605
+ });
11394
11606
  function focusedField() {
11395
11607
  return u.presence(document.activeElement, isField);
11396
11608
  }
@@ -11399,14 +11611,18 @@ up.form = (function () {
11399
11611
  return config.matches(form, 'submitSelectors');
11400
11612
  }
11401
11613
  up.on('submit', config.selectorFn('submitSelectors'), function (event, form) {
11614
+ const submitButton = u.presence(event.submitter, isSubmitButton);
11615
+ if ((submitButton === null || submitButton === void 0 ? void 0 : submitButton.getAttribute('up-submit')) === 'false')
11616
+ return;
11402
11617
  if (event.defaultPrevented)
11403
11618
  return;
11404
- const submitButton = u.presence(event.submitter, isSubmitButton);
11405
11619
  up.event.halt(event, { log: true });
11406
11620
  up.error.muteUncriticalRejection(submit(form, { submitButton }));
11407
11621
  });
11408
- up.compiler('form', function (form) {
11409
- getFormValidator(form);
11622
+ up.compiler('[up-validate]', { rerun: true }, function (element) {
11623
+ let form = getForm(element);
11624
+ if (form)
11625
+ getFormValidator(form);
11410
11626
  });
11411
11627
  up.compiler('[up-switch]', (switcher) => {
11412
11628
  return new up.Switcher(switcher).start();
@@ -11418,6 +11634,7 @@ up.form = (function () {
11418
11634
  submit,
11419
11635
  submitOptions,
11420
11636
  destinationOptions,
11637
+ submitButtonOverrides,
11421
11638
  watchOptions,
11422
11639
  validateOptions,
11423
11640
  isSubmittable,
@@ -11494,8 +11711,8 @@ up.status = (function () {
11494
11711
  function getMatchableLayerLocation(layer) {
11495
11712
  return u.matchableURL(layer.location);
11496
11713
  }
11497
- function findActivatableArea(element) {
11498
- return e.ancestor(element, SELECTOR_LINK) || element;
11714
+ function findActivatableAreas(element) {
11715
+ return element.upExpandedPair || [element];
11499
11716
  }
11500
11717
  function runPreviews(request, renderOptions) {
11501
11718
  let { bindLayer } = request;
@@ -11556,7 +11773,7 @@ up.status = (function () {
11556
11773
  }
11557
11774
  function getActiveElements({ origin, activeElements }) {
11558
11775
  activeElements || (activeElements = u.wrapList(origin));
11559
- return activeElements.map(findActivatableArea);
11776
+ return u.flatMap(activeElements, findActivatableAreas);
11560
11777
  }
11561
11778
  function getFeedbackClassesPreviewFn(feedbackOption, fragments) {
11562
11779
  if (!feedbackOption)