unpoly-rails 0.51.1 → 0.52.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 +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
|
|