unpoly-rails 0.22.0 → 0.22.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/CHANGELOG.md +14 -0
- data/README_RAILS.md +1 -1
- data/dist/unpoly.js +271 -157
- data/dist/unpoly.min.js +2 -2
- data/lib/assets/javascripts/unpoly/bus.js.coffee +52 -26
- data/lib/assets/javascripts/unpoly/flow.js.coffee +10 -5
- data/lib/assets/javascripts/unpoly/history.js.coffee +1 -0
- data/lib/assets/javascripts/unpoly/layout.js.coffee +17 -5
- data/lib/assets/javascripts/unpoly/link.js.coffee +60 -61
- data/lib/assets/javascripts/unpoly/log.js.coffee +8 -0
- data/lib/assets/javascripts/unpoly/motion.js.coffee +20 -9
- data/lib/assets/javascripts/unpoly/proxy.js.coffee +42 -37
- data/lib/assets/javascripts/unpoly/syntax.js.coffee +46 -7
- data/lib/assets/javascripts/unpoly/util.js.coffee +4 -3
- data/lib/unpoly/rails/version.rb +1 -1
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +104 -9
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6109418137600ed7280a7f3ecb2adb7ab5da2b4f
|
4
|
+
data.tar.gz: 118d634ab654710610a010e42d0d55223cd65a6b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4bd0e2d984e5c55654d201fd095eb4424105000d46f1d22273190f8fea325189a9727152a16d5bf549eb9a990f49f3ef9f5366ff06260b012ad81b7343629e87
|
7
|
+
data.tar.gz: 4f8a3ba9acf52274f0a26a21a600e4d0092694366b935de0ba1e992283f43bbf7b2b6979ef844335ab9d7bf16e985362da3ae3a0c67848ee4ff2ef5425730698
|
data/CHANGELOG.md
CHANGED
@@ -14,6 +14,20 @@ Unreleased
|
|
14
14
|
### Breaking changes
|
15
15
|
|
16
16
|
|
17
|
+
0.22.1
|
18
|
+
------
|
19
|
+
|
20
|
+
### Compatible changes
|
21
|
+
|
22
|
+
- Fix a bug where the document title wasn't restored when using the back
|
23
|
+
and forward buttons
|
24
|
+
- Fix a bug where links would be followed multiple times if the link
|
25
|
+
had an [`up-dash`](/up-dash) attribute without a value and also an `up-target` attribute.
|
26
|
+
- Fix a bug where a link would be followed multiple times if the link's
|
27
|
+
click area was expanded using [`[up-expand]`](/up-expand) and if the
|
28
|
+
link also had an [`up-dash`](/up-dash) attribute.
|
29
|
+
|
30
|
+
|
17
31
|
0.22.0
|
18
32
|
------
|
19
33
|
|
data/README_RAILS.md
CHANGED
@@ -17,7 +17,7 @@ To test whether the current request is a [fragment update](http://unpoly.com/up.
|
|
17
17
|
|
18
18
|
To retrieve the CSS selector that is being [updated](http://unpoly.com/up.replace):
|
19
19
|
|
20
|
-
up.
|
20
|
+
up.target
|
21
21
|
|
22
22
|
The Unpoly frontend will expect an HTML response containing an element that matches this selector. If no such element is found, an error is shown to the user. Server-side code is free to optimize its response by only returning HTML that matches this selector.
|
23
23
|
|
data/dist/unpoly.js
CHANGED
@@ -1110,7 +1110,7 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1110
1110
|
@internal
|
1111
1111
|
*/
|
1112
1112
|
measure = function($element, opts) {
|
1113
|
-
var $context, box, contextCoords, coordinates, elementCoords
|
1113
|
+
var $context, $viewport, box, contextCoords, coordinates, elementCoords;
|
1114
1114
|
opts = options(opts, {
|
1115
1115
|
relative: false,
|
1116
1116
|
inner: false,
|
@@ -1147,9 +1147,9 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1147
1147
|
box.height = $element.outerHeight();
|
1148
1148
|
}
|
1149
1149
|
if (opts.full) {
|
1150
|
-
viewport =
|
1151
|
-
box.right = viewport.width - (box.left + box.width);
|
1152
|
-
box.bottom = viewport.height - (box.top + box.height);
|
1150
|
+
$viewport = up.layout.viewportOf($element);
|
1151
|
+
box.right = $viewport.width() - (box.left + box.width);
|
1152
|
+
box.bottom = $viewport.height() - (box.top + box.height);
|
1153
1153
|
}
|
1154
1154
|
return box;
|
1155
1155
|
};
|
@@ -1890,6 +1890,16 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1890
1890
|
up.error = up.util.error;
|
1891
1891
|
|
1892
1892
|
}).call(this);
|
1893
|
+
|
1894
|
+
/**
|
1895
|
+
Logging
|
1896
|
+
=======
|
1897
|
+
|
1898
|
+
Elaborate wrappers around `window.console`.
|
1899
|
+
Should only used internally since they prefix `ᴜᴘ` to each
|
1900
|
+
printed message.
|
1901
|
+
*/
|
1902
|
+
|
1893
1903
|
(function() {
|
1894
1904
|
var slice = [].slice;
|
1895
1905
|
|
@@ -2280,40 +2290,48 @@ we can't currently get rid off.
|
|
2280
2290
|
Events
|
2281
2291
|
======
|
2282
2292
|
|
2283
|
-
Unpoly
|
2284
|
-
|
2285
|
-
up.on('click', 'button', function(event, $button) {
|
2286
|
-
// $button is a jQuery collection containing
|
2287
|
-
// the clicked <button> element
|
2288
|
-
});
|
2289
|
-
|
2290
|
-
This is roughly equivalent to binding an event listener to `document`
|
2291
|
-
using jQuery's [`on`](http://api.jquery.com/on/).
|
2293
|
+
Most Unpoly interactions emit DOM events that are prefixed with `up:`.
|
2292
2294
|
|
2293
|
-
|
2294
|
-
leaving you with an application without Javascript. This is typically preferable to
|
2295
|
-
a soup of randomly broken Javascript in ancient browsers.
|
2296
|
-
- A jQuery object with the target element is automatically passed to the event handler.
|
2297
|
-
- You can [attach structured data](/up.on#attaching-structured-data) to observed elements.
|
2298
|
-
- The call is shorter.
|
2299
|
-
|
2300
|
-
Many Unpoly interactions also emit DOM events that are prefixed with `up:`.
|
2301
|
-
|
2302
|
-
up.on('up:modal:opened', function(event) {
|
2295
|
+
$(document).on('up:modal:opened', function(event) {
|
2303
2296
|
console.log('A new modal has just opened!');
|
2304
2297
|
});
|
2305
2298
|
|
2306
|
-
Events often have both present (`up:modal:open`
|
2299
|
+
Events often have both present ([`up:modal:open`](/up:modal:open))
|
2300
|
+
and past forms ([`up:modal:opened`](/up:modal:opened)).
|
2301
|
+
|
2307
2302
|
You can usually prevent an action by listening to the present form
|
2308
2303
|
and call `preventDefault()` on the `event` object:
|
2309
2304
|
|
2310
|
-
|
2305
|
+
$(document).on('up:modal:open', function(event) {
|
2311
2306
|
if (event.url == '/evil') {
|
2312
2307
|
// Prevent the modal from opening
|
2313
2308
|
event.preventDefault();
|
2314
2309
|
}
|
2315
2310
|
});
|
2316
2311
|
|
2312
|
+
|
2313
|
+
A better way to bind event listeners
|
2314
|
+
------------------------------------
|
2315
|
+
|
2316
|
+
Instead of using jQuery to bind an event handler to `document`, you can also
|
2317
|
+
use the more convenient [`up.on`](/up.on):
|
2318
|
+
|
2319
|
+
up.on('click', 'button', function(event, $button) {
|
2320
|
+
// $button is a jQuery collection containing
|
2321
|
+
// the clicked <button> element
|
2322
|
+
});
|
2323
|
+
|
2324
|
+
This is roughly equivalent to binding an event listener to `document`
|
2325
|
+
using jQuery's [`on`](http://api.jquery.com/on/).
|
2326
|
+
|
2327
|
+
- Event listeners on [unsupported browsers](/up.browser.isSupported) are silently discarded,
|
2328
|
+
leaving you with an application without Javascript. This is typically preferable to
|
2329
|
+
a soup of randomly broken Javascript in ancient browsers.
|
2330
|
+
- A jQuery object with the target element is automatically passed to the event handler
|
2331
|
+
as a second argument.
|
2332
|
+
- You use an [`up-data`](/up-data) attribute to [attach structured data](/up.on#attaching-structured-data)
|
2333
|
+
to observed elements.
|
2334
|
+
|
2317
2335
|
@class up.bus
|
2318
2336
|
*/
|
2319
2337
|
|
@@ -2418,9 +2436,27 @@ and call `preventDefault()` on the `event` object:
|
|
2418
2436
|
|
2419
2437
|
\#\#\#\# Stopping to listen
|
2420
2438
|
|
2421
|
-
`up.on` returns a function that unbinds the event listeners when called
|
2439
|
+
`up.on` returns a function that unbinds the event listeners when called:
|
2440
|
+
|
2441
|
+
// Define the listener
|
2442
|
+
var listener = function() { ... };
|
2443
|
+
|
2444
|
+
// Binding the listener returns an unbind function
|
2445
|
+
unbind = up.on('click', listener);
|
2446
|
+
|
2447
|
+
// Unbind the listener
|
2448
|
+
unbind()
|
2449
|
+
|
2450
|
+
There is also a function [`up.off`](/up.off) which you can use for the same purpose:
|
2451
|
+
|
2452
|
+
// Define the listener
|
2453
|
+
var listener = function() { ... };
|
2454
|
+
|
2455
|
+
// Bind the listener
|
2456
|
+
up.on('click', listener);
|
2422
2457
|
|
2423
|
-
|
2458
|
+
// Unbind the listener
|
2459
|
+
up.off('click', listener)
|
2424
2460
|
|
2425
2461
|
@function up.on
|
2426
2462
|
@param {String} events
|
@@ -2432,7 +2468,7 @@ and call `preventDefault()` on the `event` object:
|
|
2432
2468
|
@param {Function(event, $element, data)} behavior
|
2433
2469
|
The handler that should be called.
|
2434
2470
|
The function takes the affected element as the first argument (as a jQuery object).
|
2435
|
-
If the element has an `up-data` attribute, its value is parsed as JSON
|
2471
|
+
If the element has an [`up-data`](/up-data) attribute, its value is parsed as JSON
|
2436
2472
|
and passed as a second argument.
|
2437
2473
|
@return {Function}
|
2438
2474
|
A function that unbinds the event listeners when called.
|
@@ -2453,13 +2489,13 @@ and call `preventDefault()` on the `event` object:
|
|
2453
2489
|
};
|
2454
2490
|
|
2455
2491
|
/**
|
2456
|
-
|
2492
|
+
Unbinds an event listener previously bound with [`up.on`](/up.on).
|
2457
2493
|
|
2458
2494
|
\#\#\#\# Example
|
2459
2495
|
|
2460
2496
|
Let's say you are listing to clicks on `.button` elements:
|
2461
2497
|
|
2462
|
-
var listener = function() { };
|
2498
|
+
var listener = function() { ... };
|
2463
2499
|
up.on('click', '.button', listener);
|
2464
2500
|
|
2465
2501
|
You can stop listening to these events like this:
|
@@ -2771,11 +2807,11 @@ later.
|
|
2771
2807
|
Registers a function to be called whenever an element with
|
2772
2808
|
the given selector is inserted into the DOM.
|
2773
2809
|
|
2774
|
-
|
2810
|
+
up.compiler('.action', function($element) {
|
2775
2811
|
// your code here
|
2776
2812
|
});
|
2777
2813
|
|
2778
|
-
|
2814
|
+
The functions will be called on elements maching `.action` when
|
2779
2815
|
the page loads, or whenever a matching fragment is [updated through Unpoly](/up.replace)
|
2780
2816
|
later.
|
2781
2817
|
|
@@ -2860,7 +2896,7 @@ later.
|
|
2860
2896
|
{ lat: 48.75, lng: 11.45, title: 'Ingolstadt' }
|
2861
2897
|
]"></div>
|
2862
2898
|
|
2863
|
-
The JSON will parsed and handed to your
|
2899
|
+
The JSON will parsed and handed to your compiler as a second argument:
|
2864
2900
|
|
2865
2901
|
up.compiler('.google-map', function($element, pins) {
|
2866
2902
|
|
@@ -2920,7 +2956,7 @@ later.
|
|
2920
2956
|
@param {Function($element, data)} compiler
|
2921
2957
|
The function to call when a matching element is inserted.
|
2922
2958
|
The function takes the new element as the first argument (as a jQuery object).
|
2923
|
-
If the element has an `up-data` attribute, its value is parsed as JSON
|
2959
|
+
If the element has an [`up-data`](/up-data) attribute, its value is parsed as JSON
|
2924
2960
|
and passed as a second argument.
|
2925
2961
|
|
2926
2962
|
The function may return a destructor function that destroys the compiled
|
@@ -3094,11 +3130,21 @@ later.
|
|
3094
3130
|
};
|
3095
3131
|
|
3096
3132
|
/**
|
3097
|
-
Checks if the given element has an `up-data` attribute.
|
3133
|
+
Checks if the given element has an [`up-data`](/up-data) attribute.
|
3098
3134
|
If yes, parses the attribute value as JSON and returns the parsed object.
|
3099
3135
|
|
3100
3136
|
Returns an empty object if the element has no `up-data` attribute.
|
3101
3137
|
|
3138
|
+
\#\#\#\# Example
|
3139
|
+
|
3140
|
+
You have an element with JSON data serialized into an `up-data` attribute:
|
3141
|
+
|
3142
|
+
<span class="person" up-data="{ age: 18, name: 'Bob' }">Bob</span>
|
3143
|
+
|
3144
|
+
Calling `up.syntax.data` will deserialize the JSON string into a Javascript object:
|
3145
|
+
|
3146
|
+
up.syntax.data('.person') // returns { age: 18, name: 'Bob' }
|
3147
|
+
|
3102
3148
|
@function up.syntax.data
|
3103
3149
|
@param {String|Element|jQuery} elementOrSelector
|
3104
3150
|
@return
|
@@ -3108,15 +3154,44 @@ later.
|
|
3108
3154
|
@experimental
|
3109
3155
|
*/
|
3110
3156
|
|
3111
|
-
|
3157
|
+
/**
|
3112
3158
|
If an element annotated with [`up-data`] is inserted into the DOM,
|
3113
3159
|
Up will parse the JSON and pass the resulting object to any matching
|
3114
|
-
[`up.compiler`](/up.
|
3160
|
+
[`up.compiler`](/up.compiler) handlers.
|
3161
|
+
|
3162
|
+
For instance, a container for a [Google Map](https://developers.google.com/maps/documentation/javascript/tutorial)
|
3163
|
+
might attach the location and names of its marker pins:
|
3164
|
+
|
3165
|
+
<div class="google-map" up-data="[
|
3166
|
+
{ lat: 48.36, lng: 10.99, title: 'Friedberg' },
|
3167
|
+
{ lat: 48.75, lng: 11.45, title: 'Ingolstadt' }
|
3168
|
+
]"></div>
|
3169
|
+
|
3170
|
+
The JSON will parsed and handed to your compiler as a second argument:
|
3171
|
+
|
3172
|
+
up.compiler('.google-map', function($element, pins) {
|
3173
|
+
|
3174
|
+
var map = new google.maps.Map($element);
|
3175
|
+
|
3176
|
+
pins.forEach(function(pin) {
|
3177
|
+
var position = new google.maps.LatLng(pin.lat, pin.lng);
|
3178
|
+
new google.maps.Marker({
|
3179
|
+
position: position,
|
3180
|
+
map: map,
|
3181
|
+
title: pin.title
|
3182
|
+
});
|
3183
|
+
});
|
3184
|
+
|
3185
|
+
});
|
3115
3186
|
|
3116
3187
|
Similarly, when an event is triggered on an element annotated with
|
3117
3188
|
[`up-data`], the parsed object will be passed to any matching
|
3118
3189
|
[`up.on`](/up.on) handlers.
|
3119
3190
|
|
3191
|
+
up.on('click', '.google-map', function(event, $element, pins) {
|
3192
|
+
console.log("There are %d pins on the clicked map", pins.length);
|
3193
|
+
});
|
3194
|
+
|
3120
3195
|
@selector [up-data]
|
3121
3196
|
@param {JSON} up-data
|
3122
3197
|
A serialized JSON string
|
@@ -3334,6 +3409,7 @@ We need to work on this page:
|
|
3334
3409
|
popSelector = config.popTargets.join(', ');
|
3335
3410
|
return up.replace(popSelector, url, {
|
3336
3411
|
history: false,
|
3412
|
+
title: true,
|
3337
3413
|
reveal: false,
|
3338
3414
|
transition: 'none',
|
3339
3415
|
saveScroll: false,
|
@@ -3424,7 +3500,19 @@ We need to work on this page:
|
|
3424
3500
|
Application layout
|
3425
3501
|
==================
|
3426
3502
|
|
3427
|
-
|
3503
|
+
You can [make Unpoly aware](/up.layout.config) of fixed elements in your
|
3504
|
+
layout, such as navigation bars or headers. Unpoly will respect these sticky
|
3505
|
+
elements when [revealing elements](/up.reveal) or [opening a modal dialog](/up-modal).
|
3506
|
+
|
3507
|
+
This modules also contains functions to programmatically [scroll a viewport](/up.scroll)
|
3508
|
+
or [reveal an element within its viewport](/up.reveal).
|
3509
|
+
|
3510
|
+
Bootstrap integration
|
3511
|
+
---------------------
|
3512
|
+
|
3513
|
+
When using Bootstrap integration (`unpoly-bootstrap3.js` and `unpoly-bootstrap3.css`)
|
3514
|
+
Unpoly will automatically be aware of sticky Bootstrap components such as
|
3515
|
+
[fixed navbar](https://getbootstrap.com/examples/navbar-fixed-top/).
|
3428
3516
|
|
3429
3517
|
@class up.layout
|
3430
3518
|
*/
|
@@ -3452,17 +3540,17 @@ This modules contains functions to scroll the viewport and reveal contained elem
|
|
3452
3540
|
@param {Array} [config.anchoredRight]
|
3453
3541
|
An array of CSS selectors that find elements anchored to the
|
3454
3542
|
right edge of the screen (using `position: fixed` or `position: absolute`).
|
3455
|
-
@param {Number} [config.duration]
|
3543
|
+
@param {Number} [config.duration=0]
|
3456
3544
|
The duration of the scrolling animation in milliseconds.
|
3457
3545
|
Setting this to `0` will disable scrolling animations.
|
3458
|
-
@param {String} [config.easing]
|
3546
|
+
@param {String} [config.easing='swing']
|
3459
3547
|
The timing function that controls the animation's acceleration.
|
3460
3548
|
See [W3C documentation](http://www.w3.org/TR/css3-transitions/#transition-timing-function)
|
3461
3549
|
for a list of pre-defined timing functions.
|
3462
|
-
@param {Number} [config.snap]
|
3550
|
+
@param {Number} [config.snap=50]
|
3463
3551
|
When [revealing](/up.reveal) elements, Unpoly will scroll an viewport
|
3464
3552
|
to the top when the revealed element is closer to the top than `config.snap`.
|
3465
|
-
@param {Number} [config.substance]
|
3553
|
+
@param {Number} [config.substance=150]
|
3466
3554
|
A number indicating how many top pixel rows of an element to [reveal](/up.reveal).
|
3467
3555
|
@stable
|
3468
3556
|
*/
|
@@ -4034,8 +4122,8 @@ This modules contains functions to scroll the viewport and reveal contained elem
|
|
4034
4122
|
Changing page fragments programmatically
|
4035
4123
|
========================================
|
4036
4124
|
|
4037
|
-
This module contains Unpoly's core functions to [change](/up.replace) or
|
4038
|
-
|
4125
|
+
This module contains Unpoly's core functions to [change](/up.replace) or
|
4126
|
+
[destroy](/up.destroy) page fragments via Javascript.
|
4039
4127
|
|
4040
4128
|
All the other Unpoly modules (like [`up.link`](/up.link) or [`up.modal`](/up.modal))
|
4041
4129
|
are based on this module.
|
@@ -4167,7 +4255,7 @@ are based on this module.
|
|
4167
4255
|
the CSS selector for the updating fragment.
|
4168
4256
|
|
4169
4257
|
If you are using the `unpoly-rails` gem you can also access the selector via
|
4170
|
-
`up.
|
4258
|
+
`up.target` in all controllers, views and helpers.
|
4171
4259
|
|
4172
4260
|
\#\#\#\# Events
|
4173
4261
|
|
@@ -4262,6 +4350,9 @@ are based on this module.
|
|
4262
4350
|
var isReloadable, newRequest, query, urlFromServer;
|
4263
4351
|
options.method = u.normalizeMethod(u.option(u.methodFromXhr(xhr), options.method));
|
4264
4352
|
options.title = u.option(u.titleFromXhr(xhr), options.title);
|
4353
|
+
if (!(options.title === false || u.isString(options.title) || (options.history === false && options.title !== true))) {
|
4354
|
+
options.title = u.titleFromXhr(xhr);
|
4355
|
+
}
|
4265
4356
|
isReloadable = options.method === 'GET';
|
4266
4357
|
if (urlFromServer = u.locationFromXhr(xhr)) {
|
4267
4358
|
url = urlFromServer;
|
@@ -4424,10 +4515,10 @@ are based on this module.
|
|
4424
4515
|
};
|
4425
4516
|
};
|
4426
4517
|
updateHistory = function(options) {
|
4518
|
+
if (options.title) {
|
4519
|
+
document.title = options.title;
|
4520
|
+
}
|
4427
4521
|
if (options.history) {
|
4428
|
-
if (options.title) {
|
4429
|
-
document.title = options.title;
|
4430
|
-
}
|
4431
4522
|
return up.history[options.historyMethod](options.history);
|
4432
4523
|
}
|
4433
4524
|
};
|
@@ -4645,7 +4736,7 @@ are based on this module.
|
|
4645
4736
|
|
4646
4737
|
/**
|
4647
4738
|
Compiles a page fragment that has been inserted into the DOM
|
4648
|
-
|
4739
|
+
by external code.
|
4649
4740
|
|
4650
4741
|
**As long as you manipulate the DOM using Unpoly, you will never
|
4651
4742
|
need to call this method.** You only need to use `up.hello` if the
|
@@ -4938,6 +5029,9 @@ to smoothly fade out the old `.list` while fading in the new `.list`:
|
|
4938
5029
|
|
4939
5030
|
<a href="/users" up-target=".list" up-transition="cross-fade">Show users</a>
|
4940
5031
|
|
5032
|
+
Transitions vs. animations
|
5033
|
+
--------------------------
|
5034
|
+
|
4941
5035
|
When we morph between an old an new element, we call it a *transition*.
|
4942
5036
|
In contrast, when we animate a new element without simultaneously removing an
|
4943
5037
|
old element, we call it an *animation*.
|
@@ -4947,6 +5041,9 @@ using the `up-animation` attribute:
|
|
4947
5041
|
|
4948
5042
|
<a href="/users" up-modal=".list" up-animation="move-from-top">Show users</a>
|
4949
5043
|
|
5044
|
+
Predefined animations and transitions
|
5045
|
+
-------------------------------------
|
5046
|
+
|
4950
5047
|
Unpoly ships with a number of predefined [animations](/up.animate#named-animation)
|
4951
5048
|
and [transitions](/up.morph#named-animation).
|
4952
5049
|
You can also easily [define your own animations](/up.animation)
|
@@ -5391,7 +5488,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
5391
5488
|
If you choose to *not* use `up.animate` and roll your own
|
5392
5489
|
logic instead, your code must honor the following contract:
|
5393
5490
|
|
5394
|
-
1. It must honor the passed options
|
5491
|
+
1. It must honor the passed options `{ delay, duration, easing }` if present
|
5395
5492
|
2. It must *not* remove any of the given elements from the DOM.
|
5396
5493
|
3. It returns a promise that is resolved when the transition ends
|
5397
5494
|
4. The returned promise responds to a `resolve()` function that
|
@@ -5414,8 +5511,8 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
5414
5511
|
|
5415
5512
|
Here is the definition of the pre-defined `fade-in` animation:
|
5416
5513
|
|
5417
|
-
up.animation('fade-in', function($
|
5418
|
-
$
|
5514
|
+
up.animation('fade-in', function($element, options) {
|
5515
|
+
$element.css(opacity: 0);
|
5419
5516
|
up.animate($ghost, { opacity: 1 }, options);
|
5420
5517
|
})
|
5421
5518
|
|
@@ -5426,7 +5523,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
5426
5523
|
If you choose to *not* use `up.animate` and roll your own
|
5427
5524
|
animation code instead, your code must honor the following contract:
|
5428
5525
|
|
5429
|
-
1. It must honor the passed options
|
5526
|
+
1. It must honor the passed options `{ delay, duration, easing }` if present
|
5430
5527
|
2. It must *not* remove the passed element from the DOM.
|
5431
5528
|
3. It returns a promise that is resolved when the animation ends
|
5432
5529
|
4. The returned promise responds to a `resolve()` function that
|
@@ -5449,15 +5546,20 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
5449
5546
|
};
|
5450
5547
|
|
5451
5548
|
/**
|
5452
|
-
Returns a new
|
5549
|
+
Returns a new deferred that resolves once all given deferreds have resolved.
|
5453
5550
|
|
5454
5551
|
Other then [`$.when` from jQuery](https://api.jquery.com/jquery.when/),
|
5455
|
-
the combined
|
5456
|
-
will resolve all the wrapped
|
5552
|
+
the combined deferred will have a `resolve` method. This `resolve` method
|
5553
|
+
will resolve all the wrapped deferreds.
|
5554
|
+
|
5555
|
+
This is important when composing multiple existing animations into
|
5556
|
+
a [custom transition](/up.transition), since the transition function
|
5557
|
+
must return a deferred with a `resolve` function that fast-forwards
|
5558
|
+
the animation to its last frame.
|
5457
5559
|
|
5458
5560
|
@function up.motion.when
|
5459
|
-
@param
|
5460
|
-
@return A new
|
5561
|
+
@param {Array<Deferred>} deferreds...
|
5562
|
+
@return {Deferred} A new deferred
|
5461
5563
|
@experimental
|
5462
5564
|
*/
|
5463
5565
|
resolvableWhen = u.resolvableWhen;
|
@@ -5641,7 +5743,7 @@ Caching and preloading
|
|
5641
5743
|
All HTTP requests go through the Unpoly proxy.
|
5642
5744
|
It caches a [limited](/up.proxy.config) number of server responses
|
5643
5745
|
for a [limited](/up.proxy.config) amount of time,
|
5644
|
-
making requests to these URLs return
|
5746
|
+
making requests to these URLs return instantly.
|
5645
5747
|
|
5646
5748
|
The cache is cleared whenever the user makes a non-`GET` request
|
5647
5749
|
(like `POST`, `PUT` or `DELETE`).
|
@@ -5651,42 +5753,6 @@ links when the user hovers over the click area](/up-preload) (or puts the mouse/
|
|
5651
5753
|
down before releasing). This way the response will already be cached when
|
5652
5754
|
the user performs the click.
|
5653
5755
|
|
5654
|
-
Spinners
|
5655
|
-
--------
|
5656
|
-
|
5657
|
-
You can [listen](/up.on) to the [`up:proxy:slow`](/up:proxy:slow)
|
5658
|
-
and [`up:proxy:recover`](/up:proxy:recover) events to implement a spinner
|
5659
|
-
that appears during a long-running request,
|
5660
|
-
and disappears once the response has been received:
|
5661
|
-
|
5662
|
-
<div class="spinner">Please wait!</div>
|
5663
|
-
|
5664
|
-
Here is the Javascript to make it alive:
|
5665
|
-
|
5666
|
-
up.compiler('.spinner', function($element) {
|
5667
|
-
|
5668
|
-
show = function() { $element.show() };
|
5669
|
-
hide = function() { $element.hide() };
|
5670
|
-
|
5671
|
-
showOff = up.on('up:proxy:slow', show);
|
5672
|
-
hideOff = up.on('up:proxy:recover', hide);
|
5673
|
-
|
5674
|
-
hide();
|
5675
|
-
|
5676
|
-
// Clean up when the element is removed from the DOM
|
5677
|
-
return function() {
|
5678
|
-
showOff();
|
5679
|
-
hideOff();
|
5680
|
-
};
|
5681
|
-
|
5682
|
-
});
|
5683
|
-
|
5684
|
-
The `up:proxy:slow` event will be emitted after a delay of 300 ms
|
5685
|
-
to prevent the spinner from flickering on and off.
|
5686
|
-
You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.config) like this:
|
5687
|
-
|
5688
|
-
up.proxy.config.slowDelay = 150;
|
5689
|
-
|
5690
5756
|
@class up.proxy
|
5691
5757
|
*/
|
5692
5758
|
|
@@ -5987,6 +6053,43 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5987
6053
|
Note that if additional requests are made while Unpoly is already busy
|
5988
6054
|
waiting, **no** additional `up:proxy:slow` events will be triggered.
|
5989
6055
|
|
6056
|
+
|
6057
|
+
\#\#\#\# Spinners
|
6058
|
+
|
6059
|
+
You can [listen](/up.on) to the `up:proxy:slow`
|
6060
|
+
and [`up:proxy:recover`](/up:proxy:recover) events to implement a spinner
|
6061
|
+
that appears during a long-running request,
|
6062
|
+
and disappears once the response has been received:
|
6063
|
+
|
6064
|
+
<div class="spinner">Please wait!</div>
|
6065
|
+
|
6066
|
+
Here is the Javascript to make it alive:
|
6067
|
+
|
6068
|
+
up.compiler('.spinner', function($element) {
|
6069
|
+
|
6070
|
+
show = function() { $element.show() };
|
6071
|
+
hide = function() { $element.hide() };
|
6072
|
+
|
6073
|
+
showOff = up.on('up:proxy:slow', show);
|
6074
|
+
hideOff = up.on('up:proxy:recover', hide);
|
6075
|
+
|
6076
|
+
hide();
|
6077
|
+
|
6078
|
+
// Clean up when the element is removed from the DOM
|
6079
|
+
return function() {
|
6080
|
+
showOff();
|
6081
|
+
hideOff();
|
6082
|
+
};
|
6083
|
+
|
6084
|
+
});
|
6085
|
+
|
6086
|
+
The `up:proxy:slow` event will be emitted after a delay of 300 ms
|
6087
|
+
to prevent the spinner from flickering on and off.
|
6088
|
+
You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.config) like this:
|
6089
|
+
|
6090
|
+
up.proxy.config.slowDelay = 150;
|
6091
|
+
|
6092
|
+
|
5990
6093
|
@event up:proxy:slow
|
5991
6094
|
@stable
|
5992
6095
|
*/
|
@@ -6004,6 +6107,10 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
6004
6107
|
This event is [emitted]/(up.emit) when [AJAX requests](/up.ajax)
|
6005
6108
|
have [taken long to finish](/up:proxy:slow), but have finished now.
|
6006
6109
|
|
6110
|
+
See [`up:proxy:slow`](/up:proxy:slow) for more documentation on
|
6111
|
+
how to use this event for implementing a spinner that shows during
|
6112
|
+
long-running requests.
|
6113
|
+
|
6007
6114
|
@event up:proxy:recover
|
6008
6115
|
@stable
|
6009
6116
|
*/
|
@@ -6186,10 +6293,27 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
6186
6293
|
Linking to page fragments
|
6187
6294
|
=========================
|
6188
6295
|
|
6189
|
-
|
6296
|
+
Standard HTML links are a poor fit for modern applications:
|
6297
|
+
|
6298
|
+
- State changes caused by AJAX updates get lost during the page transition.
|
6299
|
+
- Unsaved form changes get lost during the page transition.
|
6300
|
+
- The Javascript VM is reset during the page transition.
|
6301
|
+
- If the page layout is composed from multiple srollable containers
|
6302
|
+
(e.g. a pane view), the scroll positions get lost during the page transition.
|
6303
|
+
- The user sees a "flash" as the browser loads and renders the new page,
|
6304
|
+
even if large portions of the old and new page are the same (navigation, layout, etc.).
|
6305
|
+
|
6306
|
+
Unpoly fixes this by letting you annotate links with an [`up-target`](/up-target)
|
6307
|
+
attribute. The value of this attribute is a CSS selector that indicates which page
|
6308
|
+
fragment to update. The rest of the page will remain unchanged.
|
6309
|
+
|
6310
|
+
|
6311
|
+
Exammple
|
6312
|
+
--------
|
6190
6313
|
|
6191
6314
|
Let's say we are rendering three pages with a tabbed navigation to switch between screens:
|
6192
6315
|
|
6316
|
+
|
6193
6317
|
```
|
6194
6318
|
/pages/a /pages/b /pages/c
|
6195
6319
|
|
@@ -6216,27 +6340,8 @@ Your HTML could look like this:
|
|
6216
6340
|
</article>
|
6217
6341
|
```
|
6218
6342
|
|
6219
|
-
|
6220
|
-
|
6221
|
-
|
6222
|
-
- State changes caused by AJAX updates get lost during the page transition.
|
6223
|
-
- Unsaved form changes get lost during the page transition.
|
6224
|
-
- The Javascript VM is reset during the page transition.
|
6225
|
-
- If the page layout is composed from multiple srollable containers
|
6226
|
-
(e.g. a pane view), the scroll positions get lost during the page transition.
|
6227
|
-
- The user sees a "flash" as the browser loads and renders the new page,
|
6228
|
-
even if large portions of the old and new page are the same (navigation, layout, etc.).
|
6229
|
-
|
6230
|
-
|
6231
|
-
Smoother flow by updating fragments
|
6232
|
-
-----------------------------------
|
6233
|
-
|
6234
|
-
In Unpoly you annotate navigation links with an `up-target` attribute.
|
6235
|
-
The value of this attribute is a CSS selector that indicates which page
|
6236
|
-
fragment to update.
|
6237
|
-
|
6238
|
-
Since we only want to update the `<article>` tag, we will use `up-target="article"`:
|
6239
|
-
|
6343
|
+
Since we only want to update the `<article>` tag, we annotate the links
|
6344
|
+
with an `up-target` attribute:
|
6240
6345
|
|
6241
6346
|
```
|
6242
6347
|
<nav>
|
@@ -6246,10 +6351,11 @@ Since we only want to update the `<article>` tag, we will use `up-target="articl
|
|
6246
6351
|
</nav>
|
6247
6352
|
```
|
6248
6353
|
|
6249
|
-
|
6354
|
+
Note that instead of `article` you can use any other CSS selector like `#main .article`.
|
6250
6355
|
|
6251
|
-
With these `up-target` annotations Unpoly only updates the targeted part of the screen.
|
6252
|
-
Javascript will
|
6356
|
+
With these [`up-target`](/up-target) annotations Unpoly only updates the targeted part of the screen.
|
6357
|
+
The Javascript environment will persist and the user will not see a white flash while the
|
6358
|
+
new page is loading.
|
6253
6359
|
|
6254
6360
|
|
6255
6361
|
Read on
|
@@ -6594,6 +6700,41 @@ Read on
|
|
6594
6700
|
return follow($link);
|
6595
6701
|
});
|
6596
6702
|
|
6703
|
+
/**
|
6704
|
+
Marks up the current link to be followed *as fast as possible*.
|
6705
|
+
This is done by:
|
6706
|
+
|
6707
|
+
- [Following the link through AJAX](/up-target) instead of a full page load
|
6708
|
+
- [Preloading the link's destination URL](/up-preload)
|
6709
|
+
- [Triggering the link on `mousedown`](/up-instant) instead of on `click`
|
6710
|
+
|
6711
|
+
Use `up-dash` like this:
|
6712
|
+
|
6713
|
+
<a href="/users" up-dash=".main">User list</a>
|
6714
|
+
|
6715
|
+
Note that this is shorthand for:
|
6716
|
+
|
6717
|
+
<a href="/users" up-target=".main" up-instant up-preload>User list</a>
|
6718
|
+
|
6719
|
+
@selector [up-dash]
|
6720
|
+
@stable
|
6721
|
+
*/
|
6722
|
+
up.macro('[up-dash]', function($element) {
|
6723
|
+
var newAttrs, target;
|
6724
|
+
target = u.castedAttr($element, 'up-dash');
|
6725
|
+
$element.removeAttr('up-dash');
|
6726
|
+
newAttrs = {
|
6727
|
+
'up-preload': '',
|
6728
|
+
'up-instant': ''
|
6729
|
+
};
|
6730
|
+
if (target === true) {
|
6731
|
+
makeFollowable($element);
|
6732
|
+
} else {
|
6733
|
+
newAttrs['up-target'] = target;
|
6734
|
+
}
|
6735
|
+
return u.setMissingAttrs($element, newAttrs);
|
6736
|
+
});
|
6737
|
+
|
6597
6738
|
/**
|
6598
6739
|
Add an `up-expand` class to any element that contains a link
|
6599
6740
|
in order to enlarge the link's click area.
|
@@ -6654,41 +6795,6 @@ Read on
|
|
6654
6795
|
return makeFollowable($area);
|
6655
6796
|
}
|
6656
6797
|
});
|
6657
|
-
|
6658
|
-
/**
|
6659
|
-
Marks up the current link to be followed *as fast as possible*.
|
6660
|
-
This is done by:
|
6661
|
-
|
6662
|
-
- [Following the link through AJAX](/up-target) instead of a full page load
|
6663
|
-
- [Preloading the link's destination URL](/up-preload)
|
6664
|
-
- [Triggering the link on `mousedown`](/up-instant) instead of on `click`
|
6665
|
-
|
6666
|
-
Use `up-dash` like this:
|
6667
|
-
|
6668
|
-
<a href="/users" up-dash=".main">User list</a>
|
6669
|
-
|
6670
|
-
Note that this is shorthand for:
|
6671
|
-
|
6672
|
-
<a href="/users" up-target=".main" up-instant up-preload>User list</a>
|
6673
|
-
|
6674
|
-
@selector [up-dash]
|
6675
|
-
@stable
|
6676
|
-
*/
|
6677
|
-
up.macro('[up-dash]', function($element) {
|
6678
|
-
var newAttrs, target;
|
6679
|
-
target = u.castedAttr($element, 'up-dash');
|
6680
|
-
newAttrs = {
|
6681
|
-
'up-preload': 'true',
|
6682
|
-
'up-instant': 'true'
|
6683
|
-
};
|
6684
|
-
if (target === true) {
|
6685
|
-
newAttrs['up-follow'] = '';
|
6686
|
-
} else {
|
6687
|
-
newAttrs['up-target'] = target;
|
6688
|
-
}
|
6689
|
-
u.setMissingAttrs($element, newAttrs);
|
6690
|
-
return $element.removeAttr('up-dash');
|
6691
|
-
});
|
6692
6798
|
return {
|
6693
6799
|
knife: eval(typeof Knife !== "undefined" && Knife !== null ? Knife.point : void 0),
|
6694
6800
|
visit: visit,
|
@@ -7028,7 +7134,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
7028
7134
|
|
7029
7135
|
@function up.autosubmit
|
7030
7136
|
@param {String|Element|jQuery} selectorOrElement
|
7031
|
-
The form
|
7137
|
+
The field or form to observe.
|
7032
7138
|
@param {Object} [options]
|
7033
7139
|
See options for [`up.observe`](/up.observe)
|
7034
7140
|
@return {Function}
|
@@ -7579,7 +7685,15 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
7579
7685
|
text field value changes:
|
7580
7686
|
|
7581
7687
|
<form method="GET" action="/search" up-autosubmit>
|
7582
|
-
<input type="query">
|
7688
|
+
<input type="search" name="query">
|
7689
|
+
</form>
|
7690
|
+
|
7691
|
+
The following would submit the form only if the query was changed,
|
7692
|
+
but not if the checkbox was changed:
|
7693
|
+
|
7694
|
+
<form method="GET" action="/search">
|
7695
|
+
<input type="search" name="query" autosubmit>
|
7696
|
+
<input type="checkbox"> Include archive
|
7583
7697
|
</form>
|
7584
7698
|
|
7585
7699
|
@selector [up-autosubmit]
|