unpoly-rails 0.60.2 → 0.62.1
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/.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]
|