unpoly-rails 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of unpoly-rails might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91c3f510e29295809e0304db849e1853897d8f14fbe6b363519458dca5c0294a
4
- data.tar.gz: 43a927f3a2946f63e02c2676514eeee7d5689750e38de4528d6d140e1be2a47e
3
+ metadata.gz: beba0d8578cac674b4e6cda8f8a062eae1217198fdc6e1f6e0a525b6bb61c395
4
+ data.tar.gz: 6b962622c193cd2c3910c0dba3830a092dbfb6c7b02ea58ce47d15765dc488a4
5
5
  SHA512:
6
- metadata.gz: 501d2a3533c6c3225fd702d6ce4de682c0359d13f9e8063c1390c547ec8782afb0f70597e9b768ce945b69fde2b72c21a1bcc099c13b15d7107207201ebd5300
7
- data.tar.gz: 513bbe7a3764942a35696d3ea5d7335fff289b914732a1b17bbe31f5da896ca7979f263e8fa000373641dd939f1a2e1bb2c26cf6b5290325fc24598b2cff8a3a
6
+ metadata.gz: 00ce246b00f89e57b7996c42489e72ba249d2976747d8a46bb21a5ebd35dd3575f29acb1b00bbd012b44c25633c1d3cb41c67be4748fe0feb6044b349475eede
7
+ data.tar.gz: c07e6975fe87448e624eb5be7d90a862a9abdb9a4f07a970acee59dd106d0499adec32a884a18b341e38c1de1d2cb35df336ef9ef3194f7eb0ffb0a796eb3491
@@ -8,7 +8,7 @@
8
8
  @module up
9
9
  */
10
10
  window.up = {
11
- version: '2.3.0'
11
+ version: '2.4.0'
12
12
  };
13
13
 
14
14
 
