unpoly-rails 3.5.1 → 3.6.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.5.1'
8
+ version: '3.6.0'
9
9
  };
10
10
 
11
11
 
@@ -397,7 +397,8 @@ up.util = (function () {
397
397
  return value[value.length - 1];
398
398
  }
399
399
  function contains(value, subValue) {
400
- return value.indexOf(subValue) >= 0;
400
+ let indexOf = value.indexOf || Array.prototype.indexOf;
401
+ return indexOf.call(value, subValue) >= 0;
401
402
  }
402
403
  function objectContains(object, subObject) {
403
404
  const reducedValue = pick(object, Object.keys(subObject));
@@ -904,14 +905,7 @@ up.browser = (function () {
904
905
  function canJQuery() {
905
906
  return !!window.jQuery;
906
907
  }
907
- const canEval = u.memoize(function () {
908
- try {
909
- return new Function('return true')();
910
- }
911
- catch (_a) {
912
- return false;
913
- }
914
- });
908
+ const canHasSelector = u.memoize(() => CSS.supports('selector(:has(*))'));
915
909
  function popCookie(name) {
916
910
  var _a;
917
911
  let value = (_a = document.cookie.match(new RegExp(name + "=(\\w+)"))) === null || _a === void 0 ? void 0 : _a[1];
@@ -931,9 +925,9 @@ up.browser = (function () {
931
925
  submitForm,
932
926
  canPushState,
933
927
  canJQuery,
934
- canEval,
935
928
  assertConfirmed,
936
929
  popCookie,
930
+ canHasSelector,
937
931
  };
938
932
  })();
939
933
 
@@ -1211,12 +1205,8 @@ up.element = (function () {
1211
1205
  function createBrokenDocumentFromHTML(html) {
1212
1206
  return new DOMParser().parseFromString(html, 'text/html');
1213
1207
  }
1214
- function fixScriptish(scriptish) {
1215
- let clone = document.createElement(scriptish.tagName);
1216
- for (let { name, value } of scriptish.attributes) {
1217
- clone.setAttribute(name, value);
1218
- }
1219
- clone.textContent = scriptish.innerHTML;
1208
+ function fixParserDamage(scriptish) {
1209
+ let clone = createFromHTML(scriptish.outerHTML);
1220
1210
  scriptish.replaceWith(clone);
1221
1211
  }
1222
1212
  function createFromHTML(html) {
@@ -1458,16 +1448,12 @@ up.element = (function () {
1458
1448
  jQuery(element).remove();
1459
1449
  }
1460
1450
  }
1461
- function filteredQuery(parent, includeSelectors, excludeSelectors) {
1462
- let fullIncludeSelector = includeSelectors.join();
1463
- let fullExcludeSelector = excludeSelectors.join();
1464
- let elements = parent.querySelectorAll(fullIncludeSelector);
1465
- let isExcluded = (element) => element.matches(fullExcludeSelector);
1466
- return u.reject(elements, isExcluded);
1467
- }
1468
1451
  function isEmpty(element) {
1469
1452
  return !element.children.length > 0 && !element.innerText.trim();
1470
1453
  }
1454
+ function crossOriginSelector(attr) {
1455
+ return `[${attr}*="//"]:not([${attr}*="//${location.host}/"])`;
1456
+ }
1471
1457
  return {
1472
1458
  subtree,
1473
1459
  contains,
@@ -1491,7 +1477,7 @@ up.element = (function () {
1491
1477
  attrSelector,
1492
1478
  tagName: elementTagName,
1493
1479
  createBrokenDocumentFromHTML,
1494
- fixScriptish,
1480
+ fixParserDamage,
1495
1481
  createFromHTML,
1496
1482
  get root() { return getRoot(); },
1497
1483
  paint,
@@ -1522,8 +1508,8 @@ up.element = (function () {
1522
1508
  setTemporaryAttr,
1523
1509
  cleanJQuery,
1524
1510
  parseSelector,
1525
- filteredQuery,
1526
1511
  isEmpty,
1512
+ crossOriginSelector,
1527
1513
  };
1528
1514
  })();
1529
1515
 
@@ -1632,14 +1618,30 @@ up.Record = class Record {
1632
1618
  /* 17 */
1633
1619
  /***/ (() => {
1634
1620
 
1621
+ const u = up.util;
1635
1622
  up.Config = class Config {
1636
1623
  constructor(blueprintFn = (() => ({}))) {
1637
1624
  this._blueprintFn = blueprintFn;
1638
1625
  this.reset();
1626
+ document.addEventListener('up:framework:reset', () => this.reset());
1639
1627
  }
1640
1628
  reset() {
1641
1629
  Object.assign(this, this._blueprintFn());
1642
1630
  }
1631
+ matches(element, prop) {
1632
+ return element.matches(this.selector(prop));
1633
+ }
1634
+ selector(prop) {
1635
+ let includes = this[prop];
1636
+ let excludes = this['no' + u.upperCaseFirst(prop)];
1637
+ let selector = `:is(${includes.join()})`;
1638
+ if (u.isPresent(excludes))
1639
+ selector += `:not(${excludes.join()})`;
1640
+ return selector;
1641
+ }
1642
+ selectorFn(prop) {
1643
+ return () => this.selector(prop);
1644
+ }
1643
1645
  };
1644
1646
 
1645
1647
 
@@ -2257,6 +2259,7 @@ up.Change.OpenLayer = class OpenLayer extends up.Change.Addition {
2257
2259
  _renderOverlayContent() {
2258
2260
  this._handleHistory();
2259
2261
  this.handleLayerChangeRequests();
2262
+ this.responseDoc.commitElement(this._content);
2260
2263
  this.layer.setContent(this._content);
2261
2264
  this.setReloadAttrs({ newElement: this._content, source: this.options.source });
2262
2265
  this.responseDoc.finalizeElement(this._content);
@@ -2563,8 +2566,9 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2563
2566
  const morphOptions = Object.assign(Object.assign({}, step), { beforeStart() {
2564
2567
  up.fragment.markAsDestroying(step.oldElement);
2565
2568
  }, afterInsert: () => {
2566
- this.responseDoc.finalizeElement(step.newElement);
2567
2569
  this._restoreKeepables(step);
2570
+ this.responseDoc.finalizeElement(step.newElement);
2571
+ this._unmarkKeepables(step);
2568
2572
  up.hello(step.newElement, step);
2569
2573
  this._addToResult(step.newElement);
2570
2574
  }, beforeDetach: () => {
@@ -2643,6 +2647,8 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2643
2647
  if (keepPlan) {
2644
2648
  const keepableClone = keepable.cloneNode(true);
2645
2649
  keepable.insertAdjacentElement('beforebegin', keepableClone);
2650
+ keepable.classList.add('up-keeping');
2651
+ up.script.disableSubtree(keepPlan.newElement);
2646
2652
  let viewports = up.viewport.subtree(keepPlan.oldElement);
2647
2653
  keepPlan.revivers = viewports.map(function (viewport) {
2648
2654
  let cursorProps = up.viewport.copyCursorProps(viewport);
@@ -2668,6 +2674,11 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2668
2674
  }
2669
2675
  }
2670
2676
  }
2677
+ _unmarkKeepables(step) {
2678
+ for (let keepPlan of step.keepPlans) {
2679
+ keepPlan.oldElement.classList.remove('up-keeping');
2680
+ }
2681
+ }
2671
2682
  _willChangeElement(element) {
2672
2683
  return u.some(this._steps, (step) => step.oldElement.contains(element));
2673
2684
  }
@@ -3935,7 +3946,7 @@ up.FormValidator = class FormValidator {
3935
3946
  options.failOptions = false;
3936
3947
  options.params = up.Params.merge(options.params, ...u.map(dirtyRenderOptionsList, 'params'));
3937
3948
  options.headers = u.merge(...u.map(dirtyRenderOptionsList, 'headers'));
3938
- options.headers[up.protocol.headerize('validate')] = dirtyNames.join(' ') || ':unknown';
3949
+ this._addValidateHeader(options.headers, dirtyNames);
3939
3950
  options.guardEvent = up.event.build('up:form:validate', {
3940
3951
  fields: dirtyFields,
3941
3952
  log: 'Validating form',
@@ -3961,6 +3972,13 @@ up.FormValidator = class FormValidator {
3961
3972
  }
3962
3973
  });
3963
3974
  }
3975
+ _addValidateHeader(headers, names) {
3976
+ let key = up.protocol.headerize('validate');
3977
+ let value = names.join(' ');
3978
+ if (!value || value.length > up.protocol.config.maxHeaderSize)
3979
+ value = ':unknown';
3980
+ headers[key] = value;
3981
+ }
3964
3982
  _buildDataMap(solutions) {
3965
3983
  let dataMap = {};
3966
3984
  for (let solution of solutions) {
@@ -4102,7 +4120,7 @@ up.FragmentFinder = class FragmentFinder {
4102
4120
  }
4103
4121
  _findInRegion() {
4104
4122
  var _a;
4105
- if (this._match === 'region' && ((_a = this._origin) === null || _a === void 0 ? void 0 : _a.isConnected)) {
4123
+ if (this._match === 'region' && !up.fragment.containsMainPseudo(this._selector) && ((_a = this._origin) === null || _a === void 0 ? void 0 : _a.isConnected)) {
4106
4124
  return this._findClosest() || this._findDescendantInRegion();
4107
4125
  }
4108
4126
  }
@@ -5565,25 +5583,19 @@ up.NonceableCallback = class NonceableCallback {
5565
5583
  return new this(match[3], match[2]);
5566
5584
  }
5567
5585
  toFunction(...argNames) {
5568
- if (up.browser.canEval()) {
5569
- return new Function(...argNames, this.script);
5570
- }
5571
- else if (this.nonce) {
5586
+ if (this.nonce) {
5572
5587
  let callbackThis = this;
5573
5588
  return function (...args) {
5574
5589
  return callbackThis._runAsNoncedFunction(this, argNames, args);
5575
5590
  };
5576
5591
  }
5577
5592
  else {
5578
- return this._cannotRun.bind(this);
5593
+ return new Function(...argNames, this.script);
5579
5594
  }
5580
5595
  }
5581
5596
  toString() {
5582
5597
  return `nonce-${this.nonce} ${this.script}`;
5583
5598
  }
5584
- _cannotRun() {
5585
- throw new Error(`Your Content Security Policy disallows inline JavaScript (${this.script}). See https://unpoly.com/csp for solutions.`);
5586
- }
5587
5599
  _runAsNoncedFunction(thisArg, argNames, args) {
5588
5600
  let wrappedScript = `
5589
5601
  try {
@@ -6936,7 +6948,7 @@ up.Response = class Response extends up.Record {
6936
6948
  return this.header('Content-Type');
6937
6949
  }
6938
6950
  get cspNonces() {
6939
- return up.protocol.cspNoncesFromHeader(this.header('Content-Security-Policy'));
6951
+ return up.protocol.cspNoncesFromHeader(this.header('Content-Security-Policy') || this.header('Content-Security-Policy-Report-Only'));
6940
6952
  }
6941
6953
  get lastModified() {
6942
6954
  let header = this.header('Last-Modified');
@@ -6982,9 +6994,6 @@ up.ResponseDoc = (_a = class ResponseDoc {
6982
6994
  else {
6983
6995
  this._parseContent(content || '', target);
6984
6996
  }
6985
- if (!up.fragment.config.runScripts) {
6986
- this._document.querySelectorAll('script').forEach((e) => e.remove());
6987
- }
6988
6997
  this._cspNonces = cspNonces;
6989
6998
  if (origin) {
6990
6999
  let originSelector = up.fragment.tryToTarget(origin);
@@ -6996,7 +7005,7 @@ up.ResponseDoc = (_a = class ResponseDoc {
6996
7005
  }
6997
7006
  _parseDocument(document) {
6998
7007
  document = this._parse(document, e.createBrokenDocumentFromHTML);
6999
- this._scriptishNeedFix = true;
7008
+ this._isDocumentBroken = true;
7000
7009
  this._useParseResult(document);
7001
7010
  }
7002
7011
  _parseFragment(fragment) {
@@ -7073,12 +7082,7 @@ up.ResponseDoc = (_a = class ResponseDoc {
7073
7082
  });
7074
7083
  }
7075
7084
  commitSteps(steps) {
7076
- return steps.filter((step) => {
7077
- if (this._document.contains(step.newElement)) {
7078
- step.newElement.remove();
7079
- return true;
7080
- }
7081
- });
7085
+ return steps.filter((step) => this.commitElement(step.newElement));
7082
7086
  }
7083
7087
  _trySelectStep(step) {
7084
7088
  if (step.newElement) {
@@ -7105,10 +7109,20 @@ up.ResponseDoc = (_a = class ResponseDoc {
7105
7109
  throw new up.CannotMatch();
7106
7110
  }
7107
7111
  }
7112
+ commitElement(element) {
7113
+ if (this._document.contains(element)) {
7114
+ if (!up.fragment.config.runScripts) {
7115
+ up.script.disableSubtree(element);
7116
+ }
7117
+ element.remove();
7118
+ return true;
7119
+ }
7120
+ }
7108
7121
  finalizeElement(element) {
7109
7122
  up.NonceableCallback.adoptNonces(element, this._cspNonces);
7110
- if (this._scriptishNeedFix) {
7111
- element.querySelectorAll('noscript, script').forEach(e.fixScriptish);
7123
+ if (this._isDocumentBroken) {
7124
+ let brokenElements = e.subtree(element, ':is(noscript,script,audio,video):not(.up-keeping, .up-keeping *)');
7125
+ u.each(brokenElements, e.fixParserDamage);
7112
7126
  }
7113
7127
  }
7114
7128
  },
@@ -7138,8 +7152,8 @@ up.RevealMotion = class RevealMotion {
7138
7152
  this._padding = (_d = (_c = this._options.padding) !== null && _c !== void 0 ? _c : this._options.revealPadding) !== null && _d !== void 0 ? _d : viewportConfig.revealPadding;
7139
7153
  this._top = (_f = (_e = this._options.top) !== null && _e !== void 0 ? _e : this._options.revealTop) !== null && _f !== void 0 ? _f : viewportConfig.revealTop;
7140
7154
  this._max = (_h = (_g = this._options.max) !== null && _g !== void 0 ? _g : this._options.revealMax) !== null && _h !== void 0 ? _h : viewportConfig.revealMax;
7141
- this._topObstructions = viewportConfig.fixedTopSelectors;
7142
- this._bottomObstructions = viewportConfig.fixedBottomSelectors;
7155
+ this._topObstructionSelector = viewportConfig.selector('fixedTopSelectors');
7156
+ this._bottomObstructionSelector = viewportConfig.selector('fixedBottomSelectors');
7143
7157
  }
7144
7158
  start() {
7145
7159
  const viewportRect = this._getViewportRect(this._viewport);
@@ -7191,12 +7205,12 @@ up.RevealMotion = class RevealMotion {
7191
7205
  elementRect.top -= this._padding;
7192
7206
  elementRect.height += 2 * this._padding;
7193
7207
  }
7194
- _selectObstructions(selectors) {
7195
- let elements = up.fragment.all(selectors.join(), { layer: this._obstructionsLayer });
7208
+ _selectObstructions(selector) {
7209
+ let elements = up.fragment.all(selector, { layer: this._obstructionsLayer });
7196
7210
  return u.filter(elements, e.isVisible);
7197
7211
  }
7198
7212
  _substractObstructions(viewportRect) {
7199
- for (let obstruction of this._selectObstructions(this._topObstructions)) {
7213
+ for (let obstruction of this._selectObstructions(this._topObstructionSelector)) {
7200
7214
  let obstructionRect = up.Rect.fromElement(obstruction);
7201
7215
  let diff = obstructionRect.bottom - viewportRect.top;
7202
7216
  if (diff > 0) {
@@ -7204,7 +7218,7 @@ up.RevealMotion = class RevealMotion {
7204
7218
  viewportRect.height -= diff;
7205
7219
  }
7206
7220
  }
7207
- for (let obstruction of this._selectObstructions(this._bottomObstructions)) {
7221
+ for (let obstruction of this._selectObstructions(this._bottomObstructionSelector)) {
7208
7222
  let obstructionRect = up.Rect.fromElement(obstruction);
7209
7223
  let diff = viewportRect.bottom - obstructionRect.top;
7210
7224
  if (diff > 0) {
@@ -7243,10 +7257,12 @@ up.Selector = class Selector {
7243
7257
  }
7244
7258
  let expandedTargets = up.fragment.expandTargets(selector, Object.assign(Object.assign({}, options), { layer: expandTargetLayer }));
7245
7259
  this._selectors = expandedTargets.map((target) => {
7246
- target = target.replace(CSS_HAS_SUFFIX_PATTERN, (match, descendantSelector) => {
7247
- this._filters.push(element => element.querySelector(descendantSelector));
7248
- return '';
7249
- });
7260
+ if (!up.browser.canHasSelector()) {
7261
+ target = target.replace(CSS_HAS_SUFFIX_PATTERN, (match, descendantSelector) => {
7262
+ this._filters.push(element => element.querySelector(descendantSelector));
7263
+ return '';
7264
+ });
7265
+ }
7250
7266
  return target || '*';
7251
7267
  });
7252
7268
  this._unionSelector = this._selectors.join() || 'match-none';
@@ -7740,6 +7756,7 @@ up.protocol = (function () {
7740
7756
  csrfToken() { return e.metaContent('csrf-token'); },
7741
7757
  cspNonce() { return e.metaContent('csp-nonce'); },
7742
7758
  csrfHeader: 'X-CSRF-Token',
7759
+ maxHeaderSize: 2048,
7743
7760
  }));
7744
7761
  function csrfHeader() {
7745
7762
  return u.evalOption(config.csrfHeader);
@@ -7773,13 +7790,8 @@ up.protocol = (function () {
7773
7790
  params.add(config.methodParam, method);
7774
7791
  return 'POST';
7775
7792
  }
7776
- function reset() {
7777
- config.reset();
7778
- }
7779
- up.on('up:framework:reset', reset);
7780
7793
  return {
7781
7794
  config,
7782
- reset,
7783
7795
  locationFromXHR,
7784
7796
  titleFromXHR,
7785
7797
  targetFromXHR,
@@ -7810,9 +7822,6 @@ up.protocol = (function () {
7810
7822
  up.log = (function () {
7811
7823
  const u = up.util;
7812
7824
  const config = new up.LogConfig();
7813
- function reset() {
7814
- config.reset();
7815
- }
7816
7825
  function printToStandard(...args) {
7817
7826
  if (config.enabled) {
7818
7827
  printToStream('log', ...args);
@@ -7867,7 +7876,6 @@ up.log = (function () {
7867
7876
  }
7868
7877
  }
7869
7878
  up.on('up:framework:boot', printBanner);
7870
- up.on('up:framework:reset', reset);
7871
7879
  function enable() {
7872
7880
  config.enabled = true;
7873
7881
  }
@@ -7914,6 +7922,12 @@ up.script = (function () {
7914
7922
  'up-on-error',
7915
7923
  'up-on-offline',
7916
7924
  ],
7925
+ scriptSelectors: [
7926
+ 'script'
7927
+ ],
7928
+ noScriptSelectors: [
7929
+ 'script[type="application/ld+json"]'
7930
+ ]
7917
7931
  }));
7918
7932
  const SYSTEM_MACRO_PRIORITIES = {
7919
7933
  '[up-back]': -100,
@@ -8037,7 +8051,7 @@ up.script = (function () {
8037
8051
  return Object.assign(Object.assign(Object.assign({}, element.dataset), parsedJSON), element.upCompileData);
8038
8052
  }
8039
8053
  function findAssets(head = document.head) {
8040
- return e.filteredQuery(head, config.assetSelectors, config.noAssetSelectors);
8054
+ return head.querySelectorAll(config.selector('assetSelectors'));
8041
8055
  }
8042
8056
  function assertAssetsOK(newAssets, renderOptions) {
8043
8057
  let oldAssets = findAssets();
@@ -8047,10 +8061,16 @@ up.script = (function () {
8047
8061
  up.event.assertEmitted('up:assets:changed', { oldAssets, newAssets, renderOptions });
8048
8062
  }
8049
8063
  }
8064
+ function disableScript(scriptElement) {
8065
+ scriptElement.type = 'up-disabled-script';
8066
+ }
8067
+ function disableScriptsInSubtree(root) {
8068
+ let selector = config.selector('scriptSelectors');
8069
+ u.each(e.subtree(root, selector), disableScript);
8070
+ }
8050
8071
  function reset() {
8051
8072
  registeredCompilers = u.filter(registeredCompilers, 'isDefault');
8052
8073
  registeredMacros = u.filter(registeredMacros, 'isDefault');
8053
- config.reset();
8054
8074
  }
8055
8075
  up.on('up:framework:reset', reset);
8056
8076
  return {
@@ -8063,6 +8083,7 @@ up.script = (function () {
8063
8083
  data: readData,
8064
8084
  findAssets,
8065
8085
  assertAssetsOK,
8086
+ disableSubtree: disableScriptsInSubtree,
8066
8087
  };
8067
8088
  })();
8068
8089
  up.compiler = up.script.compiler;
@@ -8089,6 +8110,7 @@ up.history = (function () {
8089
8110
  'link[rel=canonical]',
8090
8111
  'link[rel=icon]',
8091
8112
  '[up-meta]',
8113
+ 'script[type="application/ld+json"]',
8092
8114
  ],
8093
8115
  noMetaTagSelectors: [
8094
8116
  'meta[http-equiv]',
@@ -8099,7 +8121,6 @@ up.history = (function () {
8099
8121
  let previousLocation;
8100
8122
  let nextPreviousLocation;
8101
8123
  function reset() {
8102
- config.reset();
8103
8124
  previousLocation = undefined;
8104
8125
  nextPreviousLocation = undefined;
8105
8126
  trackCurrentLocation();
@@ -8201,7 +8222,7 @@ up.history = (function () {
8201
8222
  }
8202
8223
  });
8203
8224
  function findMetaTags(head = document.head) {
8204
- return e.filteredQuery(head, config.metaTagSelectors, config.noMetaTagSelectors);
8225
+ return head.querySelectorAll(config.selector('metaTagSelectors'));
8205
8226
  }
8206
8227
  function updateMetaTags(newMetaTags) {
8207
8228
  let oldMetaTags = findMetaTags();
@@ -8295,9 +8316,6 @@ up.fragment = (function () {
8295
8316
  skipResponse: defaultSkipResponse
8296
8317
  }));
8297
8318
  u.delegate(config, ['mainTargets'], () => up.layer.config.any);
8298
- function reset() {
8299
- config.reset();
8300
- }
8301
8319
  function defaultSkipResponse({ response, expiredResponse }) {
8302
8320
  return !response.text || response.text === (expiredResponse === null || expiredResponse === void 0 ? void 0 : expiredResponse.text);
8303
8321
  }
@@ -8561,18 +8579,11 @@ up.fragment = (function () {
8561
8579
  let isGood = (klass) => !u.some(config.badTargetClasses, (badTargetClass) => matchesPattern(badTargetClass, klass));
8562
8580
  return u.filter(element.classList, isGood);
8563
8581
  }
8564
- function modernResolveOrigin(target, { origin } = {}) {
8565
- return target.replace(/:origin\b/, function (match) {
8566
- if (origin) {
8567
- return toTarget(origin);
8568
- }
8569
- else {
8570
- up.fail('Missing { origin } element to resolve "%s" reference (found in %s)', match, target);
8571
- }
8572
- });
8573
- }
8574
- function resolveOrigin(...args) {
8575
- return (up.migrate.resolveOrigin || modernResolveOrigin)(...args);
8582
+ const MAIN_PSEUDO = /:main\b/;
8583
+ const LAYER_PSEUDO = /:layer\b/;
8584
+ const ORIGIN_PSEUDO = /:origin\b/;
8585
+ function containsMainPseudo(target) {
8586
+ return MAIN_PSEUDO.test(target);
8576
8587
  }
8577
8588
  function expandTargets(targets, options = {}) {
8578
8589
  const { layer } = options;
@@ -8582,21 +8593,19 @@ up.fragment = (function () {
8582
8593
  targets = u.copy(u.wrapList(targets));
8583
8594
  const expanded = [];
8584
8595
  while (targets.length) {
8585
- const target = targets.shift();
8586
- if (target === ':main' || target === true) {
8587
- let mode;
8588
- if (layer === 'new') {
8589
- mode = options.mode || up.fail('Must pass a { mode } option together with { layer: "new" }');
8590
- }
8591
- else {
8592
- mode = layer.mode;
8593
- }
8594
- targets.unshift(...up.layer.mainTargets(mode));
8595
- }
8596
- else if (target === ':layer') {
8597
- if (layer !== 'new' && !layer.opening) {
8598
- targets.unshift(layer.getFirstSwappableElement());
8599
- }
8596
+ let target = targets.shift();
8597
+ if (target === true)
8598
+ target = ':main';
8599
+ if (containsMainPseudo(target)) {
8600
+ let mode = resolveMode(options);
8601
+ let replaced = up.layer.mainTargets(mode).map((mainTarget) => target.replace(MAIN_PSEUDO, mainTarget));
8602
+ targets.unshift(...replaced);
8603
+ }
8604
+ else if (LAYER_PSEUDO.test(target)) {
8605
+ if (layer === 'new' || layer.opening)
8606
+ continue;
8607
+ let firstSwappableTarget = toTarget(layer.getFirstSwappableElement(), options);
8608
+ targets.unshift(target.replace(LAYER_PSEUDO, firstSwappableTarget));
8600
8609
  }
8601
8610
  else if (u.isElementish(target)) {
8602
8611
  expanded.push(toTarget(target, options));
@@ -8604,11 +8613,30 @@ up.fragment = (function () {
8604
8613
  else if (u.isString(target)) {
8605
8614
  expanded.push(resolveOrigin(target, options));
8606
8615
  }
8607
- else {
8608
- }
8609
8616
  }
8610
8617
  return u.uniq(expanded);
8611
8618
  }
8619
+ function resolveMode({ layer, mode }) {
8620
+ if (layer === 'new') {
8621
+ return mode || up.fail('Must pass a { mode } option together with { layer: "new" }');
8622
+ }
8623
+ else {
8624
+ return layer.mode;
8625
+ }
8626
+ }
8627
+ function modernResolveOrigin(target, { origin } = {}) {
8628
+ return target.replace(ORIGIN_PSEUDO, function (match) {
8629
+ if (origin) {
8630
+ return toTarget(origin);
8631
+ }
8632
+ else {
8633
+ up.fail('Missing { origin } element to resolve "%s" reference (found in %s)', match, target);
8634
+ }
8635
+ });
8636
+ }
8637
+ function resolveOrigin(...args) {
8638
+ return (up.migrate.resolveOrigin || modernResolveOrigin)(...args);
8639
+ }
8612
8640
  function splitTarget(target) {
8613
8641
  return u.parseTokens(target, { separator: 'comma' });
8614
8642
  }
@@ -8715,7 +8743,6 @@ up.fragment = (function () {
8715
8743
  return up.warn('Cannot push history changes. Next fragment update will load in a new page.');
8716
8744
  }
8717
8745
  });
8718
- up.on('up:framework:reset', reset);
8719
8746
  return {
8720
8747
  config,
8721
8748
  reload,
@@ -8754,6 +8781,7 @@ up.fragment = (function () {
8754
8781
  isNotDestroying,
8755
8782
  targetForSteps,
8756
8783
  compressNestedSteps,
8784
+ containsMainPseudo,
8757
8785
  };
8758
8786
  })();
8759
8787
  up.reload = up.fragment.reload;
@@ -8790,13 +8818,7 @@ up.viewport = (function () {
8790
8818
  revealMax() { return 0.5 * window.innerHeight; },
8791
8819
  }));
8792
8820
  const bodyShifter = new up.BodyShifter();
8793
- function reset() {
8794
- config.reset();
8795
- }
8796
- function fullAnchoredRightSelector() {
8797
- return config.anchoredRightSelectors.join();
8798
- }
8799
- up.compiler(fullAnchoredRightSelector, function (element) {
8821
+ up.compiler(config.selectorFn('anchoredRightSelectors'), function (element) {
8800
8822
  return bodyShifter.onAnchoredElementInserted(element);
8801
8823
  });
8802
8824
  function reveal(element, options) {
@@ -9064,7 +9086,6 @@ up.viewport = (function () {
9064
9086
  });
9065
9087
  });
9066
9088
  up.on(window, 'hashchange', () => revealHash());
9067
- up.on('up:framework:reset', reset);
9068
9089
  return {
9069
9090
  reveal,
9070
9091
  revealHash,
@@ -9135,7 +9156,6 @@ up.motion = (function () {
9135
9156
  motionController.reset();
9136
9157
  namedAnimations = pickDefault(namedAnimations);
9137
9158
  namedTransitions = pickDefault(namedTransitions);
9138
- config.reset();
9139
9159
  }
9140
9160
  function isEnabled() {
9141
9161
  return config.enabled;
@@ -9412,7 +9432,6 @@ up.network = (function () {
9412
9432
  function reset() {
9413
9433
  abortRequests();
9414
9434
  queue.reset();
9415
- config.reset();
9416
9435
  cache.reset();
9417
9436
  progressBar === null || progressBar === void 0 ? void 0 : progressBar.destroy();
9418
9437
  progressBar = null;
@@ -9692,7 +9711,6 @@ up.layer = (function () {
9692
9711
  return e.callbackAttr(link, attr, { exposedKeys: ['layer', 'value', 'response'] });
9693
9712
  }
9694
9713
  function reset() {
9695
- config.reset();
9696
9714
  stack.reset();
9697
9715
  handlers = u.filter(handlers, 'isDefault');
9698
9716
  }
@@ -9725,7 +9743,7 @@ up.layer = (function () {
9725
9743
  }
9726
9744
  }
9727
9745
  function isWithinForeignOverlay(element) {
9728
- let selector = config.foreignOverlaySelectors.join();
9746
+ let selector = config.selector('foreignOverlaySelectors');
9729
9747
  return !!(selector && element.closest(selector));
9730
9748
  }
9731
9749
  up.on('up:fragment:destroyed', function () {
@@ -9807,7 +9825,7 @@ up.link = (function () {
9807
9825
  }
9808
9826
  const config = new up.Config(() => ({
9809
9827
  followSelectors: combineFollowableSelectors(LINKS_WITH_REMOTE_HTML, ATTRIBUTES_SUGGESTING_FOLLOW).concat(LINKS_WITH_LOCAL_HTML),
9810
- noFollowSelectors: ['[up-follow=false]', 'a[download]', 'a[target]', 'a[href^="#"]:not([up-content]):not([up-fragment]):not([up-document])', 'a[href^="javascript:"]'],
9828
+ 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')],
9811
9829
  instantSelectors: ['[up-instant]'],
9812
9830
  noInstantSelectors: ['[up-instant=false]', '[onclick]'],
9813
9831
  preloadSelectors: combineFollowableSelectors(LINKS_WITH_REMOTE_HTML, ['[up-preload]']),
@@ -9815,26 +9833,8 @@ up.link = (function () {
9815
9833
  clickableSelectors: LINKS_WITH_LOCAL_HTML.concat(['[up-emit]', '[up-accept]', '[up-dismiss]', '[up-clickable]']),
9816
9834
  preloadDelay: 90,
9817
9835
  }));
9818
- function fullFollowSelector() {
9819
- return config.followSelectors.join();
9820
- }
9821
- function fullPreloadSelector() {
9822
- return config.preloadSelectors.join();
9823
- }
9824
- function fullInstantSelector() {
9825
- return config.instantSelectors.join();
9826
- }
9827
- function fullClickableSelector() {
9828
- return config.clickableSelectors.join();
9829
- }
9830
- function isFollowDisabled(link) {
9831
- return link.matches(config.noFollowSelectors.join()) || u.isCrossOrigin(link);
9832
- }
9833
9836
  function isPreloadDisabled(link) {
9834
- return !up.browser.canPushState() ||
9835
- link.matches(config.noPreloadSelectors.join()) ||
9836
- isFollowDisabled(link) ||
9837
- !willCache(link);
9837
+ return !up.browser.canPushState() || !isFollowable(link) || !willCache(link);
9838
9838
  }
9839
9839
  function willCache(link) {
9840
9840
  const options = parseRequestOptions(link);
@@ -9847,12 +9847,8 @@ up.link = (function () {
9847
9847
  return request.willCache();
9848
9848
  }
9849
9849
  }
9850
- function isInstantDisabled(link) {
9851
- return link.matches(config.noInstantSelectors.join()) || isFollowDisabled(link);
9852
- }
9853
9850
  function reset() {
9854
9851
  lastMousedownTarget = null;
9855
- config.reset();
9856
9852
  linkPreloader.reset();
9857
9853
  }
9858
9854
  const follow = up.mockable(function (link, options) {
@@ -9962,7 +9958,7 @@ up.link = (function () {
9962
9958
  }
9963
9959
  function isFollowable(link) {
9964
9960
  link = up.fragment.get(link);
9965
- return link.matches(fullFollowSelector()) && !isFollowDisabled(link);
9961
+ return config.matches(link, 'followSelectors');
9966
9962
  }
9967
9963
  function makeFollowable(link) {
9968
9964
  if (!isFollowable(link)) {
@@ -9984,9 +9980,9 @@ up.link = (function () {
9984
9980
  }
9985
9981
  });
9986
9982
  }
9987
- up.macro(fullClickableSelector, makeClickable);
9983
+ up.macro(config.selectorFn('clickableSelectors'), makeClickable);
9988
9984
  function shouldFollowEvent(event, link) {
9989
- if (event.defaultPrevented || isFollowDisabled(link)) {
9985
+ if (event.defaultPrevented) {
9990
9986
  return false;
9991
9987
  }
9992
9988
  const betterTargetSelector = `a, [up-href], ${up.form.fieldSelector()}`;
@@ -9994,9 +9990,12 @@ up.link = (function () {
9994
9990
  return !betterTarget || (betterTarget === link);
9995
9991
  }
9996
9992
  function isInstant(linkOrDescendant) {
9997
- const element = linkOrDescendant.closest(fullInstantSelector());
9993
+ const element = linkOrDescendant.closest(config.selector('instantSelectors'));
9998
9994
  return element && !isInstantDisabled(element);
9999
9995
  }
9996
+ function isInstantDisabled(link) {
9997
+ return config.matches(link, 'noInstantSelectors') || config.matches(link, 'noFollowSelectors');
9998
+ }
10000
9999
  function convertClicks(layer) {
10001
10000
  layer.on('click', function (event, element) {
10002
10001
  if (!up.event.isUnmodified(event)) {
@@ -10032,7 +10031,7 @@ up.link = (function () {
10032
10031
  const method = followMethod(link);
10033
10032
  return up.network.isSafeMethod(method);
10034
10033
  }
10035
- up.on('up:click', fullFollowSelector, function (event, link) {
10034
+ up.on('up:click', config.selectorFn('followSelectors'), function (event, link) {
10036
10035
  if (shouldFollowEvent(event, link)) {
10037
10036
  up.event.halt(event, { log: true });
10038
10037
  up.focus(link, { preventScroll: true });
@@ -10051,7 +10050,7 @@ up.link = (function () {
10051
10050
  makeFollowable(area);
10052
10051
  }
10053
10052
  });
10054
- up.compiler(fullPreloadSelector, function (link) {
10053
+ up.compiler(config.selectorFn('preloadSelectors'), function (link) {
10055
10054
  if (!isPreloadDisabled(link)) {
10056
10055
  linkPreloader.watchLink(link);
10057
10056
  }
@@ -10070,8 +10069,6 @@ up.link = (function () {
10070
10069
  convertClicks,
10071
10070
  config,
10072
10071
  combineFollowableSelectors,
10073
- preloadSelector: fullPreloadSelector,
10074
- followSelector: fullFollowSelector,
10075
10072
  preloadIssue,
10076
10073
  };
10077
10074
  })();
@@ -10096,18 +10093,12 @@ up.form = (function () {
10096
10093
  groupSelectors: ['[up-form-group]', 'fieldset', 'label', 'form'],
10097
10094
  fieldSelectors: ['select', 'input:not([type=submit]):not([type=image])', 'button[type]:not([type=submit])', 'textarea'],
10098
10095
  submitSelectors: up.link.combineFollowableSelectors(['form'], ATTRIBUTES_SUGGESTING_SUBMIT),
10099
- noSubmitSelectors: ['[up-submit=false]', '[target]'],
10096
+ noSubmitSelectors: ['[up-submit=false]', '[target]', e.crossOriginSelector('action')],
10100
10097
  submitButtonSelectors: ['input[type=submit]', 'input[type=image]', 'button[type=submit]', 'button:not([type])'],
10101
10098
  watchInputEvents: ['input', 'change'],
10102
10099
  watchInputDelay: 0,
10103
10100
  watchChangeEvents: ['change'],
10104
10101
  }));
10105
- function fullSubmitSelector() {
10106
- return config.submitSelectors.join();
10107
- }
10108
- function reset() {
10109
- config.reset();
10110
- }
10111
10102
  function fieldSelector(suffix = '') {
10112
10103
  return config.fieldSelectors.map(field => field + suffix).join();
10113
10104
  }
@@ -10139,7 +10130,7 @@ up.form = (function () {
10139
10130
  return e.get(form, selector);
10140
10131
  }
10141
10132
  function submitButtonSelector() {
10142
- return config.submitButtonSelectors.join();
10133
+ return config.selector('submitButtonSelectors');
10143
10134
  }
10144
10135
  const submit = up.mockable((form, options) => {
10145
10136
  return up.render(submitOptions(form, options));
@@ -10419,15 +10410,11 @@ up.form = (function () {
10419
10410
  }
10420
10411
  function isSubmittable(form) {
10421
10412
  form = up.fragment.get(form);
10422
- return form.matches(fullSubmitSelector()) && !isSubmitDisabled(form);
10413
+ return config.matches(form, 'submitSelectors');
10423
10414
  }
10424
- function isSubmitDisabled(form) {
10425
- return form.matches(config.noSubmitSelectors.join());
10426
- }
10427
- up.on('submit', fullSubmitSelector, function (event, form) {
10428
- if (event.defaultPrevented || isSubmitDisabled(form)) {
10415
+ up.on('submit', config.selectorFn('submitSelectors'), function (event, form) {
10416
+ if (event.defaultPrevented)
10429
10417
  return;
10430
- }
10431
10418
  up.event.halt(event, { log: true });
10432
10419
  up.error.muteUncriticalRejection(submit(form));
10433
10420
  });
@@ -10449,7 +10436,6 @@ up.form = (function () {
10449
10436
  });
10450
10437
  up.compiler('[up-watch]', (formOrField) => watch(formOrField));
10451
10438
  up.compiler('[up-autosubmit]', (formOrField) => autosubmit(formOrField));
10452
- up.on('up:framework:reset', reset);
10453
10439
  return {
10454
10440
  config,
10455
10441
  submit,
@@ -10492,14 +10478,13 @@ up.feedback = (function () {
10492
10478
  navSelectors: ['[up-nav]', 'nav'],
10493
10479
  }));
10494
10480
  function reset() {
10495
- config.reset();
10496
10481
  up.layer.root.feedbackLocation = null;
10497
10482
  }
10498
10483
  const CLASS_ACTIVE = 'up-active';
10499
10484
  const CLASS_LOADING = 'up-loading';
10500
10485
  const SELECTOR_LINK = 'a, [up-href]';
10501
10486
  function navSelector() {
10502
- return config.navSelectors.join();
10487
+ return config.selector('navSelectors');
10503
10488
  }
10504
10489
  function normalizeURL(url) {
10505
10490
  if (url) {
@@ -10607,15 +10592,12 @@ up.radio = (function () {
10607
10592
  hungrySelectors: ['[up-hungry]'],
10608
10593
  pollInterval: 30000,
10609
10594
  }));
10610
- function reset() {
10611
- config.reset();
10612
- }
10613
10595
  function hungrySteps(renderOptions) {
10614
10596
  let { useHungry, origin, layer: renderLayer } = renderOptions;
10615
10597
  let steps = { current: [], other: [] };
10616
10598
  if (!useHungry)
10617
10599
  return steps;
10618
- let hungrySelector = config.hungrySelectors.join();
10600
+ let hungrySelector = config.selector('hungrySelectors');
10619
10601
  const layerPreference = [renderLayer, ...renderLayer.ancestors, ...renderLayer.descendants];
10620
10602
  for (let elementLayer of layerPreference) {
10621
10603
  let hungries = up.fragment.all(elementLayer.element, hungrySelector, { layer: elementLayer });
@@ -10668,7 +10650,6 @@ up.radio = (function () {
10668
10650
  event.preventDefault();
10669
10651
  });
10670
10652
  });
10671
- up.on('up:framework:reset', reset);
10672
10653
  return {
10673
10654
  config,
10674
10655
  hungrySteps,