unpoly-rails 0.51.1 → 0.52.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/CHANGELOG.md +21 -2
- data/dist/unpoly.js +102 -33
- data/dist/unpoly.min.js +4 -4
- data/lib/assets/javascripts/unpoly/classes/follow_variant.coffee +3 -2
- data/lib/assets/javascripts/unpoly/classes/request.coffee +20 -7
- data/lib/assets/javascripts/unpoly/form.coffee +23 -9
- data/lib/assets/javascripts/unpoly/link.coffee +13 -0
- data/lib/assets/javascripts/unpoly/protocol.coffee +5 -7
- data/lib/assets/javascripts/unpoly/proxy.coffee +1 -1
- data/lib/assets/javascripts/unpoly/syntax.coffee +6 -0
- data/lib/assets/javascripts/unpoly/util.coffee +16 -2
- data/lib/unpoly/rails/version.rb +1 -1
- data/package.json +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/app/controllers/form_test/redirects_controller.rb +17 -0
- data/spec_app/app/views/form_test/redirects/new.erb +27 -0
- data/spec_app/app/views/form_test/redirects/target.erb +4 -0
- data/spec_app/app/views/pages/start.erb +1 -0
- data/spec_app/config/routes.rb +5 -0
- data/spec_app/spec/javascripts/helpers/last_request.js.coffee +2 -0
- data/spec_app/spec/javascripts/up/browser_spec.js.coffee +19 -0
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +18 -0
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +18 -0
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +59 -0
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +8 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24e1c3554a4c11b5fea24fea4397140f394ff0a9
|
4
|
+
data.tar.gz: 7ade92982a0beb9ddb8cac452aa13ba4dfbada61
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b470bc42358455541f1ec11e3d08b1655be173a911aeb9acd0babe9a8cd47c76fab5128c899b79c8ba4f47baa5a4e6d464a35f0402d6577f866f92699d4f5cf
|
7
|
+
data.tar.gz: fb755591fd57695660aacde41c4b09f8c3de8fc24bfaa07b24e9d3ab82920c5e76ed96a0cfd8b1a35e46c0740970d776c9f91f3820a4cb230bb8dda20c07d053
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,27 @@ Changes to this project will be documented in this file.
|
|
6
6
|
This project mostly adheres to [Semantic Versioning](http://semver.org/).
|
7
7
|
|
8
8
|
|
9
|
+
0.52.0
|
10
|
+
------
|
11
|
+
|
12
|
+
### Browser support
|
13
|
+
|
14
|
+
- No longer prints an error to console when registering a [macro](/up.macro) on an unsupported browser.
|
15
|
+
|
16
|
+
### AJAX requests
|
17
|
+
|
18
|
+
- Unpoly can now detect the final URL of a redirect response without the [optional server protocol](/up.protocol).
|
19
|
+
The server protocol is still needed to detect redirects on Internet Explorer 11.
|
20
|
+
- When making HTTP requests Unpoly will now always merge params in the URL's query section with params from the `{ data }` option.
|
21
|
+
|
22
|
+
### Forms
|
23
|
+
|
24
|
+
- [Following](/up.follow) a link now emits an [`up:link:follow`](/up:link:follow) event. The event can be prevented.
|
25
|
+
|
26
|
+
### Forms
|
27
|
+
|
28
|
+
- [Submitting](/up.submit) a form through Unpoly now emits an [`up:form:submit`](/up:form:submit) event. The event can be prevented.
|
29
|
+
|
9
30
|
|
10
31
|
0.51.1
|
11
32
|
------
|
@@ -15,7 +36,6 @@ This project mostly adheres to [Semantic Versioning](http://semver.org/).
|
|
15
36
|
- Fix a bug where Unpoly would crash when replacing a fragment with a `<script>` tag with a later sibling element.
|
16
37
|
|
17
38
|
|
18
|
-
|
19
39
|
0.51.0
|
20
40
|
------
|
21
41
|
|
@@ -28,7 +48,6 @@ This project mostly adheres to [Semantic Versioning](http://semver.org/).
|
|
28
48
|
- Work around a [bug in IE11 and Edge](https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12453464/) where `<noscript>` tags that were inserted by a fragment update could not be found with jQuery or `document.querySelectorAll()`.
|
29
49
|
|
30
50
|
|
31
|
-
|
32
51
|
0.50.2
|
33
52
|
------
|
34
53
|
|
data/dist/unpoly.js
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
(function() {
|
7
7
|
window.up = {
|
8
|
-
version: "0.
|
8
|
+
version: "0.52.0",
|
9
9
|
renamedModule: function(oldName, newName) {
|
10
10
|
return typeof Object.defineProperty === "function" ? Object.defineProperty(up, oldName, {
|
11
11
|
get: function() {
|
@@ -41,7 +41,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
41
41
|
@function up.util.noop
|
42
42
|
@experimental
|
43
43
|
*/
|
44
|
-
var $createElementFromSelector, $createPlaceholder, $submittingButton, DivertibleChain, ESCAPE_HTML_ENTITY_MAP, all, always, any, appendRequestData, assign, assignPolyfill, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElementFromHtml, cssAnimate, detachWith, detect, documentHasVerticalScrollbar, each, escapeHtml, escapePressed, evalOption, except, extractOptions, fail, fixedToAbsolute, flatten, forceCompositing, forceRepaint, horizontalScreenHalf, identity, intersect, isArray, isBlank, isBodyDescendant, isCrossDomain, isDefined, isDetached, isElement, isFixed, isFormData, isFunction, isGiven, isJQuery, isMissing, isNull, isNumber, isObject, isOptions, isPresent, isPromise, isStandardPort, isString, isTruthy, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, last, map, margins, measure, memoize, merge, methodAllowsPayload, microtask, multiSelector, newDeferred, nextFrame, nonUpClasses, noop, normalizeMethod, normalizeUrl, nullJQuery, offsetParent, once, only, opacity, openConfig, option, options, parseUrl, pluckData, pluckKey, presence, presentAttr, previewable, promiseTimer, reject, rejectOnError, remove, renameKey, requestDataAsArray, requestDataAsQuery, requestDataFromForm, scrollbarWidth, select, selectInDynasty, selectInSubtree, selectorForElement, sequence, setMissingAttrs, setTimer, submittedValue, temporaryCss, times, toArray, trim, unJQuery, uniq, unresolvablePromise, unwrapElement, whenReady;
|
44
|
+
var $createElementFromSelector, $createPlaceholder, $submittingButton, DivertibleChain, ESCAPE_HTML_ENTITY_MAP, all, always, any, appendRequestData, assign, assignPolyfill, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElementFromHtml, cssAnimate, detachWith, detect, documentHasVerticalScrollbar, each, escapeHtml, escapePressed, evalOption, except, extractOptions, fail, fixedToAbsolute, flatten, forceCompositing, forceRepaint, horizontalScreenHalf, identity, intersect, isArray, isBlank, isBodyDescendant, isCrossDomain, isDefined, isDetached, isElement, isFixed, isFormData, isFunction, isGiven, isJQuery, isMissing, isNull, isNumber, isObject, isOptions, isPresent, isPromise, isStandardPort, isString, isTruthy, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, last, map, margins, measure, memoize, merge, mergeRequestData, methodAllowsPayload, microtask, multiSelector, newDeferred, nextFrame, nonUpClasses, noop, normalizeMethod, normalizeUrl, nullJQuery, offsetParent, once, only, opacity, openConfig, option, options, parseUrl, pluckData, pluckKey, presence, presentAttr, previewable, promiseTimer, reject, rejectOnError, remove, renameKey, requestDataAsArray, requestDataAsQuery, requestDataFromForm, scrollbarWidth, select, selectInDynasty, selectInSubtree, selectorForElement, sequence, setMissingAttrs, setTimer, submittedValue, temporaryCss, times, toArray, trim, unJQuery, uniq, unresolvablePromise, unwrapElement, whenReady;
|
45
45
|
noop = $.noop;
|
46
46
|
|
47
47
|
/**
|
@@ -1618,9 +1618,8 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1618
1618
|
purpose: 'url'
|
1619
1619
|
});
|
1620
1620
|
if (isString(data)) {
|
1621
|
-
data;
|
1622
|
-
}
|
1623
|
-
if (isFormData(data)) {
|
1621
|
+
return data.replace(/^\?/, '');
|
1622
|
+
} else if (isFormData(data)) {
|
1624
1623
|
return up.fail('Cannot convert FormData into a query string');
|
1625
1624
|
} else if (isPresent(data)) {
|
1626
1625
|
query = $.param(data);
|
@@ -1708,6 +1707,20 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
1708
1707
|
return data;
|
1709
1708
|
};
|
1710
1709
|
|
1710
|
+
/**
|
1711
|
+
Merges the request data in `source` into `target`.
|
1712
|
+
Will modify the passed-in `target`.
|
1713
|
+
|
1714
|
+
@return
|
1715
|
+
The merged form data.
|
1716
|
+
*/
|
1717
|
+
mergeRequestData = function(target, source) {
|
1718
|
+
each(requestDataAsArray(source), function(field) {
|
1719
|
+
return target = appendRequestData(target, field.name, field.value);
|
1720
|
+
});
|
1721
|
+
return target;
|
1722
|
+
};
|
1723
|
+
|
1711
1724
|
/**
|
1712
1725
|
Throws a [JavaScript error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)
|
1713
1726
|
with the given message.
|
@@ -2076,7 +2089,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2076
2089
|
@internal
|
2077
2090
|
*/
|
2078
2091
|
rejectOnError = function(block) {
|
2079
|
-
var error
|
2092
|
+
var error;
|
2080
2093
|
try {
|
2081
2094
|
return block();
|
2082
2095
|
} catch (error1) {
|
@@ -2098,6 +2111,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2098
2111
|
requestDataAsArray: requestDataAsArray,
|
2099
2112
|
requestDataAsQuery: requestDataAsQuery,
|
2100
2113
|
appendRequestData: appendRequestData,
|
2114
|
+
mergeRequestData: mergeRequestData,
|
2101
2115
|
requestDataFromForm: requestDataFromForm,
|
2102
2116
|
offsetParent: offsetParent,
|
2103
2117
|
fixedToAbsolute: fixedToAbsolute,
|
@@ -2803,9 +2817,13 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
2803
2817
|
if (options == null) {
|
2804
2818
|
options = {};
|
2805
2819
|
}
|
2806
|
-
return up.
|
2820
|
+
return up.bus.whenEmitted('up:link:follow', {
|
2821
|
+
$element: $link
|
2822
|
+
}).then((function(_this) {
|
2807
2823
|
return function() {
|
2808
|
-
return
|
2824
|
+
return up.feedback.start($link, options, function() {
|
2825
|
+
return _this.followNow($link, options);
|
2826
|
+
});
|
2809
2827
|
};
|
2810
2828
|
})(this));
|
2811
2829
|
};
|
@@ -3108,6 +3126,7 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
3108
3126
|
this.navigate = bind(this.navigate, this);
|
3109
3127
|
this.send = bind(this.send, this);
|
3110
3128
|
this.isSafe = bind(this.isSafe, this);
|
3129
|
+
this.transferSearchToData = bind(this.transferSearchToData, this);
|
3111
3130
|
this.transferDataToUrl = bind(this.transferDataToUrl, this);
|
3112
3131
|
this.extractHashFromUrl = bind(this.extractHashFromUrl, this);
|
3113
3132
|
this.normalize = bind(this.normalize, this);
|
@@ -3119,7 +3138,9 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
3119
3138
|
this.method = u.normalizeMethod(this.method);
|
3120
3139
|
this.headers || (this.headers = {});
|
3121
3140
|
this.extractHashFromUrl();
|
3122
|
-
if (
|
3141
|
+
if (u.methodAllowsPayload(this.method)) {
|
3142
|
+
return this.transferSearchToData();
|
3143
|
+
} else {
|
3123
3144
|
return this.transferDataToUrl();
|
3124
3145
|
}
|
3125
3146
|
};
|
@@ -3135,10 +3156,24 @@ that might save you from loading something like [Lodash](https://lodash.com/).
|
|
3135
3156
|
|
3136
3157
|
Request.prototype.transferDataToUrl = function() {
|
3137
3158
|
var query, separator;
|
3138
|
-
|
3139
|
-
|
3140
|
-
|
3141
|
-
|
3159
|
+
if (this.data && !u.isFormData(this.data)) {
|
3160
|
+
query = u.requestDataAsQuery(this.data);
|
3161
|
+
separator = u.contains(this.url, '?') ? '&' : '?';
|
3162
|
+
this.url += separator + query;
|
3163
|
+
return this.data = void 0;
|
3164
|
+
}
|
3165
|
+
};
|
3166
|
+
|
3167
|
+
Request.prototype.transferSearchToData = function() {
|
3168
|
+
var query, urlParts;
|
3169
|
+
urlParts = u.parseUrl(this.url);
|
3170
|
+
query = urlParts.search;
|
3171
|
+
if (query) {
|
3172
|
+
this.data = u.mergeRequestData(this.data, query);
|
3173
|
+
return this.url = u.normalizeUrl(urlParts, {
|
3174
|
+
search: false
|
3175
|
+
});
|
3176
|
+
}
|
3142
3177
|
};
|
3143
3178
|
|
3144
3179
|
Request.prototype.isSafe = function() {
|
@@ -3471,13 +3506,11 @@ in your controllers and views. If your server-side app uses another language
|
|
3471
3506
|
or framework, you should be able to implement the protocol in a very short time.
|
3472
3507
|
|
3473
3508
|
|
3474
|
-
\#\#\# Redirect detection
|
3509
|
+
\#\#\# Redirect detection for IE11
|
3475
3510
|
|
3476
|
-
|
3477
|
-
|
3478
|
-
|
3479
|
-
After the form's action performs a redirect, the next response should include the new
|
3480
|
-
URL in the HTTP headers:
|
3511
|
+
On Internet Explorer 11, Unpoly cannot detect the final URL after a redirect.
|
3512
|
+
You can fix this edge case by delivering an additional HTTP header
|
3513
|
+
with the *last* response in a series of redirects:
|
3481
3514
|
|
3482
3515
|
```http
|
3483
3516
|
X-Up-Location: /current-url
|
@@ -3630,7 +3663,7 @@ an existing cookie should be deleted.
|
|
3630
3663
|
@internal
|
3631
3664
|
*/
|
3632
3665
|
locationFromXhr = function(xhr) {
|
3633
|
-
return xhr.getResponseHeader(config.locationHeader);
|
3666
|
+
return xhr.getResponseHeader(config.locationHeader) || xhr.responseURL;
|
3634
3667
|
};
|
3635
3668
|
|
3636
3669
|
/**
|
@@ -4055,7 +4088,6 @@ Internet Explorer 10 or lower
|
|
4055
4088
|
@internal
|
4056
4089
|
*/
|
4057
4090
|
sessionStorage = u.memoize(function() {
|
4058
|
-
var error;
|
4059
4091
|
try {
|
4060
4092
|
return window.sessionStorage;
|
4061
4093
|
} catch (error) {
|
@@ -5165,6 +5197,9 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
|
|
5165
5197
|
compiler = function() {
|
5166
5198
|
var args, callback, options, selector;
|
5167
5199
|
selector = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
5200
|
+
if (!up.browser.isSupported()) {
|
5201
|
+
return;
|
5202
|
+
}
|
5168
5203
|
callback = args.pop();
|
5169
5204
|
options = u.options(args[0]);
|
5170
5205
|
return insertCompiler(compilers, selector, options, callback);
|
@@ -5214,6 +5249,9 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
|
|
5214
5249
|
macro = function() {
|
5215
5250
|
var args, callback, options, selector;
|
5216
5251
|
selector = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
5252
|
+
if (!up.browser.isSupported()) {
|
5253
|
+
return;
|
5254
|
+
}
|
5217
5255
|
callback = args.pop();
|
5218
5256
|
options = u.options(args[0]);
|
5219
5257
|
if (isBooting) {
|
@@ -6774,7 +6812,7 @@ is built from these functions. You can use them to extend Unpoly from your
|
|
6774
6812
|
@stable
|
6775
6813
|
*/
|
6776
6814
|
replace = function(selectorOrElement, url, options) {
|
6777
|
-
var e,
|
6815
|
+
var e, failureOptions, fullLoad, improvedFailTarget, improvedTarget, onFailure, onSuccess, promise, request, successOptions;
|
6778
6816
|
options = u.options(options);
|
6779
6817
|
options.inspectResponse = fullLoad = function() {
|
6780
6818
|
return up.browser.navigate(url, u.only(options, 'method', 'data'));
|
@@ -8796,7 +8834,7 @@ Other Unpoly modules contain even more tricks to outsmart network latency:
|
|
8796
8834
|
registerAliasForRedirect = function(response) {
|
8797
8835
|
var newRequest, request;
|
8798
8836
|
request = response.request;
|
8799
|
-
if (request.url !== response.url) {
|
8837
|
+
if (response.url && request.url !== response.url) {
|
8800
8838
|
newRequest = request.copy({
|
8801
8839
|
method: response.method,
|
8802
8840
|
url: response.url
|
@@ -9122,6 +9160,8 @@ new page is loading.
|
|
9122
9160
|
or [`[up-modal]`](/a-up-modal), the corresponding UJS behavior will be activated
|
9123
9161
|
just as if the user had clicked on the link.
|
9124
9162
|
|
9163
|
+
Emits the event [`up:link:follow`](/up:link:follow).
|
9164
|
+
|
9125
9165
|
\#\#\# Examples
|
9126
9166
|
|
9127
9167
|
Let's say you have a link with an [`a[up-target]`](/a-up-target) attribute:
|
@@ -9154,6 +9194,17 @@ new page is loading.
|
|
9154
9194
|
return variant.followLink($link, options);
|
9155
9195
|
};
|
9156
9196
|
|
9197
|
+
/**
|
9198
|
+
This event is [emitted](/up.emit) when a link is [followed](/up.follow) through Unpoly.
|
9199
|
+
|
9200
|
+
@event up:link:follow
|
9201
|
+
@param {jQuery} event.$element
|
9202
|
+
The link element that will be followed.
|
9203
|
+
@param event.preventDefault()
|
9204
|
+
Event listeners may call this method to prevent the link from being followed.
|
9205
|
+
@stable
|
9206
|
+
*/
|
9207
|
+
|
9157
9208
|
/**
|
9158
9209
|
@function defaultFollow
|
9159
9210
|
@internal
|
@@ -9688,6 +9739,8 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
9688
9739
|
See the documentation for [`form[up-target]`](/form-up-target) for more
|
9689
9740
|
information on how AJAX form submissions work in Unpoly.
|
9690
9741
|
|
9742
|
+
Emits the event [`up:form:submit`](/up:form:submit).
|
9743
|
+
|
9691
9744
|
@function up.submit
|
9692
9745
|
@param {Element|jQuery|string} formOrSelector
|
9693
9746
|
A reference or selector for the form to submit.
|
@@ -9755,7 +9808,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
9755
9808
|
@stable
|
9756
9809
|
*/
|
9757
9810
|
submit = function(formOrSelector, options) {
|
9758
|
-
var $form,
|
9811
|
+
var $form, target, url;
|
9759
9812
|
$form = $(formOrSelector).closest('form');
|
9760
9813
|
options = u.options(options);
|
9761
9814
|
target = u.option(options.target, $form.attr('up-target'), 'body');
|
@@ -9781,18 +9834,34 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
9781
9834
|
options.failTransition = false;
|
9782
9835
|
options.headers[up.protocol.config.validateHeader] = options.validate;
|
9783
9836
|
}
|
9784
|
-
up.
|
9785
|
-
|
9786
|
-
|
9787
|
-
|
9788
|
-
|
9789
|
-
|
9790
|
-
|
9791
|
-
|
9837
|
+
return up.bus.whenEmitted('up:form:submit', {
|
9838
|
+
$element: $form
|
9839
|
+
}).then(function() {
|
9840
|
+
var promise;
|
9841
|
+
up.feedback.start($form);
|
9842
|
+
if (!(up.browser.canPushState() || options.history === false)) {
|
9843
|
+
$form.get(0).submit();
|
9844
|
+
return u.unresolvablePromise();
|
9845
|
+
}
|
9846
|
+
promise = up.replace(target, url, options);
|
9847
|
+
u.always(promise, function() {
|
9848
|
+
return up.feedback.stop($form);
|
9849
|
+
});
|
9850
|
+
return promise;
|
9792
9851
|
});
|
9793
|
-
return promise;
|
9794
9852
|
};
|
9795
9853
|
|
9854
|
+
/**
|
9855
|
+
This event is [emitted](/up.emit) when a form is [submitted](/up.submit) through Unpoly.
|
9856
|
+
|
9857
|
+
@event up:form:submit
|
9858
|
+
@param {jQuery} event.$element
|
9859
|
+
The `<form>` element that will be submitted.
|
9860
|
+
@param event.preventDefault()
|
9861
|
+
Event listeners may call this method to prevent the form from being submitted.
|
9862
|
+
@stable
|
9863
|
+
*/
|
9864
|
+
|
9796
9865
|
/**
|
9797
9866
|
Observes form fields and runs a callback when a value changes.
|
9798
9867
|
|