unpoly-rails 3.7.3.2 → 3.8.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.7.3'
8
+ version: '3.8.0'
9
9
  };
10
10
 
11
11
 
@@ -230,11 +230,6 @@ up.util = (function () {
230
230
  function isArguments(value) {
231
231
  return Object.prototype.toString.call(value) === '[object Arguments]';
232
232
  }
233
- function nullToUndefined(value) {
234
- if (!isNull(value)) {
235
- return value;
236
- }
237
- }
238
233
  function wrapList(value) {
239
234
  if (isList(value)) {
240
235
  return value;
@@ -338,9 +333,6 @@ up.util = (function () {
338
333
  function compact(array) {
339
334
  return filterList(array, isGiven);
340
335
  }
341
- function filterMap(list, mapping) {
342
- return filterList(map(list, mapping), isDefined);
343
- }
344
336
  function compactObject(object) {
345
337
  return pickBy(object, isGiven);
346
338
  }
@@ -390,9 +382,6 @@ up.util = (function () {
390
382
  function queueTask(task) {
391
383
  return setTimeout(task);
392
384
  }
393
- function queueMicrotask(task) {
394
- return Promise.resolve().then(task);
395
- }
396
385
  function last(value) {
397
386
  return value[value.length - 1];
398
387
  }
@@ -400,6 +389,9 @@ up.util = (function () {
400
389
  let indexOf = value.indexOf || Array.prototype.indexOf;
401
390
  return indexOf.call(value, subValue) >= 0;
402
391
  }
392
+ function containsAll(values, subValues) {
393
+ return every(subValues, (subValue) => contains(values, subValue));
394
+ }
403
395
  function objectContains(object, subObject) {
404
396
  const reducedValue = pick(object, Object.keys(subObject));
405
397
  return isEqual(subObject, reducedValue);
@@ -583,6 +575,14 @@ up.util = (function () {
583
575
  function reverse(list) {
584
576
  return copy(list).reverse();
585
577
  }
578
+ function replaceValue(value, matchValue, replacementValue) {
579
+ if (value === matchValue) {
580
+ return replacementValue;
581
+ }
582
+ else {
583
+ return value;
584
+ }
585
+ }
586
586
  function renameKeys(object, renameKeyFn) {
587
587
  const renamed = {};
588
588
  for (let key in object) {
@@ -734,7 +734,6 @@ up.util = (function () {
734
734
  normalizeMethod,
735
735
  methodAllowsPayload,
736
736
  copy,
737
- copyArrayLike,
738
737
  merge,
739
738
  mergeDefined,
740
739
  options: newOptions,
@@ -748,7 +747,6 @@ up.util = (function () {
748
747
  every,
749
748
  find: findInList,
750
749
  filter: filterList,
751
- filterMap: filterMap,
752
750
  reject,
753
751
  intersect,
754
752
  compact,
@@ -780,6 +778,7 @@ up.util = (function () {
780
778
  isRegExp,
781
779
  timer: scheduleTimer,
782
780
  contains,
781
+ containsAll,
783
782
  objectContains,
784
783
  toArray,
785
784
  pick,
@@ -806,7 +805,6 @@ up.util = (function () {
806
805
  isBasicObjectProperty,
807
806
  isCrossOrigin,
808
807
  task: queueTask,
809
- microtask: queueMicrotask,
810
808
  isEqual,
811
809
  parseTokens,
812
810
  wrapList,
@@ -817,10 +815,9 @@ up.util = (function () {
817
815
  delegate: defineDelegates,
818
816
  reverse,
819
817
  camelToKebabCase,
820
- nullToUndefined,
818
+ replaceValue,
821
819
  sprintf,
822
820
  renameKeys,
823
- negate,
824
821
  memoizeMethod,
825
822
  safeStringifyJSON,
826
823
  variant,
@@ -887,7 +884,9 @@ up.fail = up.error.fail;
887
884
  /* 5 */
888
885
  /***/ (() => {
889
886
 
890
- up.migrate = { config: {} };
887
+ up.migrate = {
888
+ config: {},
889
+ };
891
890
 
892
891
 
893
892
  /***/ }),
@@ -1184,7 +1183,7 @@ up.element = (function () {
1184
1183
  }
1185
1184
  }
1186
1185
  function idSelector(id) {
1187
- if (id.match(/^[a-z0-9\-_]+$/i)) {
1186
+ if (id.match(/^[a-z][a-z0-9\-_]*$/i)) {
1188
1187
  return `#${id}`;
1189
1188
  }
1190
1189
  else {
@@ -1223,16 +1222,9 @@ up.element = (function () {
1223
1222
  paint(element);
1224
1223
  return undo;
1225
1224
  }
1226
- function hasCSSTransition(elementOrStyleHash) {
1227
- let styleHash;
1228
- if (u.isOptions(elementOrStyleHash)) {
1229
- styleHash = elementOrStyleHash;
1230
- }
1231
- else {
1232
- styleHash = computedStyle(elementOrStyleHash);
1233
- }
1234
- const prop = styleHash.transitionProperty;
1235
- const duration = styleHash.transitionDuration;
1225
+ function hasCSSTransition(styleHash) {
1226
+ const prop = styleHash['transition-property'];
1227
+ const duration = styleHash['transition-duration'];
1236
1228
  const noTransition = ((prop === 'none') || ((prop === 'all') && (duration === 0)));
1237
1229
  return !noTransition;
1238
1230
  }
@@ -1241,8 +1233,8 @@ up.element = (function () {
1241
1233
  element.style.position = 'absolute';
1242
1234
  const offsetParentRect = element.offsetParent.getBoundingClientRect();
1243
1235
  setInlineStyle(element, {
1244
- left: elementRectAsFixed.left - computedStyleNumber(element, 'margin-left') - offsetParentRect.left,
1245
- top: elementRectAsFixed.top - computedStyleNumber(element, 'margin-top') - offsetParentRect.top,
1236
+ left: (elementRectAsFixed.left - computedStyleNumber(element, 'margin-left') - offsetParentRect.left) + 'px',
1237
+ top: (elementRectAsFixed.top - computedStyleNumber(element, 'margin-top') - offsetParentRect.top) + 'px',
1246
1238
  right: '',
1247
1239
  bottom: ''
1248
1240
  });
@@ -1274,9 +1266,6 @@ up.element = (function () {
1274
1266
  element.appendChild(wrapper);
1275
1267
  return wrapper;
1276
1268
  }
1277
- function isWrapper(element) {
1278
- return element.matches('up-wrapper');
1279
- }
1280
1269
  function preservingFocus(fn) {
1281
1270
  const oldFocusElement = document.activeElement;
1282
1271
  try {
@@ -1289,7 +1278,8 @@ up.element = (function () {
1289
1278
  }
1290
1279
  }
1291
1280
  function stringAttr(element, attribute) {
1292
- return u.nullToUndefined(element.getAttribute(attribute));
1281
+ let value = element.getAttribute(attribute);
1282
+ return u.replaceValue(value, null, undefined);
1293
1283
  }
1294
1284
  function booleanAttr(element, attribute, pass) {
1295
1285
  if (!element.hasAttribute(attribute))
@@ -1314,14 +1304,15 @@ up.element = (function () {
1314
1304
  }
1315
1305
  }
1316
1306
  }
1317
- function booleanOrStringAttr(element, attribute) {
1318
- return booleanAttr(element, attribute, true);
1307
+ function booleanOrStringAttr(element, attribute, trueValue = true) {
1308
+ let value = booleanAttr(element, attribute, true);
1309
+ return value === true ? trueValue : value;
1319
1310
  }
1320
1311
  function numberAttr(element, attribute) {
1321
1312
  let value = element.getAttribute(attribute);
1322
1313
  if (value) {
1323
1314
  value = value.replace(/_/g, '');
1324
- if (value.match(/^[\d.]+$/)) {
1315
+ if (value.match(/^-?[\d.]+$/)) {
1325
1316
  return parseFloat(value);
1326
1317
  }
1327
1318
  }
@@ -1358,17 +1349,13 @@ up.element = (function () {
1358
1349
  element.classList.add(klass);
1359
1350
  return () => element.classList.remove(klass);
1360
1351
  }
1361
- function setTemporaryAttr(element, attr, value) {
1362
- element.setAttribute(attr, value);
1363
- return () => element.removeAttribute(element, attr);
1364
- }
1365
1352
  function computedStyle(element, props) {
1366
1353
  const style = window.getComputedStyle(element);
1367
1354
  return extractFromStyleObject(style, props);
1368
1355
  }
1369
1356
  function computedStyleNumber(element, prop) {
1370
1357
  const rawValue = computedStyle(element, prop);
1371
- if (u.isGiven(rawValue)) {
1358
+ if (u.isPresent(rawValue)) {
1372
1359
  return parseFloat(rawValue);
1373
1360
  }
1374
1361
  }
@@ -1377,14 +1364,18 @@ up.element = (function () {
1377
1364
  return extractFromStyleObject(style, props);
1378
1365
  }
1379
1366
  function extractFromStyleObject(style, keyOrKeys) {
1367
+ if (up.migrate.loaded)
1368
+ keyOrKeys = up.migrate.fixStyleProps(keyOrKeys);
1380
1369
  if (u.isString(keyOrKeys)) {
1381
- return style[keyOrKeys];
1370
+ return style.getPropertyValue(keyOrKeys);
1382
1371
  }
1383
1372
  else {
1384
- return u.pick(style, keyOrKeys);
1373
+ return u.mapObject(keyOrKeys, (key) => [key, style.getPropertyValue(key)]);
1385
1374
  }
1386
1375
  }
1387
- function setInlineStyle(element, props) {
1376
+ function setInlineStyle(element, props, unit = '') {
1377
+ if (up.migrate.loaded)
1378
+ props = up.migrate.fixStyleProps(props, unit);
1388
1379
  if (u.isString(props)) {
1389
1380
  element.setAttribute('style', props);
1390
1381
  }
@@ -1392,37 +1383,10 @@ up.element = (function () {
1392
1383
  const { style } = element;
1393
1384
  for (let key in props) {
1394
1385
  let value = props[key];
1395
- value = normalizeStyleValueForWrite(key, value);
1396
- style[key] = value;
1386
+ style.setProperty(key, value + unit);
1397
1387
  }
1398
1388
  }
1399
1389
  }
1400
- function normalizeStyleValueForWrite(key, value) {
1401
- if (u.isMissing(value)) {
1402
- value = '';
1403
- }
1404
- else if (CSS_LENGTH_PROPS.has(key.toLowerCase().replace(/-/, ''))) {
1405
- value = cssLength(value);
1406
- }
1407
- return value;
1408
- }
1409
- const CSS_LENGTH_PROPS = new Set([
1410
- 'top', 'right', 'bottom', 'left',
1411
- 'padding', 'paddingtop', 'paddingright', 'paddingbottom', 'paddingleft',
1412
- 'margin', 'margintop', 'marginright', 'marginbottom', 'marginleft',
1413
- 'borderwidth', 'bordertopwidth', 'borderrightwidth', 'borderbottomwidth', 'borderleftwidth',
1414
- 'width', 'height',
1415
- 'maxwidth', 'maxheight',
1416
- 'minwidth', 'minheight',
1417
- ]);
1418
- function cssLength(obj) {
1419
- if (u.isNumber(obj) || (u.isString(obj) && /^\d+$/.test(obj))) {
1420
- return obj.toString() + "px";
1421
- }
1422
- else {
1423
- return obj;
1424
- }
1425
- }
1426
1390
  function isVisible(element) {
1427
1391
  return !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
1428
1392
  }
@@ -1447,6 +1411,18 @@ up.element = (function () {
1447
1411
  function crossOriginSelector(attr) {
1448
1412
  return `[${attr}*="//"]:not([${attr}*="//${location.host}/"])`;
1449
1413
  }
1414
+ function isIntersectingWindow(element, { margin = 0 } = {}) {
1415
+ const rect = up.Rect.fromElement(element);
1416
+ rect.grow(margin);
1417
+ return (rect.bottom > 0) && (rect.top < window.innerHeight) &&
1418
+ (rect.right > 0) && (rect.left < window.innerWidth);
1419
+ }
1420
+ function unionSelector(includes, excludes) {
1421
+ let selector = `:is(${includes.join()})`;
1422
+ if (u.isPresent(excludes))
1423
+ selector += `:not(${excludes.join()})`;
1424
+ return selector;
1425
+ }
1450
1426
  return {
1451
1427
  subtree,
1452
1428
  contains,
@@ -1481,7 +1457,6 @@ up.element = (function () {
1481
1457
  setMissingAttr,
1482
1458
  unwrap,
1483
1459
  wrapChildren,
1484
- isWrapper,
1485
1460
  attr: stringAttr,
1486
1461
  booleanAttr,
1487
1462
  numberAttr,
@@ -1498,11 +1473,12 @@ up.element = (function () {
1498
1473
  upClasses,
1499
1474
  toggleAttr,
1500
1475
  addTemporaryClass,
1501
- setTemporaryAttr,
1502
1476
  cleanJQuery,
1503
1477
  parseSelector,
1504
1478
  isEmpty,
1505
1479
  crossOriginSelector,
1480
+ isIntersectingWindow,
1481
+ unionSelector,
1506
1482
  };
1507
1483
  })();
1508
1484
 
@@ -1612,6 +1588,7 @@ up.Record = class Record {
1612
1588
  /***/ (() => {
1613
1589
 
1614
1590
  const u = up.util;
1591
+ const e = up.element;
1615
1592
  up.Config = class Config {
1616
1593
  constructor(blueprintFn = (() => ({}))) {
1617
1594
  this._blueprintFn = blueprintFn;
@@ -1627,10 +1604,7 @@ up.Config = class Config {
1627
1604
  selector(prop) {
1628
1605
  let includes = this[prop];
1629
1606
  let excludes = this['no' + u.upperCaseFirst(prop)];
1630
- let selector = `:is(${includes.join()})`;
1631
- if (u.isPresent(excludes))
1632
- selector += `:not(${excludes.join()})`;
1633
- return selector;
1607
+ return e.unionSelector(includes, excludes);
1634
1608
  }
1635
1609
  selectorFn(prop) {
1636
1610
  return () => this.selector(prop);
@@ -1801,6 +1775,12 @@ up.Rect = class Rect extends up.Record {
1801
1775
  get right() {
1802
1776
  return this.left + this.width;
1803
1777
  }
1778
+ grow(padding) {
1779
+ this.left -= padding;
1780
+ this.top -= padding;
1781
+ this.width += padding * 2;
1782
+ this.height += padding * 2;
1783
+ }
1804
1784
  static fromElement(element) {
1805
1785
  return new (this)(element.getBoundingClientRect());
1806
1786
  }
@@ -1812,64 +1792,49 @@ up.Rect = class Rect extends up.Record {
1812
1792
  /***/ (() => {
1813
1793
 
1814
1794
  const e = up.element;
1795
+ const SHIFT_CLASS = 'up-scrollbar-away';
1815
1796
  up.BodyShifter = class BodyShifter {
1816
1797
  constructor() {
1817
- this._unshiftFns = [];
1818
1798
  this._anchoredElements = new Set();
1819
1799
  this._stack = 0;
1800
+ this._cleaners = [];
1820
1801
  }
1821
1802
  lowerStack() {
1822
- this._stack--;
1823
- if (this._stack === 0) {
1803
+ if (--this._stack === 0)
1824
1804
  this._unshiftNow();
1825
- }
1826
1805
  }
1827
1806
  raiseStack() {
1828
- this._stack++;
1829
- if (this._stack === 1) {
1807
+ if (++this._stack === 1)
1830
1808
  this._shiftNow();
1831
- }
1832
1809
  }
1833
1810
  onAnchoredElementInserted(element) {
1834
1811
  this._anchoredElements.add(element);
1835
- if (this._isShifted()) {
1836
- this._shiftAnchoredElement(element);
1837
- }
1812
+ this._shiftElement(element, 'right');
1838
1813
  return () => this._anchoredElements.delete(element);
1839
1814
  }
1840
1815
  _isShifted() {
1841
- return this._scrollbarTookSpace && this._stack > 0;
1816
+ return this._rootScrollbarWidth && this._stack > 0;
1842
1817
  }
1843
1818
  _shiftNow() {
1844
- this._scrollbarWidth = up.viewport.scrollbarWidth();
1845
- this._scrollbarTookSpace = up.viewport.rootHasReducedWidthFromScrollbar();
1846
- if (!this._scrollbarTookSpace)
1847
- return;
1848
- this._shiftBody();
1819
+ this._rootScrollbarWidth = up.viewport.rootScrollbarWidth();
1820
+ this._cleaners.push(e.setTemporaryStyle(e.root, {
1821
+ '--up-scrollbar-width': this._rootScrollbarWidth + 'px'
1822
+ }));
1823
+ this._shiftElement(document.body, 'padding-right');
1849
1824
  for (let element of this._anchoredElements) {
1850
- this._shiftAnchoredElement(element);
1825
+ this._shiftElement(element, 'right');
1851
1826
  }
1852
1827
  }
1853
- _shiftBody() {
1854
- const overflowElement = up.viewport.rootOverflowElement();
1855
- this._changeStyle(overflowElement, { overflowY: 'hidden' });
1856
- const { body } = document;
1857
- const bodyRightPadding = e.styleNumber(body, 'paddingRight');
1858
- const bodyRightShift = this._scrollbarWidth + bodyRightPadding;
1859
- this._changeStyle(body, { paddingRight: bodyRightShift });
1860
- }
1861
- _shiftAnchoredElement(element) {
1862
- const elementRight = e.styleNumber(element, 'right');
1863
- const elementRightShift = this._scrollbarWidth + elementRight;
1864
- this._changeStyle(element, { right: elementRightShift });
1865
- }
1866
- _changeStyle(element, styles) {
1867
- this._unshiftFns.push(e.setTemporaryStyle(element, styles));
1828
+ _shiftElement(element, styleProp) {
1829
+ if (!this._isShifted())
1830
+ return;
1831
+ let originalValue = e.style(element, styleProp);
1832
+ this._cleaners.push(e.setTemporaryStyle(e.root, { ['--up-original-' + styleProp]: originalValue }), e.addTemporaryClass(element, SHIFT_CLASS));
1868
1833
  }
1869
1834
  _unshiftNow() {
1870
- let unshiftFn;
1871
- while (unshiftFn = this._unshiftFns.pop()) {
1872
- unshiftFn();
1835
+ let cleaner;
1836
+ while (cleaner = this._cleaners.pop()) {
1837
+ cleaner();
1873
1838
  }
1874
1839
  }
1875
1840
  };
@@ -3078,6 +3043,7 @@ up.Change.FromContent = (_a = class FromContent extends up.Change {
3078
3043
  }
3079
3044
  this.options.title = this.improveHistoryValue(this.options.title, responseDoc.title);
3080
3045
  this.options.metaTags = this.improveHistoryValue(this.options.metaTags, responseDoc.metaTags);
3046
+ this.options.lang = this.improveHistoryValue(this.options.lang, responseDoc.lang);
3081
3047
  }
3082
3048
  _defaultPlacement() {
3083
3049
  if (!this.options.document && !this.options.fragment) {
@@ -3250,20 +3216,17 @@ up.CompilerPass = class CompilerPass {
3250
3216
  const u = up.util;
3251
3217
  const e = up.element;
3252
3218
  up.CSSTransition = class CSSTransition {
3253
- constructor(element, lastFrameKebab, options) {
3219
+ constructor(element, lastFrame, options) {
3254
3220
  this._element = element;
3255
- this._lastFrameKebab = lastFrameKebab;
3256
- this._lastFrameKeysKebab = Object.keys(this._lastFrameKebab);
3257
- if (u.some(this._lastFrameKeysKebab, key => key.match(/A-Z/))) {
3258
- up.fail('Animation keys must be kebab-case');
3259
- }
3221
+ this._lastFrame = lastFrame;
3222
+ this._lastFrameKeys = Object.keys(this._lastFrame);
3260
3223
  this._finishEvent = options.finishEvent;
3261
3224
  this._duration = options.duration;
3262
3225
  this._easing = options.easing;
3263
3226
  this._finished = false;
3264
3227
  }
3265
3228
  start() {
3266
- if (this._lastFrameKeysKebab.length === 0) {
3229
+ if (this._lastFrameKeys.length === 0) {
3267
3230
  this._finished = true;
3268
3231
  return Promise.resolve();
3269
3232
  }
@@ -3287,9 +3250,7 @@ up.CSSTransition = class CSSTransition {
3287
3250
  }
3288
3251
  _startFallbackTimer() {
3289
3252
  const timingTolerance = 100;
3290
- this._fallbackTimer = u.timer((this._duration + timingTolerance), () => {
3291
- this._finish();
3292
- });
3253
+ this._fallbackTimer = u.timer((this._duration + timingTolerance), () => this._finish());
3293
3254
  }
3294
3255
  _stopFallbackTimer() {
3295
3256
  clearTimeout(this._fallbackTimer);
@@ -3305,11 +3266,10 @@ up.CSSTransition = class CSSTransition {
3305
3266
  if (elapsed <= (0.25 * this._duration)) {
3306
3267
  return;
3307
3268
  }
3308
- const completedPropertyKebab = event.propertyName;
3309
- if (!u.contains(this._lastFrameKeysKebab, completedPropertyKebab)) {
3310
- return;
3269
+ const completedProperty = event.propertyName;
3270
+ if (u.contains(this._lastFrameKeys, completedProperty)) {
3271
+ this._finish();
3311
3272
  }
3312
- this._finish();
3313
3273
  }
3314
3274
  _finish() {
3315
3275
  var _a, _b;
@@ -3326,16 +3286,16 @@ up.CSSTransition = class CSSTransition {
3326
3286
  }
3327
3287
  _pauseOldTransition() {
3328
3288
  const oldTransition = e.style(this._element, [
3329
- 'transitionProperty',
3330
- 'transitionDuration',
3331
- 'transitionDelay',
3332
- 'transitionTimingFunction'
3289
+ 'transition-property',
3290
+ 'transition-duration',
3291
+ 'transition-delay',
3292
+ 'transition-timing-function'
3333
3293
  ]);
3334
3294
  if (e.hasCSSTransition(oldTransition)) {
3335
- if (oldTransition.transitionProperty !== 'all') {
3336
- const oldTransitionProperties = oldTransition.transitionProperty.split(/\s*,\s*/);
3337
- const oldTransitionFrameKebab = e.style(this._element, oldTransitionProperties);
3338
- this._setOldTransitionTargetFrame = e.setTemporaryStyle(this._element, oldTransitionFrameKebab);
3295
+ if (oldTransition['transition-property'] !== 'all') {
3296
+ const oldTransitionProperties = oldTransition['transition-property'].split(/\s*,\s*/);
3297
+ const oldTransitionFrame = e.style(this._element, oldTransitionProperties);
3298
+ this._setOldTransitionTargetFrame = e.setTemporaryStyle(this._element, oldTransitionFrame);
3339
3299
  }
3340
3300
  this._setOldTransition = e.concludeCSSTransition(this._element);
3341
3301
  }
@@ -3347,11 +3307,11 @@ up.CSSTransition = class CSSTransition {
3347
3307
  }
3348
3308
  _startMotion() {
3349
3309
  e.setStyle(this._element, {
3350
- transitionProperty: Object.keys(this._lastFrameKebab).join(', '),
3351
- transitionDuration: `${this._duration}ms`,
3352
- transitionTimingFunction: this._easing
3310
+ 'transition-property': this._lastFrameKeys.join(),
3311
+ 'transition-duration': `${this._duration}ms`,
3312
+ 'transition-timing-function': this._easing
3353
3313
  });
3354
- e.setStyle(this._element, this._lastFrameKebab);
3314
+ e.setStyle(this._element, this._lastFrame);
3355
3315
  }
3356
3316
  };
3357
3317
 
@@ -3831,6 +3791,7 @@ var __rest = (this && this.__rest) || function (s, e) {
3831
3791
  return t;
3832
3792
  };
3833
3793
  const u = up.util;
3794
+ const e = up.element;
3834
3795
  up.FormValidator = class FormValidator {
3835
3796
  constructor(form) {
3836
3797
  this._form = form;
@@ -3891,7 +3852,7 @@ up.FormValidator = class FormValidator {
3891
3852
  }
3892
3853
  }
3893
3854
  _getTargetSelectorSolutions({ target, origin }) {
3894
- if (u.isString(target) && target) {
3855
+ if (u.isString(target)) {
3895
3856
  up.puts('up.validate()', 'Validating target "%s"', target);
3896
3857
  let simpleSelectors = up.fragment.splitTarget(target);
3897
3858
  return u.compact(simpleSelectors.map(function (simpleSelector) {
@@ -3920,7 +3881,7 @@ up.FormValidator = class FormValidator {
3920
3881
  _getValidateAttrSolutions(field) {
3921
3882
  let containerWithAttr = field.closest('[up-validate]');
3922
3883
  if (containerWithAttr) {
3923
- let target = containerWithAttr.getAttribute('up-validate');
3884
+ let target = e.booleanOrStringAttr(containerWithAttr, 'up-validate');
3924
3885
  return this._getTargetSelectorSolutions({ target, origin: field });
3925
3886
  }
3926
3887
  }
@@ -3968,7 +3929,8 @@ up.FormValidator = class FormValidator {
3968
3929
  options.guardEvent = up.event.build('up:form:validate', {
3969
3930
  fields: dirtyFields,
3970
3931
  log: 'Validating form',
3971
- params: options.params
3932
+ params: options.params,
3933
+ form: this._form,
3972
3934
  });
3973
3935
  this._rendering = true;
3974
3936
  let renderingPromise = this._nextRenderPromise;
@@ -4617,6 +4579,7 @@ up.Layer = class Layer extends up.Record {
4617
4579
  this.savedTitle = document.title;
4618
4580
  this.savedMetaTags = up.history.findMetaTags();
4619
4581
  this.savedLocation = up.history.location;
4582
+ this.savedLang = up.history.getLang();
4620
4583
  }
4621
4584
  }
4622
4585
  restoreHistory() {
@@ -4632,6 +4595,9 @@ up.Layer = class Layer extends up.Record {
4632
4595
  if (this.savedMetaTags) {
4633
4596
  up.history.updateMetaTags(this.savedMetaTags);
4634
4597
  }
4598
+ if (u.isString(this.savedLang)) {
4599
+ up.history.updateLang(this.savedLang);
4600
+ }
4635
4601
  }
4636
4602
  asCurrent(fn) {
4637
4603
  return this.stack.asCurrent(this, fn);
@@ -4648,6 +4614,9 @@ up.Layer = class Layer extends up.Record {
4648
4614
  if (u.isString(options.title)) {
4649
4615
  this.title = options.title;
4650
4616
  }
4617
+ if (u.isString(options.lang)) {
4618
+ this.lang = options.lang;
4619
+ }
4651
4620
  }
4652
4621
  showsLiveHistory() {
4653
4622
  return this.history && this.isFront();
@@ -4680,6 +4649,20 @@ up.Layer = class Layer extends up.Record {
4680
4649
  up.history.updateMetaTags(metaTags);
4681
4650
  }
4682
4651
  }
4652
+ get lang() {
4653
+ if (this.showsLiveHistory()) {
4654
+ return up.history.getLang();
4655
+ }
4656
+ else {
4657
+ return this.savedLang;
4658
+ }
4659
+ }
4660
+ set lang(lang) {
4661
+ this.savedLang = lang;
4662
+ if (this.showsLiveHistory()) {
4663
+ up.history.updateLang(lang);
4664
+ }
4665
+ }
4683
4666
  get location() {
4684
4667
  if (this.showsLiveHistory()) {
4685
4668
  return up.history.location;
@@ -5408,7 +5391,10 @@ up.LinkFeedbackURLs = class LinkFeedbackURLs {
5408
5391
  }
5409
5392
  isCurrent(normalizedLocation) {
5410
5393
  var _a, _b;
5411
- return this._isSafe && !!(this.href === normalizedLocation ||
5394
+ if (!normalizedLocation) {
5395
+ return false;
5396
+ }
5397
+ return !!(this.href === normalizedLocation ||
5412
5398
  this._upHREF === normalizedLocation ||
5413
5399
  ((_b = (_a = this._aliasPattern) === null || _a === void 0 ? void 0 : _a.test) === null || _b === void 0 ? void 0 : _b.call(_a, normalizedLocation, false)));
5414
5400
  }
@@ -5421,62 +5407,41 @@ up.LinkFeedbackURLs = class LinkFeedbackURLs {
5421
5407
 
5422
5408
  const u = up.util;
5423
5409
  const e = up.element;
5424
- up.LinkPreloader = class LinkPreloader {
5425
- watchLink(link) {
5426
- if (!up.link.preloadIssue(link)) {
5427
- this._on(link, 'mouseenter', (event) => this._considerPreload(event, true));
5428
- this._on(link, 'mousedown touchstart', (event) => this._considerPreload(event));
5429
- this._on(link, 'mouseleave', (event) => this._stopPreload(event));
5430
- }
5431
- }
5432
- _on(link, eventTypes, callback) {
5433
- up.on(link, eventTypes, { passive: true }, callback);
5434
- }
5435
- _considerPreload(event, applyDelay) {
5436
- const link = event.target;
5437
- if (link !== this._currentLink) {
5438
- this.reset();
5439
- this._currentLink = link;
5440
- if (up.link.shouldFollowEvent(event, link)) {
5441
- if (applyDelay) {
5442
- this._preloadAfterDelay(event, link);
5443
- }
5444
- else {
5445
- this._preloadNow(event, link);
5446
- }
5447
- }
5448
- }
5410
+ up.LinkFollowIntent = class LinkFollowIntent {
5411
+ constructor(link, callback) {
5412
+ this._link = link;
5413
+ this._callback = callback;
5414
+ this._on('mouseenter mousedown touchstart', (event) => this._scheduleCallback(event));
5415
+ this._on('mouseleave', () => this._unscheduleCallback());
5416
+ up.fragment.onAborted(this._link, () => this._unscheduleCallback());
5449
5417
  }
5450
- _stopPreload(event) {
5451
- if (event.target === this._currentLink) {
5452
- return this.reset();
5453
- }
5418
+ _on(eventType, callback) {
5419
+ up.on(this._link, eventType, { passive: true }, callback);
5454
5420
  }
5455
- reset() {
5456
- var _a;
5457
- if (!this._currentLink) {
5421
+ _scheduleCallback(event) {
5422
+ if (!up.link.shouldFollowEvent(event, this._link))
5458
5423
  return;
5424
+ this._unscheduleCallback();
5425
+ const applyDelay = (event.type === 'mouseenter');
5426
+ if (applyDelay) {
5427
+ let delay = this._parseDelay();
5428
+ this._timer = u.timer(delay, () => this._runCallback(event));
5459
5429
  }
5460
- clearTimeout(this._timer);
5461
- if ((_a = this._currentRequest) === null || _a === void 0 ? void 0 : _a.background) {
5462
- this._currentRequest.abort();
5430
+ else {
5431
+ this._runCallback(event);
5463
5432
  }
5464
- this._currentLink = undefined;
5465
- this._currentRequest = undefined;
5466
5433
  }
5467
- _preloadAfterDelay(event, link) {
5434
+ _unscheduleCallback() {
5435
+ clearTimeout(this._timer);
5436
+ up.network.abort((request) => (request.origin === this._link) && request.background);
5437
+ }
5438
+ _parseDelay() {
5468
5439
  var _a;
5469
- const delay = (_a = e.numberAttr(link, 'up-preload-delay')) !== null && _a !== void 0 ? _a : up.link.config.preloadDelay;
5470
- this._timer = u.timer(delay, () => this._preloadNow(event, link));
5440
+ return (_a = e.numberAttr(this._link, 'up-preload-delay')) !== null && _a !== void 0 ? _a : up.link.config.preloadDelay;
5471
5441
  }
5472
- _preloadNow(event, link) {
5473
- if (!link.isConnected) {
5474
- this.reset();
5475
- return;
5476
- }
5477
- const onQueued = request => { return this._currentRequest = request; };
5442
+ _runCallback(event) {
5478
5443
  up.log.putsEvent(event);
5479
- up.error.muteUncriticalRejection(up.link.preload(link, { onQueued }));
5444
+ up.error.muteUncriticalRejection(this._callback());
5480
5445
  }
5481
5446
  };
5482
5447
 
@@ -6236,7 +6201,6 @@ up.Request = (_a = class Request extends up.Record {
6236
6201
  'wrapMethod',
6237
6202
  'contentType',
6238
6203
  'payload',
6239
- 'onQueued',
6240
6204
  'onLoading',
6241
6205
  'fail',
6242
6206
  'abortable',
@@ -6271,7 +6235,7 @@ up.Request = (_a = class Request extends up.Record {
6271
6235
  }
6272
6236
  this.deferred = u.newDeferred();
6273
6237
  (_d = this.badResponseTime) !== null && _d !== void 0 ? _d : (this.badResponseTime = u.evalOption(up.network.config.badResponseTime, this));
6274
- this._addAutoHeaders();
6238
+ this._setAutoHeaders();
6275
6239
  }
6276
6240
  get xhr() {
6277
6241
  var _b;
@@ -6281,7 +6245,7 @@ up.Request = (_a = class Request extends up.Record {
6281
6245
  if (this._fragments) {
6282
6246
  return this._fragments;
6283
6247
  }
6284
- else if (this.target) {
6248
+ else {
6285
6249
  let steps = up.fragment.parseTargetSteps(this.target);
6286
6250
  let selectors = u.map(steps, 'selector');
6287
6251
  let lookupOpts = { origin: this.origin, layer: this.layer };
@@ -6337,9 +6301,7 @@ up.Request = (_a = class Request extends up.Record {
6337
6301
  return u.evalAutoOption(this.cache, up.network.config.autoCache, this);
6338
6302
  }
6339
6303
  runQueuedCallbacks() {
6340
- var _b;
6341
6304
  u.always(this, () => this._evictExpensiveAttrs());
6342
- (_b = this.onQueued) === null || _b === void 0 ? void 0 : _b.call(this, this);
6343
6305
  }
6344
6306
  load() {
6345
6307
  var _b;
@@ -6484,9 +6446,6 @@ up.Request = (_a = class Request extends up.Record {
6484
6446
  return this.method + ' ' + this.url;
6485
6447
  }
6486
6448
  isPartOfSubtree(subtreeElements) {
6487
- if (!this.fragments || !subtreeElements) {
6488
- return false;
6489
- }
6490
6449
  subtreeElements = u.wrapList(subtreeElements);
6491
6450
  return u.some(this.fragments, function (fragment) {
6492
6451
  return u.some(subtreeElements, (subtreeElement) => subtreeElement.contains(fragment));
@@ -6498,17 +6457,20 @@ up.Request = (_a = class Request extends up.Record {
6498
6457
  header(name) {
6499
6458
  return this.headers[name];
6500
6459
  }
6501
- _addAutoHeaders() {
6460
+ _setAutoHeaders() {
6502
6461
  for (let key of ['target', 'failTarget', 'mode', 'failMode', 'context', 'failContext']) {
6503
- this._addAutoHeader(up.protocol.headerize(key), this[key]);
6462
+ this._setPropertyHeader(key);
6504
6463
  }
6505
6464
  let csrfHeader, csrfToken;
6506
6465
  if ((csrfHeader = this.csrfHeader()) && (csrfToken = this.csrfToken())) {
6507
- this._addAutoHeader(csrfHeader, csrfToken);
6466
+ this._setAutoHeader(csrfHeader, csrfToken);
6508
6467
  }
6509
- this._addAutoHeader(up.protocol.headerize('version'), up.version);
6468
+ this._setAutoHeader(up.protocol.headerize('version'), up.version);
6469
+ }
6470
+ _setPropertyHeader(key) {
6471
+ this._setAutoHeader(up.protocol.headerize(key), this[key]);
6510
6472
  }
6511
- _addAutoHeader(name, value) {
6473
+ _setAutoHeader(name, value) {
6512
6474
  if (u.isMissing(value)) {
6513
6475
  return;
6514
6476
  }
@@ -6517,6 +6479,16 @@ up.Request = (_a = class Request extends up.Record {
6517
6479
  }
6518
6480
  this.headers[name] = value;
6519
6481
  }
6482
+ mergeIfUnsent(trackingRequest) {
6483
+ if (this.state !== 'new')
6484
+ return;
6485
+ if (!this.target || !trackingRequest.target)
6486
+ return;
6487
+ let targetAtoms = up.fragment.splitTarget(this.target + ',' + trackingRequest.target);
6488
+ this.target = u.uniq(targetAtoms).join(', ');
6489
+ this._setPropertyHeader('target');
6490
+ this._fragments = u.uniq([...this.fragments, ...trackingRequest.fragments]);
6491
+ }
6520
6492
  static tester(condition, { except } = {}) {
6521
6493
  let testFn;
6522
6494
  if (u.isFunction(condition)) {
@@ -6560,78 +6532,85 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
6560
6532
  });
6561
6533
  };
6562
6534
  const u = up.util;
6535
+ class Route {
6536
+ constructor() {
6537
+ this.varyHeaders = new Set();
6538
+ this.requests = [];
6539
+ }
6540
+ matchBest(newRequest) {
6541
+ let matches = this.requests.filter((cachedRequest) => this.satisfies(cachedRequest, newRequest));
6542
+ return u.last(matches);
6543
+ }
6544
+ delete(request) {
6545
+ u.remove(this.requests, request);
6546
+ }
6547
+ put(request) {
6548
+ this.requests.push(request);
6549
+ }
6550
+ updateVary(response) {
6551
+ for (let headerName of response.varyHeaderNames) {
6552
+ this.varyHeaders.add(headerName);
6553
+ }
6554
+ }
6555
+ satisfies(cachedRequest, newRequest) {
6556
+ if (cachedRequest === newRequest)
6557
+ return true;
6558
+ return u.every(this.varyHeaders, (varyHeader) => {
6559
+ let cachedValue = cachedRequest.header(varyHeader);
6560
+ let newValue = newRequest.header(varyHeader);
6561
+ if (varyHeader === 'X-Up-Target' || varyHeader === 'X-Up-Fail-Target') {
6562
+ if (!cachedValue)
6563
+ return true;
6564
+ if (!newValue)
6565
+ return false;
6566
+ let cachedTokens = u.parseTokens(cachedValue, { separator: 'comma' });
6567
+ let newTokens = u.parseTokens(newValue, { separator: 'comma' });
6568
+ return u.containsAll(cachedTokens, newTokens);
6569
+ }
6570
+ else {
6571
+ return cachedValue === newValue;
6572
+ }
6573
+ });
6574
+ }
6575
+ }
6563
6576
  up.Request.Cache = class Cache {
6564
6577
  constructor() {
6565
6578
  this.reset();
6566
6579
  }
6567
6580
  reset() {
6568
- this._varyInfo = {};
6569
- this._map = new Map();
6570
- }
6571
- _cacheKey(request) {
6572
- let influencingHeaders = this._getPreviousInfluencingHeaders(request);
6573
- let varyPart = u.flatMap(influencingHeaders, (headerName) => [headerName, request.header(headerName)]);
6574
- return [request.description, ...varyPart].join(':');
6575
- }
6576
- _getPreviousInfluencingHeaders(request) {
6577
- var _a, _b;
6578
- return ((_a = this._varyInfo)[_b = request.description] || (_a[_b] = new Set()));
6581
+ this._routes = {};
6582
+ this._requests = [];
6579
6583
  }
6580
6584
  get(request) {
6581
6585
  request = this._wrap(request);
6582
- let cacheKey = this._cacheKey(request);
6583
- let cachedRequest = this._map.get(cacheKey);
6586
+ let route = this._getRoute(request);
6587
+ let cachedRequest = route.matchBest(request);
6584
6588
  if (cachedRequest) {
6585
6589
  if (this._isUsable(cachedRequest)) {
6586
6590
  return cachedRequest;
6587
6591
  }
6588
6592
  else {
6589
- this._map.delete(cacheKey);
6593
+ this._delete(request, route);
6590
6594
  }
6591
6595
  }
6592
6596
  }
6593
- get _capacity() {
6594
- return up.network.config.cacheSize;
6595
- }
6596
- _isUsable(request) {
6597
- return request.age < up.network.config.cacheEvictAge;
6598
- }
6599
6597
  put(request) {
6600
6598
  return __awaiter(this, void 0, void 0, function* () {
6601
6599
  request = this._wrap(request);
6602
- this._makeRoom();
6603
- let cacheKey = this._updateCacheKey(request);
6604
- this._map.set(cacheKey, request);
6600
+ let route = this._getRoute(request);
6601
+ let { response } = request;
6602
+ if (response)
6603
+ route.updateVary(response);
6604
+ let superseded = route.requests.filter((oldRequest) => route.satisfies(request, oldRequest));
6605
+ for (let r of superseded) {
6606
+ this._delete(r);
6607
+ }
6608
+ request.cacheRoute = route;
6609
+ route.put(request);
6610
+ this._requests.push(request);
6611
+ this._limitSize();
6605
6612
  });
6606
6613
  }
6607
- _updateCacheKey(request) {
6608
- let oldCacheKey = this._cacheKey(request);
6609
- let { response } = request;
6610
- if (response) {
6611
- this._mergePreviousHeaderNames(request, response);
6612
- let newCacheKey = this._cacheKey(request);
6613
- this._renameMapKey(oldCacheKey, newCacheKey);
6614
- return newCacheKey;
6615
- }
6616
- else {
6617
- return oldCacheKey;
6618
- }
6619
- }
6620
- _renameMapKey(oldKey, newKey) {
6621
- if (oldKey !== newKey && this._map.has(oldKey)) {
6622
- this._map.set(newKey, this._map.get(oldKey));
6623
- this._map.delete(oldKey);
6624
- }
6625
- }
6626
- _mergePreviousHeaderNames(request, response) {
6627
- let headersInfluencingResponse = response.ownInfluncingHeaders;
6628
- if (headersInfluencingResponse.length) {
6629
- let previousInfluencingHeaders = this._getPreviousInfluencingHeaders(request);
6630
- for (let headerName of headersInfluencingResponse) {
6631
- previousInfluencingHeaders.add(headerName);
6632
- }
6633
- }
6634
- }
6635
6614
  alias(existingCachedRequest, newRequest) {
6636
6615
  existingCachedRequest = this.get(existingCachedRequest);
6637
6616
  if (!existingCachedRequest)
@@ -6648,7 +6627,7 @@ up.Request.Cache = class Cache {
6648
6627
  newRequest.state = 'tracking';
6649
6628
  let value = yield u.always(existingRequest);
6650
6629
  if (value instanceof up.Response) {
6651
- if (options.force || this._isCacheCompatible(existingRequest, newRequest)) {
6630
+ if (options.force || existingRequest.cacheRoute.satisfies(existingRequest, newRequest)) {
6652
6631
  newRequest.fromCache = true;
6653
6632
  value = u.variant(value, { request: newRequest });
6654
6633
  newRequest.respondWith(value);
@@ -6669,31 +6648,45 @@ up.Request.Cache = class Cache {
6669
6648
  willHaveSameResponse(existingRequest, newRequest) {
6670
6649
  return existingRequest === newRequest || existingRequest === newRequest.trackedRequest;
6671
6650
  }
6672
- _delete(request) {
6673
- request = this._wrap(request);
6674
- let cacheKey = this._cacheKey(request);
6675
- this._map.delete(cacheKey);
6676
- }
6677
6651
  evict(condition = true, testerOptions) {
6678
6652
  this._eachMatch(condition, testerOptions, (request) => this._delete(request));
6679
6653
  }
6680
6654
  expire(condition = true, testerOptions) {
6681
6655
  this._eachMatch(condition, testerOptions, (request) => request.expired = true);
6682
6656
  }
6683
- _makeRoom() {
6684
- while (this._map.size >= this._capacity) {
6685
- let oldestKey = this._map.keys().next().value;
6686
- this._map.delete(oldestKey);
6657
+ reindex(request) {
6658
+ this._delete(request);
6659
+ this.put(request);
6660
+ }
6661
+ _delete(request) {
6662
+ var _a;
6663
+ u.remove(this._requests, request);
6664
+ (_a = request.cacheRoute) === null || _a === void 0 ? void 0 : _a.delete(request);
6665
+ delete request.cacheRoute;
6666
+ }
6667
+ _getRoute(request) {
6668
+ var _a, _b;
6669
+ return request.cacheRoute || ((_a = this._routes)[_b = request.description] || (_a[_b] = new Route()));
6670
+ }
6671
+ _isUsable(request) {
6672
+ return request.age < up.network.config.cacheEvictAge;
6673
+ }
6674
+ get _size() {
6675
+ return this._requests.length;
6676
+ }
6677
+ get _capacity() {
6678
+ return up.network.config.cacheSize;
6679
+ }
6680
+ _limitSize() {
6681
+ for (let i = 0; i < (this._size - this._capacity); i++) {
6682
+ this._delete(this._requests[0]);
6687
6683
  }
6688
6684
  }
6689
6685
  _eachMatch(condition = true, testerOptions, fn) {
6690
6686
  let tester = up.Request.tester(condition, testerOptions);
6691
- let results = u.filter(this._map.values(), tester);
6687
+ let results = u.filter(this._requests, tester);
6692
6688
  u.each(results, fn);
6693
6689
  }
6694
- _isCacheCompatible(request1, request2) {
6695
- return this._cacheKey(request1) === this._cacheKey(request2);
6696
- }
6697
6690
  _wrap(requestOrOptions) {
6698
6691
  return u.wrapValue(up.Request, requestOrOptions);
6699
6692
  }
@@ -6722,7 +6715,7 @@ up.Request.Queue = class Queue {
6722
6715
  u.always(request, responseOrError => this._onRequestSettled(request, responseOrError));
6723
6716
  this._scheduleSlowTimer(request);
6724
6717
  this._queueRequest(request);
6725
- u.microtask(() => this._poke());
6718
+ queueMicrotask(() => this._poke());
6726
6719
  }
6727
6720
  promoteToForeground(request) {
6728
6721
  if (request.background) {
@@ -6763,7 +6756,7 @@ up.Request.Queue = class Queue {
6763
6756
  up.network.registerAliasForRedirect(request, responseOrError);
6764
6757
  }
6765
6758
  this._checkLate();
6766
- u.microtask(() => this._poke());
6759
+ queueMicrotask(() => this._poke());
6767
6760
  }
6768
6761
  _poke() {
6769
6762
  let request;
@@ -6959,16 +6952,13 @@ up.Response = class Response extends up.Record {
6959
6952
  get none() {
6960
6953
  return !this.text;
6961
6954
  }
6962
- isCacheable() {
6963
- return this.ok && !this.none;
6964
- }
6965
6955
  header(name) {
6966
6956
  var _a;
6967
6957
  return this.headers[name] || ((_a = this.xhr) === null || _a === void 0 ? void 0 : _a.getResponseHeader(name));
6968
6958
  }
6969
- get ownInfluncingHeaders() {
6970
- let influencingHeaders = up.protocol.influencingHeadersFromResponse(this);
6971
- return u.filter(influencingHeaders, (headerName) => this.request.header(headerName));
6959
+ get varyHeaderNames() {
6960
+ let varyHeaderValue = this.header('Vary');
6961
+ return u.parseTokens(varyHeaderValue, { separator: 'comma' });
6972
6962
  }
6973
6963
  get contentType() {
6974
6964
  return this.header('Content-Type');
@@ -7009,6 +6999,7 @@ up.Response = class Response extends up.Record {
7009
6999
  var _a;
7010
7000
  const u = up.util;
7011
7001
  const e = up.element;
7002
+ const FULL_DOCUMENT_PATTERN = /^\s*<(html|!DOCTYPE)\b/i;
7012
7003
  up.ResponseDoc = (_a = class ResponseDoc {
7013
7004
  constructor({ document, fragment, content, target, origin, cspNonces, match }) {
7014
7005
  if (document) {
@@ -7029,43 +7020,43 @@ up.ResponseDoc = (_a = class ResponseDoc {
7029
7020
  }
7030
7021
  this._match = match;
7031
7022
  }
7032
- _parseDocument(document) {
7033
- document = this._parse(document, e.createBrokenDocumentFromHTML);
7034
- this._isDocumentBroken = true;
7035
- this._useParseResult(document);
7036
- }
7037
- _parseFragment(fragment) {
7038
- fragment = this._parse(fragment, e.createFromHTML);
7039
- this._useParseResult(fragment);
7040
- }
7041
- _parseContent(content, target) {
7042
- if (!target)
7043
- up.fail("must pass a { target } when passing { content }");
7044
- target = u.map(up.fragment.parseTargetSteps(target), 'selector').join();
7045
- const matchingElement = e.createFromSelector(target);
7046
- if (u.isString(content)) {
7047
- matchingElement.innerHTML = content;
7023
+ _parseDocument(value) {
7024
+ if (value instanceof Document) {
7025
+ this._document = value;
7026
+ this._isFullDocument = true;
7027
+ }
7028
+ else if (u.isString(value)) {
7029
+ this._document = e.createBrokenDocumentFromHTML(value);
7030
+ this._isFullDocument = FULL_DOCUMENT_PATTERN.test(value);
7031
+ this._isDocumentBroken = true;
7048
7032
  }
7049
7033
  else {
7050
- matchingElement.appendChild(content);
7034
+ this._document = this._buildFauxDocument(value);
7035
+ this._isFullDocument = value.matches('html');
7051
7036
  }
7052
- this._useParseResult(matchingElement);
7053
7037
  }
7054
- _parse(value, parseFn) {
7055
- if (u.isString(value)) {
7056
- value = parseFn(value);
7057
- }
7058
- return value;
7038
+ _parseFragment(value) {
7039
+ let parsed = u.isString(value) ? e.createFromHTML(value) : value;
7040
+ this._document = this._buildFauxDocument(parsed);
7059
7041
  }
7060
- _useParseResult(node) {
7061
- if (node instanceof Document) {
7062
- this._document = node;
7042
+ _parseContent(value, target) {
7043
+ if (!target)
7044
+ up.fail("must pass a { target } when passing { content }");
7045
+ let simplifiedTarget = u.map(up.fragment.parseTargetSteps(target), 'selector').join();
7046
+ const matchingElement = e.createFromSelector(simplifiedTarget);
7047
+ if (u.isString(value)) {
7048
+ matchingElement.innerHTML = value;
7063
7049
  }
7064
7050
  else {
7065
- this._document = document.createElement('up-document');
7066
- this._document.append(node);
7067
- this._document.documentElement = node;
7051
+ matchingElement.appendChild(value);
7068
7052
  }
7053
+ this._document = this._buildFauxDocument(matchingElement);
7054
+ }
7055
+ _buildFauxDocument(node) {
7056
+ let fauxDocument = document.createElement('up-document');
7057
+ fauxDocument.append(node);
7058
+ fauxDocument.documentElement = node;
7059
+ return fauxDocument;
7069
7060
  }
7070
7061
  rootSelector() {
7071
7062
  return up.fragment.toTarget(this._document.documentElement);
@@ -7074,9 +7065,8 @@ up.ResponseDoc = (_a = class ResponseDoc {
7074
7065
  return this._fromHead(this._getTitleText);
7075
7066
  }
7076
7067
  _getHead() {
7077
- let { head } = this._document;
7078
- if (head && head.childNodes.length > 0) {
7079
- return head;
7068
+ if (this._isFullDocument) {
7069
+ return this._document.head;
7080
7070
  }
7081
7071
  }
7082
7072
  _fromHead(fn) {
@@ -7089,6 +7079,11 @@ up.ResponseDoc = (_a = class ResponseDoc {
7089
7079
  get assets() {
7090
7080
  return this._fromHead(up.script.findAssets);
7091
7081
  }
7082
+ get lang() {
7083
+ if (this._isFullDocument) {
7084
+ return up.history.getLang(this._document);
7085
+ }
7086
+ }
7092
7087
  _getTitleText(head) {
7093
7088
  var _b;
7094
7089
  return (_b = head.querySelector('title')) === null || _b === void 0 ? void 0 : _b.textContent;
@@ -7188,7 +7183,7 @@ up.RevealMotion = class RevealMotion {
7188
7183
  const maxPixels = u.evalOption(this._max, this._element);
7189
7184
  elementRect.height = Math.min(elementRect.height, maxPixels);
7190
7185
  }
7191
- this._addPadding(elementRect);
7186
+ elementRect.grow(this._padding);
7192
7187
  this._substractObstructions(viewportRect);
7193
7188
  if (viewportRect.height < 0) {
7194
7189
  up.fail('Viewport has no visible area');
@@ -7227,10 +7222,6 @@ up.RevealMotion = class RevealMotion {
7227
7222
  return up.Rect.fromElement(this._viewport);
7228
7223
  }
7229
7224
  }
7230
- _addPadding(elementRect) {
7231
- elementRect.top -= this._padding;
7232
- elementRect.height += 2 * this._padding;
7233
- }
7234
7225
  _selectObstructions(selector) {
7235
7226
  let elements = up.fragment.all(selector, { layer: this._obstructionsLayer });
7236
7227
  return u.filter(elements, e.isVisible);
@@ -7368,10 +7359,10 @@ up.Tether = class Tether {
7368
7359
  sync() {
7369
7360
  const elementBox = this._element.getBoundingClientRect();
7370
7361
  const elementMargin = {
7371
- top: e.styleNumber(this._element, 'marginTop'),
7372
- right: e.styleNumber(this._element, 'marginRight'),
7373
- bottom: e.styleNumber(this._element, 'marginBottom'),
7374
- left: e.styleNumber(this._element, 'marginLeft')
7362
+ top: e.styleNumber(this._element, 'margin-top'),
7363
+ right: e.styleNumber(this._element, 'margin-right'),
7364
+ bottom: e.styleNumber(this._element, 'margin-bottom'),
7365
+ left: e.styleNumber(this._element, 'margin-left')
7375
7366
  };
7376
7367
  const anchorBox = this._anchor.getBoundingClientRect();
7377
7368
  let left;
@@ -7439,7 +7430,7 @@ up.Tether = class Tether {
7439
7430
  _setOffset(left, top) {
7440
7431
  this.offsetLeft = left;
7441
7432
  this.offsetTop = top;
7442
- e.setStyle(this._element, { left, top });
7433
+ e.setStyle(this._element, { left, top }, 'px');
7443
7434
  }
7444
7435
  };
7445
7436
 
@@ -7783,10 +7774,6 @@ up.protocol = (function () {
7783
7774
  function locationFromXHR(xhr) {
7784
7775
  return extractHeader(xhr, 'location') || xhr.responseURL;
7785
7776
  }
7786
- function influencingHeadersFromResponse(response) {
7787
- let varyHeaderValue = response.header('Vary');
7788
- return u.parseTokens(varyHeaderValue, { separator: 'comma' });
7789
- }
7790
7777
  const config = new up.Config(() => ({
7791
7778
  methodParam: '_method',
7792
7779
  csrfParam() { return e.metaContent('csrf-param'); },
@@ -7847,7 +7834,6 @@ up.protocol = (function () {
7847
7834
  headerize,
7848
7835
  wrapMethod,
7849
7836
  cspNoncesFromHeader,
7850
- influencingHeadersFromResponse,
7851
7837
  };
7852
7838
  })();
7853
7839
 
@@ -7983,44 +7969,61 @@ up.script = (function () {
7983
7969
  let registeredCompilers = [];
7984
7970
  let registeredMacros = [];
7985
7971
  function registerCompiler(...args) {
7986
- const compiler = buildCompiler(args);
7987
- return insertCompiler(registeredCompilers, compiler);
7972
+ registerProcessor(args);
7988
7973
  }
7989
7974
  function registerMacro(...args) {
7990
- const macro = buildCompiler(args);
7991
- if (up.framework.evaling) {
7992
- macro.priority || (macro.priority = detectSystemMacroPriority(macro.selector) ||
7993
- up.fail('Unregistered priority for system macro %o', macro.selector));
7994
- }
7995
- return insertCompiler(registeredMacros, macro);
7975
+ registerProcessor(args, { macro: true });
7976
+ }
7977
+ function registerAttrCompiler(...args) {
7978
+ let [attr, options, valueCallback] = parseProcessorArgs(args);
7979
+ let selector = `[${attr}]`;
7980
+ let callback = (element) => {
7981
+ let value = e.booleanOrStringAttr(element, attr, options.defaultValue);
7982
+ if (!value)
7983
+ return;
7984
+ return valueCallback(element, value);
7985
+ };
7986
+ registerProcessor([selector, options, callback]);
7996
7987
  }
7997
7988
  function detectSystemMacroPriority(macroSelector) {
7998
7989
  macroSelector = u.evalOption(macroSelector);
7999
7990
  for (let substr in SYSTEM_MACRO_PRIORITIES) {
8000
- const priority = SYSTEM_MACRO_PRIORITIES[substr];
8001
7991
  if (macroSelector.indexOf(substr) >= 0) {
8002
- return priority;
7992
+ return SYSTEM_MACRO_PRIORITIES[substr];
8003
7993
  }
8004
7994
  }
7995
+ up.fail('Unregistered priority for system macro %o', macroSelector);
8005
7996
  }
8006
- const parseCompilerArgs = function (args) {
7997
+ function registerProcessor(args, overrides = {}) {
7998
+ let processor = buildProcessor(args, overrides);
7999
+ if (processor.macro) {
8000
+ if (up.framework.evaling) {
8001
+ processor.priority || (processor.priority = detectSystemMacroPriority(processor.selector));
8002
+ }
8003
+ insertProcessor(registeredMacros, processor);
8004
+ }
8005
+ else {
8006
+ insertProcessor(registeredCompilers, processor);
8007
+ }
8008
+ }
8009
+ const parseProcessorArgs = function (args) {
8007
8010
  const defaults = u.extractOptions(args);
8008
8011
  const selector = args.shift();
8009
8012
  const callback = args.pop();
8010
8013
  const options = Object.assign(Object.assign({}, defaults), u.extractOptions(args));
8011
8014
  return [selector, options, callback];
8012
8015
  };
8013
- function buildCompiler(args) {
8014
- let [selector, options, callback] = parseCompilerArgs(args);
8016
+ function buildProcessor(args, overrides) {
8017
+ let [selector, options, callback] = parseProcessorArgs(args);
8015
8018
  options = u.options(options, {
8016
8019
  selector,
8017
8020
  isDefault: up.framework.evaling,
8018
8021
  priority: 0,
8019
8022
  batch: false,
8020
8023
  });
8021
- return Object.assign(callback, options);
8024
+ return Object.assign(callback, options, overrides);
8022
8025
  }
8023
- function insertCompiler(queue, newCompiler) {
8026
+ function insertProcessor(queue, newCompiler) {
8024
8027
  let existingCompiler;
8025
8028
  let index = 0;
8026
8029
  while ((existingCompiler = queue[index]) && (existingCompiler.priority >= newCompiler.priority)) {
@@ -8114,6 +8117,7 @@ up.script = (function () {
8114
8117
  config,
8115
8118
  compiler: registerCompiler,
8116
8119
  macro: registerMacro,
8120
+ attrCompiler: registerAttrCompiler,
8117
8121
  destructor: registerDestructor,
8118
8122
  hello,
8119
8123
  clean,
@@ -8128,6 +8132,7 @@ up.destructor = up.script.destructor;
8128
8132
  up.macro = up.script.macro;
8129
8133
  up.data = up.script.data;
8130
8134
  up.hello = up.script.hello;
8135
+ up.attribute = up.script.attrCompiler;
8131
8136
 
8132
8137
 
8133
8138
  /***/ }),
@@ -8218,10 +8223,8 @@ up.history = (function () {
8218
8223
  return;
8219
8224
  }
8220
8225
  let location = currentLocation();
8221
- if (up.emit('up:location:restore', { location, log: `Restoring location ${location}` }).defaultPrevented) {
8222
- return;
8223
- }
8224
8226
  up.render({
8227
+ guardEvent: up.event.build('up:location:restore', { location, log: `Restoring location ${location}` }),
8225
8228
  url: location,
8226
8229
  target: config.restoreTargets,
8227
8230
  fail: false,
@@ -8229,7 +8232,8 @@ up.history = (function () {
8229
8232
  location,
8230
8233
  peel: true,
8231
8234
  layer: 'root',
8232
- cache: true,
8235
+ cache: 'auto',
8236
+ revalidate: 'auto',
8233
8237
  saveScroll: false,
8234
8238
  scroll: ['restore', 'auto'],
8235
8239
  saveFocus: false,
@@ -8270,6 +8274,15 @@ up.history = (function () {
8270
8274
  document.head.append(newMetaTag);
8271
8275
  }
8272
8276
  }
8277
+ function getLang(doc = document) {
8278
+ let { documentElement } = doc;
8279
+ if (documentElement.matches('html')) {
8280
+ return doc.documentElement.lang;
8281
+ }
8282
+ }
8283
+ function updateLang(newLang) {
8284
+ e.toggleAttr(e.root, 'lang', newLang, !!newLang);
8285
+ }
8273
8286
  up.macro('a[up-back], [up-href][up-back]', function (link) {
8274
8287
  if (previousLocation) {
8275
8288
  e.setMissingAttrs(link, {
@@ -8291,6 +8304,8 @@ up.history = (function () {
8291
8304
  isLocation,
8292
8305
  findMetaTags,
8293
8306
  updateMetaTags,
8307
+ getLang,
8308
+ updateLang,
8294
8309
  };
8295
8310
  })();
8296
8311
 
@@ -8773,6 +8788,25 @@ up.fragment = (function () {
8773
8788
  up.destructor(fragment, unsubscribe);
8774
8789
  return unsubscribe;
8775
8790
  }
8791
+ function onFirstIntersect(origin, callback, { margin = 0 } = {}) {
8792
+ if (e.isIntersectingWindow(origin, { margin })) {
8793
+ callback();
8794
+ return;
8795
+ }
8796
+ function processIntersectEntries(entries) {
8797
+ for (let entry of entries) {
8798
+ if (entry.isIntersecting) {
8799
+ disconnect();
8800
+ callback();
8801
+ return;
8802
+ }
8803
+ }
8804
+ }
8805
+ let observer = new IntersectionObserver(processIntersectEntries, { rootMargin: `${margin}px` });
8806
+ let disconnect = () => observer.disconnect();
8807
+ observer.observe(origin);
8808
+ onAborted(origin, disconnect);
8809
+ }
8776
8810
  up.on('up:framework:boot', function () {
8777
8811
  const { documentElement } = document;
8778
8812
  documentElement.setAttribute('up-source', u.normalizeURL(location.href, { hash: false }));
@@ -8813,6 +8847,7 @@ up.fragment = (function () {
8813
8847
  shouldRevalidate,
8814
8848
  abort,
8815
8849
  onAborted,
8850
+ onFirstIntersect,
8816
8851
  splitTarget,
8817
8852
  parseTargetSteps,
8818
8853
  isAlive,
@@ -8942,33 +8977,9 @@ up.viewport = (function () {
8942
8977
  function isRoot(element) {
8943
8978
  return element === getRoot();
8944
8979
  }
8945
- function rootHasReducedWidthFromScrollbar() {
8946
- return window.innerWidth > document.documentElement.offsetWidth;
8947
- }
8948
- function rootOverflowElement() {
8949
- const { body } = document;
8950
- const html = document.documentElement;
8951
- const element = u.find([html, body], wasChosenAsOverflowingElement);
8952
- return element || getRoot();
8953
- }
8954
- function wasChosenAsOverflowingElement(element) {
8955
- const overflowY = e.style(element, 'overflow-y');
8956
- return overflowY === 'auto' || overflowY === 'scroll';
8957
- }
8958
- const scrollbarWidth = u.memoize(function () {
8959
- const outerStyle = {
8960
- position: 'absolute',
8961
- top: '0',
8962
- left: '0',
8963
- width: '100px',
8964
- height: '100px',
8965
- overflowY: 'scroll'
8966
- };
8967
- const outer = up.element.affix(document.body, '[up-viewport]', { style: outerStyle });
8968
- const width = outer.offsetWidth - outer.clientWidth;
8969
- outer.remove();
8970
- return width;
8971
- });
8980
+ function rootScrollbarWidth() {
8981
+ return window.innerWidth - rootWidth();
8982
+ }
8972
8983
  function scrollTopKey(viewport) {
8973
8984
  return up.fragment.tryToTarget(viewport);
8974
8985
  }
@@ -9085,7 +9096,7 @@ up.viewport = (function () {
9085
9096
  const moveBounds = function (diffX, diffY) {
9086
9097
  boundsRect.left += diffX;
9087
9098
  boundsRect.top += diffY;
9088
- return e.setStyle(bounds, boundsRect);
9099
+ return e.setStyle(bounds, boundsRect, 'px');
9089
9100
  };
9090
9101
  moveBounds(0, 0);
9091
9102
  const newElementRect = element.getBoundingClientRect();
@@ -9146,10 +9157,8 @@ up.viewport = (function () {
9146
9157
  get root() { return getRoot(); },
9147
9158
  rootWidth,
9148
9159
  rootHeight,
9149
- rootHasReducedWidthFromScrollbar,
9150
- rootOverflowElement,
9151
9160
  isRoot,
9152
- scrollbarWidth,
9161
+ rootScrollbarWidth,
9153
9162
  saveScroll,
9154
9163
  restoreScroll,
9155
9164
  resetScroll,
@@ -9234,13 +9243,16 @@ up.motion = (function () {
9234
9243
  return Promise.resolve();
9235
9244
  }
9236
9245
  function animateNow(element, lastFrame, options) {
9246
+ if (up.migrate.loaded)
9247
+ lastFrame = up.migrate.fixStyleProps(lastFrame);
9237
9248
  options = Object.assign(Object.assign({}, options), { finishEvent: motionController.finishEvent });
9238
9249
  const cssTransition = new up.CSSTransition(element, lastFrame, options);
9239
9250
  return cssTransition.start();
9240
9251
  }
9241
9252
  function applyConfig(options) {
9242
- options.easing || (options.easing = config.easing);
9243
- options.duration || (options.duration = config.duration);
9253
+ var _a, _b;
9254
+ (_a = options.easing) !== null && _a !== void 0 ? _a : (options.easing = config.easing);
9255
+ (_b = options.duration) !== null && _b !== void 0 ? _b : (options.duration = config.duration);
9244
9256
  }
9245
9257
  function findNamedAnimation(name) {
9246
9258
  return namedAnimations[name] || up.fail("Unknown animation %o", name);
@@ -9390,7 +9402,7 @@ up.motion = (function () {
9390
9402
  return { transform: `translate(${dx}px, ${dy}px)` };
9391
9403
  }
9392
9404
  function noTranslateCSS() {
9393
- return { transform: null };
9405
+ return { transform: '' };
9394
9406
  }
9395
9407
  function untranslatedBox(element) {
9396
9408
  e.setStyle(element, noTranslateCSS());
@@ -9510,6 +9522,7 @@ up.network = (function () {
9510
9522
  if (!newRequest.background) {
9511
9523
  queue.promoteToForeground(cachedRequest);
9512
9524
  }
9525
+ cachedRequest.mergeIfUnsent(newRequest);
9513
9526
  cache.track(cachedRequest, newRequest, { onIncompatible: processRequest });
9514
9527
  return true;
9515
9528
  }
@@ -9522,10 +9535,10 @@ up.network = (function () {
9522
9535
  function handleCaching(request) {
9523
9536
  if (request.willCache()) {
9524
9537
  cache.put(request);
9525
- request.onLoading = () => cache.put(request);
9538
+ request.onLoading = () => cache.reindex(request);
9526
9539
  }
9527
9540
  u.always(request, function (responseOrError) {
9528
- var _a, _b, _c, _d, _e;
9541
+ var _a, _b, _c, _d;
9529
9542
  let expireCache = (_b = (_a = responseOrError.expireCache) !== null && _a !== void 0 ? _a : request.expireCache) !== null && _b !== void 0 ? _b : u.evalOption(config.expireCache, request, responseOrError);
9530
9543
  if (expireCache) {
9531
9544
  cache.expire(expireCache, { except: request });
@@ -9534,12 +9547,21 @@ up.network = (function () {
9534
9547
  if (evictCache) {
9535
9548
  cache.evict(evictCache, { except: request });
9536
9549
  }
9537
- if (cache.get(request)) {
9538
- cache.put(request);
9550
+ let hasCacheEntry = cache.get(request);
9551
+ let isResponse = responseOrError instanceof up.Response;
9552
+ let isNetworkError = !isResponse;
9553
+ let isSuccessResponse = isResponse && responseOrError.ok;
9554
+ let isErrorResponse = isResponse && !responseOrError.ok;
9555
+ let isEmptyResponse = isResponse && responseOrError.none;
9556
+ if (isErrorResponse) {
9557
+ cache.evict(request.url);
9539
9558
  }
9540
- if (!((_e = responseOrError.isCacheable) === null || _e === void 0 ? void 0 : _e.call(responseOrError))) {
9559
+ else if (isNetworkError || isEmptyResponse) {
9541
9560
  cache.evict(request);
9542
9561
  }
9562
+ else if (isSuccessResponse && hasCacheEntry) {
9563
+ cache.put(request);
9564
+ }
9543
9565
  });
9544
9566
  }
9545
9567
  function isBusy() {
@@ -9557,7 +9579,8 @@ up.network = (function () {
9557
9579
  if (request.cache && response.url && request.url !== response.url) {
9558
9580
  const newRequest = u.variant(request, {
9559
9581
  method: response.method,
9560
- url: response.url
9582
+ url: response.url,
9583
+ cacheRoute: null,
9561
9584
  });
9562
9585
  cache.alias(request, newRequest);
9563
9586
  }
@@ -9864,7 +9887,6 @@ __webpack_require__(96);
9864
9887
  up.link = (function () {
9865
9888
  const u = up.util;
9866
9889
  const e = up.element;
9867
- const linkPreloader = new up.LinkPreloader();
9868
9890
  let lastMousedownTarget = null;
9869
9891
  const LINKS_WITH_LOCAL_HTML = ['a[up-content]', 'a[up-fragment]', 'a[up-document]'];
9870
9892
  const LINKS_WITH_REMOTE_HTML = ['a[href]', '[up-href]'];
@@ -9898,10 +9920,9 @@ up.link = (function () {
9898
9920
  }
9899
9921
  function reset() {
9900
9922
  lastMousedownTarget = null;
9901
- linkPreloader.reset();
9902
9923
  }
9903
- const follow = up.mockable(function (link, options) {
9904
- return up.render(followOptions(link, options));
9924
+ const follow = up.mockable(function (link, options, parserOptions) {
9925
+ return up.render(followOptions(link, options, parserOptions));
9905
9926
  });
9906
9927
  function parseRequestOptions(link, options, parserOptions) {
9907
9928
  options = u.options(options);
@@ -9923,6 +9944,7 @@ up.link = (function () {
9923
9944
  return options;
9924
9945
  }
9925
9946
  function followOptions(link, options, parserOptions) {
9947
+ var _a;
9926
9948
  link = up.fragment.get(link);
9927
9949
  options = u.options(options);
9928
9950
  const parser = new up.OptionsParser(link, options, Object.assign({ fail: true }, parserOptions));
@@ -9976,10 +9998,9 @@ up.link = (function () {
9976
9998
  parser.booleanOrString('location');
9977
9999
  parser.booleanOrString('title');
9978
10000
  parser.boolean('metaTags');
10001
+ parser.booleanOrString('lang');
9979
10002
  parser.include(up.motion.motionOptions);
9980
- if (!options.guardEvent) {
9981
- options.guardEvent = up.event.build('up:link:follow', { log: 'Following link' });
9982
- }
10003
+ (_a = options.guardEvent) !== null && _a !== void 0 ? _a : (options.guardEvent = up.event.build('up:link:follow', { log: ['Following link %o', link] }));
9983
10004
  return options;
9984
10005
  }
9985
10006
  function preload(link, options) {
@@ -10018,9 +10039,10 @@ up.link = (function () {
10018
10039
  if (link.matches('a[href], button')) {
10019
10040
  return;
10020
10041
  }
10042
+ let role = link.matches('a') ? 'link' : 'button';
10021
10043
  e.setMissingAttrs(link, {
10022
10044
  tabindex: '0',
10023
- role: 'link',
10045
+ role,
10024
10046
  'up-clickable': ''
10025
10047
  });
10026
10048
  link.addEventListener('keydown', function (event) {
@@ -10080,6 +10102,38 @@ up.link = (function () {
10080
10102
  const method = followMethod(link);
10081
10103
  return up.network.isSafeMethod(method);
10082
10104
  }
10105
+ function onLoadCondition(condition, link, callback) {
10106
+ switch (condition) {
10107
+ case 'insert':
10108
+ callback();
10109
+ break;
10110
+ case 'reveal': {
10111
+ let margin = e.numberAttr(link, 'up-intersect-margin');
10112
+ up.fragment.onFirstIntersect(link, callback, { margin });
10113
+ break;
10114
+ }
10115
+ case 'hover':
10116
+ new up.LinkFollowIntent(link, callback);
10117
+ break;
10118
+ case 'manual':
10119
+ break;
10120
+ }
10121
+ }
10122
+ function loadDeferred(link, options) {
10123
+ let guardEvent = up.event.build('up:deferred:load', { log: ['Loading deferred %o', link] });
10124
+ let forcedOptions = Object.assign({ navigate: false, guardEvent }, options);
10125
+ let defaults = {
10126
+ target: ':origin',
10127
+ cache: 'auto',
10128
+ revalidate: 'auto',
10129
+ feedback: true,
10130
+ };
10131
+ return follow(link, forcedOptions, { defaults });
10132
+ }
10133
+ up.attribute('up-defer', { defaultValue: 'insert' }, function (link, condition) {
10134
+ let doLoad = () => up.error.muteUncriticalRejection(loadDeferred(link));
10135
+ onLoadCondition(condition, link, doLoad);
10136
+ });
10083
10137
  up.on('up:click', config.selectorFn('followSelectors'), function (event, link) {
10084
10138
  if (shouldFollowEvent(event, link)) {
10085
10139
  up.event.halt(event, { log: true });
@@ -10087,21 +10141,20 @@ up.link = (function () {
10087
10141
  up.error.muteUncriticalRejection(follow(link));
10088
10142
  }
10089
10143
  });
10090
- up.macro('[up-expand]', function (area) {
10091
- const selector = area.getAttribute('up-expand') || 'a, [up-href]';
10092
- let childLink = e.get(area, selector);
10144
+ up.attribute('up-expand', { defaultValue: 'a, [up-href]', macro: true }, function (area, childLinkSelector) {
10145
+ let childLink = e.get(area, childLinkSelector);
10093
10146
  if (childLink) {
10094
- const areaAttrs = e.upAttrs(childLink);
10095
- areaAttrs['up-href'] || (areaAttrs['up-href'] = childLink.getAttribute('href'));
10096
- e.setMissingAttrs(area, areaAttrs);
10097
- const areaClasses = e.upClasses(childLink);
10098
- area.classList.add(...areaClasses);
10147
+ e.setMissingAttrs(area, Object.assign({ 'up-href': e.attr(childLink, 'href') }, e.upAttrs(childLink)));
10148
+ area.classList.add(...e.upClasses(childLink));
10099
10149
  makeFollowable(area);
10100
10150
  }
10101
10151
  });
10102
10152
  up.compiler(config.selectorFn('preloadSelectors'), function (link) {
10153
+ var _a;
10103
10154
  if (!isPreloadDisabled(link)) {
10104
- linkPreloader.watchLink(link);
10155
+ let doPreload = () => up.error.muteUncriticalRejection(preload(link));
10156
+ let condition = (_a = e.booleanOrStringAttr(link, 'up-preload', null)) !== null && _a !== void 0 ? _a : 'hover';
10157
+ onLoadCondition(condition, link, doPreload);
10105
10158
  }
10106
10159
  });
10107
10160
  up.on('up:framework:reset', reset);
@@ -10110,18 +10163,17 @@ up.link = (function () {
10110
10163
  followOptions,
10111
10164
  preload,
10112
10165
  makeFollowable,
10113
- makeClickable,
10114
10166
  isSafe,
10115
10167
  isFollowable,
10116
10168
  shouldFollowEvent,
10117
- followMethod,
10118
10169
  convertClicks,
10119
10170
  config,
10120
10171
  combineFollowableSelectors,
10121
- preloadIssue,
10172
+ loadDeferred,
10122
10173
  };
10123
10174
  })();
10124
10175
  up.follow = up.link.follow;
10176
+ up.deferred = { load: up.link.loadDeferred };
10125
10177
 
10126
10178
 
10127
10179
  /***/ }),
@@ -10194,7 +10246,8 @@ up.form = (function () {
10194
10246
  options.guardEvent || (options.guardEvent = up.event.build('up:form:submit', {
10195
10247
  submitButton: options.submitButton,
10196
10248
  log: 'Submitting form',
10197
- params: options.params
10249
+ params: options.params,
10250
+ form,
10198
10251
  }));
10199
10252
  options.origin || (options.origin = up.viewport.focusedElementWithin(form) || options.submitButton || form);
10200
10253
  parser.include(up.link.followOptions);
@@ -10469,7 +10522,9 @@ up.form = (function () {
10469
10522
  validator.watchContainer(fieldOrForm);
10470
10523
  });
10471
10524
  function validatingFieldSelector() {
10472
- return config.fieldSelectors.map((selector) => `${selector}[up-validate], [up-validate] ${selector}`).join(', ');
10525
+ let includes = config.fieldSelectors.map((selector) => `${selector}[up-validate], [up-validate] ${selector}`);
10526
+ let excludes = ['[up-validate=false]'];
10527
+ return e.unionSelector(includes, excludes);
10473
10528
  }
10474
10529
  up.compiler('[up-switch]', (switcher) => {
10475
10530
  switchTargets(switcher);
@@ -10480,8 +10535,8 @@ up.form = (function () {
10480
10535
  up.compiler('[up-show-for]:not(.up-switched), [up-hide-for]:not(.up-switched)', (element) => {
10481
10536
  switchTarget(element);
10482
10537
  });
10483
- up.compiler('[up-watch]', (formOrField) => watch(formOrField));
10484
- up.compiler('[up-autosubmit]', (formOrField) => autosubmit(formOrField));
10538
+ up.attribute('up-watch', (formOrField) => watch(formOrField));
10539
+ up.attribute('up-autosubmit', (formOrField) => autosubmit(formOrField));
10485
10540
  return {
10486
10541
  config,
10487
10542
  submit,
@@ -10523,6 +10578,7 @@ up.feedback = (function () {
10523
10578
  const config = new up.Config(() => ({
10524
10579
  currentClasses: ['up-current'],
10525
10580
  navSelectors: ['[up-nav]', 'nav'],
10581
+ noNavSelectors: ['[up-nav=false]'],
10526
10582
  }));
10527
10583
  function reset() {
10528
10584
  up.layer.root.feedbackLocation = null;
@@ -10530,9 +10586,6 @@ up.feedback = (function () {
10530
10586
  const CLASS_ACTIVE = 'up-active';
10531
10587
  const CLASS_LOADING = 'up-loading';
10532
10588
  const SELECTOR_LINK = 'a, [up-href]';
10533
- function navSelector() {
10534
- return config.selector('navSelectors');
10535
- }
10536
10589
  function normalizeURL(url) {
10537
10590
  if (url) {
10538
10591
  return u.normalizeURL(url, { trailingSlash: false, hash: false });
@@ -10541,40 +10594,23 @@ up.feedback = (function () {
10541
10594
  function linkURLs(link) {
10542
10595
  return link.upFeedbackURLs || (link.upFeedbackURLs = new up.LinkFeedbackURLs(link));
10543
10596
  }
10544
- function updateFragment(fragment) {
10545
- const layerOption = { layer: up.layer.get(fragment) };
10546
- if (up.fragment.closest(fragment, navSelector(), layerOption)) {
10547
- const links = up.fragment.subtree(fragment, SELECTOR_LINK, layerOption);
10548
- updateLinks(links, layerOption);
10549
- }
10550
- else {
10551
- updateLinksWithinNavs(fragment, layerOption);
10597
+ function updateFragment(fragment, { layer } = {}) {
10598
+ layer || (layer = up.layer.get(fragment));
10599
+ let layerLocation = getNormalizedLayerLocation(layer);
10600
+ const navSelector = config.selector('navSelectors');
10601
+ const navLinkSelector = `${navSelector} :is(${SELECTOR_LINK}), ${navSelector}:is(${SELECTOR_LINK})`;
10602
+ const links = up.fragment.all(navLinkSelector, { layer });
10603
+ for (let link of links) {
10604
+ const isCurrent = linkURLs(link).isCurrent(layerLocation);
10605
+ for (let currentClass of config.currentClasses) {
10606
+ link.classList.toggle(currentClass, isCurrent);
10607
+ }
10608
+ e.toggleAttr(link, 'aria-current', 'page', isCurrent);
10552
10609
  }
10553
10610
  }
10554
- function updateLinksWithinNavs(fragment, options) {
10555
- const navs = up.fragment.subtree(fragment, navSelector(), options);
10556
- const links = u.flatMap(navs, nav => e.subtree(nav, SELECTOR_LINK));
10557
- updateLinks(links, options);
10558
- }
10559
10611
  function getNormalizedLayerLocation(layer) {
10560
10612
  return layer.feedbackLocation || normalizeURL(layer.location);
10561
10613
  }
10562
- function updateLinks(links, options = {}) {
10563
- if (!links.length) {
10564
- return;
10565
- }
10566
- const layer = options.layer || up.layer.get(links[0]);
10567
- let layerLocation = getNormalizedLayerLocation(layer);
10568
- if (layerLocation) {
10569
- for (let link of links) {
10570
- const isCurrent = linkURLs(link).isCurrent(layerLocation);
10571
- for (let currentClass of config.currentClasses) {
10572
- link.classList.toggle(currentClass, isCurrent);
10573
- }
10574
- e.toggleAttr(link, 'aria-current', 'page', isCurrent);
10575
- }
10576
- }
10577
- }
10578
10614
  function findActivatableArea(element) {
10579
10615
  return e.ancestor(element, SELECTOR_LINK) || element;
10580
10616
  }
@@ -10602,7 +10638,7 @@ up.feedback = (function () {
10602
10638
  const layerLocation = getNormalizedLayerLocation(layer.location);
10603
10639
  if (!processedLocation || (processedLocation !== layerLocation)) {
10604
10640
  layer.feedbackLocation = layerLocation;
10605
- updateLinksWithinNavs(layer.element, { layer });
10641
+ updateFragment(layer.element, { layer });
10606
10642
  }
10607
10643
  }
10608
10644
  function onBrowserLocationChanged() {
@@ -10637,6 +10673,7 @@ up.radio = (function () {
10637
10673
  const e = up.element;
10638
10674
  const config = new up.Config(() => ({
10639
10675
  hungrySelectors: ['[up-hungry]'],
10676
+ noHungrySelectors: ['[up-hungry=false]'],
10640
10677
  pollInterval: 30000,
10641
10678
  }));
10642
10679
  function hungrySteps(renderOptions) {
@@ -10682,7 +10719,7 @@ up.radio = (function () {
10682
10719
  parser.string('ifLayer', { default: 'front' });
10683
10720
  return options;
10684
10721
  }
10685
- up.compiler('[up-poll]:not([up-poll=false])', function (fragment) {
10722
+ up.attribute('up-poll', function (fragment) {
10686
10723
  up.FragmentPolling.forFragment(fragment).onPollAttributeObserved();
10687
10724
  });
10688
10725
  up.macro('[up-flashes]', function (fragment) {