unpoly-rails 3.5.1 → 3.6.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.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,