unpoly-rails 0.60.2 → 0.62.1
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/.ruby-version +1 -2
- data/CHANGELOG.md +105 -0
- data/Rakefile +5 -1
- data/dist/unpoly.js +199 -80
- data/dist/unpoly.min.js +4 -4
- data/lib/assets/javascripts/unpoly/browser.coffee.erb +10 -5
- data/lib/assets/javascripts/unpoly/classes/body_shifter.coffee +21 -12
- data/lib/assets/javascripts/unpoly/classes/compile_pass.coffee +2 -2
- data/lib/assets/javascripts/unpoly/classes/event_listener.coffee +1 -1
- data/lib/assets/javascripts/unpoly/classes/follow_variant.coffee +11 -3
- data/lib/assets/javascripts/unpoly/classes/params.coffee.erb +2 -1
- data/lib/assets/javascripts/unpoly/element.coffee.erb +4 -4
- data/lib/assets/javascripts/unpoly/event.coffee.erb +12 -4
- data/lib/assets/javascripts/unpoly/form.coffee.erb +77 -15
- data/lib/assets/javascripts/unpoly/fragment.coffee.erb +7 -3
- data/lib/assets/javascripts/unpoly/link.coffee.erb +1 -1
- data/lib/assets/javascripts/unpoly/modal.coffee.erb +4 -2
- data/lib/assets/javascripts/unpoly/motion.coffee.erb +1 -1
- data/lib/assets/javascripts/unpoly/protocol.coffee +1 -1
- data/lib/assets/javascripts/unpoly/syntax.coffee.erb +3 -4
- data/lib/assets/javascripts/unpoly/util.coffee.erb +2 -1
- data/lib/assets/javascripts/unpoly/viewport.coffee.erb +26 -2
- data/lib/unpoly/rails/version.rb +1 -1
- data/package.json +1 -1
- data/spec_app/Gemfile +2 -4
- data/spec_app/Gemfile.lock +23 -27
- data/spec_app/app/views/css_test/modal.erb +1 -1
- data/spec_app/app/views/css_test/popup.erb +1 -1
- data/spec_app/app/views/pages/start.erb +2 -1
- data/spec_app/app/views/replace_test/table.erb +16 -0
- data/spec_app/spec/javascripts/up/event_spec.js.coffee +34 -0
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +137 -9
- data/spec_app/spec/javascripts/up/fragment_spec.js.coffee +36 -1
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +7 -2
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +23 -1
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +2 -1
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +14 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '079979a47b22899b849e8b53275d23c2f6bf8a4ac14bf1b6001ac00330518cc9'
|
4
|
+
data.tar.gz: 033c8335552505a36214999db839d7c54a7e22c93fd168d8d8b25b7ccb5e40aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7be2bf8bd27d709d479000a591320731ac8fdbe2c0f613883a41af4258d4125bf4e793ec1712f83f56083f27335c39d1a5136cc8a501440fe35403ebd536cff
|
7
|
+
data.tar.gz: d4493b591597cda5245c5d0cf5000d034922cde09316fc030776ceacaaf44330975199eb3b9bd1c5c3a61134c56e38a8f175f6b7e126c50c33c54377d3e31927
|
data/.ruby-version
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
2.
|
2
|
-
|
1
|
+
2.3.8
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,111 @@ Changes to this project will be documented in this file.
|
|
6
6
|
You may browse a formatted and hyperlinked version of this file at <https://unpoly.com/changes>.
|
7
7
|
|
8
8
|
|
9
|
+
0.62.1
|
10
|
+
------
|
11
|
+
|
12
|
+
This is another maintenance release while we're finishing [the next major version of Unpoly](https://groups.google.com/forum/#!topic/unpoly/FDdVjxbjNLg).
|
13
|
+
|
14
|
+
Community members were involved in every change of this release:
|
15
|
+
|
16
|
+
- [`up.submit()`](/up.submit) has a new options `{ params }`. It may be used to pass extra form [parameters](/up.Params) that will be submitted in addition to the parameters from the form. (fix by @robinvdvleuten)
|
17
|
+
- [`a[up-modal]`](/a-up-modal) will now honor an [`[up-cache]`](/a-up-target#up-cache) attribute on the same link. (fix by @adam12)
|
18
|
+
- Prevent destructor function from being called twice if [`up.destroy()`](/up.destroy) is called twice with the same element (reported by @kratob)
|
19
|
+
- On devices that don't show a vertical scrollbar, users can no longer scroll the underlying page while a [modal overlay](/up.modal) is open. (reported by @msurdi)
|
20
|
+
|
21
|
+
|
22
|
+
0.62.0
|
23
|
+
------
|
24
|
+
|
25
|
+
This release backports a number of accessibility improvements from [the next major version of Unpoly](https://groups.google.com/forum/#!topic/unpoly/FDdVjxbjNLg).
|
26
|
+
We encourage everyone to upgrade to this release in order to better support users with visual impairments.
|
27
|
+
|
28
|
+
The following changes are included:
|
29
|
+
|
30
|
+
- Links with an [`[up-instant]`](/a-up-instant) attribute can now be followed with the keyboard.
|
31
|
+
- Fragments that are being [destroyed](/up.destroy) now get an [`[aria-hidden=true]`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-hidden_attribute)
|
32
|
+
attribute while its disappearance is being animated. When a fragment is being swapped with a new version, the old fragment version is also
|
33
|
+
given `[aria-hidden=true]` while it's disappearing.
|
34
|
+
- [Modal dialogs](/up.modal) now get an [`[aria-modal=true]`](https://a11ysupport.io/tech/aria/aria-modal_attribute) attribute.
|
35
|
+
|
36
|
+
The next major version of Unpoly will include additional accessibility improvements. In particular the
|
37
|
+
new modal ("layer") implementation will implement all best practices for accessible dialogs.
|
38
|
+
|
39
|
+
|
40
|
+
0.61.1
|
41
|
+
------
|
42
|
+
|
43
|
+
This is a maintenance release while we're getting ready for [the next major version of Unpoly](https://groups.google.com/forum/#!topic/unpoly/FDdVjxbjNLg).
|
44
|
+
|
45
|
+
- Fix a bug where [`up.destroy()`](/up.destroy) wouldn't clean up the global jQuery cache. This is only relevant when using Unpoly together with jQuery.
|
46
|
+
- Fields outside a <form> are now recognized when they have a matching [form] attribute (fixes #85)
|
47
|
+
- [`up.form.fields()`](/up.form.fields) now accepts a jQuery collection as a first argument, as was already documented.
|
48
|
+
|
49
|
+
|
50
|
+
0.61.0
|
51
|
+
------
|
52
|
+
|
53
|
+
This release makes it easier to migrate to a recent version of Unpoly when your app still depends on jQuery.
|
54
|
+
Unpoly dropped its jQuery dependency with version 0.60.0, but retains optional jQuery support through functions like
|
55
|
+
[`up.$compiler()`](/up.$compiler) and [`up.$on()`](/up.$on). All Unpoly functions that take a native element as an
|
56
|
+
argument may also be called with a jQuery collection as an argument.
|
57
|
+
|
58
|
+
The following changes to the optional jQuery support were implemented:
|
59
|
+
|
60
|
+
- In an ES6 build pipeline, Unpoly's jQuery support no longer requires `window.jQuery` to be defined before
|
61
|
+
Unpoly is imported into the build. You still need to define `window.jQuery`, but you may do so at any time in your
|
62
|
+
scripts, regardless of load order.
|
63
|
+
- jQuery support functions like [`up.$compiler()`](/up.$compiler) now fail with a helpful message if the developer
|
64
|
+
forgets to define `window.jQuery`.
|
65
|
+
|
66
|
+
This release also exposes some convenience functions and selectors:
|
67
|
+
|
68
|
+
- New experimental function [`up.event.halt()`](/up.event.halt). It prevents the event from bubbling up the DOM.
|
69
|
+
It also prevents other event handlers bound on the same element. It also prevents the event's default action.
|
70
|
+
- New experimental function [`up.form.fields()`](/up.form.fields). It returns a list of form fields within the given element.
|
71
|
+
- The selector [`form[up-validate]`](/form-up-validate) is now supported. It performs
|
72
|
+
[server-side validation](/input-up-validate) when any fieldset within this form changes. Previously only the variant
|
73
|
+
[`input[up-validate]`](/input-up-validate) was supported.
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
0.60.3
|
78
|
+
------
|
79
|
+
|
80
|
+
[`[up-validate]`](/up-validate) again recognizes the `[up-fieldset]` attribute to find the form fragment
|
81
|
+
that should be replaced with validation results.
|
82
|
+
|
83
|
+
In the example below, changing the `email` input would only validate the first fieldset:
|
84
|
+
|
85
|
+
```html
|
86
|
+
<form action="/users" id="registration">
|
87
|
+
|
88
|
+
<div up-fieldset>
|
89
|
+
Validation message
|
90
|
+
<input type="text" name="email" up-validate />
|
91
|
+
</div>
|
92
|
+
|
93
|
+
<div up-fieldset>
|
94
|
+
Validation message
|
95
|
+
<input type="password" name="password" up-validate />
|
96
|
+
</div>
|
97
|
+
|
98
|
+
</form>
|
99
|
+
```
|
100
|
+
|
101
|
+
|
102
|
+
0.60.2
|
103
|
+
------
|
104
|
+
|
105
|
+
- When [submitting](/up-form) a form with a GET method, any query parameters in the form's `[action]` URL are now discarded.
|
106
|
+
This matches the standard browser behavior when submitting a form without Unpoly.
|
107
|
+
- When [submitting](/up-form) a form with a POST method, any query parameters in the form's `[action]` URL are now kept in the
|
108
|
+
URL, instead of being merged into the form's data payload.
|
109
|
+
This matches the standard browser behavior when submitting a form without Unpoly.
|
110
|
+
- New experimental function [`up.Params.stripURL(url)`](/up.Params.stripURL).
|
111
|
+
It returns the given URL without its [query string](https://en.wikipedia.org/wiki/Query_string).
|
112
|
+
|
113
|
+
|
9
114
|
0.60.1
|
10
115
|
------
|
11
116
|
|
data/Rakefile
CHANGED
@@ -42,7 +42,10 @@ end
|
|
42
42
|
|
43
43
|
namespace :publish do
|
44
44
|
task :confirm do
|
45
|
-
puts "
|
45
|
+
puts "Before publishing new Unpoly version:"
|
46
|
+
puts "- Bump the version in version.rb"
|
47
|
+
puts "- Update the CHANGELOG"
|
48
|
+
puts "Ready to publish to all release channels? [y/N] "
|
46
49
|
reply = STDIN.gets.strip.downcase
|
47
50
|
unless reply == 'y'
|
48
51
|
puts "Aborted"
|
@@ -105,6 +108,7 @@ namespace :publish do
|
|
105
108
|
puts "Now remember to:"
|
106
109
|
puts "- update unpoly.com so user see the updated CHANGELOG and CDN link"
|
107
110
|
puts "- send a message to the e-mail group announcing the new release"
|
111
|
+
puts "- tweet a link to the CHANGELOG as @unpolyjs"
|
108
112
|
end
|
109
113
|
|
110
114
|
desc 'Build artifacts, push to git and release to package managers'
|
data/dist/unpoly.js
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
(function() {
|
7
7
|
window.up = {
|
8
|
-
version: "0.
|
8
|
+
version: "0.62.1"
|
9
9
|
};
|
10
10
|
|
11
11
|
}).call(this);
|
@@ -595,7 +595,7 @@ to not include another library in your asset bundle.
|
|
595
595
|
@stable
|
596
596
|
*/
|
597
597
|
isJQuery = function(object) {
|
598
|
-
return
|
598
|
+
return !!(object != null ? object.jquery : void 0);
|
599
599
|
};
|
600
600
|
|
601
601
|
/***
|
@@ -1898,8 +1898,10 @@ Internet Explorer 10 or lower
|
|
1898
1898
|
*/
|
1899
1899
|
|
1900
1900
|
(function() {
|
1901
|
+
var slice = [].slice;
|
1902
|
+
|
1901
1903
|
up.browser = (function() {
|
1902
|
-
var canAnimationFrame, canConsole, canControlScrollRestoration, canCssTransition, canCustomElements, canDOMParser, canFormData, canInputEvent, canInspectFormData, canJQuery, canPromise, canPushState, isIE10OrWorse, isIE11, isSupported, navigate, popCookie, submitForm, u, url, whenConfirmed;
|
1904
|
+
var callJQuery, canAnimationFrame, canConsole, canControlScrollRestoration, canCssTransition, canCustomElements, canDOMParser, canFormData, canInputEvent, canInspectFormData, canJQuery, canPromise, canPushState, isIE10OrWorse, isIE11, isSupported, navigate, popCookie, submitForm, u, url, whenConfirmed;
|
1903
1905
|
u = up.util;
|
1904
1906
|
|
1905
1907
|
/***
|
@@ -2038,15 +2040,15 @@ Internet Explorer 10 or lower
|
|
2038
2040
|
canCustomElements = u.memoize(function() {
|
2039
2041
|
return !!window.customElements;
|
2040
2042
|
});
|
2041
|
-
canJQuery = u.memoize(function() {
|
2042
|
-
return !!window.jQuery;
|
2043
|
-
});
|
2044
2043
|
canAnimationFrame = u.memoize(function() {
|
2045
2044
|
return 'requestAnimationFrame' in window;
|
2046
2045
|
});
|
2047
2046
|
canControlScrollRestoration = u.memoize(function() {
|
2048
2047
|
return 'scrollRestoration' in history;
|
2049
2048
|
});
|
2049
|
+
canJQuery = function() {
|
2050
|
+
return !!window.jQuery;
|
2051
|
+
};
|
2050
2052
|
popCookie = function(name) {
|
2051
2053
|
var ref, value;
|
2052
2054
|
value = (ref = document.cookie.match(new RegExp(name + "=(\\w+)"))) != null ? ref[1] : void 0;
|
@@ -2086,6 +2088,12 @@ Internet Explorer 10 or lower
|
|
2086
2088
|
isSupported = function() {
|
2087
2089
|
return !isIE10OrWorse() && canConsole() && canDOMParser() && canFormData() && canCssTransition() && canInputEvent() && canPromise() && canAnimationFrame();
|
2088
2090
|
};
|
2091
|
+
callJQuery = function() {
|
2092
|
+
var args;
|
2093
|
+
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
2094
|
+
canJQuery() || up.fail("jQuery must be published as window.jQuery");
|
2095
|
+
return jQuery.apply(null, args);
|
2096
|
+
};
|
2089
2097
|
return {
|
2090
2098
|
url: url,
|
2091
2099
|
navigate: navigate,
|
@@ -2094,11 +2102,12 @@ Internet Explorer 10 or lower
|
|
2094
2102
|
canFormData: canFormData,
|
2095
2103
|
canInspectFormData: canInspectFormData,
|
2096
2104
|
canCustomElements: canCustomElements,
|
2097
|
-
canJQuery: canJQuery,
|
2098
2105
|
canControlScrollRestoration: canControlScrollRestoration,
|
2106
|
+
canJQuery: canJQuery,
|
2099
2107
|
whenConfirmed: whenConfirmed,
|
2100
2108
|
isSupported: isSupported,
|
2101
2109
|
popCookie: popCookie,
|
2110
|
+
jQuery: callJQuery,
|
2102
2111
|
isIE11: isIE11
|
2103
2112
|
};
|
2104
2113
|
})();
|
@@ -2346,7 +2355,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
2346
2355
|
@function up.element.closest
|
2347
2356
|
@param {Element} element
|
2348
2357
|
The element on which to start the search.
|
2349
|
-
@param {string}
|
2358
|
+
@param {string} selector
|
2350
2359
|
The CSS selector to match.
|
2351
2360
|
@return {Element|null|undefined} element
|
2352
2361
|
The matching element.
|
@@ -2762,11 +2771,11 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
2762
2771
|
element.className // returns 'klass'
|
2763
2772
|
|
2764
2773
|
@function up.element.affix
|
2765
|
-
@
|
2774
|
+
@param {Element} parent
|
2766
2775
|
The parent to which to attach the created element.
|
2767
|
-
@
|
2776
|
+
@param {string} selector
|
2768
2777
|
The CSS selector from which to create an element.
|
2769
|
-
@
|
2778
|
+
@param {Object} attrs
|
2770
2779
|
An object of attributes to set on the created element.
|
2771
2780
|
@param {Object} attrs.text
|
2772
2781
|
The [text content](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent) of the created element.
|
@@ -3419,32 +3428,32 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
3419
3428
|
}
|
3420
3429
|
|
3421
3430
|
BodyShifter.prototype.shift = function() {
|
3422
|
-
var anchor, body, bodyRightPadding, bodyRightShift, elementRight, elementRightShift, i, len, overflowElement, ref, results, scrollbarWidth;
|
3423
|
-
|
3424
|
-
return;
|
3425
|
-
}
|
3426
|
-
body = document.body;
|
3431
|
+
var anchor, body, bodyRightPadding, bodyRightShift, elementRight, elementRightShift, i, len, overflowElement, ref, results, rootHadVerticalScrollbar, scrollbarWidth;
|
3432
|
+
rootHadVerticalScrollbar = up.viewport.rootHasVerticalScrollbar();
|
3427
3433
|
overflowElement = up.viewport.rootOverflowElement();
|
3428
|
-
scrollbarWidth = up.viewport.scrollbarWidth();
|
3429
|
-
bodyRightPadding = e.styleNumber(body, 'paddingRight');
|
3430
|
-
bodyRightShift = scrollbarWidth + bodyRightPadding;
|
3431
|
-
this.unshiftFns.push(e.setTemporaryStyle(body, {
|
3432
|
-
paddingRight: bodyRightShift
|
3433
|
-
}));
|
3434
3434
|
this.unshiftFns.push(e.setTemporaryStyle(overflowElement, {
|
3435
3435
|
overflowY: 'hidden'
|
3436
3436
|
}));
|
3437
|
-
|
3438
|
-
|
3439
|
-
|
3440
|
-
|
3441
|
-
|
3442
|
-
|
3443
|
-
|
3444
|
-
|
3445
|
-
|
3437
|
+
if (rootHadVerticalScrollbar) {
|
3438
|
+
body = document.body;
|
3439
|
+
scrollbarWidth = up.viewport.scrollbarWidth();
|
3440
|
+
bodyRightPadding = e.styleNumber(body, 'paddingRight');
|
3441
|
+
bodyRightShift = scrollbarWidth + bodyRightPadding;
|
3442
|
+
this.unshiftFns.push(e.setTemporaryStyle(body, {
|
3443
|
+
paddingRight: bodyRightShift
|
3444
|
+
}));
|
3445
|
+
ref = up.viewport.anchoredRight();
|
3446
|
+
results = [];
|
3447
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
3448
|
+
anchor = ref[i];
|
3449
|
+
elementRight = e.styleNumber(anchor, 'right');
|
3450
|
+
elementRightShift = scrollbarWidth + elementRight;
|
3451
|
+
results.push(this.unshiftFns.push(e.setTemporaryStyle(anchor, {
|
3452
|
+
right: elementRightShift
|
3453
|
+
})));
|
3454
|
+
}
|
3455
|
+
return results;
|
3446
3456
|
}
|
3447
|
-
return results;
|
3448
3457
|
};
|
3449
3458
|
|
3450
3459
|
BodyShifter.prototype.unshift = function() {
|
@@ -3774,7 +3783,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
3774
3783
|
|
3775
3784
|
CompilePass.prototype.compileOneElement = function(compiler, element) {
|
3776
3785
|
var compileArgs, data, destructorOrDestructors, elementArg, result;
|
3777
|
-
elementArg = compiler.jQuery ? jQuery(element) : element;
|
3786
|
+
elementArg = compiler.jQuery ? up.browser.jQuery(element) : element;
|
3778
3787
|
compileArgs = [elementArg];
|
3779
3788
|
if (compiler.length !== 1) {
|
3780
3789
|
data = up.syntax.data(element);
|
@@ -3788,7 +3797,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
3788
3797
|
|
3789
3798
|
CompilePass.prototype.compileBatch = function(compiler, elements) {
|
3790
3799
|
var compileArgs, dataList, elementsArgs, result;
|
3791
|
-
elementsArgs = compiler.jQuery ? jQuery(elements) : elements;
|
3800
|
+
elementsArgs = compiler.jQuery ? up.browser.jQuery(elements) : elements;
|
3792
3801
|
compileArgs = [elementsArgs];
|
3793
3802
|
if (compiler.length !== 1) {
|
3794
3803
|
dataList = u.map(elements, up.syntax.data);
|
@@ -4126,7 +4135,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
4126
4135
|
element = e.closest(element, this.selector);
|
4127
4136
|
}
|
4128
4137
|
if (element) {
|
4129
|
-
elementArg = this.jQuery ? jQuery(element) : element;
|
4138
|
+
elementArg = this.jQuery ? up.browser.jQuery(element) : element;
|
4130
4139
|
args = [event, elementArg];
|
4131
4140
|
expectedArgCount = this.callback.length;
|
4132
4141
|
if (!(expectedArgCount === 1 || expectedArgCount === 2)) {
|
@@ -4683,8 +4692,9 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
4683
4692
|
|
4684
4693
|
FollowVariant.prototype.onClick = function(event, link) {
|
4685
4694
|
if (up.link.shouldProcessEvent(event, link)) {
|
4686
|
-
if (e.matches(link, '[up-instant]')) {
|
4687
|
-
|
4695
|
+
if (e.matches(link, '[up-instant]') && link.upInstantSupported) {
|
4696
|
+
up.event.halt(event);
|
4697
|
+
link.upInstantSupported = false;
|
4688
4698
|
} else {
|
4689
4699
|
up.event.consumeAction(event);
|
4690
4700
|
return this.followLink(link);
|
@@ -4696,6 +4706,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
4696
4706
|
|
4697
4707
|
FollowVariant.prototype.onMousedown = function(event, link) {
|
4698
4708
|
if (up.link.shouldProcessEvent(event, link)) {
|
4709
|
+
link.upInstantSupported = true;
|
4699
4710
|
up.event.consumeAction(event);
|
4700
4711
|
return this.followLink(link);
|
4701
4712
|
}
|
@@ -5347,18 +5358,19 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
5347
5358
|
if (u.isMissing(raw)) {
|
5348
5359
|
|
5349
5360
|
} else if (raw instanceof this.constructor) {
|
5350
|
-
|
5361
|
+
(ref = this.entries).push.apply(ref, raw.entries);
|
5351
5362
|
} else if (u.isArray(raw)) {
|
5352
|
-
|
5363
|
+
(ref1 = this.entries).push.apply(ref1, raw);
|
5353
5364
|
} else if (u.isString(raw)) {
|
5354
|
-
|
5365
|
+
this.addAllFromQuery(raw);
|
5355
5366
|
} else if (u.isFormData(raw)) {
|
5356
|
-
|
5367
|
+
this.addAllFromFormData(raw);
|
5357
5368
|
} else if (u.isObject(raw)) {
|
5358
|
-
|
5369
|
+
this.addAllFromObject(raw);
|
5359
5370
|
} else {
|
5360
|
-
|
5371
|
+
up.fail("Unsupport params type: %o", raw);
|
5361
5372
|
}
|
5373
|
+
return this;
|
5362
5374
|
};
|
5363
5375
|
|
5364
5376
|
Params.prototype.addAllFromObject = function(object) {
|
@@ -5708,7 +5720,7 @@ It complements [native `Element` methods](https://www.w3schools.com/jsref/dom_ob
|
|
5708
5720
|
};
|
5709
5721
|
|
5710
5722
|
|
5711
|
-
|
5723
|
+
/***
|
5712
5724
|
Returns the given URL without its [query string](https://en.wikipedia.org/wiki/Query_string).
|
5713
5725
|
|
5714
5726
|
\#\#\# Example
|
@@ -6951,7 +6963,7 @@ There are some advantages to using `up.on()`:
|
|
6951
6963
|
for [event delegation](https://davidwalsh.name/event-delegate):
|
6952
6964
|
|
6953
6965
|
var form = document.querySelector('form')
|
6954
|
-
|
6966
|
+
up.on(form, 'click', 'a', function(event, link) {
|
6955
6967
|
console.log("Click on a link %o within %o", link, form)
|
6956
6968
|
})
|
6957
6969
|
|
@@ -7263,14 +7275,22 @@ There are some advantages to using `up.on()`:
|
|
7263
7275
|
};
|
7264
7276
|
|
7265
7277
|
/***
|
7266
|
-
|
7278
|
+
Prevents the event from bubbling up the DOM.
|
7279
|
+
Also prevents other event handlers bound on the same element.
|
7280
|
+
Also prevents the event's default action.
|
7281
|
+
|
7282
|
+
\#\#\# Example
|
7283
|
+
|
7284
|
+
up.on('click', 'link.disabled', function(event) {
|
7285
|
+
up.event.halt(event)
|
7286
|
+
})
|
7267
7287
|
|
7268
7288
|
@function up.event.halt
|
7269
|
-
@
|
7289
|
+
@param {Event} event
|
7290
|
+
@experimental
|
7270
7291
|
*/
|
7271
7292
|
halt = function(event) {
|
7272
7293
|
event.stopImmediatePropagation();
|
7273
|
-
event.stopPropagation();
|
7274
7294
|
return event.preventDefault();
|
7275
7295
|
};
|
7276
7296
|
|
@@ -7579,7 +7599,7 @@ an existing cookie should be deleted.
|
|
7579
7599
|
The parameter name can be configured as a string or as function that returns the parameter name.
|
7580
7600
|
If no name is set, no token will be sent.
|
7581
7601
|
|
7582
|
-
Defaults to the `content` attribute of a `<meta>` tag named `csrf-
|
7602
|
+
Defaults to the `content` attribute of a `<meta>` tag named `csrf-param`:
|
7583
7603
|
|
7584
7604
|
<meta name="csrf-param" content="authenticity_token" />
|
7585
7605
|
|
@@ -8234,7 +8254,7 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
|
|
8234
8254
|
/***
|
8235
8255
|
Registers a [compiler](/up.compiler) that is run before all other compilers.
|
8236
8256
|
|
8237
|
-
Use `up.macro()` to register a compiler that sets
|
8257
|
+
Use `up.macro()` to register a compiler that sets multiple Unpoly attributes.
|
8238
8258
|
|
8239
8259
|
\#\#\# Example
|
8240
8260
|
|
@@ -8413,15 +8433,14 @@ or when a matching fragment is [inserted via AJAX](/up.link) later.
|
|
8413
8433
|
var cleanables;
|
8414
8434
|
cleanables = e.subtree(fragment, '.up-can-clean');
|
8415
8435
|
return u.each(cleanables, function(cleanable) {
|
8416
|
-
var destructor, destructors, i, len
|
8417
|
-
if (destructors = cleanable
|
8418
|
-
results = [];
|
8436
|
+
var destructor, destructors, i, len;
|
8437
|
+
if (destructors = u.pluckKey(cleanable, 'upDestructors')) {
|
8419
8438
|
for (i = 0, len = destructors.length; i < len; i++) {
|
8420
8439
|
destructor = destructors[i];
|
8421
|
-
|
8440
|
+
destructor();
|
8422
8441
|
}
|
8423
|
-
return results;
|
8424
8442
|
}
|
8443
|
+
return cleanable.classList.remove('up-can-clean');
|
8425
8444
|
});
|
8426
8445
|
};
|
8427
8446
|
|
@@ -9380,13 +9399,37 @@ Unpoly will automatically be aware of sticky Bootstrap components such as
|
|
9380
9399
|
|
9381
9400
|
The scroll positions will be associated with the current URL.
|
9382
9401
|
They can later be restored by calling [`up.viewport.restoreScroll()`](/up.viewport.restoreScroll)
|
9383
|
-
at the same URL
|
9402
|
+
at the same URL, or by following a link with an [`[up-restore-scroll]`](/a-up-follow#up-restore-scroll)
|
9403
|
+
attribute.
|
9404
|
+
|
9405
|
+
Unpoly automatically saves scroll positions before a [fragment update](/up.replace)
|
9406
|
+
you will rarely need to call this function yourself.
|
9407
|
+
|
9408
|
+
\#\#\# Examples
|
9409
|
+
|
9410
|
+
Should you need to save the current scroll positions outside of a [fragment update](/up.replace),
|
9411
|
+
you may call:
|
9384
9412
|
|
9385
|
-
|
9413
|
+
up.viewport.saveScroll()
|
9414
|
+
|
9415
|
+
Instead of saving the current scroll positions for the current URL, you may also pass another
|
9416
|
+
url or vertical scroll positionsfor each viewport:
|
9417
|
+
|
9418
|
+
up.viewport.saveScroll({
|
9419
|
+
url: '/inbox',
|
9420
|
+
tops: {
|
9421
|
+
'body': 0,
|
9422
|
+
'.sidebar', 100,
|
9423
|
+
'.main', 320
|
9424
|
+
}
|
9425
|
+
})
|
9386
9426
|
|
9387
9427
|
@function up.viewport.saveScroll
|
9388
9428
|
@param {string} [options.url]
|
9429
|
+
The URL for which to save scroll positions.
|
9430
|
+
If omitted, the current browser location is used.
|
9389
9431
|
@param {Object<string, number>} [options.tops]
|
9432
|
+
An object mapping viewport selectors to vertical scroll positions in pixels.
|
9390
9433
|
@experimental
|
9391
9434
|
*/
|
9392
9435
|
saveScroll = function(options) {
|
@@ -9767,7 +9810,7 @@ is built from `up.fragment` functions. You may use them to extend Unpoly from yo
|
|
9767
9810
|
|
9768
9811
|
\#\#\# Example
|
9769
9812
|
|
9770
|
-
Let's say your
|
9813
|
+
Let's say your current HTML looks like this:
|
9771
9814
|
|
9772
9815
|
<div class="one">old one</div>
|
9773
9816
|
<div class="two">old two</div>
|
@@ -10018,7 +10061,7 @@ is built from `up.fragment` functions. You may use them to extend Unpoly from yo
|
|
10018
10061
|
|
10019
10062
|
\#\#\# Example
|
10020
10063
|
|
10021
|
-
Let's say your
|
10064
|
+
Let's say your current HTML looks like this:
|
10022
10065
|
|
10023
10066
|
<div class="one">old one</div>
|
10024
10067
|
<div class="two">old two</div>
|
@@ -10568,7 +10611,11 @@ is built from `up.fragment` functions. You may use them to extend Unpoly from yo
|
|
10568
10611
|
var parent;
|
10569
10612
|
parent = element.parentNode;
|
10570
10613
|
up.syntax.clean(element);
|
10571
|
-
|
10614
|
+
if (up.browser.canJQuery()) {
|
10615
|
+
jQuery(element).remove();
|
10616
|
+
} else {
|
10617
|
+
e.remove(element);
|
10618
|
+
}
|
10572
10619
|
return emitFragmentDestroyed(element, {
|
10573
10620
|
parent: parent,
|
10574
10621
|
log: options.log
|
@@ -10593,7 +10640,8 @@ is built from `up.fragment` functions. You may use them to extend Unpoly from yo
|
|
10593
10640
|
@stable
|
10594
10641
|
*/
|
10595
10642
|
markElementAsDestroying = function(element) {
|
10596
|
-
|
10643
|
+
element.classList.add('up-destroying');
|
10644
|
+
return element.setAttribute('aria-hidden', 'true');
|
10597
10645
|
};
|
10598
10646
|
|
10599
10647
|
/***
|
@@ -10789,7 +10837,7 @@ You can define custom animations using [`up.transition()`](/up.transition) and
|
|
10789
10837
|
|
10790
10838
|
You can pass additional options:
|
10791
10839
|
|
10792
|
-
up.animate('warning', '
|
10840
|
+
up.animate('.warning', 'fade-in', {
|
10793
10841
|
delay: 1000,
|
10794
10842
|
duration: 250,
|
10795
10843
|
easing: 'linear'
|
@@ -12107,7 +12155,7 @@ This makes for an unfriendly experience:
|
|
12107
12155
|
- State changes caused by AJAX updates get lost during the page transition.
|
12108
12156
|
- Unsaved form changes get lost during the page transition.
|
12109
12157
|
- The JavaScript VM is reset during the page transition.
|
12110
|
-
- If the page layout is composed from multiple
|
12158
|
+
- If the page layout is composed from multiple scrollable containers
|
12111
12159
|
(e.g. a pane view), the scroll positions get lost during the page transition.
|
12112
12160
|
- The user sees a "flash" as the browser loads and renders the new page,
|
12113
12161
|
even if large portions of the old and new page are the same (navigation, layout, etc.).
|
@@ -12831,7 +12879,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
12831
12879
|
@stable
|
12832
12880
|
*/
|
12833
12881
|
config = new up.Config({
|
12834
|
-
validateTargets: ['fieldset:has(&)', 'label:has(&)', 'form:has(&)'],
|
12882
|
+
validateTargets: ['[up-fieldset]:has(&)', 'fieldset:has(&)', 'label:has(&)', 'form:has(&)'],
|
12835
12883
|
fields: ['select', 'input:not([type=submit]):not([type=image])', 'button[type]:not([type=submit])', 'textarea'],
|
12836
12884
|
submitButtons: ['input[type=submit]', 'input[type=image]', 'button[type=submit]', 'button:not([type])'],
|
12837
12885
|
observeDelay: 0
|
@@ -12844,16 +12892,42 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
12844
12892
|
@function up.form.fieldSelector
|
12845
12893
|
@internal
|
12846
12894
|
*/
|
12847
|
-
fieldSelector = function() {
|
12848
|
-
|
12895
|
+
fieldSelector = function(suffix) {
|
12896
|
+
if (suffix == null) {
|
12897
|
+
suffix = '';
|
12898
|
+
}
|
12899
|
+
return config.fields.map(function(field) {
|
12900
|
+
return field + suffix;
|
12901
|
+
}).join(',');
|
12849
12902
|
};
|
12850
12903
|
|
12851
12904
|
/***
|
12905
|
+
Returns a list of form fields within the given element.
|
12906
|
+
|
12907
|
+
You can configure what Unpoly considers a form field by adding CSS selectors to the
|
12908
|
+
[`up.form.config.fields`](/up.form.config#config.fields) array.
|
12909
|
+
|
12910
|
+
If the given element is itself a form field, a list of that given element is returned.
|
12911
|
+
|
12852
12912
|
@function up.form.fields
|
12853
|
-
@
|
12913
|
+
@param {Element|jQuery} root
|
12914
|
+
The element to scan for contained form fields.
|
12915
|
+
|
12916
|
+
If the element is itself a form field, a list of that element is returned.
|
12917
|
+
@return {NodeList<Element>|Array<Element>}
|
12918
|
+
@experimental
|
12854
12919
|
*/
|
12855
12920
|
findFields = function(root) {
|
12856
|
-
|
12921
|
+
var fields, outsideFieldSelector, outsideFields;
|
12922
|
+
root = e.get(root);
|
12923
|
+
fields = e.subtree(root, fieldSelector());
|
12924
|
+
if (e.matches(root, 'form[id]')) {
|
12925
|
+
outsideFieldSelector = fieldSelector(e.attributeSelector('form', root.id));
|
12926
|
+
outsideFields = e.all(outsideFieldSelector);
|
12927
|
+
fields.push.apply(fields, outsideFields);
|
12928
|
+
fields = u.uniq(fields);
|
12929
|
+
}
|
12930
|
+
return fields;
|
12857
12931
|
};
|
12858
12932
|
|
12859
12933
|
/****
|
@@ -12980,6 +13054,9 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
12980
13054
|
If set to `'auto'` (default), Unpoly will try to find a match in the form's layer.
|
12981
13055
|
@param {string} [options.failLayer='auto']
|
12982
13056
|
The name of the layer that ought to be updated if the server sends a non-200 status code.
|
13057
|
+
@param {Object|FormData|string|Array|up.Params} [options.params]
|
13058
|
+
Extra form [parameters](/up.Params) that will be submitted in addition to
|
13059
|
+
the parameters from the form.
|
12983
13060
|
@return {Promise}
|
12984
13061
|
A promise for the successful form submission.
|
12985
13062
|
@stable
|
@@ -13029,7 +13106,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
13029
13106
|
if (options.failLayer == null) {
|
13030
13107
|
options.failLayer = form.getAttribute('up-fail-layer');
|
13031
13108
|
}
|
13032
|
-
options.params = up.Params.fromForm(form);
|
13109
|
+
options.params = up.Params.fromForm(form).addAll(options.params);
|
13033
13110
|
options = u.merge(options, up.motion.animateOptions(options, form));
|
13034
13111
|
if (options.validate) {
|
13035
13112
|
options.headers || (options.headers = {});
|
@@ -13379,7 +13456,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
13379
13456
|
|
13380
13457
|
\#\#\# Redirects
|
13381
13458
|
|
13382
|
-
Unpoly requires an additional response
|
13459
|
+
Unpoly requires an additional response header to detect redirects,
|
13383
13460
|
which are otherwise undetectable for an AJAX client.
|
13384
13461
|
|
13385
13462
|
After the form's action performs a redirect, the next response should echo
|
@@ -13614,7 +13691,19 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
13614
13691
|
This defaults to a fieldset or form group around the validating field.
|
13615
13692
|
@stable
|
13616
13693
|
*/
|
13617
|
-
|
13694
|
+
|
13695
|
+
/***
|
13696
|
+
Performs [server-side validation](/input-up-validate) when any fieldset within this form changes.
|
13697
|
+
|
13698
|
+
You can configure what Unpoly considers a fieldset by adding CSS selectors to the
|
13699
|
+
[`up.form.config.validateTargets`](/up.form.config#config.validateTargets) array.
|
13700
|
+
|
13701
|
+
@selector form[up-validate]
|
13702
|
+
@stable
|
13703
|
+
*/
|
13704
|
+
up.on('change', '[up-validate]', function(event) {
|
13705
|
+
var field;
|
13706
|
+
field = findFields(event.target)[0];
|
13618
13707
|
return u.muteRejection(validate(field));
|
13619
13708
|
});
|
13620
13709
|
|
@@ -13732,18 +13821,16 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
13732
13821
|
|
13733
13822
|
The programmatic variant of this is the [`up.observe()`](/up.observe) function.
|
13734
13823
|
|
13735
|
-
\#\#\#
|
13824
|
+
\#\#\# Example
|
13736
13825
|
|
13737
13826
|
The following would run a global `showSuggestions(value)` function
|
13738
13827
|
whenever the `<input>` changes:
|
13739
13828
|
|
13740
|
-
<
|
13741
|
-
<input name="query" up-observe="showSuggestions(value)">
|
13742
|
-
</form>
|
13829
|
+
<input name="query" up-observe="showSuggestions(value)">
|
13743
13830
|
|
13744
13831
|
\#\#\# Callback context
|
13745
13832
|
|
13746
|
-
The script given to `up-observe` runs with the following context:
|
13833
|
+
The script given to `[up-observe]` runs with the following context:
|
13747
13834
|
|
13748
13835
|
| Name | Type | Description |
|
13749
13836
|
| -------- | --------- | ------------------------------------- |
|
@@ -13751,6 +13838,20 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
13751
13838
|
| `this` | `Element` | The form field |
|
13752
13839
|
| `$field` | `jQuery` | The form field as a jQuery collection |
|
13753
13840
|
|
13841
|
+
\#\#\# Observing radio buttons
|
13842
|
+
|
13843
|
+
Multiple radio buttons with the same `[name]` (a radio button group)
|
13844
|
+
produce a single value for the form.
|
13845
|
+
|
13846
|
+
To observe radio buttons group, use the `[up-observe]` attribute on an
|
13847
|
+
element that contains all radio button elements with a given name:
|
13848
|
+
|
13849
|
+
<div up-observe="formatSelected(value)">
|
13850
|
+
<input type="radio" name="format" value="html"> HTML format
|
13851
|
+
<input type="radio" name="format" value="pdf"> PDF format
|
13852
|
+
<input type="radio" name="format" value="txt"> Text format
|
13853
|
+
</div>
|
13854
|
+
|
13754
13855
|
@selector input[up-observe]
|
13755
13856
|
@param {string} up-observe
|
13756
13857
|
The code to run when the field's value changes.
|
@@ -13799,7 +13900,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
13799
13900
|
});
|
13800
13901
|
|
13801
13902
|
/***
|
13802
|
-
|
13903
|
+
Submits this field's form when this field changes its values.
|
13803
13904
|
|
13804
13905
|
Both the form and the changed field will be assigned a CSS class [`up-active`](/form-up-active)
|
13805
13906
|
while the autosubmitted form is loading.
|
@@ -13815,6 +13916,20 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
13815
13916
|
<input type="checkbox" name="archive"> Include archive
|
13816
13917
|
</form>
|
13817
13918
|
|
13919
|
+
\#\#\# Auto-submitting radio buttons
|
13920
|
+
|
13921
|
+
Multiple radio buttons with the same `[name]` (a radio button group)
|
13922
|
+
produce a single value for the form.
|
13923
|
+
|
13924
|
+
To auto-submit radio buttons group, use the `[up-submit]` attribute on an
|
13925
|
+
element that contains all radio button elements with a given name:
|
13926
|
+
|
13927
|
+
<div up-autosubmit>
|
13928
|
+
<input type="radio" name="format" value="html"> HTML format
|
13929
|
+
<input type="radio" name="format" value="pdf"> PDF format
|
13930
|
+
<input type="radio" name="format" value="txt"> Text format
|
13931
|
+
</div>
|
13932
|
+
|
13818
13933
|
@selector input[up-autosubmit]
|
13819
13934
|
@param {string} up-delay
|
13820
13935
|
The number of miliseconds to wait after a change before the form is submitted.
|
@@ -13822,7 +13937,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
13822
13937
|
*/
|
13823
13938
|
|
13824
13939
|
/***
|
13825
|
-
|
13940
|
+
Submits the form when *any* field changes.
|
13826
13941
|
|
13827
13942
|
Both the form and the field will be assigned a CSS class [`up-active`](/form-up-active)
|
13828
13943
|
while the autosubmitted form is loading.
|
@@ -14698,6 +14813,7 @@ or function.
|
|
14698
14813
|
var closeElement, contentElement, dialogStyles, html, modalElement;
|
14699
14814
|
html = templateHtml();
|
14700
14815
|
state.modalElement = modalElement = e.createFromHtml(html);
|
14816
|
+
modalElement.setAttribute('aria-modal', 'true');
|
14701
14817
|
modalElement.setAttribute('up-flavor', state.flavor);
|
14702
14818
|
if (u.isPresent(state.position)) {
|
14703
14819
|
modalElement.setAttribute('up-position', state.position);
|
@@ -14736,7 +14852,7 @@ or function.
|
|
14736
14852
|
var link = document.querySelector('a')
|
14737
14853
|
up.modal.follow(link)
|
14738
14854
|
|
14739
|
-
Any option attributes for [`a[up-modal]`](/a
|
14855
|
+
Any option attributes for [`a[up-modal]`](/a-up-modal) will be honored.
|
14740
14856
|
|
14741
14857
|
Emits events [`up:modal:open`](/up:modal:open) and [`up:modal:opened`](/up:modal:opened).
|
14742
14858
|
|
@@ -14919,6 +15035,9 @@ or function.
|
|
14919
15035
|
if (options.failLayer == null) {
|
14920
15036
|
options.failLayer = (ref12 = link.getAttribute('up-fail-layer')) != null ? ref12 : 'auto';
|
14921
15037
|
}
|
15038
|
+
if (options.cache == null) {
|
15039
|
+
options.cache = e.booleanAttr(link, 'up-cache');
|
15040
|
+
}
|
14922
15041
|
animateOptions = up.motion.animateOptions(options, link, {
|
14923
15042
|
duration: flavorDefault('openDuration', options.flavor),
|
14924
15043
|
easing: flavorDefault('openEasing', options.flavor)
|
@@ -15175,7 +15294,7 @@ or function.
|
|
15175
15294
|
|
15176
15295
|
Clicking would request the path `/blog` and select `.blog-list` from
|
15177
15296
|
the HTML response. Unpoly will dim the page
|
15178
|
-
and place the matching `.blog-list` tag
|
15297
|
+
and place the matching `.blog-list` tag in
|
15179
15298
|
a modal dialog.
|
15180
15299
|
|
15181
15300
|
@selector a[up-modal]
|