unpoly-rails 2.3.0 → 2.4.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.
Potentially problematic release.
This version of unpoly-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/assets/unpoly/unpoly.es5.js +151 -66
- data/assets/unpoly/unpoly.es5.min.js +1 -1
- data/assets/unpoly/unpoly.js +151 -65
- data/assets/unpoly/unpoly.min.js +1 -1
- data/lib/unpoly/rails/version.rb +1 -1
- metadata +2 -2
data/assets/unpoly/unpoly.js
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
@module up
|
9
9
|
*/
|
10
10
|
window.up = {
|
11
|
-
version: '2.
|
11
|
+
version: '2.4.0'
|
12
12
|
};
|
13
13
|
|
14
14
|
|
@@ -96,27 +96,63 @@ up.util = (function () {
|
|
96
96
|
}
|
97
97
|
const NORMALIZE_URL_DEFAULTS = {
|
98
98
|
host: 'cross-domain',
|
99
|
-
stripTrailingSlash: false,
|
100
|
-
search: true,
|
101
|
-
hash: false
|
102
99
|
};
|
103
100
|
/*-
|
104
|
-
|
101
|
+
Returns a normalized version of the given URL string.
|
102
|
+
|
103
|
+
Two URLs that point to the same resource should normalize to the same string.
|
104
|
+
|
105
|
+
### Comparing normalized URLs
|
106
|
+
|
107
|
+
The main purpose of this function is to normalize two URLs for string comparison:
|
108
|
+
|
109
|
+
```js
|
110
|
+
up.util.normalizeURL('http://current-host/path') === up.util.normalizeURL('/path') // => true
|
111
|
+
```
|
112
|
+
|
113
|
+
By default the hostname is only included if it points to a different origin:
|
114
|
+
|
115
|
+
```js
|
116
|
+
up.util.normalizeURL('http://current-host/path') // => '/path'
|
117
|
+
up.util.normalizeURL('http://other-host/path') // => 'http://other-host/path'
|
118
|
+
```
|
119
|
+
|
120
|
+
Relative paths are normalized to absolute paths:
|
121
|
+
|
122
|
+
```js
|
123
|
+
up.util.normalizeURL('index.html') // => '/path/index.html'
|
124
|
+
```
|
125
|
+
|
126
|
+
### Excluding URL components
|
127
|
+
|
128
|
+
You may pass options to exclude URL components from the normalized string:
|
129
|
+
|
130
|
+
```js
|
131
|
+
up.util.normalizeURL('/foo?query=bar', { query: false }) => '/foo'
|
132
|
+
up.util.normalizeURL('/bar#hash', { hash: false }) => '/bar'
|
133
|
+
```
|
134
|
+
|
135
|
+
### Limitations
|
136
|
+
|
137
|
+
- Username and password are always omitted from the normalized URL.
|
138
|
+
- Only `http` and `https` schemes are supported.
|
105
139
|
|
106
140
|
@function up.util.normalizeURL
|
107
141
|
@param {boolean} [options.host='cross-domain']
|
108
142
|
Whether to include protocol, hostname and port in the normalized URL.
|
109
143
|
|
110
|
-
|
111
|
-
|
112
|
-
|
144
|
+
When set to `'cross-domain'` (the default), the host is only included if it differ's from the page's hostname.
|
145
|
+
|
146
|
+
The port is omitted if the port is the standard port for the given protocol, e.g. `:443` for `https://`.
|
147
|
+
@param {boolean} [options.hash=true]
|
148
|
+
Whether to include an `#hash` anchor in the normalized URL.
|
113
149
|
@param {boolean} [options.search=true]
|
114
|
-
Whether to include a `?query` string in the normalized URL
|
115
|
-
@param {boolean} [options.
|
116
|
-
Whether to
|
150
|
+
Whether to include a `?query` string in the normalized URL.
|
151
|
+
@param {boolean} [options.trailingSlash=true]
|
152
|
+
Whether to include a trailing slash from the pathname.
|
117
153
|
@return {string}
|
118
154
|
The normalized URL.
|
119
|
-
@
|
155
|
+
@experimental
|
120
156
|
*/
|
121
157
|
function normalizeURL(urlOrAnchor, options) {
|
122
158
|
options = newOptions(options, NORMALIZE_URL_DEFAULTS);
|
@@ -135,21 +171,18 @@ up.util = (function () {
|
|
135
171
|
}
|
136
172
|
}
|
137
173
|
let { pathname } = parts;
|
138
|
-
if (options.
|
174
|
+
if (options.trailingSlash === false && pathname !== '/') {
|
139
175
|
pathname = pathname.replace(/\/$/, '');
|
140
176
|
}
|
141
177
|
normalized += pathname;
|
142
|
-
if (options.search) {
|
178
|
+
if (options.search !== false) {
|
143
179
|
normalized += parts.search;
|
144
180
|
}
|
145
|
-
if (options.hash) {
|
181
|
+
if (options.hash !== false) {
|
146
182
|
normalized += parts.hash;
|
147
183
|
}
|
148
184
|
return normalized;
|
149
185
|
}
|
150
|
-
function urlWithoutHost(url) {
|
151
|
-
return normalizeURL(url, { host: false });
|
152
|
-
}
|
153
186
|
function matchURLs(leftURL, rightURL) {
|
154
187
|
return normalizeURL(leftURL) === normalizeURL(rightURL);
|
155
188
|
}
|
@@ -1911,7 +1944,6 @@ up.util = (function () {
|
|
1911
1944
|
return {
|
1912
1945
|
parseURL,
|
1913
1946
|
normalizeURL,
|
1914
|
-
urlWithoutHost,
|
1915
1947
|
matchURLs,
|
1916
1948
|
normalizeMethod,
|
1917
1949
|
methodAllowsPayload,
|
@@ -3858,7 +3890,7 @@ up.Change.Addition = class Addition extends up.Change {
|
|
3858
3890
|
// (1) Don't set a source if { false } is passed.
|
3859
3891
|
// (2) Don't set a source if the element HTML already has an [up-source] attribute.
|
3860
3892
|
if (source) {
|
3861
|
-
e.setMissingAttr(newElement, 'up-source', u.normalizeURL(source));
|
3893
|
+
e.setMissingAttr(newElement, 'up-source', u.normalizeURL(source, { hash: false }));
|
3862
3894
|
}
|
3863
3895
|
}
|
3864
3896
|
};
|
@@ -12962,7 +12994,7 @@ up.history = (function () {
|
|
12962
12994
|
/*-
|
12963
12995
|
Returns a normalized URL for the previous history entry.
|
12964
12996
|
|
12965
|
-
Only history entries
|
12997
|
+
Only history entries added by Unpoly functions will be considered.
|
12966
12998
|
|
12967
12999
|
@property up.history.previousLocation
|
12968
13000
|
@param {string} previousLocation
|
@@ -12976,13 +13008,20 @@ up.history = (function () {
|
|
12976
13008
|
nextPreviousLocation = undefined;
|
12977
13009
|
trackCurrentLocation();
|
12978
13010
|
}
|
12979
|
-
|
12980
|
-
|
12981
|
-
|
13011
|
+
const DEFAULT_NORMALIZE_OPTIONS = { hash: true };
|
13012
|
+
function normalizeURL(url, options) {
|
13013
|
+
// The reason why we this takes an { options } object is that
|
13014
|
+
// isCurrentLocation() ignores a trailing slash. This is used to check whether
|
13015
|
+
// we're already at the given URL before pushing a history state.
|
13016
|
+
options = u.merge(DEFAULT_NORMALIZE_OPTIONS, options);
|
13017
|
+
return u.normalizeURL(url, options);
|
12982
13018
|
}
|
12983
13019
|
/*-
|
12984
13020
|
Returns a normalized URL for the current browser location.
|
12985
13021
|
|
13022
|
+
The returned URL is an absolute pathname like `"/path"` without a hostname or port.
|
13023
|
+
It will include a `#hash` fragment and query string, if present.
|
13024
|
+
|
12986
13025
|
Note that if the current [layer](/up.layer) does not have [visible history](/up.Layer.prototype.history),
|
12987
13026
|
the browser's address bar will show the location of an ancestor layer.
|
12988
13027
|
To get the location of the current layer, use `up.layer.location`.
|
@@ -13008,11 +13047,51 @@ up.history = (function () {
|
|
13008
13047
|
}
|
13009
13048
|
}
|
13010
13049
|
trackCurrentLocation();
|
13011
|
-
|
13012
|
-
|
13013
|
-
|
13014
|
-
|
13015
|
-
|
13050
|
+
// Some web frameworks care about a trailing slash, some consider it optional.
|
13051
|
+
// Only for the equality test ("is this the current URL?") we consider it optional.
|
13052
|
+
// Note that we inherit { hash: true } from DEFAULT_NORMALIZE_OPTIONS.
|
13053
|
+
const ADDITIONAL_NORMALIZE_OPTIONS_FOR_COMPARISON = { trailingSlash: false };
|
13054
|
+
/*-
|
13055
|
+
Returns whether the given URL matches the [current browser location](/up.history.location).
|
13056
|
+
|
13057
|
+
### Examples
|
13058
|
+
|
13059
|
+
```js
|
13060
|
+
location.hostname // => '/path'
|
13061
|
+
|
13062
|
+
up.history.isLocation('/path') // => true
|
13063
|
+
up.history.isLocation('/path?query') // => false
|
13064
|
+
up.history.isLocation('/path#hash') // => false
|
13065
|
+
up.history.isLocation('/other') // => false
|
13066
|
+
```
|
13067
|
+
|
13068
|
+
The given URL is [normalized](/up.util.normalizeURL), so any URL string pointing to the browser location
|
13069
|
+
will match:
|
13070
|
+
|
13071
|
+
```js
|
13072
|
+
location.hostname // => '/current-host'
|
13073
|
+
location.pathname // => '/foo'
|
13074
|
+
|
13075
|
+
up.history.isLocation('/foo') // => true
|
13076
|
+
up.history.isLocation('http://current-host/foo') // => true
|
13077
|
+
up.history.isLocation('http://otgher-host/foo') // => false
|
13078
|
+
```
|
13079
|
+
|
13080
|
+
@function up.history.isLocation
|
13081
|
+
@param {string} url
|
13082
|
+
The URL to compare against the current browser location.
|
13083
|
+
|
13084
|
+
This can be a either an absolute pathname (`/path`), a relative filename (`index.html`) or a fully qualified URL (`https://...`).
|
13085
|
+
@param {boolean} [options.hash=true]
|
13086
|
+
Whether to consider `#hash` fragments in the given or current URLs.
|
13087
|
+
|
13088
|
+
When set to `false` this function will consider the URLs `/foo#one` and `/foo#two` to be equal.
|
13089
|
+
@return {boolean}
|
13090
|
+
@experimental
|
13091
|
+
*/
|
13092
|
+
function isLocation(url, options) {
|
13093
|
+
options = u.merge(ADDITIONAL_NORMALIZE_OPTIONS_FOR_COMPARISON, options);
|
13094
|
+
return normalizeURL(url, options) === currentLocation(options);
|
13016
13095
|
}
|
13017
13096
|
/*-
|
13018
13097
|
Replaces the current history entry and updates the
|
@@ -13031,8 +13110,9 @@ up.history = (function () {
|
|
13031
13110
|
@internal
|
13032
13111
|
*/
|
13033
13112
|
function replace(url, options = {}) {
|
13113
|
+
url = normalizeURL(url);
|
13034
13114
|
if (manipulate('replaceState', url) && (options.event !== false)) {
|
13035
|
-
emit('up:location:changed', { url, reason: 'replace', log: `Replaced state for ${
|
13115
|
+
emit('up:location:changed', { url, reason: 'replace', log: `Replaced state for ${url}` });
|
13036
13116
|
}
|
13037
13117
|
}
|
13038
13118
|
/*-
|
@@ -13045,6 +13125,8 @@ up.history = (function () {
|
|
13045
13125
|
Note that [fragment navigation](/navigation) will automatically update the
|
13046
13126
|
browser's location bar for you.
|
13047
13127
|
|
13128
|
+
Does not add a history entry if the the given URL is already the current browser location.
|
13129
|
+
|
13048
13130
|
Emits event `up:location:changed`.
|
13049
13131
|
|
13050
13132
|
@function up.history.push
|
@@ -13054,8 +13136,8 @@ up.history = (function () {
|
|
13054
13136
|
*/
|
13055
13137
|
function push(url) {
|
13056
13138
|
url = normalizeURL(url);
|
13057
|
-
if (!
|
13058
|
-
up.emit('up:location:changed', { url, reason: 'push', log: `Advanced to location ${
|
13139
|
+
if (!isLocation(url) && manipulate('pushState', url)) {
|
13140
|
+
up.emit('up:location:changed', { url, reason: 'push', log: `Advanced to location ${url}` });
|
13059
13141
|
}
|
13060
13142
|
}
|
13061
13143
|
/*-
|
@@ -13204,8 +13286,8 @@ up.history = (function () {
|
|
13204
13286
|
replace,
|
13205
13287
|
get location() { return currentLocation(); },
|
13206
13288
|
get previousLocation() { return previousLocation; },
|
13207
|
-
|
13208
|
-
|
13289
|
+
normalizeURL,
|
13290
|
+
isLocation
|
13209
13291
|
};
|
13210
13292
|
})();
|
13211
13293
|
|
@@ -14957,7 +15039,7 @@ up.fragment = (function () {
|
|
14957
15039
|
}
|
14958
15040
|
up.on('up:framework:boot', function () {
|
14959
15041
|
const { body } = document;
|
14960
|
-
body.setAttribute('up-source',
|
15042
|
+
body.setAttribute('up-source', u.normalizeURL(location.href, { hash: false }));
|
14961
15043
|
hello(body);
|
14962
15044
|
if (!up.browser.canPushState()) {
|
14963
15045
|
return up.warn('Cannot push history changes. Next fragment update will load in a new page.');
|
@@ -15585,7 +15667,7 @@ up.viewport = (function () {
|
|
15585
15667
|
const [viewports, options] = parseOptions(args);
|
15586
15668
|
const url = options.layer.location;
|
15587
15669
|
const scrollTopsForURL = options.layer.lastScrollTops.get(url) || {};
|
15588
|
-
up.puts('up.viewport.restoreScroll()', 'Restoring scroll positions for URL %s to %o',
|
15670
|
+
up.puts('up.viewport.restoreScroll()', 'Restoring scroll positions for URL %s to %o', url, scrollTopsForURL);
|
15589
15671
|
return setScrollTops(viewports, scrollTopsForURL);
|
15590
15672
|
}
|
15591
15673
|
function parseOptions(args) {
|
@@ -17031,20 +17113,11 @@ up.network = (function () {
|
|
17031
17113
|
function makeRequest(...args) {
|
17032
17114
|
const request = new up.Request(parseRequestOptions(args));
|
17033
17115
|
useCachedRequest(request) || queueRequest(request);
|
17034
|
-
|
17035
|
-
if (solo) {
|
17036
|
-
// The { solo } option may also contain a function.
|
17037
|
-
// This way users can excempt some requests from being solo-aborted
|
17038
|
-
// by configuring up.fragment.config.navigateOptions.
|
17039
|
-
queue.abortExcept(request, solo);
|
17040
|
-
}
|
17116
|
+
handleSolo(request);
|
17041
17117
|
return request;
|
17042
17118
|
}
|
17043
17119
|
function mimicLocalRequest(options) {
|
17044
|
-
|
17045
|
-
if (solo) {
|
17046
|
-
abortRequests(solo);
|
17047
|
-
}
|
17120
|
+
handleSolo(options);
|
17048
17121
|
// We cannot consult config.clearCache since there is no up.Request
|
17049
17122
|
// for a local update.
|
17050
17123
|
let clearCache = options.clearCache;
|
@@ -17052,6 +17125,21 @@ up.network = (function () {
|
|
17052
17125
|
cache.clear(clearCache);
|
17053
17126
|
}
|
17054
17127
|
}
|
17128
|
+
function handleSolo(requestOrOptions) {
|
17129
|
+
let solo = requestOrOptions.solo;
|
17130
|
+
if (solo && isBusy()) {
|
17131
|
+
up.puts('up.request()', 'Change with { solo } option will abort other requests');
|
17132
|
+
// The { solo } option may also contain a function.
|
17133
|
+
// This way users can excempt some requests from being solo-aborted
|
17134
|
+
// by configuring up.fragment.config.navigateOptions.
|
17135
|
+
if (requestOrOptions instanceof up.Request) {
|
17136
|
+
queue.abortExcept(requestOrOptions, solo);
|
17137
|
+
}
|
17138
|
+
else {
|
17139
|
+
abortRequests(solo);
|
17140
|
+
}
|
17141
|
+
}
|
17142
|
+
}
|
17055
17143
|
function parseRequestOptions(args) {
|
17056
17144
|
const options = u.extractOptions(args);
|
17057
17145
|
if (!options.url) {
|
@@ -21156,10 +21244,11 @@ up.feedback = (function () {
|
|
21156
21244
|
*/
|
21157
21245
|
const config = new up.Config(() => ({
|
21158
21246
|
currentClasses: ['up-current'],
|
21159
|
-
navSelectors: ['[up-nav]', 'nav']
|
21247
|
+
navSelectors: ['[up-nav]', 'nav'],
|
21160
21248
|
}));
|
21161
21249
|
function reset() {
|
21162
21250
|
config.reset();
|
21251
|
+
up.layer.root.feedbackLocation = null;
|
21163
21252
|
}
|
21164
21253
|
const CLASS_ACTIVE = 'up-active';
|
21165
21254
|
const SELECTOR_LINK = 'a, [up-href]';
|
@@ -21168,7 +21257,7 @@ up.feedback = (function () {
|
|
21168
21257
|
}
|
21169
21258
|
function normalizeURL(url) {
|
21170
21259
|
if (url) {
|
21171
|
-
return u.normalizeURL(url, {
|
21260
|
+
return u.normalizeURL(url, { trailingSlash: false, hash: false });
|
21172
21261
|
}
|
21173
21262
|
}
|
21174
21263
|
function linkURLs(link) {
|
@@ -21203,17 +21292,11 @@ up.feedback = (function () {
|
|
21203
21292
|
const links = u.flatMap(navs, nav => e.subtree(nav, SELECTOR_LINK));
|
21204
21293
|
updateLinks(links, options);
|
21205
21294
|
}
|
21206
|
-
|
21207
|
-
|
21208
|
-
|
21209
|
-
|
21210
|
-
|
21211
|
-
// The { feedbackLocation } property may be nil if:
|
21212
|
-
// (1) The layer was opened without a location, e.g. if it was created from local HTML.
|
21213
|
-
// (2) The layer is the root layer and the location was never changed.
|
21214
|
-
// The initial page load does not emit an up:layer:location:changed event for
|
21215
|
-
// the root layer to be consistent with up:location:changed.
|
21216
|
-
layer.feedbackLocation || layer.location;
|
21295
|
+
function getNormalizedLayerLocation(layer) {
|
21296
|
+
// Don't re-use layer.feedbackLocation since the current layer returns
|
21297
|
+
// location.href in case someone changed the history using the pushState API.
|
21298
|
+
return layer.feedbackLocation || normalizeURL(layer.location);
|
21299
|
+
}
|
21217
21300
|
function updateLinks(links, options = {}) {
|
21218
21301
|
if (!links.length) {
|
21219
21302
|
return;
|
@@ -21221,7 +21304,7 @@ up.feedback = (function () {
|
|
21221
21304
|
const layer = options.layer || up.layer.get(links[0]);
|
21222
21305
|
// An overlay might not have a { location } property, e.g. if it was created
|
21223
21306
|
// from local { content }. In this case we do not set .up-current.
|
21224
|
-
let layerLocation =
|
21307
|
+
let layerLocation = getNormalizedLayerLocation(layer);
|
21225
21308
|
if (layerLocation) {
|
21226
21309
|
for (let link of links) {
|
21227
21310
|
const isCurrent = linkURLs(link).isCurrent(layerLocation);
|
@@ -21436,6 +21519,8 @@ up.feedback = (function () {
|
|
21436
21519
|
- the link's `[up-href]` attribute
|
21437
21520
|
- the URL pattern in the link's [`[up-alias]`](/a-up-alias) attribute
|
21438
21521
|
|
21522
|
+
Any `#hash` fragments in the link's or current URLs will be ignored.
|
21523
|
+
|
21439
21524
|
@selector [up-nav]
|
21440
21525
|
@stable
|
21441
21526
|
*/
|
@@ -21470,13 +21555,14 @@ up.feedback = (function () {
|
|
21470
21555
|
*/
|
21471
21556
|
function updateLayerIfLocationChanged(layer) {
|
21472
21557
|
const processedLocation = layer.feedbackLocation;
|
21473
|
-
const
|
21558
|
+
const layerLocation = getNormalizedLayerLocation(layer.location);
|
21474
21559
|
// A history change might call this function multiple times,
|
21475
21560
|
// since we listen to both up:location:changed and up:layer:location:changed.
|
21561
|
+
// We also don't want to unnecessarily reprocess nav links, which is expensive.
|
21476
21562
|
// For this reason we check whether the current location differs from
|
21477
21563
|
// the last processed location.
|
21478
|
-
if (!processedLocation || (processedLocation !==
|
21479
|
-
layer.feedbackLocation =
|
21564
|
+
if (!processedLocation || (processedLocation !== layerLocation)) {
|
21565
|
+
layer.feedbackLocation = layerLocation;
|
21480
21566
|
updateLinksWithinNavs(layer.element, { layer });
|
21481
21567
|
}
|
21482
21568
|
}
|
@@ -21506,7 +21592,7 @@ up.feedback = (function () {
|
|
21506
21592
|
stop,
|
21507
21593
|
around,
|
21508
21594
|
aroundForOptions,
|
21509
|
-
normalizeURL
|
21595
|
+
normalizeURL,
|
21510
21596
|
};
|
21511
21597
|
})();
|
21512
21598
|
|