unpoly-rails 3.5.2 → 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.2'
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
 
@@ -1215,9 +1209,6 @@ up.element = (function () {
1215
1209
  let clone = createFromHTML(scriptish.outerHTML);
1216
1210
  scriptish.replaceWith(clone);
1217
1211
  }
1218
- function disableScript(scriptElement) {
1219
- scriptElement.type = 'up-disabled-script';
1220
- }
1221
1212
  function createFromHTML(html) {
1222
1213
  const range = document.createRange();
1223
1214
  range.setStart(document.body, 0);
@@ -1457,16 +1448,12 @@ up.element = (function () {
1457
1448
  jQuery(element).remove();
1458
1449
  }
1459
1450
  }
1460
- function filteredQuery(parent, includeSelectors, excludeSelectors) {
1461
- let fullIncludeSelector = includeSelectors.join();
1462
- let fullExcludeSelector = excludeSelectors.join();
1463
- let elements = parent.querySelectorAll(fullIncludeSelector);
1464
- let isExcluded = (element) => element.matches(fullExcludeSelector);
1465
- return u.reject(elements, isExcluded);
1466
- }
1467
1451
  function isEmpty(element) {
1468
1452
  return !element.children.length > 0 && !element.innerText.trim();
1469
1453
  }
1454
+ function crossOriginSelector(attr) {
1455
+ return `[${attr}*="//"]:not([${attr}*="//${location.host}/"])`;
1456
+ }
1470
1457
  return {
1471
1458
  subtree,
1472
1459
  contains,
@@ -1521,9 +1508,8 @@ up.element = (function () {
1521
1508
  setTemporaryAttr,
1522
1509
  cleanJQuery,
1523
1510
  parseSelector,
1524
- filteredQuery,
1525
1511
  isEmpty,
1526
- disableScript,
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);
@@ -2645,7 +2648,7 @@ up.Change.UpdateSteps = class UpdateSteps extends up.Change.Addition {
2645
2648
  const keepableClone = keepable.cloneNode(true);
2646
2649
  keepable.insertAdjacentElement('beforebegin', keepableClone);
2647
2650
  keepable.classList.add('up-keeping');
2648
- u.each(e.subtree(keepPlan.newElement, 'script'), e.disableScript);
2651
+ up.script.disableSubtree(keepPlan.newElement);
2649
2652
  let viewports = up.viewport.subtree(keepPlan.oldElement);
2650
2653
  keepPlan.revivers = viewports.map(function (viewport) {
2651
2654
  let cursorProps = up.viewport.copyCursorProps(viewport);
@@ -3943,7 +3946,7 @@ up.FormValidator = class FormValidator {
3943
3946
  options.failOptions = false;
3944
3947
  options.params = up.Params.merge(options.params, ...u.map(dirtyRenderOptionsList, 'params'));
3945
3948
  options.headers = u.merge(...u.map(dirtyRenderOptionsList, 'headers'));
3946
- options.headers[up.protocol.headerize('validate')] = dirtyNames.join(' ') || ':unknown';
3949
+ this._addValidateHeader(options.headers, dirtyNames);
3947
3950
  options.guardEvent = up.event.build('up:form:validate', {
3948
3951
  fields: dirtyFields,
3949
3952
  log: 'Validating form',
@@ -3969,6 +3972,13 @@ up.FormValidator = class FormValidator {
3969
3972
  }
3970
3973
  });
3971
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
+ }
3972
3982
  _buildDataMap(solutions) {
3973
3983
  let dataMap = {};
3974
3984
  for (let solution of solutions) {
@@ -4110,7 +4120,7 @@ up.FragmentFinder = class FragmentFinder {
4110
4120
  }
4111
4121
  _findInRegion() {
4112
4122
  var _a;
4113
- 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)) {
4114
4124
  return this._findClosest() || this._findDescendantInRegion();
4115
4125
  }
4116
4126
  }
@@ -5573,25 +5583,19 @@ up.NonceableCallback = class NonceableCallback {
5573
5583
  return new this(match[3], match[2]);
5574
5584
  }
5575
5585
  toFunction(...argNames) {
5576
- if (up.browser.canEval()) {
5577
- return new Function(...argNames, this.script);
5578
- }
5579
- else if (this.nonce) {
5586
+ if (this.nonce) {
5580
5587
  let callbackThis = this;
5581
5588
  return function (...args) {
5582
5589
  return callbackThis._runAsNoncedFunction(this, argNames, args);
5583
5590
  };
5584
5591
  }
5585
5592
  else {
5586
- return this._cannotRun.bind(this);
5593
+ return new Function(...argNames, this.script);
5587
5594
  }
5588
5595
  }
5589
5596
  toString() {
5590
5597
  return `nonce-${this.nonce} ${this.script}`;
5591
5598
  }
5592
- _cannotRun() {
5593
- throw new Error(`Your Content Security Policy disallows inline JavaScript (${this.script}). See https://unpoly.com/csp for solutions.`);
5594
- }
5595
5599
  _runAsNoncedFunction(thisArg, argNames, args) {
5596
5600
  let wrappedScript = `
5597
5601
  try {
@@ -6944,7 +6948,7 @@ up.Response = class Response extends up.Record {
6944
6948
  return this.header('Content-Type');
6945
6949
  }
6946
6950
  get cspNonces() {
6947
- 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'));
6948
6952
  }
6949
6953
  get lastModified() {
6950
6954
  let header = this.header('Last-Modified');
@@ -6990,9 +6994,6 @@ up.ResponseDoc = (_a = class ResponseDoc {
6990
6994
  else {
6991
6995
  this._parseContent(content || '', target);
6992
6996
  }
6993
- if (!up.fragment.config.runScripts) {
6994
- this._document.querySelectorAll('script').forEach((e) => e.remove());
6995
- }
6996
6997
  this._cspNonces = cspNonces;
6997
6998
  if (origin) {
6998
6999
  let originSelector = up.fragment.tryToTarget(origin);
@@ -7081,12 +7082,7 @@ up.ResponseDoc = (_a = class ResponseDoc {
7081
7082
  });
7082
7083
  }
7083
7084
  commitSteps(steps) {
7084
- return steps.filter((step) => {
7085
- if (this._document.contains(step.newElement)) {
7086
- step.newElement.remove();
7087
- return true;
7088
- }
7089
- });
7085
+ return steps.filter((step) => this.commitElement(step.newElement));
7090
7086
  }
7091
7087
  _trySelectStep(step) {
7092
7088
  if (step.newElement) {
@@ -7113,6 +7109,15 @@ up.ResponseDoc = (_a = class ResponseDoc {
7113
7109
  throw new up.CannotMatch();
7114
7110
  }
7115
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
+ }
7116
7121
  finalizeElement(element) {
7117
7122
  up.NonceableCallback.adoptNonces(element, this._cspNonces);
7118
7123
  if (this._isDocumentBroken) {
@@ -7147,8 +7152,8 @@ up.RevealMotion = class RevealMotion {
7147
7152
  this._padding = (_d = (_c = this._options.padding) !== null && _c !== void 0 ? _c : this._options.revealPadding) !== null && _d !== void 0 ? _d : viewportConfig.revealPadding;
7148
7153
  this._top = (_f = (_e = this._options.top) !== null && _e !== void 0 ? _e : this._options.revealTop) !== null && _f !== void 0 ? _f : viewportConfig.revealTop;
7149
7154
  this._max = (_h = (_g = this._options.max) !== null && _g !== void 0 ? _g : this._options.revealMax) !== null && _h !== void 0 ? _h : viewportConfig.revealMax;
7150
- this._topObstructions = viewportConfig.fixedTopSelectors;
7151
- this._bottomObstructions = viewportConfig.fixedBottomSelectors;
7155
+ this._topObstructionSelector = viewportConfig.selector('fixedTopSelectors');
7156
+ this._bottomObstructionSelector = viewportConfig.selector('fixedBottomSelectors');
7152
7157
  }
7153
7158
  start() {
7154
7159
  const viewportRect = this._getViewportRect(this._viewport);
@@ -7200,12 +7205,12 @@ up.RevealMotion = class RevealMotion {
7200
7205
  elementRect.top -= this._padding;
7201
7206
  elementRect.height += 2 * this._padding;
7202
7207
  }
7203
- _selectObstructions(selectors) {
7204
- let elements = up.fragment.all(selectors.join(), { layer: this._obstructionsLayer });
7208
+ _selectObstructions(selector) {
7209
+ let elements = up.fragment.all(selector, { layer: this._obstructionsLayer });
7205
7210
  return u.filter(elements, e.isVisible);
7206
7211
  }
7207
7212
  _substractObstructions(viewportRect) {
7208
- for (let obstruction of this._selectObstructions(this._topObstructions)) {
7213
+ for (let obstruction of this._selectObstructions(this._topObstructionSelector)) {
7209
7214
  let obstructionRect = up.Rect.fromElement(obstruction);
7210
7215
  let diff = obstructionRect.bottom - viewportRect.top;
7211
7216
  if (diff > 0) {
@@ -7213,7 +7218,7 @@ up.RevealMotion = class RevealMotion {
7213
7218
  viewportRect.height -= diff;
7214
7219
  }
7215
7220
  }
7216
- for (let obstruction of this._selectObstructions(this._bottomObstructions)) {
7221
+ for (let obstruction of this._selectObstructions(this._bottomObstructionSelector)) {
7217
7222
  let obstructionRect = up.Rect.fromElement(obstruction);
7218
7223
  let diff = viewportRect.bottom - obstructionRect.top;
7219
7224
  if (diff > 0) {
@@ -7252,10 +7257,12 @@ up.Selector = class Selector {
7252
7257
  }
7253
7258
  let expandedTargets = up.fragment.expandTargets(selector, Object.assign(Object.assign({}, options), { layer: expandTargetLayer }));
7254
7259
  this._selectors = expandedTargets.map((target) => {
7255
- target = target.replace(CSS_HAS_SUFFIX_PATTERN, (match, descendantSelector) => {
7256
- this._filters.push(element => element.querySelector(descendantSelector));
7257
- return '';
7258
- });
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
+ }
7259
7266
  return target || '*';
7260
7267
  });
7261
7268
  this._unionSelector = this._selectors.join() || 'match-none';
@@ -7749,6 +7756,7 @@ up.protocol = (function () {
7749
7756
  csrfToken() { return e.metaContent('csrf-token'); },
7750
7757
  cspNonce() { return e.metaContent('csp-nonce'); },
7751
7758
  csrfHeader: 'X-CSRF-Token',
7759
+ maxHeaderSize: 2048,
7752
7760
  }));
7753
7761
  function csrfHeader() {
7754
7762
  return u.evalOption(config.csrfHeader);
@@ -7782,13 +7790,8 @@ up.protocol = (function () {
7782
7790
  params.add(config.methodParam, method);
7783
7791
  return 'POST';
7784
7792
  }
7785
- function reset() {
7786
- config.reset();
7787
- }
7788
- up.on('up:framework:reset', reset);
7789
7793
  return {
7790
7794
  config,
7791
- reset,
7792
7795
  locationFromXHR,
7793
7796
  titleFromXHR,
7794
7797
  targetFromXHR,
@@ -7819,9 +7822,6 @@ up.protocol = (function () {
7819
7822
  up.log = (function () {
7820
7823
  const u = up.util;
7821
7824
  const config = new up.LogConfig();
7822
- function reset() {
7823
- config.reset();
7824
- }
7825
7825
  function printToStandard(...args) {
7826
7826
  if (config.enabled) {
7827
7827
  printToStream('log', ...args);
@@ -7876,7 +7876,6 @@ up.log = (function () {
7876
7876
  }
7877
7877
  }
7878
7878
  up.on('up:framework:boot', printBanner);
7879
- up.on('up:framework:reset', reset);
7880
7879
  function enable() {
7881
7880
  config.enabled = true;
7882
7881
  }
@@ -7923,6 +7922,12 @@ up.script = (function () {
7923
7922
  'up-on-error',
7924
7923
  'up-on-offline',
7925
7924
  ],
7925
+ scriptSelectors: [
7926
+ 'script'
7927
+ ],
7928
+ noScriptSelectors: [
7929
+ 'script[type="application/ld+json"]'
7930
+ ]
7926
7931
  }));
7927
7932
  const SYSTEM_MACRO_PRIORITIES = {
7928
7933
  '[up-back]': -100,
@@ -8046,7 +8051,7 @@ up.script = (function () {
8046
8051
  return Object.assign(Object.assign(Object.assign({}, element.dataset), parsedJSON), element.upCompileData);
8047
8052
  }
8048
8053
  function findAssets(head = document.head) {
8049
- return e.filteredQuery(head, config.assetSelectors, config.noAssetSelectors);
8054
+ return head.querySelectorAll(config.selector('assetSelectors'));
8050
8055
  }
8051
8056
  function assertAssetsOK(newAssets, renderOptions) {
8052
8057
  let oldAssets = findAssets();
@@ -8056,10 +8061,16 @@ up.script = (function () {
8056
8061
  up.event.assertEmitted('up:assets:changed', { oldAssets, newAssets, renderOptions });
8057
8062
  }
8058
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
+ }
8059
8071
  function reset() {
8060
8072
  registeredCompilers = u.filter(registeredCompilers, 'isDefault');
8061
8073
  registeredMacros = u.filter(registeredMacros, 'isDefault');
8062
- config.reset();
8063
8074
  }
8064
8075
  up.on('up:framework:reset', reset);
8065
8076
  return {
@@ -8072,6 +8083,7 @@ up.script = (function () {
8072
8083
  data: readData,
8073
8084
  findAssets,
8074
8085
  assertAssetsOK,
8086
+ disableSubtree: disableScriptsInSubtree,
8075
8087
  };
8076
8088
  })();
8077
8089
  up.compiler = up.script.compiler;
@@ -8098,6 +8110,7 @@ up.history = (function () {
8098
8110
  'link[rel=canonical]',
8099
8111
  'link[rel=icon]',
8100
8112
  '[up-meta]',
8113
+ 'script[type="application/ld+json"]',
8101
8114
  ],
8102
8115
  noMetaTagSelectors: [
8103
8116
  'meta[http-equiv]',
@@ -8108,7 +8121,6 @@ up.history = (function () {
8108
8121
  let previousLocation;
8109
8122
  let nextPreviousLocation;
8110
8123
  function reset() {
8111
- config.reset();
8112
8124
  previousLocation = undefined;
8113
8125
  nextPreviousLocation = undefined;
8114
8126
  trackCurrentLocation();
@@ -8210,7 +8222,7 @@ up.history = (function () {
8210
8222
  }
8211
8223
  });
8212
8224
  function findMetaTags(head = document.head) {
8213
- return e.filteredQuery(head, config.metaTagSelectors, config.noMetaTagSelectors);
8225
+ return head.querySelectorAll(config.selector('metaTagSelectors'));
8214
8226
  }
8215
8227
  function updateMetaTags(newMetaTags) {
8216
8228
  let oldMetaTags = findMetaTags();
@@ -8304,9 +8316,6 @@ up.fragment = (function () {
8304
8316
  skipResponse: defaultSkipResponse
8305
8317
  }));
8306
8318
  u.delegate(config, ['mainTargets'], () => up.layer.config.any);
8307
- function reset() {
8308
- config.reset();
8309
- }
8310
8319
  function defaultSkipResponse({ response, expiredResponse }) {
8311
8320
  return !response.text || response.text === (expiredResponse === null || expiredResponse === void 0 ? void 0 : expiredResponse.text);
8312
8321
  }
@@ -8570,18 +8579,11 @@ up.fragment = (function () {
8570
8579
  let isGood = (klass) => !u.some(config.badTargetClasses, (badTargetClass) => matchesPattern(badTargetClass, klass));
8571
8580
  return u.filter(element.classList, isGood);
8572
8581
  }
8573
- function modernResolveOrigin(target, { origin } = {}) {
8574
- return target.replace(/:origin\b/, function (match) {
8575
- if (origin) {
8576
- return toTarget(origin);
8577
- }
8578
- else {
8579
- up.fail('Missing { origin } element to resolve "%s" reference (found in %s)', match, target);
8580
- }
8581
- });
8582
- }
8583
- function resolveOrigin(...args) {
8584
- 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);
8585
8587
  }
8586
8588
  function expandTargets(targets, options = {}) {
8587
8589
  const { layer } = options;
@@ -8591,21 +8593,19 @@ up.fragment = (function () {
8591
8593
  targets = u.copy(u.wrapList(targets));
8592
8594
  const expanded = [];
8593
8595
  while (targets.length) {
8594
- const target = targets.shift();
8595
- if (target === ':main' || target === true) {
8596
- let mode;
8597
- if (layer === 'new') {
8598
- mode = options.mode || up.fail('Must pass a { mode } option together with { layer: "new" }');
8599
- }
8600
- else {
8601
- mode = layer.mode;
8602
- }
8603
- targets.unshift(...up.layer.mainTargets(mode));
8604
- }
8605
- else if (target === ':layer') {
8606
- if (layer !== 'new' && !layer.opening) {
8607
- targets.unshift(layer.getFirstSwappableElement());
8608
- }
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));
8609
8609
  }
8610
8610
  else if (u.isElementish(target)) {
8611
8611
  expanded.push(toTarget(target, options));
@@ -8613,11 +8613,30 @@ up.fragment = (function () {
8613
8613
  else if (u.isString(target)) {
8614
8614
  expanded.push(resolveOrigin(target, options));
8615
8615
  }
8616
- else {
8617
- }
8618
8616
  }
8619
8617
  return u.uniq(expanded);
8620
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
+ }
8621
8640
  function splitTarget(target) {
8622
8641
  return u.parseTokens(target, { separator: 'comma' });
8623
8642
  }
@@ -8724,7 +8743,6 @@ up.fragment = (function () {
8724
8743
  return up.warn('Cannot push history changes. Next fragment update will load in a new page.');
8725
8744
  }
8726
8745
  });
8727
- up.on('up:framework:reset', reset);
8728
8746
  return {
8729
8747
  config,
8730
8748
  reload,
@@ -8763,6 +8781,7 @@ up.fragment = (function () {
8763
8781
  isNotDestroying,
8764
8782
  targetForSteps,
8765
8783
  compressNestedSteps,
8784
+ containsMainPseudo,
8766
8785
  };
8767
8786
  })();
8768
8787
  up.reload = up.fragment.reload;
@@ -8799,13 +8818,7 @@ up.viewport = (function () {
8799
8818
  revealMax() { return 0.5 * window.innerHeight; },
8800
8819
  }));
8801
8820
  const bodyShifter = new up.BodyShifter();
8802
- function reset() {
8803
- config.reset();
8804
- }
8805
- function fullAnchoredRightSelector() {
8806
- return config.anchoredRightSelectors.join();
8807
- }
8808
- up.compiler(fullAnchoredRightSelector, function (element) {
8821
+ up.compiler(config.selectorFn('anchoredRightSelectors'), function (element) {
8809
8822
  return bodyShifter.onAnchoredElementInserted(element);
8810
8823
  });
8811
8824
  function reveal(element, options) {
@@ -9073,7 +9086,6 @@ up.viewport = (function () {
9073
9086
  });
9074
9087
  });
9075
9088
  up.on(window, 'hashchange', () => revealHash());
9076
- up.on('up:framework:reset', reset);
9077
9089
  return {
9078
9090
  reveal,
9079
9091
  revealHash,
@@ -9144,7 +9156,6 @@ up.motion = (function () {
9144
9156
  motionController.reset();
9145
9157
  namedAnimations = pickDefault(namedAnimations);
9146
9158
  namedTransitions = pickDefault(namedTransitions);
9147
- config.reset();
9148
9159
  }
9149
9160
  function isEnabled() {
9150
9161
  return config.enabled;
@@ -9421,7 +9432,6 @@ up.network = (function () {
9421
9432
  function reset() {
9422
9433
  abortRequests();
9423
9434
  queue.reset();
9424
- config.reset();
9425
9435
  cache.reset();
9426
9436
  progressBar === null || progressBar === void 0 ? void 0 : progressBar.destroy();
9427
9437
  progressBar = null;
@@ -9701,7 +9711,6 @@ up.layer = (function () {
9701
9711
  return e.callbackAttr(link, attr, { exposedKeys: ['layer', 'value', 'response'] });
9702
9712
  }
9703
9713
  function reset() {
9704
- config.reset();
9705
9714
  stack.reset();
9706
9715
  handlers = u.filter(handlers, 'isDefault');
9707
9716
  }
@@ -9734,7 +9743,7 @@ up.layer = (function () {
9734
9743
  }
9735
9744
  }
9736
9745
  function isWithinForeignOverlay(element) {
9737
- let selector = config.foreignOverlaySelectors.join();
9746
+ let selector = config.selector('foreignOverlaySelectors');
9738
9747
  return !!(selector && element.closest(selector));
9739
9748
  }
9740
9749
  up.on('up:fragment:destroyed', function () {
@@ -9816,7 +9825,7 @@ up.link = (function () {
9816
9825
  }
9817
9826
  const config = new up.Config(() => ({
9818
9827
  followSelectors: combineFollowableSelectors(LINKS_WITH_REMOTE_HTML, ATTRIBUTES_SUGGESTING_FOLLOW).concat(LINKS_WITH_LOCAL_HTML),
9819
- 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')],
9820
9829
  instantSelectors: ['[up-instant]'],
9821
9830
  noInstantSelectors: ['[up-instant=false]', '[onclick]'],
9822
9831
  preloadSelectors: combineFollowableSelectors(LINKS_WITH_REMOTE_HTML, ['[up-preload]']),
@@ -9824,26 +9833,8 @@ up.link = (function () {
9824
9833
  clickableSelectors: LINKS_WITH_LOCAL_HTML.concat(['[up-emit]', '[up-accept]', '[up-dismiss]', '[up-clickable]']),
9825
9834
  preloadDelay: 90,
9826
9835
  }));
9827
- function fullFollowSelector() {
9828
- return config.followSelectors.join();
9829
- }
9830
- function fullPreloadSelector() {
9831
- return config.preloadSelectors.join();
9832
- }
9833
- function fullInstantSelector() {
9834
- return config.instantSelectors.join();
9835
- }
9836
- function fullClickableSelector() {
9837
- return config.clickableSelectors.join();
9838
- }
9839
- function isFollowDisabled(link) {
9840
- return link.matches(config.noFollowSelectors.join()) || u.isCrossOrigin(link);
9841
- }
9842
9836
  function isPreloadDisabled(link) {
9843
- return !up.browser.canPushState() ||
9844
- link.matches(config.noPreloadSelectors.join()) ||
9845
- isFollowDisabled(link) ||
9846
- !willCache(link);
9837
+ return !up.browser.canPushState() || !isFollowable(link) || !willCache(link);
9847
9838
  }
9848
9839
  function willCache(link) {
9849
9840
  const options = parseRequestOptions(link);
@@ -9856,12 +9847,8 @@ up.link = (function () {
9856
9847
  return request.willCache();
9857
9848
  }
9858
9849
  }
9859
- function isInstantDisabled(link) {
9860
- return link.matches(config.noInstantSelectors.join()) || isFollowDisabled(link);
9861
- }
9862
9850
  function reset() {
9863
9851
  lastMousedownTarget = null;
9864
- config.reset();
9865
9852
  linkPreloader.reset();
9866
9853
  }
9867
9854
  const follow = up.mockable(function (link, options) {
@@ -9971,7 +9958,7 @@ up.link = (function () {
9971
9958
  }
9972
9959
  function isFollowable(link) {
9973
9960
  link = up.fragment.get(link);
9974
- return link.matches(fullFollowSelector()) && !isFollowDisabled(link);
9961
+ return config.matches(link, 'followSelectors');
9975
9962
  }
9976
9963
  function makeFollowable(link) {
9977
9964
  if (!isFollowable(link)) {
@@ -9993,9 +9980,9 @@ up.link = (function () {
9993
9980
  }
9994
9981
  });
9995
9982
  }
9996
- up.macro(fullClickableSelector, makeClickable);
9983
+ up.macro(config.selectorFn('clickableSelectors'), makeClickable);
9997
9984
  function shouldFollowEvent(event, link) {
9998
- if (event.defaultPrevented || isFollowDisabled(link)) {
9985
+ if (event.defaultPrevented) {
9999
9986
  return false;
10000
9987
  }
10001
9988
  const betterTargetSelector = `a, [up-href], ${up.form.fieldSelector()}`;
@@ -10003,9 +9990,12 @@ up.link = (function () {
10003
9990
  return !betterTarget || (betterTarget === link);
10004
9991
  }
10005
9992
  function isInstant(linkOrDescendant) {
10006
- const element = linkOrDescendant.closest(fullInstantSelector());
9993
+ const element = linkOrDescendant.closest(config.selector('instantSelectors'));
10007
9994
  return element && !isInstantDisabled(element);
10008
9995
  }
9996
+ function isInstantDisabled(link) {
9997
+ return config.matches(link, 'noInstantSelectors') || config.matches(link, 'noFollowSelectors');
9998
+ }
10009
9999
  function convertClicks(layer) {
10010
10000
  layer.on('click', function (event, element) {
10011
10001
  if (!up.event.isUnmodified(event)) {
@@ -10041,7 +10031,7 @@ up.link = (function () {
10041
10031
  const method = followMethod(link);
10042
10032
  return up.network.isSafeMethod(method);
10043
10033
  }
10044
- up.on('up:click', fullFollowSelector, function (event, link) {
10034
+ up.on('up:click', config.selectorFn('followSelectors'), function (event, link) {
10045
10035
  if (shouldFollowEvent(event, link)) {
10046
10036
  up.event.halt(event, { log: true });
10047
10037
  up.focus(link, { preventScroll: true });
@@ -10060,7 +10050,7 @@ up.link = (function () {
10060
10050
  makeFollowable(area);
10061
10051
  }
10062
10052
  });
10063
- up.compiler(fullPreloadSelector, function (link) {
10053
+ up.compiler(config.selectorFn('preloadSelectors'), function (link) {
10064
10054
  if (!isPreloadDisabled(link)) {
10065
10055
  linkPreloader.watchLink(link);
10066
10056
  }
@@ -10079,8 +10069,6 @@ up.link = (function () {
10079
10069
  convertClicks,
10080
10070
  config,
10081
10071
  combineFollowableSelectors,
10082
- preloadSelector: fullPreloadSelector,
10083
- followSelector: fullFollowSelector,
10084
10072
  preloadIssue,
10085
10073
  };
10086
10074
  })();
@@ -10105,18 +10093,12 @@ up.form = (function () {
10105
10093
  groupSelectors: ['[up-form-group]', 'fieldset', 'label', 'form'],
10106
10094
  fieldSelectors: ['select', 'input:not([type=submit]):not([type=image])', 'button[type]:not([type=submit])', 'textarea'],
10107
10095
  submitSelectors: up.link.combineFollowableSelectors(['form'], ATTRIBUTES_SUGGESTING_SUBMIT),
10108
- noSubmitSelectors: ['[up-submit=false]', '[target]'],
10096
+ noSubmitSelectors: ['[up-submit=false]', '[target]', e.crossOriginSelector('action')],
10109
10097
  submitButtonSelectors: ['input[type=submit]', 'input[type=image]', 'button[type=submit]', 'button:not([type])'],
10110
10098
  watchInputEvents: ['input', 'change'],
10111
10099
  watchInputDelay: 0,
10112
10100
  watchChangeEvents: ['change'],
10113
10101
  }));
10114
- function fullSubmitSelector() {
10115
- return config.submitSelectors.join();
10116
- }
10117
- function reset() {
10118
- config.reset();
10119
- }
10120
10102
  function fieldSelector(suffix = '') {
10121
10103
  return config.fieldSelectors.map(field => field + suffix).join();
10122
10104
  }
@@ -10148,7 +10130,7 @@ up.form = (function () {
10148
10130
  return e.get(form, selector);
10149
10131
  }
10150
10132
  function submitButtonSelector() {
10151
- return config.submitButtonSelectors.join();
10133
+ return config.selector('submitButtonSelectors');
10152
10134
  }
10153
10135
  const submit = up.mockable((form, options) => {
10154
10136
  return up.render(submitOptions(form, options));
@@ -10428,15 +10410,11 @@ up.form = (function () {
10428
10410
  }
10429
10411
  function isSubmittable(form) {
10430
10412
  form = up.fragment.get(form);
10431
- return form.matches(fullSubmitSelector()) && !isSubmitDisabled(form);
10413
+ return config.matches(form, 'submitSelectors');
10432
10414
  }
10433
- function isSubmitDisabled(form) {
10434
- return form.matches(config.noSubmitSelectors.join());
10435
- }
10436
- up.on('submit', fullSubmitSelector, function (event, form) {
10437
- if (event.defaultPrevented || isSubmitDisabled(form)) {
10415
+ up.on('submit', config.selectorFn('submitSelectors'), function (event, form) {
10416
+ if (event.defaultPrevented)
10438
10417
  return;
10439
- }
10440
10418
  up.event.halt(event, { log: true });
10441
10419
  up.error.muteUncriticalRejection(submit(form));
10442
10420
  });
@@ -10458,7 +10436,6 @@ up.form = (function () {
10458
10436
  });
10459
10437
  up.compiler('[up-watch]', (formOrField) => watch(formOrField));
10460
10438
  up.compiler('[up-autosubmit]', (formOrField) => autosubmit(formOrField));
10461
- up.on('up:framework:reset', reset);
10462
10439
  return {
10463
10440
  config,
10464
10441
  submit,
@@ -10501,14 +10478,13 @@ up.feedback = (function () {
10501
10478
  navSelectors: ['[up-nav]', 'nav'],
10502
10479
  }));
10503
10480
  function reset() {
10504
- config.reset();
10505
10481
  up.layer.root.feedbackLocation = null;
10506
10482
  }
10507
10483
  const CLASS_ACTIVE = 'up-active';
10508
10484
  const CLASS_LOADING = 'up-loading';
10509
10485
  const SELECTOR_LINK = 'a, [up-href]';
10510
10486
  function navSelector() {
10511
- return config.navSelectors.join();
10487
+ return config.selector('navSelectors');
10512
10488
  }
10513
10489
  function normalizeURL(url) {
10514
10490
  if (url) {
@@ -10616,15 +10592,12 @@ up.radio = (function () {
10616
10592
  hungrySelectors: ['[up-hungry]'],
10617
10593
  pollInterval: 30000,
10618
10594
  }));
10619
- function reset() {
10620
- config.reset();
10621
- }
10622
10595
  function hungrySteps(renderOptions) {
10623
10596
  let { useHungry, origin, layer: renderLayer } = renderOptions;
10624
10597
  let steps = { current: [], other: [] };
10625
10598
  if (!useHungry)
10626
10599
  return steps;
10627
- let hungrySelector = config.hungrySelectors.join();
10600
+ let hungrySelector = config.selector('hungrySelectors');
10628
10601
  const layerPreference = [renderLayer, ...renderLayer.ancestors, ...renderLayer.descendants];
10629
10602
  for (let elementLayer of layerPreference) {
10630
10603
  let hungries = up.fragment.all(elementLayer.element, hungrySelector, { layer: elementLayer });
@@ -10677,7 +10650,6 @@ up.radio = (function () {
10677
10650
  event.preventDefault();
10678
10651
  });
10679
10652
  });
10680
- up.on('up:framework:reset', reset);
10681
10653
  return {
10682
10654
  config,
10683
10655
  hungrySteps,