@@ -105,27 +105,63 @@ up.util = (function () {
105
105
  }
106
106
  var NORMALIZE_URL_DEFAULTS = {
107
107
  host: 'cross-domain',
108
- stripTrailingSlash: false,
109
- search: true,
110
- hash: false
111
108
  };
112
109
  /*-
113
- Normalizes the given URL or path.
110
+ Returns a normalized version of the given URL string.
111
+
112
+ Two URLs that point to the same resource should normalize to the same string.
113
+
114
+ ### Comparing normalized URLs
115
+
116
+ The main purpose of this function is to normalize two URLs for string comparison:
117
+
118
+ ```js
119
+ up.util.normalizeURL('http://current-host/path') === up.util.normalizeURL('/path') // => true
120
+ ```
121
+
122
+ By default the hostname is only included if it points to a different origin:
123
+
124
+ ```js
125
+ up.util.normalizeURL('http://current-host/path') // => '/path'
126
+ up.util.normalizeURL('http://other-host/path') // => 'http://other-host/path'
127
+ ```
128
+
129
+ Relative paths are normalized to absolute paths:
130
+
131
+ ```js
132
+ up.util.normalizeURL('index.html') // => '/path/index.html'
133
+ ```
134
+
135
+ ### Excluding URL components
136
+
137
+ You may pass options to exclude URL components from the normalized string:
138
+
139
+ ```js
140
+ up.util.normalizeURL('/foo?query=bar', { query: false }) => '/foo'
141
+ up.util.normalizeURL('/bar#hash', { hash: false }) => '/bar'
142
+ ```
143
+
144
+ ### Limitations
145
+
146
+ - Username and password are always omitted from the normalized URL.
147
+ - Only `http` and `https` schemes are supported.
114
148
 
115
149
  @function up.util.normalizeURL
116
150
  @param {boolean} [options.host='cross-domain']
117
151
  Whether to include protocol, hostname and port in the normalized URL.
118
152
 
119
- By default the host is only included if it differ's from the page's hostname.
120
- @param {boolean} [options.hash=false]
121
- Whether to include an `#hash` anchor in the normalized URL
153
+ When set to `'cross-domain'` (the default), the host is only included if it differ's from the page's hostname.
154
+
155
+ The port is omitted if the port is the standard port for the given protocol, e.g. `:443` for `https://`.
156
+ @param {boolean} [options.hash=true]
157
+ Whether to include an `#hash` anchor in the normalized URL.
122
158
  @param {boolean} [options.search=true]
123
- Whether to include a `?query` string in the normalized URL
124
- @param {boolean} [options.stripTrailingSlash=false]
125
- Whether to strip a trailing slash from the pathname
159
+ Whether to include a `?query` string in the normalized URL.
160
+ @param {boolean} [options.trailingSlash=true]
161
+ Whether to include a trailing slash from the pathname.
126
162
  @return {string}
127
163
  The normalized URL.
128
- @internal
164
+ @experimental
129
165
  */
130
166
  function normalizeURL(urlOrAnchor, options) {
131
167
  options = newOptions(options, NORMALIZE_URL_DEFAULTS);
@@ -144,21 +180,18 @@ up.util = (function () {
144
180
  }
145
181
  }
146
182
  var pathname = parts.pathname;
147
- if (options.stripTrailingSlash) {
183
+ if (options.trailingSlash === false && pathname !== '/') {
148
184
  pathname = pathname.replace(/\/$/, '');
149
185
  }
150
186
  normalized += pathname;
151
- if (options.search) {
187
+ if (options.search !== false) {
152
188
  normalized += parts.search;
153
189
  }
154
- if (options.hash) {
190
+ if (options.hash !== false) {
155
191
  normalized += parts.hash;
156
192
  }
157
193
  return normalized;
158
194
  }
159
- function urlWithoutHost(url) {
160
- return normalizeURL(url, { host: false });
161
- }
162
195
  function matchURLs(leftURL, rightURL) {
163
196
  return normalizeURL(leftURL) === normalizeURL(rightURL);
164
197
  }
@@ -1961,7 +1994,6 @@ up.util = (function () {
1961
1994
  return {
1962
1995
  parseURL: parseURL,
1963
1996
  normalizeURL: normalizeURL,
1964
- urlWithoutHost: urlWithoutHost,
1965
1997
  matchURLs: matchURLs,
1966
1998
  normalizeMethod: normalizeMethod,
1967
1999
  methodAllowsPayload: methodAllowsPayload,
@@ -4035,7 +4067,7 @@ up.Change.Addition = /** @class */ (function (_super) {
4035
4067
  // (1) Don't set a source if { false } is passed.
4036
4068
  // (2) Don't set a source if the element HTML already has an [up-source] attribute.
4037
4069
  if (source) {
4038
- e.setMissingAttr(newElement, 'up-source', u.normalizeURL(source));
4070
+ e.setMissingAttr(newElement, 'up-source', u.normalizeURL(source, { hash: false }));
4039
4071
  }
4040
4072
  };
4041
4073
  return Addition;
@@ -14447,7 +14479,7 @@ up.history = (function () {
14447
14479
  /*-
14448
14480
  Returns a normalized URL for the previous history entry.
14449
14481
 
14450
- Only history entries pushed by Unpoly will be considered.
14482
+ Only history entries added by Unpoly functions will be considered.
14451
14483
 
14452
14484
  @property up.history.previousLocation
14453
14485
  @param {string} previousLocation
@@ -14461,14 +14493,20 @@ up.history = (function () {
14461
14493
  nextPreviousLocation = undefined;
14462
14494
  trackCurrentLocation();
14463
14495
  }
14464
- function normalizeURL(url, normalizeOptions) {
14465
- if (normalizeOptions === void 0) { normalizeOptions = {}; }
14466
- normalizeOptions.hash = true;
14467
- return u.normalizeURL(url, normalizeOptions);
14496
+ var DEFAULT_NORMALIZE_OPTIONS = { hash: true };
14497
+ function normalizeURL(url, options) {
14498
+ // The reason why we this takes an { options } object is that
14499
+ // isCurrentLocation() ignores a trailing slash. This is used to check whether
14500
+ // we're already at the given URL before pushing a history state.
14501
+ options = u.merge(DEFAULT_NORMALIZE_OPTIONS, options);
14502
+ return u.normalizeURL(url, options);
14468
14503
  }
14469
14504
  /*-
14470
14505
  Returns a normalized URL for the current browser location.
14471
14506
 
14507
+ The returned URL is an absolute pathname like `"/path"` without a hostname or port.
14508
+ It will include a `#hash` fragment and query string, if present.
14509
+
14472
14510
  Note that if the current [layer](/up.layer) does not have [visible history](/up.Layer.prototype.history),
14473
14511
  the browser's address bar will show the location of an ancestor layer.
14474
14512
  To get the location of the current layer, use `up.layer.location`.
@@ -14494,11 +14532,51 @@ up.history = (function () {
14494
14532
  }
14495
14533
  }
14496
14534
  trackCurrentLocation();
14497
- function isCurrentLocation(url) {
14498
- // Some web frameworks care about a trailing slash, some consider it optional.
14499
- // Only for the equality test (is this the current URL) we consider it optional.
14500
- var normalizeOptions = { stripTrailingSlash: true };
14501
- return normalizeURL(url, normalizeOptions) === currentLocation(normalizeOptions);
14535
+ // Some web frameworks care about a trailing slash, some consider it optional.
14536
+ // Only for the equality test ("is this the current URL?") we consider it optional.
14537
+ // Note that we inherit { hash: true } from DEFAULT_NORMALIZE_OPTIONS.
14538
+ var ADDITIONAL_NORMALIZE_OPTIONS_FOR_COMPARISON = { trailingSlash: false };
14539
+ /*-
14540
+ Returns whether the given URL matches the [current browser location](/up.history.location).
14541
+
14542
+ ### Examples
14543
+
14544
+ ```js
14545
+ location.hostname // => '/path'
14546
+
14547
+ up.history.isLocation('/path') // => true
14548
+ up.history.isLocation('/path?query') // => false
14549
+ up.history.isLocation('/path#hash') // => false
14550
+ up.history.isLocation('/other') // => false
14551
+ ```
14552
+
14553
+ The given URL is [normalized](/up.util.normalizeURL), so any URL string pointing to the browser location
14554
+ will match:
14555
+
14556
+ ```js
14557
+ location.hostname // => '/current-host'
14558
+ location.pathname // => '/foo'
14559
+
14560
+ up.history.isLocation('/foo') // => true
14561
+ up.history.isLocation('http://current-host/foo') // => true
14562
+ up.history.isLocation('http://otgher-host/foo') // => false
14563
+ ```
14564
+
14565
+ @function up.history.isLocation
14566
+ @param {string} url
14567
+ The URL to compare against the current browser location.
14568
+
14569
+ This can be a either an absolute pathname (`/path`), a relative filename (`index.html`) or a fully qualified URL (`https://...`).
14570
+ @param {boolean} [options.hash=true]
14571
+ Whether to consider `#hash` fragments in the given or current URLs.
14572
+
14573
+ When set to `false` this function will consider the URLs `/foo#one` and `/foo#two` to be equal.
14574
+ @return {boolean}
14575
+ @experimental
14576
+ */
14577
+ function isLocation(url, options) {
14578
+ options = u.merge(ADDITIONAL_NORMALIZE_OPTIONS_FOR_COMPARISON, options);
14579
+ return normalizeURL(url, options) === currentLocation(options);
14502
14580
  }
14503
14581
  /*-
14504
14582
  Replaces the current history entry and updates the
@@ -14518,8 +14596,9 @@ up.history = (function () {
14518
14596
  */
14519
14597
  function replace(url, options) {
14520
14598
  if (options === void 0) { options = {}; }
14599
+ url = normalizeURL(url);
14521
14600
  if (manipulate('replaceState', url) && (options.event !== false)) {
14522
- emit('up:location:changed', { url: url, reason: 'replace', log: "Replaced state for " + u.urlWithoutHost(url) });
14601
+ emit('up:location:changed', { url: url, reason: 'replace', log: "Replaced state for " + url });
14523
14602
  }
14524
14603
  }
14525
14604
  /*-
@@ -14532,6 +14611,8 @@ up.history = (function () {
14532
14611
  Note that [fragment navigation](/navigation) will automatically update the
14533
14612
  browser's location bar for you.
14534
14613
 
14614
+ Does not add a history entry if the the given URL is already the current browser location.
14615
+
14535
14616
  Emits event `up:location:changed`.
14536
14617
 
14537
14618
  @function up.history.push
@@ -14541,8 +14622,8 @@ up.history = (function () {
14541
14622
  */
14542
14623
  function push(url) {
14543
14624
  url = normalizeURL(url);
14544
- if (!isCurrentLocation(url) && manipulate('pushState', url)) {
14545
- up.emit('up:location:changed', { url: url, reason: 'push', log: "Advanced to location " + u.urlWithoutHost(url) });
14625
+ if (!isLocation(url) && manipulate('pushState', url)) {
14626
+ up.emit('up:location:changed', { url: url, reason: 'push', log: "Advanced to location " + url });
14546
14627
  }
14547
14628
  }
14548
14629
  /*-
@@ -14705,8 +14786,8 @@ up.history = (function () {
14705
14786
  replace: replace,
14706
14787
  get location() { return currentLocation(); },
14707
14788
  get previousLocation() { return previousLocation; },
14708
- isLocation: isCurrentLocation,
14709
- normalizeURL: normalizeURL
14789
+ normalizeURL: normalizeURL,
14790
+ isLocation: isLocation
14710
14791
  };
14711
14792
  })();
14712
14793
 
@@ -16507,7 +16588,7 @@ up.fragment = (function () {
16507
16588
  }
16508
16589
  up.on('up:framework:boot', function () {
16509
16590
  var body = document.body;
16510
- body.setAttribute('up-source', up.history.location);
16591
+ body.setAttribute('up-source', u.normalizeURL(location.href, { hash: false }));
16511
16592
  hello(body);
16512
16593
  if (!up.browser.canPushState()) {
16513
16594
  return up.warn('Cannot push history changes. Next fragment update will load in a new page.');
@@ -17157,7 +17238,7 @@ up.viewport = (function () {
17157
17238
  var _a = parseOptions(args), viewports = _a[0], options = _a[1];
17158
17239
  var url = options.layer.location;
17159
17240
  var scrollTopsForURL = options.layer.lastScrollTops.get(url) || {};
17160
- up.puts('up.viewport.restoreScroll()', 'Restoring scroll positions for URL %s to %o', u.urlWithoutHost(url), scrollTopsForURL);
17241
+ up.puts('up.viewport.restoreScroll()', 'Restoring scroll positions for URL %s to %o', url, scrollTopsForURL);
17161
17242
  return setScrollTops(viewports, scrollTopsForURL);
17162
17243
  }
17163
17244
  function parseOptions(args) {
@@ -18678,20 +18759,11 @@ up.network = (function () {
18678
18759
  }
18679
18760
  var request = new up.Request(parseRequestOptions(args));
18680
18761
  useCachedRequest(request) || queueRequest(request);
18681
- var solo = request.solo;
18682
- if (solo) {
18683
- // The { solo } option may also contain a function.
18684
- // This way users can excempt some requests from being solo-aborted
18685
- // by configuring up.fragment.config.navigateOptions.
18686
- queue.abortExcept(request, solo);
18687
- }
18762
+ handleSolo(request);
18688
18763
  return request;
18689
18764
  }
18690
18765
  function mimicLocalRequest(options) {
18691
- var solo = options.solo;
18692
- if (solo) {
18693
- abortRequests(solo);
18694
- }
18766
+ handleSolo(options);
18695
18767
  // We cannot consult config.clearCache since there is no up.Request
18696
18768
  // for a local update.
18697
18769
  var clearCache = options.clearCache;
@@ -18699,6 +18771,21 @@ up.network = (function () {
18699
18771
  cache.clear(clearCache);
18700
18772
  }
18701
18773
  }
18774
+ function handleSolo(requestOrOptions) {
18775
+ var solo = requestOrOptions.solo;
18776
+ if (solo && isBusy()) {
18777
+ up.puts('up.request()', 'Change with { solo } option will abort other requests');
18778
+ // The { solo } option may also contain a function.
18779
+ // This way users can excempt some requests from being solo-aborted
18780
+ // by configuring up.fragment.config.navigateOptions.
18781
+ if (requestOrOptions instanceof up.Request) {
18782
+ queue.abortExcept(requestOrOptions, solo);
18783
+ }
18784
+ else {
18785
+ abortRequests(solo);
18786
+ }
18787
+ }
18788
+ }
18702
18789
  function parseRequestOptions(args) {
18703
18790
  var _a, _b;
18704
18791
  var options = u.extractOptions(args);
@@ -22905,10 +22992,11 @@ up.feedback = (function () {
22905
22992
  */
22906
22993
  var config = new up.Config(function () { return ({
22907
22994
  currentClasses: ['up-current'],
22908
- navSelectors: ['[up-nav]', 'nav']
22995
+ navSelectors: ['[up-nav]', 'nav'],
22909
22996
  }); });
22910
22997
  function reset() {
22911
22998
  config.reset();
22999
+ up.layer.root.feedbackLocation = null;
22912
23000
  }
22913
23001
  var CLASS_ACTIVE = 'up-active';
22914
23002
  var SELECTOR_LINK = 'a, [up-href]';
@@ -22917,7 +23005,7 @@ up.feedback = (function () {
22917
23005
  }
22918
23006
  function normalizeURL(url) {
22919
23007
  if (url) {
22920
- return u.normalizeURL(url, { stripTrailingSlash: true });
23008
+ return u.normalizeURL(url, { trailingSlash: false, hash: false });
22921
23009
  }
22922
23010
  }
22923
23011
  function linkURLs(link) {
@@ -22952,17 +23040,11 @@ up.feedback = (function () {
22952
23040
  var links = u.flatMap(navs, function (nav) { return e.subtree(nav, SELECTOR_LINK); });
22953
23041
  updateLinks(links, options);
22954
23042
  }
22955
- var getLayerLocation = function (layer) {
22956
- // so multiple calls for the same layer won't unnecessarily reprocess links.
22957
- // We update the property on up:layer:location:changed.
22958
- //
22959
- // The { feedbackLocation } property may be nil if:
22960
- // (1) The layer was opened without a location, e.g. if it was created from local HTML.
22961
- // (2) The layer is the root layer and the location was never changed.
22962
- // The initial page load does not emit an up:layer:location:changed event for
22963
- // the root layer to be consistent with up:location:changed.
22964
- return layer.feedbackLocation || layer.location;
22965
- };
23043
+ function getNormalizedLayerLocation(layer) {
23044
+ // Don't re-use layer.feedbackLocation since the current layer returns
23045
+ // location.href in case someone changed the history using the pushState API.
23046
+ return layer.feedbackLocation || normalizeURL(layer.location);
23047
+ }
22966
23048
  function updateLinks(links, options) {
22967
23049
  if (options === void 0) { options = {}; }
22968
23050
  if (!links.length) {
@@ -22971,7 +23053,7 @@ up.feedback = (function () {
22971
23053
  var layer = options.layer || up.layer.get(links[0]);
22972
23054
  // An overlay might not have a { location } property, e.g. if it was created
22973
23055
  // from local { content }. In this case we do not set .up-current.
22974
- var layerLocation = getLayerLocation(layer);
23056
+ var layerLocation = getNormalizedLayerLocation(layer);
22975
23057
  if (layerLocation) {
22976
23058
  for (var _i = 0, links_1 = links; _i < links_1.length; _i++) {
22977
23059
  var link = links_1[_i];
@@ -23188,6 +23270,8 @@ up.feedback = (function () {
23188
23270
  - the link's `[up-href]` attribute
23189
23271
  - the URL pattern in the link's [`[up-alias]`](/a-up-alias) attribute
23190
23272
 
23273
+ Any `#hash` fragments in the link's or current URLs will be ignored.
23274
+
23191
23275
  @selector [up-nav]
23192
23276
  @stable
23193
23277
  */
@@ -23222,13 +23306,14 @@ up.feedback = (function () {
23222
23306
  */
23223
23307
  function updateLayerIfLocationChanged(layer) {
23224
23308
  var processedLocation = layer.feedbackLocation;
23225
- var currentLocation = normalizeURL(layer.location);
23309
+ var layerLocation = getNormalizedLayerLocation(layer.location);
23226
23310
  // A history change might call this function multiple times,
23227
23311
  // since we listen to both up:location:changed and up:layer:location:changed.
23312
+ // We also don't want to unnecessarily reprocess nav links, which is expensive.
23228
23313
  // For this reason we check whether the current location differs from
23229
23314
  // the last processed location.
23230
- if (!processedLocation || (processedLocation !== currentLocation)) {
23231
- layer.feedbackLocation = currentLocation;
23315
+ if (!processedLocation || (processedLocation !== layerLocation)) {
23316
+ layer.feedbackLocation = layerLocation;
23232
23317
  updateLinksWithinNavs(layer.element, { layer: layer });
23233
23318
  }
23234
23319
  }
@@ -23258,7 +23343,7 @@ up.feedback = (function () {
23258
23343
  stop: stop,
23259
23344
  around: around,
23260
23345
  aroundForOptions: aroundForOptions,
23261
- normalizeURL: normalizeURL
23346
+ normalizeURL: normalizeURL,
23262
23347
  };
23263
23348
  })();
23264
23349