unpoly-rails 3.8.0 → 3.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,7 +5,7 @@
5
5
  /***/ (() => {
6
6
 
7
7
  window.up = {
8
- version: '3.8.0'
8
+ version: '3.9.0'
9
9
  };
10
10
 
11
11
 
@@ -51,11 +51,8 @@ up.util = (function () {
51
51
  }
52
52
  };
53
53
  }
54
- const NORMALIZE_URL_DEFAULTS = {
55
- host: 'cross-domain',
56
- };
57
54
  function normalizeURL(url, options) {
58
- options = newOptions(options, NORMALIZE_URL_DEFAULTS);
55
+ options = newOptions(options, { host: 'cross-domain' });
59
56
  const parts = parseURL(url);
60
57
  let normalized = '';
61
58
  if (options.host === 'cross-domain') {
@@ -77,8 +74,22 @@ up.util = (function () {
77
74
  }
78
75
  return normalized;
79
76
  }
80
- function matchURLs(leftURL, rightURL) {
81
- return normalizeURL(leftURL) === normalizeURL(rightURL);
77
+ function matchURLs(leftURL, rightURL, options) {
78
+ return matchableURL(leftURL, options) === matchableURL(rightURL, options);
79
+ }
80
+ function matchableURL(url, options) {
81
+ if (!url)
82
+ return;
83
+ return normalizeURL(url, { hash: false, trailingSlash: false, ...options });
84
+ }
85
+ function matchableURLPatternAtom(patternAtom) {
86
+ if (patternAtom.endsWith('/'))
87
+ return [patternAtom, patternAtom.slice(0, -1)];
88
+ if (patternAtom.includes('/?'))
89
+ return [patternAtom, patternAtom.replace('/?', '?')];
90
+ if (patternAtom.endsWith('/*'))
91
+ return [patternAtom, patternAtom.slice(0, -2), patternAtom.slice(0, -2) + '?*'];
92
+ return patternAtom;
82
93
  }
83
94
  const APP_PROTOCOL = location.protocol;
84
95
  const APP_HOSTNAME = location.hostname;
@@ -728,6 +739,8 @@ up.util = (function () {
728
739
  return {
729
740
  parseURL,
730
741
  normalizeURL,
742
+ matchableURL,
743
+ matchableURLPatternAtom,
731
744
  matchURLs,
732
745
  normalizeMethod,
733
746
  methodAllowsPayload,
@@ -1825,7 +1838,7 @@ up.BodyShifter = class BodyShifter {
1825
1838
  if (!this._isShifted())
1826
1839
  return;
1827
1840
  let originalValue = e.style(element, styleProp);
1828
- this._cleaners.push(e.setTemporaryStyle(e.root, { ['--up-original-' + styleProp]: originalValue }), e.addTemporaryClass(element, SHIFT_CLASS));
1841
+ this._cleaners.push(e.setTemporaryStyle(element, { ['--up-original-' + styleProp]: originalValue }), e.addTemporaryClass(element, SHIFT_CLASS));
1829
1842
  }
1830
1843
  _unshiftNow() {
1831
1844
  let cleaner;
@@ -1917,7 +1930,7 @@ up.Change.Addition = class Addition extends up.Change {
1917
1930
  source = (oldElement && up.fragment.source(oldElement));
1918
1931
  }
1919
1932
  if (source) {
1920
- e.setMissingAttr(newElement, 'up-source', u.normalizeURL(source, { hash: false }));
1933
+ e.setMissingAttr(newElement, 'up-source', up.fragment.normalizeSource(source));
1921
1934
  }
1922
1935
  }
1923
1936
  setTime({ newElement, time }) {
@@ -1948,7 +1961,7 @@ var _a;
1948
1961
  const u = up.util;
1949
1962
  up.RenderJob = (_a = class RenderJob {
1950
1963
  constructor(options) {
1951
- this.options = up.RenderOptions.preprocess(options);
1964
+ this.options = options;
1952
1965
  }
1953
1966
  execute() {
1954
1967
  this._rendered = this._executePromise();
@@ -1957,6 +1970,7 @@ up.RenderJob = (_a = class RenderJob {
1957
1970
  async _executePromise() {
1958
1971
  try {
1959
1972
  this._guardRender();
1973
+ this.options = up.RenderOptions.preprocess(this.options);
1960
1974
  let result = await this._getChange().execute();
1961
1975
  this._handleResult(result);
1962
1976
  return result;
@@ -2396,9 +2410,6 @@ up.Change.UpdateLayer = (_a = class UpdateLayer extends up.Change.Addition {
2396
2410
  step.scroll = false;
2397
2411
  step.focus = false;
2398
2412
  }
2399
- if ((step.placement === 'swap') || (step.placement === 'content')) {
2400
- step.scrollBehavior = 'instant';
2401
- }
2402
2413
  });
2403
2414
  }
2404
2415
  _hasHistory() {
@@ -2718,11 +2729,6 @@ up.Change.CloseLayer = class CloseLayer extends up.Change.Removal {
2718
2729
  var _a;
2719
2730
  const u = up.util;
2720
2731
  up.Change.FromURL = (_a = class FromURL extends up.Change {
2721
- constructor(options) {
2722
- super(options);
2723
- this.options.layer = up.layer.getAll(this.options);
2724
- this.options.normalizeLayerOptions = false;
2725
- }
2726
2732
  execute() {
2727
2733
  let _newPageReason = this._newPageReason();
2728
2734
  if (_newPageReason) {
@@ -2941,12 +2947,13 @@ const u = up.util;
2941
2947
  up.Change.FromContent = (_a = class FromContent extends up.Change {
2942
2948
  constructor(options) {
2943
2949
  super(options);
2944
- this._origin = this.options.origin;
2945
- this._preview = this.options.preview;
2950
+ this._origin = options.origin;
2951
+ this._preview = options.preview;
2952
+ this._layers = options.layers;
2946
2953
  }
2947
2954
  _getPlans() {
2948
2955
  let plans = [];
2949
- this._lookupLayers();
2956
+ this._filterLayers();
2950
2957
  this._improveOptionsFromResponseDoc();
2951
2958
  this._expandIntoPlans(plans, this._layers, this.options.target);
2952
2959
  this._expandIntoPlans(plans, this._layers, this.options.fallback);
@@ -2955,9 +2962,8 @@ up.Change.FromContent = (_a = class FromContent extends up.Change {
2955
2962
  _isRenderableLayer(layer) {
2956
2963
  return (layer === 'new') || layer.isOpen();
2957
2964
  }
2958
- _lookupLayers() {
2959
- this._allLayers = up.layer.getAll(this.options);
2960
- this._layers = u.filter(this._allLayers, this._isRenderableLayer);
2965
+ _filterLayers() {
2966
+ this._layers = u.filter(this._layers, this._isRenderableLayer);
2961
2967
  }
2962
2968
  _expandIntoPlans(plans, layers, targets) {
2963
2969
  for (let layer of layers) {
@@ -4238,12 +4244,6 @@ up.FragmentPolling = class FragmentPolling {
4238
4244
  up.puts('[up-poll]', 'Will not poll hidden fragment');
4239
4245
  return;
4240
4246
  }
4241
- if (up.emit(this._fragment, 'up:fragment:poll', { log: ['Polling fragment', this._fragment] }).defaultPrevented) {
4242
- up.puts('[up-poll]', 'User prevented up:fragment:poll event');
4243
- this._satisfyInterval();
4244
- this._scheduleRemainingTime();
4245
- return;
4246
- }
4247
4247
  this._reloadNow();
4248
4248
  }
4249
4249
  _getFullDelay() {
@@ -4261,21 +4261,20 @@ up.FragmentPolling = class FragmentPolling {
4261
4261
  }
4262
4262
  _reloadNow() {
4263
4263
  this._clearReloadTimer();
4264
- let reloadOptions = {
4265
- url: this._options.url,
4266
- fail: false,
4267
- background: true,
4268
- };
4269
4264
  let oldAbortable = this._abortable;
4270
4265
  try {
4271
4266
  this._abortable = false;
4272
4267
  this._loading = true;
4273
- up.reload(this._fragment, reloadOptions).then(this._onReloadSuccess.bind(this), this._onReloadFailure.bind(this));
4268
+ up.reload(this._fragment, this._reloadOptions()).then(this._onReloadSuccess.bind(this), this._onReloadFailure.bind(this));
4274
4269
  }
4275
4270
  finally {
4276
4271
  this._abortable = oldAbortable;
4277
4272
  }
4278
4273
  }
4274
+ _reloadOptions() {
4275
+ let guardEvent = up.event.build('up:fragment:poll', { log: ['Polling fragment', this._fragment] });
4276
+ return { ...this._options, guardEvent };
4277
+ }
4279
4278
  _onFragmentAborted({ newLayer }) {
4280
4279
  if (this._abortable && !newLayer) {
4281
4280
  this._stop();
@@ -4492,8 +4491,8 @@ up.Layer = class Layer extends up.Record {
4492
4491
  _containsEventTarget(event) {
4493
4492
  return this.contains(event.target);
4494
4493
  }
4495
- wasHitByMouseEvent(event) {
4496
- const hittableElement = document.elementFromPoint(event.clientX, event.clientY);
4494
+ wasHitByMouseEvent({ clientX, clientY }) {
4495
+ const hittableElement = document.elementFromPoint(clientX, clientY);
4497
4496
  return !hittableElement || this.contains(hittableElement);
4498
4497
  }
4499
4498
  _buildEventEmitter(args) {
@@ -4603,7 +4602,7 @@ up.Layer = class Layer extends up.Record {
4603
4602
  }
4604
4603
  set location(location) {
4605
4604
  const previousLocation = this.location;
4606
- location = up.history.normalizeURL(location);
4605
+ location = u.normalizeURL(location);
4607
4606
  if (previousLocation !== location || this.opening) {
4608
4607
  this.savedLocation = location;
4609
4608
  if (this.showsLiveHistory()) {
@@ -4801,7 +4800,7 @@ up.Layer.Overlay = class Overlay extends up.Layer {
4801
4800
  up.log.putsEvent(event);
4802
4801
  if (halt)
4803
4802
  up.event.halt(event);
4804
- this.dismiss(':outside', { origin: event.target });
4803
+ up.error.muteUncriticalSync(() => this.dismiss(':outside', { origin: event.target }));
4805
4804
  }
4806
4805
  onEscapePressed(event) {
4807
4806
  if (this.isFront()) {
@@ -4811,7 +4810,7 @@ up.Layer.Overlay = class Overlay extends up.Layer {
4811
4810
  }
4812
4811
  else if (this._supportsDismissMethod('key')) {
4813
4812
  up.event.halt(event, { log: true });
4814
- this.dismiss(':key');
4813
+ up.error.muteUncriticalSync(() => this.dismiss(':key'));
4815
4814
  }
4816
4815
  }
4817
4816
  }
@@ -4836,7 +4835,7 @@ up.Layer.Overlay = class Overlay extends up.Layer {
4836
4835
  }
4837
4836
  return this.on(eventTypes, event => {
4838
4837
  event.preventDefault();
4839
- closeFn.call(this, event, { response: event.response });
4838
+ up.error.muteUncriticalSync(() => closeFn.call(this, event, { response: event.response }));
4840
4839
  });
4841
4840
  }
4842
4841
  tryAcceptForLocation(options) {
@@ -4849,7 +4848,7 @@ up.Layer.Overlay = class Overlay extends up.Layer {
4849
4848
  let location, resolution;
4850
4849
  if (urlPattern && (location = this.location) && (resolution = urlPattern.recognize(location))) {
4851
4850
  const closeValue = { ...resolution, location };
4852
- closeFn.call(this, closeValue, options);
4851
+ up.error.muteUncriticalSync(() => closeFn.call(this, closeValue, options));
4853
4852
  }
4854
4853
  }
4855
4854
  teardownHandlers() {
@@ -5078,92 +5077,110 @@ up.Layer.Cover = (_a = class Cover extends up.Layer.OverlayWithViewport {
5078
5077
  /* 58 */
5079
5078
  /***/ (() => {
5080
5079
 
5080
+ var _a;
5081
5081
  const u = up.util;
5082
5082
  const e = up.element;
5083
- up.LayerLookup = class LayerLookup {
5084
- constructor(stack, ...args) {
5085
- this._stack = stack;
5086
- const options = u.parseArgIntoOptions(args, 'layer');
5087
- if (options.normalizeLayerOptions !== false) {
5088
- up.layer.normalizeOptions(options);
5089
- }
5090
- this._values = u.parseTokens(options.layer);
5091
- this._origin = options.origin;
5092
- this._baseLayer = options.baseLayer || this._originLayer() || this._stack.current;
5093
- if (u.isString(this._baseLayer)) {
5094
- const recursiveOptions = { ...options, baseLayer: this._stack.current, normalizeLayerOptions: false };
5095
- this._baseLayer = new this.constructor(this._stack, this._baseLayer, recursiveOptions).first();
5083
+ up.LayerLookup = (_a = class LayerLookup {
5084
+ constructor(stack, options) {
5085
+ this._stack = stack;
5086
+ if (options.normalizeLayerOptions !== false) {
5087
+ up.layer.normalizeOptions(options);
5088
+ }
5089
+ this._options = options;
5090
+ this._values = u.parseTokens(options.layer);
5096
5091
  }
5097
- }
5098
- _originLayer() {
5099
- if (this._origin) {
5100
- return this._forElement(this._origin);
5092
+ all() {
5093
+ let results = u.flatMap(this._values, value => this._resolveValue(value));
5094
+ results = u.compact(results);
5095
+ results = u.uniq(results);
5096
+ return results;
5101
5097
  }
5102
- }
5103
- first() {
5104
- return this.all()[0];
5105
- }
5106
- all() {
5107
- let results = u.flatMap(this._values, value => this._resolveValue(value));
5108
- results = u.compact(results);
5109
- results = u.uniq(results);
5110
- return results;
5111
- }
5112
- _forElement(element) {
5113
- element = e.get(element);
5114
- return u.find(this._stack.reversed(), layer => layer.contains(element));
5115
- }
5116
- _forIndex(value) {
5117
- return this._stack.at(value);
5118
- }
5119
- _resolveValue(value) {
5120
- if (value instanceof up.Layer) {
5121
- return value;
5098
+ static all(stack, ...args) {
5099
+ const options = u.parseArgIntoOptions(args, 'layer');
5100
+ const { layer } = options;
5101
+ if (layer instanceof up.Layer) {
5102
+ return [layer];
5103
+ }
5104
+ return new this(stack, options).all();
5122
5105
  }
5123
- if (u.isNumber(value)) {
5124
- return this._forIndex(value);
5106
+ _forElement(element) {
5107
+ element = e.get(element);
5108
+ return u.find(this._stack.reversed(), layer => layer.contains(element));
5125
5109
  }
5126
- if (/^\d+$/.test(value)) {
5127
- return this._forIndex(Number(value));
5110
+ _forIndex(value) {
5111
+ return this._stack.at(value);
5128
5112
  }
5129
- if (u.isElementish(value)) {
5130
- return this._forElement(value);
5113
+ _resolveValue(value) {
5114
+ if (value instanceof up.Layer) {
5115
+ return value;
5116
+ }
5117
+ if (u.isNumber(value)) {
5118
+ return this._forIndex(value);
5119
+ }
5120
+ if (/^\d+$/.test(value)) {
5121
+ return this._forIndex(Number(value));
5122
+ }
5123
+ if (u.isElementish(value)) {
5124
+ return this._forElement(value);
5125
+ }
5126
+ switch (value) {
5127
+ case 'any':
5128
+ return [this._getBaseLayer(), ...this._stack.reversed()];
5129
+ case 'current':
5130
+ return this._getBaseLayer();
5131
+ case 'closest':
5132
+ return this._stack.selfAndAncestorsOf(this._getBaseLayer());
5133
+ case 'parent':
5134
+ return this._getBaseLayer().parent;
5135
+ case 'ancestor':
5136
+ case 'ancestors':
5137
+ return this._getBaseLayer().ancestors;
5138
+ case 'child':
5139
+ return this._getBaseLayer().child;
5140
+ case 'descendant':
5141
+ case 'descendants':
5142
+ return this._getBaseLayer().descendants;
5143
+ case 'subtree':
5144
+ return this._getBaseLayer().subtree;
5145
+ case 'new':
5146
+ return 'new';
5147
+ case 'root':
5148
+ return this._stack.root;
5149
+ case 'overlay':
5150
+ case 'overlays':
5151
+ return u.reverse(this._stack.overlays);
5152
+ case 'front':
5153
+ return this._stack.front;
5154
+ case 'origin':
5155
+ return this._getOriginLayer();
5156
+ default:
5157
+ return up.fail("Unknown { layer } option: %o", value);
5158
+ }
5159
+ }
5160
+ _getOriginLayer() {
5161
+ let { origin } = this._options;
5162
+ if (origin) {
5163
+ return this._forElement(origin);
5164
+ }
5131
5165
  }
5132
- switch (value) {
5133
- case 'any':
5134
- return [this._baseLayer, ...this._stack.reversed()];
5135
- case 'current':
5136
- return this._baseLayer;
5137
- case 'closest':
5138
- return this._stack.selfAndAncestorsOf(this._baseLayer);
5139
- case 'parent':
5140
- return this._baseLayer.parent;
5141
- case 'ancestor':
5142
- case 'ancestors':
5143
- return this._baseLayer.ancestors;
5144
- case 'child':
5145
- return this._baseLayer.child;
5146
- case 'descendant':
5147
- case 'descendants':
5148
- return this._baseLayer.descendants;
5149
- case 'subtree':
5150
- return this._baseLayer.subtree;
5151
- case 'new':
5152
- return 'new';
5153
- case 'root':
5154
- return this._stack.root;
5155
- case 'overlay':
5156
- case 'overlays':
5157
- return u.reverse(this._stack.overlays);
5158
- case 'front':
5159
- return this._stack.front;
5160
- case 'origin':
5161
- return this._originLayer();
5162
- default:
5163
- return up.fail("Unknown { layer } option: %o", value);
5166
+ _getBaseLayer() {
5167
+ let { baseLayer } = this._options;
5168
+ if (u.isString(baseLayer)) {
5169
+ const recursiveOptions = { ...this._options, baseLayer: this._stack.current, normalizeLayerOptions: false, layer: baseLayer };
5170
+ return this.constructor.all(this._stack, recursiveOptions)[0];
5171
+ }
5172
+ else {
5173
+ return baseLayer || this._getOriginLayer() || this._stack.current;
5174
+ }
5164
5175
  }
5165
- }
5166
- };
5176
+ },
5177
+ (() => {
5178
+ u.memoizeMethod(_a.prototype, {
5179
+ _getBaseLayer: true,
5180
+ _getOriginLayer: true,
5181
+ });
5182
+ })(),
5183
+ _a);
5167
5184
 
5168
5185
 
5169
5186
  /***/ }),
@@ -5231,7 +5248,7 @@ up.LayerStack = class LayerStack {
5231
5248
  return this.getAll(...args)[0];
5232
5249
  }
5233
5250
  getAll(...args) {
5234
- return new up.LayerLookup(this, ...args).all();
5251
+ return up.LayerLookup.all(this, ...args);
5235
5252
  }
5236
5253
  sync() {
5237
5254
  for (let layer of this.layers) {
@@ -5284,22 +5301,22 @@ up.LayerStack = class LayerStack {
5284
5301
  /* 60 */
5285
5302
  /***/ (() => {
5286
5303
 
5304
+ const u = up.util;
5287
5305
  up.LinkFeedbackURLs = class LinkFeedbackURLs {
5288
5306
  constructor(link) {
5289
- const normalize = up.feedback.normalizeURL;
5290
5307
  this._isSafe = up.link.isSafe(link);
5291
5308
  if (this._isSafe) {
5292
5309
  const href = link.getAttribute('href');
5293
5310
  if (href && (href !== '#')) {
5294
- this.href = normalize(href);
5311
+ this._href = u.matchableURL(href);
5295
5312
  }
5296
5313
  const upHREF = link.getAttribute('up-href');
5297
5314
  if (upHREF) {
5298
- this._upHREF = normalize(upHREF);
5315
+ this._upHREF = u.matchableURL(upHREF);
5299
5316
  }
5300
5317
  const alias = link.getAttribute('up-alias');
5301
5318
  if (alias) {
5302
- this._aliasPattern = new up.URLPattern(alias, normalize);
5319
+ this._aliasPattern = new up.URLPattern(alias);
5303
5320
  }
5304
5321
  }
5305
5322
  }
@@ -5307,7 +5324,7 @@ up.LinkFeedbackURLs = class LinkFeedbackURLs {
5307
5324
  if (!normalizedLocation) {
5308
5325
  return false;
5309
5326
  }
5310
- return !!(this.href === normalizedLocation ||
5327
+ return !!(this._href === normalizedLocation ||
5311
5328
  this._upHREF === normalizedLocation ||
5312
5329
  this._aliasPattern?.test?.(normalizedLocation, false));
5313
5330
  }
@@ -5938,6 +5955,7 @@ up.RenderOptions = (function () {
5938
5955
  'source',
5939
5956
  'saveScroll',
5940
5957
  'navigate',
5958
+ 'baseLayer',
5941
5959
  ]);
5942
5960
  const CONTENT_KEYS = [
5943
5961
  'url',
@@ -5964,7 +5982,13 @@ up.RenderOptions = (function () {
5964
5982
  function preprocess(options) {
5965
5983
  up.migrate.preprocessRenderOptions?.(options);
5966
5984
  const defaults = u.merge(GLOBAL_DEFAULTS, navigateDefaults(options));
5967
- return u.merge(u.omit(defaults, LATE_KEYS), { defaults }, { inputDevice: up.event.inputDevice }, options, preloadOverrides(options));
5985
+ return u.merge(u.omit(defaults, LATE_KEYS), { defaults }, { inputDevice: up.event.inputDevice }, options, lookupLayers(options), preloadOverrides(options));
5986
+ }
5987
+ function lookupLayers(options) {
5988
+ return {
5989
+ layers: up.layer.getAll(options),
5990
+ normalizeLayerOptions: false,
5991
+ };
5968
5992
  }
5969
5993
  function finalize(preprocessedOptions, lateDefaults) {
5970
5994
  return u.merge(preprocessedOptions.defaults, lateDefaults, preprocessedOptions);
@@ -5991,18 +6015,22 @@ up.RenderOptions = (function () {
5991
6015
  return overrides;
5992
6016
  }
5993
6017
  function deriveFailOptions(preprocessedOptions) {
6018
+ let overrides = failOverrides(preprocessedOptions);
6019
+ let layers = lookupLayers(overrides);
5994
6020
  if (preprocessedOptions.failOptions) {
5995
6021
  return {
5996
6022
  ...preprocessedOptions.defaults,
5997
6023
  ...u.pick(preprocessedOptions, SHARED_KEYS),
5998
- ...failOverrides(preprocessedOptions),
6024
+ ...overrides,
6025
+ ...layers,
5999
6026
  ...{ failPrefixForced: true }
6000
6027
  };
6001
6028
  }
6002
6029
  else {
6003
6030
  return {
6004
6031
  ...preprocessedOptions,
6005
- ...failOverrides(preprocessedOptions),
6032
+ ...overrides,
6033
+ ...layers,
6006
6034
  };
6007
6035
  }
6008
6036
  }
@@ -7036,7 +7064,7 @@ up.RevealMotion = class RevealMotion {
7036
7064
  this._element = element;
7037
7065
  this._viewport = e.get(options.viewport) || up.viewport.get(this._element);
7038
7066
  this._obstructionsLayer = up.layer.get(this._viewport);
7039
- this._behavior = options.behavior ?? 'instant';
7067
+ this._behavior = options.scrollBehavior ?? options.behavior ?? 'instant';
7040
7068
  const viewportConfig = up.viewport.config;
7041
7069
  this._snap = options.snap ?? options.revealSnap ?? viewportConfig.revealSnap;
7042
7070
  this._padding = options.padding ?? options.revealPadding ?? viewportConfig.revealPadding;
@@ -7308,8 +7336,7 @@ up.Tether = class Tether {
7308
7336
 
7309
7337
  const u = up.util;
7310
7338
  up.URLPattern = class URLPattern {
7311
- constructor(fullPattern, normalizeURL = u.normalizeURL) {
7312
- this._normalizeURL = normalizeURL;
7339
+ constructor(fullPattern) {
7313
7340
  this._groups = [];
7314
7341
  const positiveList = [];
7315
7342
  const negativeList = [];
@@ -7328,14 +7355,8 @@ up.URLPattern = class URLPattern {
7328
7355
  if (!list.length) {
7329
7356
  return;
7330
7357
  }
7331
- list = list.map((url) => {
7332
- if (url[0] === '*') {
7333
- url = '/' + url;
7334
- }
7335
- url = this._normalizeURL(url);
7336
- url = u.escapeRegExp(url);
7337
- return url;
7338
- });
7358
+ list = u.flatMap(list, u.matchableURLPatternAtom);
7359
+ list = list.map(u.escapeRegExp);
7339
7360
  let reCode = list.join('|');
7340
7361
  reCode = reCode.replace(/\\\*/g, '.*?');
7341
7362
  reCode = reCode.replace(/(:|\\\$)([a-z][\w-]*)/ig, (match, type, name) => {
@@ -7356,13 +7377,13 @@ up.URLPattern = class URLPattern {
7356
7377
  }
7357
7378
  test(url, doNormalize = true) {
7358
7379
  if (doNormalize) {
7359
- url = this._normalizeURL(url);
7380
+ url = u.matchableURL(url);
7360
7381
  }
7361
7382
  return this._positiveRegexp.test(url) && !this._isExcluded(url);
7362
7383
  }
7363
7384
  recognize(url, doNormalize = true) {
7364
7385
  if (doNormalize) {
7365
- url = this._normalizeURL(url);
7386
+ url = u.matchableURL(url);
7366
7387
  }
7367
7388
  let match = this._positiveRegexp.exec(url);
7368
7389
  if (match && !this._isExcluded(url)) {
@@ -7497,9 +7518,8 @@ up.event = (function () {
7497
7518
  }
7498
7519
  function build(...args) {
7499
7520
  const props = u.extractOptions(args);
7500
- const type = args[0] || props.type || up.fail('Expected event type to be passed as string argument or { type } property');
7501
- const event = document.createEvent('Event');
7502
- event.initEvent(type, true, true);
7521
+ const type = args[0] || props.type || up.fail('Missing event type');
7522
+ const event = new Event(type, { bubbles: true, cancelable: true });
7503
7523
  Object.assign(event, u.omit(props, ['type', 'target']));
7504
7524
  return event;
7505
7525
  }
@@ -7524,8 +7544,11 @@ up.event = (function () {
7524
7544
  return (u.isUndefined(event.button) || (event.button === 0)) &&
7525
7545
  !u.some(keyModifiers, modifier => event[modifier]);
7526
7546
  }
7547
+ function isSyntheticClick(event) {
7548
+ return u.isMissing(event.clientX);
7549
+ }
7527
7550
  function fork(originalEvent, newType, copyKeys = []) {
7528
- const newEvent = up.event.build(newType, u.pick(originalEvent, copyKeys));
7551
+ const newEvent = build(newType, u.pick(originalEvent, copyKeys));
7529
7552
  newEvent.originalEvent = originalEvent;
7530
7553
  ['stopPropagation', 'stopImmediatePropagation', 'preventDefault'].forEach(function (key) {
7531
7554
  const originalMethod = newEvent[key];
@@ -7549,7 +7572,7 @@ up.event = (function () {
7549
7572
  Object.assign(forkedEvent, eventProps);
7550
7573
  up.emit(element, forkedEvent);
7551
7574
  }
7552
- on('up:click', 'a[up-emit]', executeEmitAttr);
7575
+ on('up:click', '[up-emit]', executeEmitAttr);
7553
7576
  let inputDevices = ['unknown'];
7554
7577
  function getInputDevice() {
7555
7578
  return u.last(inputDevices);
@@ -7570,6 +7593,7 @@ up.event = (function () {
7570
7593
  onEscape,
7571
7594
  halt,
7572
7595
  isUnmodified,
7596
+ isSyntheticClick,
7573
7597
  fork,
7574
7598
  keyModifiers,
7575
7599
  get inputDevice() { return getInputDevice(); }
@@ -7818,7 +7842,7 @@ up.script = (function () {
7818
7842
  }));
7819
7843
  const SYSTEM_MACRO_PRIORITIES = {
7820
7844
  '[up-back]': -100,
7821
- '[up-content]': -200,
7845
+ '[up-clickable]': -200,
7822
7846
  '[up-drawer]': -200,
7823
7847
  '[up-modal]': -200,
7824
7848
  '[up-cover]': -200,
@@ -8035,13 +8059,8 @@ up.history = (function () {
8035
8059
  nextPreviousLocation = undefined;
8036
8060
  trackCurrentLocation();
8037
8061
  }
8038
- const DEFAULT_NORMALIZE_OPTIONS = { hash: true };
8039
- function normalizeURL(url, options) {
8040
- options = u.merge(DEFAULT_NORMALIZE_OPTIONS, options);
8041
- return u.normalizeURL(url, options);
8042
- }
8043
- function currentLocation(normalizeOptions) {
8044
- return normalizeURL(location.href, normalizeOptions);
8062
+ function currentLocation() {
8063
+ return u.normalizeURL(location.href);
8045
8064
  }
8046
8065
  function trackCurrentLocation() {
8047
8066
  const url = currentLocation();
@@ -8051,19 +8070,17 @@ up.history = (function () {
8051
8070
  }
8052
8071
  }
8053
8072
  trackCurrentLocation();
8054
- const ADDITIONAL_NORMALIZE_OPTIONS_FOR_COMPARISON = { trailingSlash: false };
8055
8073
  function isLocation(url, options) {
8056
- options = u.merge(ADDITIONAL_NORMALIZE_OPTIONS_FOR_COMPARISON, options);
8057
- return normalizeURL(url, options) === currentLocation(options);
8074
+ return u.matchURLs(url, location.href, { hash: true, ...options });
8058
8075
  }
8059
8076
  function replace(location, options = {}) {
8060
- location = normalizeURL(location);
8077
+ location = u.normalizeURL(location);
8061
8078
  if (manipulate('replaceState', location) && (options.event !== false)) {
8062
8079
  emitLocationChanged({ location, reason: 'replace', log: `Replaced state for ${location}` });
8063
8080
  }
8064
8081
  }
8065
8082
  function push(location) {
8066
- location = normalizeURL(location);
8083
+ location = u.normalizeURL(location);
8067
8084
  if (!isLocation(location) && manipulate('pushState', location)) {
8068
8085
  emitLocationChanged({ location, reason: 'push', log: `Advanced to location ${location}` });
8069
8086
  }
@@ -8090,7 +8107,7 @@ up.history = (function () {
8090
8107
  return;
8091
8108
  }
8092
8109
  let location = currentLocation();
8093
- up.render({
8110
+ up.error.muteUncriticalRejection(up.render({
8094
8111
  guardEvent: up.event.build('up:location:restore', { location, log: `Restoring location ${location}` }),
8095
8112
  url: location,
8096
8113
  target: config.restoreTargets,
@@ -8105,7 +8122,7 @@ up.history = (function () {
8105
8122
  scroll: ['restore', 'auto'],
8106
8123
  saveFocus: false,
8107
8124
  focus: ['restore', 'auto'],
8108
- });
8125
+ }));
8109
8126
  }
8110
8127
  function onPop(event) {
8111
8128
  trackCurrentLocation();
@@ -8150,7 +8167,7 @@ up.history = (function () {
8150
8167
  function updateLang(newLang) {
8151
8168
  e.toggleAttr(e.root, 'lang', newLang, !!newLang);
8152
8169
  }
8153
- up.macro('a[up-back], [up-href][up-back]', function (link) {
8170
+ up.macro('[up-back]', function (link) {
8154
8171
  if (previousLocation) {
8155
8172
  e.setMissingAttrs(link, {
8156
8173
  'up-href': previousLocation,
@@ -8167,7 +8184,6 @@ up.history = (function () {
8167
8184
  replace,
8168
8185
  get location() { return currentLocation(); },
8169
8186
  get previousLocation() { return previousLocation; },
8170
- normalizeURL,
8171
8187
  isLocation,
8172
8188
  findMetaTags,
8173
8189
  updateMetaTags,
@@ -8242,6 +8258,9 @@ up.fragment = (function () {
8242
8258
  element = getSmart(element, options);
8243
8259
  return e.closestAttr(element, 'up-source');
8244
8260
  }
8261
+ function normalizeSource(source) {
8262
+ return u.normalizeURL(source, { hash: false });
8263
+ }
8245
8264
  function timeOf(element) {
8246
8265
  let value = e.closestAttr(element, 'up-time');
8247
8266
  if (value && value !== 'false') {
@@ -8676,7 +8695,7 @@ up.fragment = (function () {
8676
8695
  }
8677
8696
  up.on('up:framework:boot', function () {
8678
8697
  const { documentElement } = document;
8679
- documentElement.setAttribute('up-source', u.normalizeURL(location.href, { hash: false }));
8698
+ documentElement.setAttribute('up-source', normalizeSource(location.href));
8680
8699
  up.hello(documentElement);
8681
8700
  if (!up.browser.canPushState()) {
8682
8701
  return up.warn('Cannot push history changes. Next fragment update will load in a new page.');
@@ -8695,6 +8714,7 @@ up.fragment = (function () {
8695
8714
  contains,
8696
8715
  closest,
8697
8716
  source: sourceOf,
8717
+ normalizeSource,
8698
8718
  visit,
8699
8719
  markAsDestroying: markFragmentAsDestroying,
8700
8720
  emitInserted: emitFragmentInserted,
@@ -8911,7 +8931,7 @@ up.viewport = (function () {
8911
8931
  }
8912
8932
  }
8913
8933
  function newStateCache() {
8914
- return new up.FIFOCache({ capacity: 30, normalizeKey: up.history.normalizeURL });
8934
+ return new up.FIFOCache({ capacity: 30, normalizeKey: u.matchableURL });
8915
8935
  }
8916
8936
  function parseOptions(args) {
8917
8937
  const options = u.copy(u.extractOptions(args));
@@ -9571,7 +9591,9 @@ up.layer = (function () {
9571
9591
  return [config[mode], config.overlay, config.any];
9572
9592
  }
9573
9593
  }
9574
- function normalizeOptions(options) {
9594
+ function normalizeLayerOption(options) {
9595
+ if (options.layer instanceof up.Layer)
9596
+ return;
9575
9597
  up.migrate.handleLayerOptions?.(options);
9576
9598
  if (u.isGiven(options.layer)) {
9577
9599
  let match = String(options.layer).match(/^(new|shatter|swap)( (\w+))?/);
@@ -9590,25 +9612,29 @@ up.layer = (function () {
9590
9612
  }
9591
9613
  }
9592
9614
  }
9593
- else {
9594
- if (options.mode) {
9595
- options.layer = 'new';
9596
- }
9597
- else if (u.isElementish(options.target)) {
9598
- options.layer = stack.get(options.target, { normalizeLayerOptions: false });
9599
- }
9600
- else if (options.origin) {
9601
- options.layer = 'origin';
9602
- }
9603
- else {
9604
- options.layer = 'current';
9605
- }
9615
+ else if (options.mode) {
9616
+ options.layer = 'new';
9606
9617
  }
9607
- if (!options.context) {
9608
- options.context = {};
9618
+ else if (u.isElementish(options.target)) {
9619
+ options.layer = stack.get(options.target, { normalizeLayerOptions: false });
9620
+ }
9621
+ else if (options.origin) {
9622
+ options.layer = 'origin';
9623
+ }
9624
+ else {
9625
+ options.layer = 'current';
9609
9626
  }
9627
+ }
9628
+ function setBaseLayerOption(options) {
9629
+ if (options.baseLayer instanceof up.Layer)
9630
+ return;
9610
9631
  options.baseLayer = stack.get('current', { ...options, normalizeLayerOptions: false });
9611
9632
  }
9633
+ function normalizeOptions(options) {
9634
+ normalizeLayerOption(options);
9635
+ options.context ??= {};
9636
+ setBaseLayerOption(options);
9637
+ }
9612
9638
  function build(options, beforeNew) {
9613
9639
  const { mode } = options;
9614
9640
  const { Class } = config[mode];
@@ -9741,20 +9767,18 @@ up.link = (function () {
9741
9767
  const u = up.util;
9742
9768
  const e = up.element;
9743
9769
  let lastMousedownTarget = null;
9744
- const LINKS_WITH_LOCAL_HTML = ['a[up-content]', 'a[up-fragment]', 'a[up-document]'];
9745
- const LINKS_WITH_REMOTE_HTML = ['a[href]', '[up-href]'];
9746
- const ATTRIBUTES_SUGGESTING_FOLLOW = ['[up-follow]', '[up-target]', '[up-layer]', '[up-transition]', '[up-preload]', '[up-instant]', '[up-href]'];
9747
- function combineFollowableSelectors(elementSelectors, attributeSelectors) {
9748
- return u.flatMap(elementSelectors, elementSelector => attributeSelectors.map(attrSelector => elementSelector + attrSelector));
9749
- }
9770
+ const ATTRS_WITH_LOCAL_HTML = '[up-content], [up-fragment], [up-document]';
9771
+ const ATTRS_SUGGESTING_FOLLOW = `${ATTRS_WITH_LOCAL_HTML}, [up-target], [up-layer], [up-transition], [up-preload]`;
9772
+ const DEFAULT_INTERACTIVE_ELEMENT = 'a[href], button';
9750
9773
  const config = new up.Config(() => ({
9751
- followSelectors: combineFollowableSelectors(LINKS_WITH_REMOTE_HTML, ATTRIBUTES_SUGGESTING_FOLLOW).concat(LINKS_WITH_LOCAL_HTML),
9752
- noFollowSelectors: ['[up-follow=false]', 'a[download]', 'a[target]', 'a[href^="#"]:not([up-content]):not([up-fragment]):not([up-document])', 'a[href^="javascript:"]', 'a[href^="mailto:"]', e.crossOriginSelector('href'), e.crossOriginSelector('up-href')],
9774
+ followSelectors: ['[up-follow]', `a:is(${ATTRS_SUGGESTING_FOLLOW})`],
9775
+ noFollowSelectors: ['[up-follow=false]', 'a[download]', 'a[target]', 'a[href^="javascript:"]', 'a[href^="mailto:"]', `a[href^="#"]:not(${ATTRS_WITH_LOCAL_HTML})`, e.crossOriginSelector('href'), e.crossOriginSelector('up-href')],
9753
9776
  instantSelectors: ['[up-instant]'],
9754
9777
  noInstantSelectors: ['[up-instant=false]', '[onclick]'],
9755
- preloadSelectors: combineFollowableSelectors(LINKS_WITH_REMOTE_HTML, ['[up-preload]']),
9778
+ preloadSelectors: ['[up-preload]'],
9756
9779
  noPreloadSelectors: ['[up-preload=false]'],
9757
- clickableSelectors: LINKS_WITH_LOCAL_HTML.concat(['[up-emit]', '[up-accept]', '[up-dismiss]', '[up-clickable]']),
9780
+ clickableSelectors: ['[up-clickable]', '[up-follow]', '[up-emit]', '[up-accept]', '[up-dismiss]', ATTRS_SUGGESTING_FOLLOW],
9781
+ noClickableSelectors: ['[up-clickable=false]', DEFAULT_INTERACTIVE_ELEMENT],
9758
9782
  preloadDelay: 90,
9759
9783
  }));
9760
9784
  function isPreloadDisabled(link) {
@@ -9892,18 +9916,15 @@ up.link = (function () {
9892
9916
  link.setAttribute('up-follow', '');
9893
9917
  }
9894
9918
  }
9895
- function makeClickable(link) {
9896
- if (link.matches('a[href], button')) {
9897
- return;
9898
- }
9899
- let role = link.matches('a') ? 'link' : 'button';
9900
- e.setMissingAttrs(link, {
9919
+ function makeClickable(element) {
9920
+ let role = element.matches('a, [up-follow]') ? 'link' : 'button';
9921
+ e.setMissingAttrs(element, {
9901
9922
  tabindex: '0',
9902
9923
  role,
9903
9924
  'up-clickable': ''
9904
9925
  });
9905
- link.addEventListener('keydown', function (event) {
9906
- if ((event.key === 'Enter') || (event.key === 'Space')) {
9926
+ element.addEventListener('keydown', function (event) {
9927
+ if ((event.key === 'Enter') || (element.role === 'button' && event.key === 'Space')) {
9907
9928
  return forkEventAsUpClick(event);
9908
9929
  }
9909
9930
  });
@@ -9913,7 +9934,7 @@ up.link = (function () {
9913
9934
  if (event.defaultPrevented) {
9914
9935
  return false;
9915
9936
  }
9916
- const betterTargetSelector = `a, [up-href], ${up.form.fieldSelector()}`;
9937
+ const betterTargetSelector = `a, [up-follow], ${up.form.fieldSelector()}`;
9917
9938
  const betterTarget = event.target.closest(betterTargetSelector);
9918
9939
  return !betterTarget || (betterTarget === link);
9919
9940
  }
@@ -9932,7 +9953,7 @@ up.link = (function () {
9932
9953
  if (isInstant(element) && lastMousedownTarget) {
9933
9954
  up.event.halt(event);
9934
9955
  }
9935
- else if (layer.wasHitByMouseEvent(event) && !didUserDragAway(event)) {
9956
+ else if (up.event.inputDevice === 'key' || up.event.isSyntheticClick(event) || (layer.wasHitByMouseEvent(event) && !didUserDragAway(event))) {
9936
9957
  forkEventAsUpClick(event);
9937
9958
  }
9938
9959
  return lastMousedownTarget = null;
@@ -10024,6 +10045,7 @@ up.link = (function () {
10024
10045
  return {
10025
10046
  follow,
10026
10047
  followOptions,
10048
+ requestOptions: parseRequestOptions,
10027
10049
  preload,
10028
10050
  makeFollowable,
10029
10051
  isSafe,
@@ -10031,7 +10053,6 @@ up.link = (function () {
10031
10053
  shouldFollowEvent,
10032
10054
  convertClicks,
10033
10055
  config,
10034
- combineFollowableSelectors,
10035
10056
  loadDeferred,
10036
10057
  };
10037
10058
  })();
@@ -10055,11 +10076,10 @@ __webpack_require__.r(__webpack_exports__);
10055
10076
  up.form = (function () {
10056
10077
  const u = up.util;
10057
10078
  const e = up.element;
10058
- const ATTRIBUTES_SUGGESTING_SUBMIT = ['[up-submit]', '[up-target]', '[up-layer]', '[up-transition]'];
10059
10079
  const config = new up.Config(() => ({
10060
10080
  groupSelectors: ['[up-form-group]', 'fieldset', 'label', 'form'],
10061
10081
  fieldSelectors: ['select', 'input:not([type=submit]):not([type=image])', 'button[type]:not([type=submit])', 'textarea'],
10062
- submitSelectors: up.link.combineFollowableSelectors(['form'], ATTRIBUTES_SUGGESTING_SUBMIT),
10082
+ submitSelectors: ['form:is([up-submit], [up-target], [up-layer], [up-transition])'],
10063
10083
  noSubmitSelectors: ['[up-submit=false]', '[target]', e.crossOriginSelector('action')],
10064
10084
  submitButtonSelectors: ['input[type=submit]', 'input[type=image]', 'button[type=submit]', 'button:not([type])'],
10065
10085
  watchInputEvents: ['input', 'change'],
@@ -10086,15 +10106,8 @@ up.form = (function () {
10086
10106
  function findSubmitButtons(root) {
10087
10107
  return e.subtree(root, submitButtonSelector());
10088
10108
  }
10089
- function submittingButton(form) {
10090
- const selector = submitButtonSelector();
10091
- const focusedElement = document.activeElement;
10092
- if (focusedElement && focusedElement.form === form) {
10093
- if (focusedElement.matches(selector)) {
10094
- return focusedElement;
10095
- }
10096
- }
10097
- return e.get(form, selector);
10109
+ function isSubmitButton(element) {
10110
+ return element?.matches(submitButtonSelector());
10098
10111
  }
10099
10112
  function submitButtonSelector() {
10100
10113
  return config.selector('submitButtonSelectors');
@@ -10201,9 +10214,8 @@ up.form = (function () {
10201
10214
  parser.string('contentType', { attr: 'enctype' });
10202
10215
  parser.json('headers');
10203
10216
  const params = up.Params.fromForm(form);
10204
- const submitButton = submittingButton(form);
10217
+ const submitButton = (options.submitButton ??= findSubmitButtons(form)[0]);
10205
10218
  if (submitButton) {
10206
- options.submitButton = submitButton;
10207
10219
  params.addField(submitButton);
10208
10220
  options.method ||= submitButton.getAttribute('formmethod');
10209
10221
  options.url ||= submitButton.getAttribute('formaction');
@@ -10221,12 +10233,6 @@ up.form = (function () {
10221
10233
  }
10222
10234
  return options;
10223
10235
  }
10224
- up.on('up:click', submitButtonSelector, function (event, button) {
10225
- const form = getForm(button);
10226
- if (form && isSubmittable(form)) {
10227
- button.focus();
10228
- }
10229
- });
10230
10236
  function watch(root, ...args) {
10231
10237
  root = up.element.get(root);
10232
10238
  const callback = u.extractCallback(args) || watchCallbackFromElement(root) || up.fail('No callback given for up.watch()');
@@ -10378,8 +10384,9 @@ up.form = (function () {
10378
10384
  up.on('submit', config.selectorFn('submitSelectors'), function (event, form) {
10379
10385
  if (event.defaultPrevented)
10380
10386
  return;
10387
+ const submitButton = u.presence(event.submitter, isSubmitButton);
10381
10388
  up.event.halt(event, { log: true });
10382
- up.error.muteUncriticalRejection(submit(form));
10389
+ up.error.muteUncriticalRejection(submit(form, { submitButton }));
10383
10390
  });
10384
10391
  up.compiler(validatingFieldSelector, function (fieldOrForm) {
10385
10392
  let validator = up.FormValidator.forElement(fieldOrForm);
@@ -10450,17 +10457,12 @@ up.feedback = (function () {
10450
10457
  const CLASS_ACTIVE = 'up-active';
10451
10458
  const CLASS_LOADING = 'up-loading';
10452
10459
  const SELECTOR_LINK = 'a, [up-href]';
10453
- function normalizeURL(url) {
10454
- if (url) {
10455
- return u.normalizeURL(url, { trailingSlash: false, hash: false });
10456
- }
10457
- }
10458
10460
  function linkURLs(link) {
10459
10461
  return link.upFeedbackURLs ||= new up.LinkFeedbackURLs(link);
10460
10462
  }
10461
10463
  function updateFragment(fragment, { layer } = {}) {
10462
10464
  layer ||= up.layer.get(fragment);
10463
- let layerLocation = getNormalizedLayerLocation(layer);
10465
+ let layerLocation = getMatchableLayerLocation(layer);
10464
10466
  const navSelector = config.selector('navSelectors');
10465
10467
  const navLinkSelector = `${navSelector} :is(${SELECTOR_LINK}), ${navSelector}:is(${SELECTOR_LINK})`;
10466
10468
  const links = up.fragment.all(navLinkSelector, { layer });
@@ -10472,8 +10474,8 @@ up.feedback = (function () {
10472
10474
  e.toggleAttr(link, 'aria-current', 'page', isCurrent);
10473
10475
  }
10474
10476
  }
10475
- function getNormalizedLayerLocation(layer) {
10476
- return layer.feedbackLocation || normalizeURL(layer.location);
10477
+ function getMatchableLayerLocation(layer) {
10478
+ return layer.feedbackLocation || u.matchableURL(layer.location);
10477
10479
  }
10478
10480
  function findActivatableArea(element) {
10479
10481
  return e.ancestor(element, SELECTOR_LINK) || element;
@@ -10499,7 +10501,7 @@ up.feedback = (function () {
10499
10501
  }
10500
10502
  function updateLayerIfLocationChanged(layer) {
10501
10503
  const processedLocation = layer.feedbackLocation;
10502
- const layerLocation = getNormalizedLayerLocation(layer.location);
10504
+ const layerLocation = getMatchableLayerLocation(layer.location);
10503
10505
  if (!processedLocation || (processedLocation !== layerLocation)) {
10504
10506
  layer.feedbackLocation = layerLocation;
10505
10507
  updateFragment(layer.element, { layer });
@@ -10524,7 +10526,6 @@ up.feedback = (function () {
10524
10526
  return {
10525
10527
  config,
10526
10528
  showAroundRequest,
10527
- normalizeURL,
10528
10529
  };
10529
10530
  })();
10530
10531
 
@@ -10589,9 +10590,11 @@ up.radio = (function () {
10589
10590
  up.FragmentPolling.forFragment(element).forceStop();
10590
10591
  }
10591
10592
  function pollOptions(fragment, options = {}) {
10592
- const parser = new up.OptionsParser(fragment, options);
10593
+ const defaults = { background: true };
10594
+ const parser = new up.OptionsParser(fragment, options, { defaults });
10593
10595
  parser.number('interval', { default: config.pollInterval });
10594
10596
  parser.string('ifLayer', { default: 'front' });
10597
+ parser.include(up.link.requestOptions);
10595
10598
  return options;
10596
10599
  }
10597
10600
  up.attribute('up-poll', function (fragment) {