upjs-rails 0.14.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
data/dist/up.js CHANGED
@@ -27,7 +27,7 @@ that might save you from loading something like [Underscore.js](http://underscor
27
27
  @function up.util.memoize
28
28
  @internal
29
29
  */
30
- var $createElementFromSelector, ANIMATION_PROMISE_KEY, CONSOLE_PLACEHOLDERS, ajax, any, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, cssAnimate, debug, detect, each, error, escapePressed, evalConsoleTemplate, extend, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, isArray, isBlank, isDeferred, isDefined, isElement, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isNumber, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, multiSelector, nextFrame, normalizeMethod, normalizeUrl, nullJQuery, offsetParent, once, only, option, options, parseUrl, presence, presentAttr, remove, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, selectorForElement, setMissingAttrs, temporaryCss, times, titleFromXhr, toArray, trim, unJQuery, uniq, unresolvablePromise, unwrapElement, warn;
30
+ var $createElementFromSelector, ANIMATION_PROMISE_KEY, CONSOLE_PLACEHOLDERS, ajax, any, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, cssAnimate, debug, detect, each, error, escapePressed, evalConsoleTemplate, extend, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, isArray, isBlank, isDeferred, isDefined, isElement, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isNumber, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, multiSelector, nextFrame, normalizeMethod, normalizeUrl, nullJQuery, offsetParent, once, only, option, options, parseUrl, presence, presentAttr, remove, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, selectorForElement, setMissingAttrs, temporaryCss, times, titleFromXhr, toArray, trim, unJQuery, uniq, unresolvableDeferred, unresolvablePromise, unwrapElement, warn;
31
31
  memoize = function(func) {
32
32
  var cache, cached;
33
33
  cache = void 0;
@@ -774,7 +774,6 @@ that might save you from loading something like [Underscore.js](http://underscor
774
774
 
775
775
  /**
776
776
  Returns the first argument that is considered present.
777
- If an argument is a function, it is called and the value is checked for presence.
778
777
 
779
778
  This function is useful when you have multiple option sources and the value can be boolean.
780
779
  In that case you cannot change the sources with a `||` operator
@@ -785,21 +784,9 @@ that might save you from loading something like [Underscore.js](http://underscor
785
784
  @internal
786
785
  */
787
786
  option = function() {
788
- var arg, args, j, len, match, value;
787
+ var args;
789
788
  args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
790
- match = void 0;
791
- for (j = 0, len = args.length; j < len; j++) {
792
- arg = args[j];
793
- value = arg;
794
- if (isFunction(value)) {
795
- value = value();
796
- }
797
- if (isGiven(value)) {
798
- match = value;
799
- break;
800
- }
801
- }
802
- return match;
789
+ return detect(args, isGiven);
803
790
  };
804
791
 
805
792
  /**
@@ -1090,7 +1077,7 @@ that might save you from loading something like [Underscore.js](http://underscor
1090
1077
  cssAnimate = function(elementOrSelector, lastFrame, opts) {
1091
1078
  var $element, deferred, endTimeout, transition, withoutCompositing, withoutTransition;
1092
1079
  $element = $(elementOrSelector);
1093
- if (up.browser.canCssAnimation()) {
1080
+ if (up.browser.canCssTransition()) {
1094
1081
  opts = options(opts, {
1095
1082
  duration: 300,
1096
1083
  delay: 0,
@@ -1361,6 +1348,17 @@ that might save you from loading something like [Underscore.js](http://underscor
1361
1348
  return resolvedDeferred().promise();
1362
1349
  };
1363
1350
 
1351
+ /**
1352
+ Returns a [Deferred object](https://api.jquery.com/category/deferred-object/) that will never be resolved.
1353
+
1354
+ @function up.util.unresolvableDeferred
1355
+ @return {Deferred}
1356
+ @experimental
1357
+ */
1358
+ unresolvableDeferred = function() {
1359
+ return $.Deferred();
1360
+ };
1361
+
1364
1362
  /**
1365
1363
  Returns a promise that will never be resolved.
1366
1364
 
@@ -1368,7 +1366,7 @@ that might save you from loading something like [Underscore.js](http://underscor
1368
1366
  @experimental
1369
1367
  */
1370
1368
  unresolvablePromise = function() {
1371
- return $.Deferred().promise();
1369
+ return unresolvableDeferred().promise();
1372
1370
  };
1373
1371
 
1374
1372
  /**
@@ -1795,6 +1793,7 @@ that might save you from loading something like [Underscore.js](http://underscor
1795
1793
  clientSize: clientSize,
1796
1794
  only: only,
1797
1795
  trim: trim,
1796
+ unresolvableDeferred: unresolvableDeferred,
1798
1797
  unresolvablePromise: unresolvablePromise,
1799
1798
  resolvedPromise: resolvedPromise,
1800
1799
  resolvedDeferred: resolvedDeferred,
@@ -1833,7 +1832,7 @@ we can't currently get rid off.
1833
1832
  var slice = [].slice;
1834
1833
 
1835
1834
  up.browser = (function($) {
1836
- var canCssAnimation, canInputEvent, canLogSubstitution, canPushState, initialRequestMethod, isIE8OrWorse, isIE9OrWorse, isRecentJQuery, isSupported, loadPage, popCookie, puts, u, url;
1835
+ var canCssTransition, canInputEvent, canLogSubstitution, canPushState, initialRequestMethod, isIE8OrWorse, isIE9OrWorse, isRecentJQuery, isSupported, loadPage, popCookie, puts, u, url;
1837
1836
  u = up.util;
1838
1837
  loadPage = function(url, options) {
1839
1838
  var $form, csrfParam, csrfToken, metadataInput, method, target;
@@ -1891,21 +1890,69 @@ we can't currently get rid off.
1891
1890
  url = function() {
1892
1891
  return location.href;
1893
1892
  };
1894
- canPushState = u.memoize(function() {
1895
- return u.isDefined(history.pushState) && initialRequestMethod() === 'get';
1896
- });
1897
1893
  isIE8OrWorse = u.memoize(function() {
1898
1894
  return u.isUndefined(document.addEventListener);
1899
1895
  });
1900
1896
  isIE9OrWorse = u.memoize(function() {
1901
1897
  return isIE8OrWorse() || navigator.appVersion.indexOf('MSIE 9.') !== -1;
1902
1898
  });
1903
- canCssAnimation = u.memoize(function() {
1899
+
1900
+ /**
1901
+ Returns whether this browser supports manipulation of the current URL
1902
+ via [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState).
1903
+
1904
+ When Up.js is asked to change history on a browser that doesn't support
1905
+ `pushState` (e.g. through [`up.follow`](/up.follow)), it will gracefully
1906
+ fall back to a full page load.
1907
+
1908
+ @function up.browser.canPushState
1909
+ @return {Boolean}
1910
+ @experimental
1911
+ */
1912
+ canPushState = u.memoize(function() {
1913
+ return u.isDefined(history.pushState) && initialRequestMethod() === 'get';
1914
+ });
1915
+
1916
+ /**
1917
+ Returns whether this browser supports animation using
1918
+ [CSS transitions](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions).
1919
+
1920
+ When Up.js is asked to animate history on a browser that doesn't support
1921
+ CSS transitions (e.g. through [`up.animate`](/up.animate)), it will skip the
1922
+ animation by instantly jumping to the last frame.
1923
+
1924
+ @function up.browser.canCssTransition
1925
+ @return {Boolean}
1926
+ @experimental
1927
+ */
1928
+ canCssTransition = u.memoize(function() {
1904
1929
  return 'transition' in document.documentElement.style;
1905
1930
  });
1931
+
1932
+ /**
1933
+ Returns whether this browser supports the DOM event [`input`](https://developer.mozilla.org/de/docs/Web/Events/input).
1934
+
1935
+ @function up.browser.canInputEvent
1936
+ @return {Boolean}
1937
+ @experimental
1938
+ */
1906
1939
  canInputEvent = u.memoize(function() {
1907
1940
  return 'oninput' in document.createElement('input');
1908
1941
  });
1942
+
1943
+ /**
1944
+ Returns whether this browser supports
1945
+ [string substitution](https://developer.mozilla.org/en-US/docs/Web/API/console#Using_string_substitutions)
1946
+ in `console` functions.
1947
+
1948
+ \#\#\#\# Example for string substition
1949
+
1950
+ console.log("Hello %o!", "Judy");
1951
+
1952
+ @function up.browser.canLogSubstitution
1953
+ @return boolean
1954
+ @internal
1955
+ */
1909
1956
  canLogSubstitution = u.memoize(function() {
1910
1957
  return !isIE9OrWorse();
1911
1958
  });
@@ -1932,6 +1979,11 @@ we can't currently get rid off.
1932
1979
  /**
1933
1980
  Returns whether Up.js supports the current browser.
1934
1981
 
1982
+ This also returns `true` if Up.js only support some features, but falls back
1983
+ gracefully for other features. E.g. IE9 is almost fully supported, but due to
1984
+ its lack of [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState)
1985
+ Up.js falls back to a full page load when asked to manipulate history.
1986
+
1935
1987
  Currently Up.js supports IE9 with jQuery 1.9+.
1936
1988
  On older browsers Up.js will prevent itself from [booting](/up.boot)
1937
1989
  and ignores all registered [event handlers](/up.on) and [compilers](/up.compiler).
@@ -1947,7 +1999,7 @@ we can't currently get rid off.
1947
1999
  url: url,
1948
2000
  loadPage: loadPage,
1949
2001
  canPushState: canPushState,
1950
- canCssAnimation: canCssAnimation,
2002
+ canCssTransition: canCssTransition,
1951
2003
  canInputEvent: canInputEvent,
1952
2004
  canLogSubstitution: canLogSubstitution,
1953
2005
  isSupported: isSupported,
@@ -2107,7 +2159,12 @@ and call `preventDefault()` on the `event` object:
2107
2159
  };
2108
2160
 
2109
2161
  /**
2110
- Emits an event with the given name and properties.
2162
+ Emits a event with the given name and properties.
2163
+
2164
+ The event will be triggered as a jQuery event on `document`.
2165
+
2166
+ Other code can subscribe to events with that name using
2167
+ [`up.on`](/up.on) or by [binding a jQuery event listener](http://api.jquery.com/on/) to `document`.
2111
2168
 
2112
2169
  \#\#\#\# Example
2113
2170
 
@@ -2228,9 +2285,11 @@ and call `preventDefault()` on the `event` object:
2228
2285
 
2229
2286
  /**
2230
2287
  Boots the Up.js framework.
2288
+
2231
2289
  This is done automatically by including the Up.js Javascript.
2232
2290
 
2233
- Does nothing if the current browser is [not supported](/up.browser.isSupported).
2291
+ Up.js will not boot if the current browser is [not supported](/up.browser.isSupported).
2292
+ This leaves you with a classic server-side application on legacy browsers.
2234
2293
 
2235
2294
  Emits the [`up:framework:boot`](/up:framework:boot) event.
2236
2295
 
@@ -2605,6 +2664,8 @@ later.
2605
2664
 
2606
2665
  @function up.hello
2607
2666
  @param {String|Element|jQuery} selectorOrElement
2667
+ @return {jQuery}
2668
+ The compiled element
2608
2669
  @stable
2609
2670
  */
2610
2671
  hello = function(selectorOrElement) {
@@ -2691,6 +2752,7 @@ We need to work on this page:
2691
2752
  @param {Boolean} [config.restoreScroll=true]
2692
2753
  Whether to restore the known scroll positions
2693
2754
  when the user goes back or forward in history.
2755
+ @stable
2694
2756
  */
2695
2757
  config = u.config({
2696
2758
  popTargets: ['body'],
@@ -2938,6 +3000,7 @@ This modules contains functions to scroll the viewport and reveal contained elem
2938
3000
  to the top when the revealed element is closer to the top than `config.snap`.
2939
3001
  @param {Number} [config.substance]
2940
3002
  A number indicating how many top pixel rows of an element to [reveal](/up.reveal).
3003
+ @stable
2941
3004
  */
2942
3005
  config = u.config({
2943
3006
  duration: 0,
@@ -3113,7 +3176,9 @@ This modules contains functions to scroll the viewport and reveal contained elem
3113
3176
  Many applications have a navigation bar fixed to the top or bottom,
3114
3177
  obstructing the view on an element.
3115
3178
 
3116
- To make `up.aware` of these fixed elements you can either:
3179
+ You can make `up.reveal` aware of these fixed elements
3180
+ so it can scroll the viewport far enough so the revealed element is fully visible.
3181
+ To make `up.reveal` aware fixed elements you can either:
3117
3182
 
3118
3183
  - give the element an attribute [`up-fixed="top"`](/up-fixed-top) or [`up-fixed="bottom"`](up-fixed-bottom)
3119
3184
  - [configure default options](/up.layout.config) for `fixedTop` or `fixedBottom`
@@ -3434,7 +3499,7 @@ This modules contains functions to scroll the viewport and reveal contained elem
3434
3499
  [`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
3435
3500
  the viewport far enough so the revealed element is fully visible.
3436
3501
 
3437
- Example:
3502
+ \#\#\#\# Example
3438
3503
 
3439
3504
  <div class="top-nav" up-fixed="top">...</div>
3440
3505
 
@@ -3449,7 +3514,7 @@ This modules contains functions to scroll the viewport and reveal contained elem
3449
3514
  [`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
3450
3515
  the viewport far enough so the revealed element is fully visible.
3451
3516
 
3452
- Example:
3517
+ \#\#\#\# Example
3453
3518
 
3454
3519
  <div class="bottom-nav" up-fixed="bottom">...</div>
3455
3520
 
@@ -3603,6 +3668,9 @@ are based on this module.
3603
3668
  that is being updated. The request's `X-Up-Selector` header will contain
3604
3669
  the CSS selector for the updating fragment.
3605
3670
 
3671
+ If you are using the `upjs-rails` gem you can also access the selector via
3672
+ `up.selector` in all controllers, views and helpers.
3673
+
3606
3674
  \#\#\#\# Events
3607
3675
 
3608
3676
  Up.js will emit [`up:fragment:destroyed`](/up:fragment:destroyed) on the element
@@ -3862,13 +3930,11 @@ are based on this module.
3862
3930
  };
3863
3931
 
3864
3932
  /**
3865
- Returns the first element matching the given selector.
3866
-
3867
- Excludes elements that also match `.up-ghost` or `.up-destroying`
3868
- or that are children of elements with these selectors.
3933
+ Returns the first element matching the given selector, but
3934
+ ignores elements that are being [destroyed](/up.destroy) or [transitioned](/up.morph).
3869
3935
 
3870
3936
  If the given argument is already a jQuery collection (or an array
3871
- of DOM elements), the first element matching these conditions
3937
+ of DOM elements), the first element matching these conditions
3872
3938
  is returned.
3873
3939
 
3874
3940
  Returns `undefined` if no element matches these conditions.
@@ -4043,7 +4109,7 @@ are based on this module.
4043
4109
  Animation
4044
4110
  =========
4045
4111
 
4046
- Whenever you change a page fragment (through methods like
4112
+ Whenever you update a page fragment (through methods like
4047
4113
  [`up.replace`](/up.replace) or UJS attributes like [`up-target`](/up-target))
4048
4114
  you can animate the change.
4049
4115
 
@@ -4067,7 +4133,6 @@ and [transitions](/up.morph#named-animation).
4067
4133
  You can also easily [define your own animations](/up.animation)
4068
4134
  or [transitions](/up.transition) using Javascript or CSS.
4069
4135
 
4070
-
4071
4136
  @class up.motion
4072
4137
  */
4073
4138
 
@@ -4087,6 +4152,7 @@ or [transitions](/up.transition) using Javascript or CSS.
4087
4152
  @param {Number} [config.duration=300]
4088
4153
  @param {Number} [config.delay=0]
4089
4154
  @param {String} [config.easing='ease']
4155
+ @stable
4090
4156
  */
4091
4157
  config = u.config({
4092
4158
  duration: 300,
@@ -4100,7 +4166,9 @@ or [transitions](/up.transition) using Javascript or CSS.
4100
4166
  };
4101
4167
 
4102
4168
  /**
4103
- Applies the given animation to the given element:
4169
+ Applies the given animation to the given element.
4170
+
4171
+ \#\#\#\# Example
4104
4172
 
4105
4173
  up.animate('.warning', 'fade-in');
4106
4174
 
@@ -4152,6 +4220,7 @@ or [transitions](/up.transition) using Javascript or CSS.
4152
4220
  The element to animate.
4153
4221
  @param {String|Function|Object} animation
4154
4222
  Can either be:
4223
+
4155
4224
  - The animation's name
4156
4225
  - A function performing the animation
4157
4226
  - An object of CSS attributes describing the last frame of the animation
@@ -4251,9 +4320,10 @@ or [transitions](/up.transition) using Javascript or CSS.
4251
4320
  };
4252
4321
 
4253
4322
  /**
4254
- Completes all animations and transitions for the given element
4255
- by jumping to the last animation frame instantly. All callbacks chained to
4256
- the original animation's promise will be called.
4323
+ Completes all [animations](/up.animate) and [transitions](/up.morph)
4324
+ for the given element by jumping to the last animation frame instantly.
4325
+
4326
+ All callbacks chained to the original animation's promise will be called.
4257
4327
 
4258
4328
  Does nothing if the given element is not currently animating.
4259
4329
 
@@ -4354,7 +4424,7 @@ or [transitions](/up.transition) using Javascript or CSS.
4354
4424
  $new = $(target);
4355
4425
  parsedOptions = u.only(options, 'reveal', 'restoreScroll', 'source');
4356
4426
  parsedOptions = u.extend(parsedOptions, animateOptions(options));
4357
- if (up.browser.canCssAnimation()) {
4427
+ if (up.browser.canCssTransition()) {
4358
4428
  finish($old);
4359
4429
  finish($new);
4360
4430
  if (transitionOrName === 'none' || transitionOrName === false || (animation = animations[transitionOrName])) {
@@ -4785,6 +4855,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
4785
4855
  @param {Number} [config.busyDelay=300]
4786
4856
  How long the proxy waits until emitting the [`up:proxy:busy` event](/up:proxy:busy).
4787
4857
  Use this to prevent flickering of spinners.
4858
+ @stable
4788
4859
  */
4789
4860
  config = u.config({
4790
4861
  busyDelay: 300,
@@ -5108,7 +5179,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
5108
5179
  The element whose destination should be preloaded.
5109
5180
  @return
5110
5181
  A promise that will be resolved when the request was loaded and cached
5111
- @stable
5182
+ @experimental
5112
5183
  */
5113
5184
  preload = function(linkOrSelector, options) {
5114
5185
  var $link, method;
@@ -5268,7 +5339,7 @@ Read on
5268
5339
  The URL to visit.
5269
5340
  @param {String} [options.target='body']
5270
5341
  The selector to replace.
5271
- @param {Object} options
5342
+ @param {Object} [options]
5272
5343
  See options for [`up.replace`](/up.replace)
5273
5344
  @stable
5274
5345
  */
@@ -5292,6 +5363,8 @@ Read on
5292
5363
  var $link = $('a:first'); // select link with jQuery
5293
5364
  up.follow($link);
5294
5365
 
5366
+ The UJS variant of this are the [`a[up-target]`](/a-up-target) and [`a[up-follow]`](/a-up-follow) selectors.
5367
+
5295
5368
  @function up.follow
5296
5369
  @param {Element|jQuery|String} linkOrSelector
5297
5370
  An element or selector which resolves to an `<a>` tag
@@ -5496,11 +5569,12 @@ Read on
5496
5569
  If applied on a link, Follows this link via AJAX and replaces the
5497
5570
  current `<body>` element with the response's `<body>` element.
5498
5571
 
5499
- Example:
5572
+ To only update a fragment instead of the entire page, see
5573
+ [`a[up-target]`](/a-up-target).
5500
5574
 
5501
- <a href="/users" up-follow>User list</a>
5575
+ \#\#\#\# Example
5502
5576
 
5503
- To only update a fragment instead of the entire page, see [`up-target`](/up-target).
5577
+ <a href="/users" up-follow>User list</a>
5504
5578
 
5505
5579
  \#\#\#\# Turn any element into a link
5506
5580
 
@@ -5534,7 +5608,12 @@ Read on
5534
5608
 
5535
5609
  /**
5536
5610
  Add an `up-expand` class to any element that contains a link
5537
- in order to enlarge the link's click area:
5611
+ in order to enlarge the link's click area.
5612
+
5613
+ `up-expand` honors all the UJS behavior in expanded links
5614
+ ([`up-target`](/up-target), [`up-instant`](/up-instant), [`up-preload`](/up-preload), etc.).
5615
+
5616
+ \#\#\#\# Example
5538
5617
 
5539
5618
  <div class="notification" up-expand>
5540
5619
  Record was saved!
@@ -5544,9 +5623,6 @@ Read on
5544
5623
  In the example above, clicking anywhere within `.notification` element
5545
5624
  would [follow](/up.follow) the *Close* link.
5546
5625
 
5547
- `up-expand` honors all the UJS behavior in expanded links
5548
- (`up-target`, `up-instant`, `up-preload`, etc.).
5549
-
5550
5626
  @selector [up-expand]
5551
5627
  @stable
5552
5628
  */
@@ -5632,14 +5708,20 @@ open dialogs with sub-forms, etc. all without losing form state.
5632
5708
  */
5633
5709
 
5634
5710
  (function() {
5711
+ var slice = [].slice;
5712
+
5635
5713
  up.form = (function($) {
5636
- var config, observe, reset, resolveValidateTarget, submit, u, validate;
5714
+ var autosubmit, config, observe, observeForm, reset, resolveValidateTarget, submit, u, validate;
5637
5715
  u = up.util;
5638
5716
 
5639
5717
  /**
5640
5718
  Sets default options for form submission and validation.
5641
5719
 
5642
5720
  @property up.form.config
5721
+ @param {Number} [config.observeDelay=0]
5722
+ The number of miliseconds to wait before [`up.observe`](/up.observe) runs the callback
5723
+ after the input value changes. Use this to limit how often the callback
5724
+ will be invoked for a fast typist.
5643
5725
  @param {Array} [config.validateTargets=['[up-fieldset]:has(&)', 'fieldset:has(&)', 'label:has(&)', 'form:has(&)']]
5644
5726
  An array of CSS selectors that are searched around a form field
5645
5727
  that wants to [validate](/up.validate). The first matching selector
@@ -5648,9 +5730,14 @@ open dialogs with sub-forms, etc. all without losing form state.
5648
5730
  By default this looks for a `<fieldset>`, `<label>` or `<form>`
5649
5731
  around the validating input field, or any element with an
5650
5732
  `up-fieldset` attribute.
5733
+ @param {String} [config.fields]
5734
+ An array of CSS selectors that represent form fields, such as `input` or `select`.
5735
+ @stable
5651
5736
  */
5652
5737
  config = u.config({
5653
- validateTargets: ['[up-fieldset]:has(&)', 'fieldset:has(&)', 'label:has(&)', 'form:has(&)']
5738
+ validateTargets: ['[up-fieldset]:has(&)', 'fieldset:has(&)', 'label:has(&)', 'form:has(&)'],
5739
+ fields: [':input'],
5740
+ observeDelay: 0
5654
5741
  });
5655
5742
  reset = function() {
5656
5743
  return config.reset();
@@ -5729,10 +5816,10 @@ open dialogs with sub-forms, etc. all without losing form state.
5729
5816
  var $form, failureSelector, failureTransition, hasFileInputs, headers, historyOption, httpMethod, implantOptions, request, successSelector, successTransition, successUrl, url, useCache;
5730
5817
  $form = $(formOrSelector).closest('form');
5731
5818
  options = u.options(options);
5732
- successSelector = up.flow.resolveSelector(u.option(options.target, $form.attr('up-target'), 'body'), options);
5733
- failureSelector = up.flow.resolveSelector(u.option(options.failTarget, $form.attr('up-fail-target'), function() {
5734
- return u.selectorForElement($form);
5735
- }), options);
5819
+ successSelector = u.option(options.target, $form.attr('up-target'), 'body');
5820
+ successSelector = up.flow.resolveSelector(successSelector, options);
5821
+ failureSelector = u.option(options.failTarget, $form.attr('up-fail-target')) || u.selectorForElement($form);
5822
+ failureSelector = up.flow.resolveSelector(failureSelector, options);
5736
5823
  historyOption = u.option(options.history, u.castedAttr($form, 'up-history'), true);
5737
5824
  successTransition = u.option(options.transition, u.castedAttr($form, 'up-transition'));
5738
5825
  failureTransition = u.option(options.failTransition, u.castedAttr($form, 'up-fail-transition'), successTransition);
@@ -5800,7 +5887,8 @@ open dialogs with sub-forms, etc. all without losing form state.
5800
5887
  };
5801
5888
 
5802
5889
  /**
5803
- Observes a form field and runs a callback when its value changes.
5890
+ Observes a field or form and runs a callback when a value changes.
5891
+
5804
5892
  This is useful for observing text fields while the user is typing.
5805
5893
 
5806
5894
  The UJS variant of this is the [`up-observe`](/up-observe) attribute.
@@ -5810,9 +5898,9 @@ open dialogs with sub-forms, etc. all without losing form state.
5810
5898
  The following would submit the form whenever the
5811
5899
  text field value changes:
5812
5900
 
5813
- up.observe('input[name=query]', { change: function(value, $input) {
5901
+ up.observe('input[name=query]', function(value, $input) {
5814
5902
  up.submit($input)
5815
- } });
5903
+ });
5816
5904
 
5817
5905
  \#\#\#\# Preventing concurrency
5818
5906
 
@@ -5830,42 +5918,58 @@ open dialogs with sub-forms, etc. all without losing form state.
5830
5918
  load on your server, you can use a `delay` option to wait
5831
5919
  a few miliseconds before executing the callback:
5832
5920
 
5833
- up.observe('input', {
5834
- delay: 100,
5835
- change: function(value, $input) { up.submit($input) }
5921
+ up.observe('input', { delay: 100 }, function(value, $input) {
5922
+ up.submit($input)
5836
5923
  });
5837
5924
 
5838
5925
  @function up.observe
5839
5926
  @param {Element|jQuery|String} fieldOrSelector
5840
- @param {Function(value, $field)|String} options.change
5927
+ @param {Number} [options.delay=up.form.config.observeDelay]
5928
+ The number of miliseconds to wait before executing the callback
5929
+ after the input value changes. Use this to limit how often the callback
5930
+ will be invoked for a fast typist.
5931
+ @param {Function(value, $field)|String} onChange
5841
5932
  The callback to execute when the field's value changes.
5842
5933
  If given as a function, it must take two arguments (`value`, `$field`).
5843
5934
  If given as a string, it will be evaled as Javascript code in a context where
5844
5935
  (`value`, `$field`) are set.
5845
- @param {Number} [options.delay=0]
5846
- The number of miliseconds to wait before executing the callback
5847
- after the input value changes. Use this to limit how often the callback
5848
- will be invoked for a fast typist.
5936
+ @return {Function}
5937
+ A destructor function that removes the observe watch when called.
5849
5938
  @stable
5850
5939
  */
5851
- observe = function(fieldOrSelector, options) {
5852
- var $field, callback, callbackPromise, callbackTimer, changeEvents, check, clearTimer, codeOnChange, delay, knownValue, nextCallback, runNextCallback;
5853
- $field = $(fieldOrSelector);
5940
+ observe = function() {
5941
+ var $element, args, callback, callbackArg, callbackPromise, callbackTimer, changeEvents, check, clearTimer, delay, knownValue, nextCallback, options, rawCallback, runNextCallback, selectorOrElement;
5942
+ selectorOrElement = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
5943
+ options = {};
5944
+ callbackArg = void 0;
5945
+ if (args.length === 1) {
5946
+ callbackArg = args[0];
5947
+ }
5948
+ if (args.length > 1) {
5949
+ options = u.options(args[0]);
5950
+ callbackArg = args[1];
5951
+ }
5952
+ $element = $(selectorOrElement);
5854
5953
  options = u.options(options);
5855
- delay = u.option($field.attr('up-delay'), options.delay, 0);
5954
+ delay = u.option($element.attr('up-delay'), options.delay, config.observeDelay);
5856
5955
  delay = parseInt(delay);
5857
- knownValue = null;
5858
5956
  callback = null;
5859
- callbackTimer = null;
5860
- if (codeOnChange = $field.attr('up-observe')) {
5957
+ if (u.isGiven(options.change)) {
5958
+ up.error('up.observe now takes the change callback as the last argument');
5959
+ }
5960
+ rawCallback = u.option(u.presentAttr($element, 'op-observe'), callbackArg);
5961
+ if (u.isString(rawCallback)) {
5861
5962
  callback = function(value, $field) {
5862
- return eval(codeOnChange);
5963
+ return eval(rawCallback);
5863
5964
  };
5864
- } else if (options.change) {
5865
- callback = options.change;
5866
5965
  } else {
5867
- u.error('up.observe: No change callback given');
5966
+ callback = rawCallback || u.error('up.observe: No change callback given');
5967
+ }
5968
+ if ($element.is('form')) {
5969
+ return observeForm($element, options, callback);
5868
5970
  }
5971
+ knownValue = null;
5972
+ callbackTimer = null;
5869
5973
  callbackPromise = u.resolvedPromise();
5870
5974
  nextCallback = null;
5871
5975
  runNextCallback = function() {
@@ -5878,14 +5982,14 @@ open dialogs with sub-forms, etc. all without losing form state.
5878
5982
  };
5879
5983
  check = function() {
5880
5984
  var skipCallback, value;
5881
- value = $field.val();
5985
+ value = $element.val();
5882
5986
  skipCallback = u.isNull(knownValue);
5883
5987
  if (knownValue !== value) {
5884
5988
  knownValue = value;
5885
5989
  if (!skipCallback) {
5886
5990
  clearTimer();
5887
5991
  nextCallback = function() {
5888
- return callback.apply($field.get(0), [value, $field]);
5992
+ return callback.apply($element.get(0), [value, $element]);
5889
5993
  };
5890
5994
  return callbackTimer = setTimeout(function() {
5891
5995
  return callbackPromise.then(function() {
@@ -5905,9 +6009,62 @@ open dialogs with sub-forms, etc. all without losing form state.
5905
6009
  return clearTimeout(callbackTimer);
5906
6010
  };
5907
6011
  changeEvents = up.browser.canInputEvent() ? 'input change' : 'input change keypress paste cut click propertychange';
5908
- $field.on(changeEvents, check);
6012
+ $element.on(changeEvents, check);
5909
6013
  check();
5910
- return clearTimer;
6014
+ return function() {
6015
+ $element.off(changeEvents, check);
6016
+ return clearTimer();
6017
+ };
6018
+ };
6019
+
6020
+ /**
6021
+ @function observeForm
6022
+ @internal
6023
+ */
6024
+ observeForm = function($form, options, callback) {
6025
+ var $fields, destructors;
6026
+ $fields = u.multiSelector(config.fields).find($form);
6027
+ destructors = u.map($fields, function($field) {
6028
+ return observe($field, callback);
6029
+ });
6030
+ return function() {
6031
+ var destructor, i, len, results;
6032
+ results = [];
6033
+ for (i = 0, len = destructors.length; i < len; i++) {
6034
+ destructor = destructors[i];
6035
+ results.push(destructor());
6036
+ }
6037
+ return results;
6038
+ };
6039
+ };
6040
+
6041
+ /**
6042
+ [Observes](/up.observe) a field or form and submits the form when a value changes.
6043
+
6044
+ The changed form field will be assigned a CSS class [`up-active`](/up-active)
6045
+ while the autosubmitted form is processing.
6046
+
6047
+ The UJS variant of this is the [`up-autosubmit`](/up-autosubmit) attribute.
6048
+
6049
+ @function up.autosubmit
6050
+ @param {String|Element|jQuery} selectorOrElement
6051
+ The form field to observe.
6052
+ @param {Object} [options]
6053
+ See options for [`up.observe`](/up.observe)
6054
+ @return {Function}
6055
+ A destructor function that removes the observe watch when called.
6056
+ @stable
6057
+ */
6058
+ autosubmit = function(selectorOrElement, options) {
6059
+ console.log("autosubmit %o", selectorOrElement);
6060
+ return observe(selectorOrElement, options, function(value, $field) {
6061
+ var $form;
6062
+ $form = $field.closest('form');
6063
+ $field.addClass('up-active');
6064
+ return submit($form).always(function() {
6065
+ return $field.removeClass('up-active');
6066
+ });
6067
+ });
5911
6068
  };
5912
6069
  resolveValidateTarget = function($field, options) {
5913
6070
  var target;
@@ -5981,13 +6138,13 @@ open dialogs with sub-forms, etc. all without losing form state.
5981
6138
 
5982
6139
  The programmatic variant of this is the [`up.submit`](/up.submit) function.
5983
6140
 
5984
- \#\#\#\# Validation errors
6141
+ \#\#\#\# Failed submission
5985
6142
 
5986
6143
  When the server was unable to save the form due to invalid data,
5987
6144
  it will usually re-render an updated copy of the form with
5988
6145
  validation messages.
5989
6146
 
5990
- For Up.js to be able to pick up a validation failure,
6147
+ For Up.js to be able to detect a failed form submission,,
5991
6148
  the form must be re-rendered with a non-200 HTTP status code.
5992
6149
  We recommend to use either 400 (bad request) or
5993
6150
  422 (unprocessable entity).
@@ -6182,7 +6339,6 @@ open dialogs with sub-forms, etc. all without losing form state.
6182
6339
  <input type="text" name="email" up-validate=".email-errors">
6183
6340
  <span class="email-errors"></span>
6184
6341
 
6185
-
6186
6342
  \#\#\#\# Updating dependent fields
6187
6343
 
6188
6344
  The `[up-validate]` behavior is also a great way to partially update a form
@@ -6218,21 +6374,23 @@ open dialogs with sub-forms, etc. all without losing form state.
6218
6374
  });
6219
6375
 
6220
6376
  /**
6221
- Observes this form field and runs the given script
6222
- when its value changes. This is useful for observing text fields
6223
- while the user is typing.
6377
+ Observes this field or form and runs a callback when a value changes.
6378
+
6379
+ This is useful for observing text fields while the user is typing.
6224
6380
 
6225
6381
  The programmatic variant of this is the [`up.observe`](/up.observe) function.
6226
6382
 
6227
6383
  \#\#\#\# Example
6228
6384
 
6229
- For instance, the following would submit the form whenever the
6230
- text field value changes:
6385
+ The following would run a global `showSuggestions(value)` function
6386
+ whenever the `<input>` changes:
6231
6387
 
6232
- <form method="GET" action="/search">
6233
- <input type="query" up-observe="up.form.submit(this)">
6388
+ <form>
6389
+ <input type="query" up-observe="showSuggestions(value)">
6234
6390
  </form>
6235
6391
 
6392
+ \#\#\#\# Callback context
6393
+
6236
6394
  The script given to `up-observe` runs with the following context:
6237
6395
 
6238
6396
  | Name | Type | Description |
@@ -6244,13 +6402,42 @@ open dialogs with sub-forms, etc. all without losing form state.
6244
6402
  @selector [up-observe]
6245
6403
  @param {String} up-observe
6246
6404
  The code to run when the field's value changes.
6405
+ @param {String} up-delay
6406
+ The number of miliseconds to wait after a change before the code is run.
6247
6407
  @stable
6248
6408
  */
6249
- up.compiler('[up-observe]', function($field) {
6250
- return observe($field);
6409
+ up.compiler('[up-observe]', function($formOrField) {
6410
+ return observe($formOrField);
6411
+ });
6412
+
6413
+ /**
6414
+ [Observes](/up.observe) this field or form and submits the form when a value changes.
6415
+
6416
+ The form field will be assigned a CSS class [`up-active`](/up-active)
6417
+ while the autosubmitted form is processing.
6418
+
6419
+ The programmatic variant of this is the [`up.autosubmit`](/up.autosubmit) function.
6420
+
6421
+ \#\#\#\# Example
6422
+
6423
+ The following would submit the form whenever the
6424
+ text field value changes:
6425
+
6426
+ <form method="GET" action="/search" up-autosubmit>
6427
+ <input type="query">
6428
+ </form>
6429
+
6430
+ @selector [up-autosubmit]
6431
+ @param {String} up-delay
6432
+ The number of miliseconds to wait after the change before the form is submitted.
6433
+ @stable
6434
+ */
6435
+ up.compiler('[up-autosubmit]', function($formOrField) {
6436
+ return autosubmit($formOrField);
6251
6437
  });
6252
6438
  up.on('up:framework:reset', reset);
6253
6439
  return {
6440
+ knife: eval(typeof Knife !== "undefined" && Knife !== null ? Knife.point : void 0),
6254
6441
  submit: submit,
6255
6442
  observe: observe,
6256
6443
  validate: validate
@@ -6261,6 +6448,8 @@ open dialogs with sub-forms, etc. all without losing form state.
6261
6448
 
6262
6449
  up.observe = up.form.observe;
6263
6450
 
6451
+ up.autosubmit = up.form.autosubmit;
6452
+
6264
6453
  up.validate = up.form.validate;
6265
6454
 
6266
6455
  }).call(this);
@@ -6270,14 +6459,13 @@ Pop-up overlays
6270
6459
  ===============
6271
6460
 
6272
6461
  Instead of [linking to a page fragment](/up.link), you can choose
6273
- to show a fragment in a popup overlay.
6462
+ to show a fragment in a popup overlay that rolls down from an anchoring element.
6274
6463
 
6275
6464
  To open a popup, add an [`up-popup` attribute](/a-up-popup) to a link,
6276
6465
  or call the Javascript function [`up.popup.attach`](/up.popup.attach).
6277
6466
 
6278
6467
  For modal dialogs see [up.modal](/up.modal) instead.
6279
6468
 
6280
-
6281
6469
  \#\#\#\# Customizing the popup design
6282
6470
 
6283
6471
  Loading the Up.js stylesheet will give you a minimal popup design:
@@ -6294,7 +6482,6 @@ By default the popup uses the following DOM structure:
6294
6482
  ...
6295
6483
  </div>
6296
6484
 
6297
-
6298
6485
  \#\#\#\# Closing behavior
6299
6486
 
6300
6487
  The popup closes when the user clicks anywhere outside the popup area.
@@ -6309,7 +6496,6 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
6309
6496
 
6310
6497
  <a href="/settings" up-popup=".options" up-sticky>Settings</a>
6311
6498
 
6312
-
6313
6499
  @class up.popup
6314
6500
  */
6315
6501
 
@@ -6354,6 +6540,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
6354
6540
  Defines where the popup is attached to the opening element.
6355
6541
 
6356
6542
  Valid values are `bottom-right`, `bottom-left`, `top-right` and `top-left`.
6543
+ @stable
6357
6544
  */
6358
6545
  config = u.config({
6359
6546
  openAnimation: 'fade-in',
@@ -6459,14 +6646,21 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
6459
6646
  return $popup;
6460
6647
  };
6461
6648
  updated = function($link, $popup, position, animation, animateOptions) {
6649
+ var deferred;
6462
6650
  $popup.show();
6463
6651
  setPosition($link, $popup, position);
6464
- return up.animate($popup, animation, animateOptions);
6652
+ deferred = up.animate($popup, animation, animateOptions);
6653
+ deferred.then(function() {
6654
+ return up.emit('up:popup:opened');
6655
+ });
6656
+ return deferred;
6465
6657
  };
6466
6658
 
6467
6659
  /**
6468
6660
  Attaches a popup overlay to the given element or selector.
6469
6661
 
6662
+ Emits events [`up:popup:open`](/up:popup:open) and [`up:popup:opened`](/up:popup:opened).
6663
+
6470
6664
  @function up.popup.attach
6471
6665
  @param {Element|jQuery|String} elementOrSelector
6472
6666
  @param {String} [options.url]
@@ -6499,39 +6693,95 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
6499
6693
  history = up.browser.canPushState() ? u.option(options.history, u.castedAttr($link, 'up-history'), false) : false;
6500
6694
  animateOptions = up.motion.animateOptions(options, $link);
6501
6695
  close();
6502
- $popup = createHiddenPopup($link, selector, sticky);
6503
- return up.replace(selector, url, {
6504
- history: history,
6505
- insert: function() {
6506
- return updated($link, $popup, position, animation, animateOptions);
6507
- }
6508
- });
6696
+ if (up.bus.nobodyPrevents('up:popup:open', {
6697
+ url: url
6698
+ })) {
6699
+ $popup = createHiddenPopup($link, selector, sticky);
6700
+ return up.replace(selector, url, {
6701
+ history: history,
6702
+ insert: function() {
6703
+ return updated($link, $popup, position, animation, animateOptions);
6704
+ }
6705
+ });
6706
+ } else {
6707
+ return u.unresolvableDeferred();
6708
+ }
6509
6709
  };
6510
6710
 
6711
+ /**
6712
+ This event is [emitted](/up.emit) when a popup is starting to open.
6713
+
6714
+ @event up:popup:open
6715
+ @param event.preventDefault()
6716
+ Event listeners may call this method to prevent the popup from opening.
6717
+ @stable
6718
+ */
6719
+
6720
+ /**
6721
+ This event is [emitted](/up.emit) when a popup has finished opening.
6722
+
6723
+ @event up:popup:opened
6724
+ @stable
6725
+ */
6726
+
6511
6727
  /**
6512
6728
  Closes a currently opened popup overlay.
6729
+
6513
6730
  Does nothing if no popup is currently open.
6514
6731
 
6732
+ Emits events [`up:popup:close`](/up:popup:close) and [`up:popup:closed`](/up:popup:closed).
6733
+
6515
6734
  @function up.popup.close
6516
6735
  @param {Object} options
6517
6736
  See options for [`up.animate`](/up.animate).
6737
+ @return {Deferred}
6738
+ A promise that will be resolved once the modal's close
6739
+ animation has finished.
6518
6740
  @stable
6519
6741
  */
6520
6742
  close = function(options) {
6521
- var $popup;
6743
+ var $popup, deferred;
6522
6744
  $popup = $('.up-popup');
6523
6745
  if ($popup.length) {
6524
- options = u.options(options, {
6525
- animation: config.closeAnimation,
6526
- url: $popup.attr('up-covered-url'),
6527
- title: $popup.attr('up-covered-title')
6528
- });
6529
- currentUrl = void 0;
6530
- return up.destroy($popup, options);
6746
+ if (up.bus.nobodyPrevents('up:popup:close', {
6747
+ $element: $popup
6748
+ })) {
6749
+ options = u.options(options, {
6750
+ animation: config.closeAnimation,
6751
+ url: $popup.attr('up-covered-url'),
6752
+ title: $popup.attr('up-covered-title')
6753
+ });
6754
+ currentUrl = void 0;
6755
+ deferred = up.destroy($popup, options);
6756
+ deferred.then(function() {
6757
+ return up.emit('up:popup:closed');
6758
+ });
6759
+ return deferred;
6760
+ } else {
6761
+ return u.unresolvableDeferred();
6762
+ }
6531
6763
  } else {
6532
- return u.resolvedPromise();
6764
+ return u.resolvedDeferred();
6533
6765
  }
6534
6766
  };
6767
+
6768
+ /**
6769
+ This event is [emitted](/up.emit) when a popup dialog
6770
+ is starting to [close](/up.popup.close).
6771
+
6772
+ @event up:popup:close
6773
+ @param event.preventDefault()
6774
+ Event listeners may call this method to prevent the popup from closing.
6775
+ @stable
6776
+ */
6777
+
6778
+ /**
6779
+ This event is [emitted](/up.emit) when a popup dialog
6780
+ is done [closing](/up.popup.close).
6781
+
6782
+ @event up:popup:closed
6783
+ @stable
6784
+ */
6535
6785
  autoclose = function() {
6536
6786
  if (!$('.up-popup').is('[up-sticky]')) {
6537
6787
  discardHistory();
@@ -6600,7 +6850,14 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
6600
6850
 
6601
6851
  /**
6602
6852
  When an element with this attribute is clicked,
6603
- a currently open popup is closed.
6853
+ a currently open popup is closed.
6854
+
6855
+ Does nothing if no popup is currently open.
6856
+
6857
+ To make a link that closes the current popup, but follows to
6858
+ a fallback destination if no popup is open:
6859
+
6860
+ <a href="/fallback" up-close>Okay</a>
6604
6861
 
6605
6862
  @selector [up-close]
6606
6863
  @stable
@@ -6640,7 +6897,8 @@ Modal dialogs
6640
6897
  =============
6641
6898
 
6642
6899
  Instead of [linking to a page fragment](/up.link), you can choose
6643
- to show a fragment in a modal dialog.
6900
+ to show a fragment in a modal dialog. The existing page will remain
6901
+ open in the background and reappear once the modal is closed.
6644
6902
 
6645
6903
  To open a modal, add an [`up-modal` attribute](/a-up-modal) to a link,
6646
6904
  or call the Javascript functions [`up.modal.follow`](/up.modal.follow)
@@ -6732,6 +6990,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
6732
6990
  @param {String} [config.closeAnimation='fade-out']
6733
6991
  The animation used to close the modal. The animation will be applied
6734
6992
  to both the dialog box and the overlay dimming the page.
6993
+ @stable
6735
6994
  */
6736
6995
  config = u.config({
6737
6996
  maxWidth: null,
@@ -6962,7 +7221,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
6962
7221
  }
6963
7222
  });
6964
7223
  } else {
6965
- return $.Deferred();
7224
+ return u.unresolvableDeferred();
6966
7225
  }
6967
7226
  };
6968
7227
 
@@ -6984,6 +7243,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
6984
7243
 
6985
7244
  /**
6986
7245
  Closes a currently opened modal overlay.
7246
+
6987
7247
  Does nothing if no modal is currently open.
6988
7248
 
6989
7249
  Emits events [`up:modal:close`](/up:modal:close) and [`up:modal:closed`](/up:modal:closed).
@@ -6991,6 +7251,9 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
6991
7251
  @function up.modal.close
6992
7252
  @param {Object} options
6993
7253
  See options for [`up.animate`](/up.animate)
7254
+ @return {Deferred}
7255
+ A promise that will be resolved once the modal's close
7256
+ animation has finished.
6994
7257
  @stable
6995
7258
  */
6996
7259
  close = function(options) {
@@ -7016,7 +7279,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
7016
7279
  });
7017
7280
  return deferred;
7018
7281
  } else {
7019
- return $.Deferred();
7282
+ return u.unresolvableDeferred();
7020
7283
  }
7021
7284
  } else {
7022
7285
  return u.resolvedDeferred();
@@ -7204,6 +7467,7 @@ The tooltip element is appended to the end of `<body>`.
7204
7467
  The animation used to open a tooltip.
7205
7468
  @param {String} [config.closeAnimation='fade-out']
7206
7469
  The animation used to close a tooltip.
7470
+ @stable
7207
7471
  */
7208
7472
  config = u.config({
7209
7473
  position: 'top',
@@ -7367,8 +7631,8 @@ The tooltip element is appended to the end of `<body>`.
7367
7631
  /**
7368
7632
  Fast interaction feedback
7369
7633
  =========================
7370
-
7371
- This module marks up link elements with classes indicating that
7634
+
7635
+ Up.js automatically marks up link elements with classes indicating that
7372
7636
  they are currently loading (class `up-active`) or linking
7373
7637
  to the current location (class `up-current`).
7374
7638
 
@@ -7389,6 +7653,7 @@ by providing instant feedback for user interactions.
7389
7653
  @property up.navigation.config
7390
7654
  @param {Number} [config.currentClasses]
7391
7655
  An array of classes to set on [links that point the current location](/up-current).
7656
+ @stable
7392
7657
  */
7393
7658
  config = u.config({
7394
7659
  currentClasses: ['up-current']
@@ -7503,8 +7768,8 @@ by providing instant feedback for user interactions.
7503
7768
 
7504
7769
  <a href="/foo" up-follow up-active>Foo</a>
7505
7770
 
7506
- Once the fragment is loaded the browser's location bar is updated
7507
- to `http://yourhost/foo` via [`history.pushState`](https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history#Adding_and_modifying_history_entries):
7771
+ Once the link destination has loaded and rendered, the `up-active` class
7772
+ is removed and the [`up-current`](/up-current) class is added:
7508
7773
 
7509
7774
  <a href="/foo" up-follow up-current>Foo</a>
7510
7775