unpoly-rails 3.8.0.1 → 3.9.1

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.8.0'
8
+ version: '3.9.1'
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]', `a:is(${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) {