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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c60ec685f23e250d3f28fb9d04edf7373e8b6639
4
- data.tar.gz: 2bd25cfa0b00d08ef506bb8018069171cdafc0c2
3
+ metadata.gz: 6109418137600ed7280a7f3ecb2adb7ab5da2b4f
4
+ data.tar.gz: 118d634ab654710610a010e42d0d55223cd65a6b
5
5
  SHA512:
6
- metadata.gz: baae73f4cc49096dea5212f6f24eb2db2d95ddf4092ab5e0b82fd5d86276d95f88887ec3e66765d4489b85a4dffcfaa30b242799c210d1cb9b415fdc3807a8ca
7
- data.tar.gz: bfac196548dc68b88a2962f34c4df7e899e257a36f8f8bb680dccc5f2e8230f83877e0d8988d33047225ca2ba34cd2073acb3df6528c4f9a62cffff2248d296c
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.selector
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, viewport;
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 = clientSize();
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 has a convenient way to [listen to DOM events](/up.on):
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
- - Event listeners on [unsupported browsers](/up.browser.isSupported) are silently discarded,
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`) and past forms (`up:modal:opened`).
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
- up.on('up:modal:open', function(event) {
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
- There is also a function [`up.off`](/up.off) which you can use for the same purpose.
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
- Unregisters an event listener previously bound with [`up.on`](/up.on).
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
- $('.action').compiler(function($element) {
2810
+ up.compiler('.action', function($element) {
2775
2811
  // your code here
2776
2812
  });
2777
2813
 
2778
- Compiler functions will be called on matching elements when
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 event handler as a second argument:
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.syntax.compiler) handlers.
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
- This modules contains functions to scroll the viewport and reveal contained elements.
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 [destroy](/up.destroy)
4038
- page fragments via Javascript.
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.selector` in all controllers, views and helpers.
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
- without Unpoly.
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($ghost, options) {
5418
- $ghost.css(opacity: 0);
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 promise that resolves once all promises in arguments resolve.
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 promise will have a `resolve` method. This `resolve` method
5456
- will resolve all the wrapped promises.
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 promises...
5460
- @return A new promise.
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 insantly.
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
- Just like in a classical web application, an Unpoly app renders a series of *full HTML pages* on the server.
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
- Using this document-oriented way of navigating between pages
6220
- is not a good fit for modern applications, for a multitude of reasons:
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
- Instead of `article` you can use any other CSS selector (e. g. `#main .article`).
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 not be reloaded, no white flash during a full page reload.
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 field to observe.
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]