upjs-rails 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f2bd908d4b8ae9ccc80617aab947a39f49e91cd6
4
- data.tar.gz: 3d82e0f710813f128f9e8ae4aa48311b0990c04f
3
+ metadata.gz: 655fa884c0c4a62058305fcaff08f3c30ae120cd
4
+ data.tar.gz: fb4bf39f399523965d43dff9ec87562448277010
5
5
  SHA512:
6
- metadata.gz: 8eac37753503ff8163ff92fc7e37b34c3a8c20a1d76033e0f5784ed6077f52cd4b4bb8e84cc3584c68e83d559f9e7f5a2d62eb9a89f292408de556428a1bfbe3
7
- data.tar.gz: e8fe7e337a8c754f45b5fe0b5e849ed79d60a8bb95b819a33236a4d98178ddaa4d228489cd48f854099692b31f2f8e21b757e85c2cf03e0ff7afa5f6fd31a4c5
6
+ metadata.gz: 02a61e45289d9e5250e17a97d27b8bfd7b1614214bbd24f7391619370d9cfc076e4b1b3bda019b4370add571dfd107b9ee4dd63d31f68f572026ab379c033a32
7
+ data.tar.gz: d79a915cbff359e71e4c9ca4e7805e10f11518d2de78ca3bd2dcf634613b7f0805de6b09b1796e6f32eb08b87a12e1cc053bbe008cdaaf4ab7499ad04848757f
data/dist/up.js CHANGED
@@ -25,7 +25,7 @@ If you use them in your own code, you will get hurt.
25
25
  var __slice = [].slice;
26
26
 
27
27
  up.util = (function() {
28
- var $createElementFromSelector, ajax, castsToFalse, castsToTrue, clientSize, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, detect, each, error, escapePressed, extend, findWithSelf, forceCompositing, get, ifGiven, isArray, isBlank, isDefined, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, keys, last, locationFromXhr, measure, merge, nextFrame, normalizeUrl, only, option, options, prependGhost, presence, presentAttr, resolvedPromise, select, temporaryCss, trim, unwrap;
28
+ var $createElementFromSelector, ANIMATION_PROMISE_KEY, ajax, castsToFalse, castsToTrue, clientSize, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, detect, each, error, escapePressed, extend, findWithSelf, finishCssAnimate, forceCompositing, get, ifGiven, isArray, isBlank, isDeferred, isDefined, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, keys, last, locationFromXhr, measure, merge, nextFrame, normalizeUrl, only, option, options, prependGhost, presence, presentAttr, resolvableWhen, resolvedDeferred, resolvedPromise, select, temporaryCss, trim, unwrap;
29
29
  get = function(url, options) {
30
30
  options = options || {};
31
31
  options.url = url;
@@ -132,12 +132,12 @@ If you use them in your own code, you will get hurt.
132
132
  return element;
133
133
  };
134
134
  error = function() {
135
- var args, message;
135
+ var args, asString;
136
136
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
137
- message = args.length === 1 && up.util.isString(args[0]) ? args[0] : JSON.stringify(args);
138
- console.log.apply(console, ["[UP] Error: " + message].concat(__slice.call(args)));
139
- alert(message);
140
- throw message;
137
+ console.log.apply(console, ["[UP] Error"].concat(__slice.call(args)));
138
+ asString = args.length === 1 && up.util.isString(args[0]) ? args[0] : JSON.stringify(args);
139
+ alert(asString);
140
+ throw asString;
141
141
  };
142
142
  createSelectorFromElement = function($element) {
143
143
  var classString, classes, id, klass, selector, _i, _len;
@@ -252,7 +252,10 @@ If you use them in your own code, you will get hurt.
252
252
  return object instanceof jQuery;
253
253
  };
254
254
  isPromise = function(object) {
255
- return isFunction(object.then);
255
+ return isObject(object) && isFunction(object.then);
256
+ };
257
+ isDeferred = function(object) {
258
+ return isPromise(object) && isFunction(object.resolve);
256
259
  };
257
260
  ifGiven = function(object) {
258
261
  if (isGiven(object)) {
@@ -408,6 +411,12 @@ If you use them in your own code, you will get hurt.
408
411
  /**
409
412
  Animates the given element's CSS properties using CSS transitions.
410
413
 
414
+ If the element is already being animated, the previous animation
415
+ will instantly jump to its last frame before the new animation begins.
416
+
417
+ To improve performance, the element will be forced into compositing for
418
+ the duration of the animation.
419
+
411
420
  @method up.util.cssAnimate
412
421
  @param {Element|jQuery|String} elementOrSelector
413
422
  The element to animate.
@@ -425,7 +434,7 @@ If you use them in your own code, you will get hurt.
425
434
  A promise for the animation's end.
426
435
  */
427
436
  cssAnimate = function(elementOrSelector, lastFrame, opts) {
428
- var $element, deferred, transition, withoutCompositing, withoutTransition;
437
+ var $element, deferred, endTimeout, transition, withoutCompositing, withoutTransition;
429
438
  $element = $(elementOrSelector);
430
439
  if (up.browser.canCssAnimation()) {
431
440
  opts = options(opts, {
@@ -445,15 +454,41 @@ If you use them in your own code, you will get hurt.
445
454
  $element.css(lastFrame);
446
455
  deferred.then(withoutCompositing);
447
456
  deferred.then(withoutTransition);
448
- setTimeout((function() {
457
+ $element.data(ANIMATION_PROMISE_KEY, deferred);
458
+ deferred.then(function() {
459
+ return $element.removeData(ANIMATION_PROMISE_KEY);
460
+ });
461
+ endTimeout = setTimeout((function() {
449
462
  return deferred.resolve();
450
463
  }), opts.duration + opts.delay);
451
- return deferred.promise();
464
+ deferred.then(function() {
465
+ return clearTimeout(endTimeout);
466
+ });
467
+ return deferred;
452
468
  } else {
453
469
  $element.css(lastFrame);
454
470
  return resolvedPromise();
455
471
  }
456
472
  };
473
+ ANIMATION_PROMISE_KEY = 'up-animation-promise';
474
+
475
+ /*
476
+ Completes the animation for the given element by jumping
477
+ to the last frame instantly. All callbacks chained to
478
+ the original animation's promise will be called.
479
+
480
+ Does nothing if the given element is not currently animating.
481
+
482
+ @param {Element|jQuery|String} elementOrSelector
483
+ */
484
+ finishCssAnimate = function(elementOrSelector) {
485
+ return $(elementOrSelector).each(function() {
486
+ var existingAnimation;
487
+ if (existingAnimation = $(this).data(ANIMATION_PROMISE_KEY)) {
488
+ return existingAnimation.resolve();
489
+ }
490
+ });
491
+ };
457
492
  measure = function($element, options) {
458
493
  var box, coordinates, viewport;
459
494
  coordinates = (options != null ? options.relative : void 0) ? $element.position() : $element.offset();
@@ -536,11 +571,25 @@ If you use them in your own code, you will get hurt.
536
571
  }
537
572
  return filtered;
538
573
  };
539
- resolvedPromise = function() {
574
+ resolvedDeferred = function() {
540
575
  var deferred;
541
576
  deferred = $.Deferred();
542
577
  deferred.resolve();
543
- return deferred.promise();
578
+ return deferred;
579
+ };
580
+ resolvedPromise = function() {
581
+ return resolvedDeferred().promise();
582
+ };
583
+ resolvableWhen = function() {
584
+ var deferreds, joined;
585
+ deferreds = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
586
+ joined = $.when.apply($, deferreds);
587
+ joined.resolve = function() {
588
+ return each(deferreds, function(deferred) {
589
+ return typeof deferred.resolve === "function" ? deferred.resolve() : void 0;
590
+ });
591
+ };
592
+ return joined;
544
593
  };
545
594
  return {
546
595
  presentAttr: presentAttr,
@@ -574,6 +623,7 @@ If you use them in your own code, you will get hurt.
574
623
  isString: isString,
575
624
  isJQuery: isJQuery,
576
625
  isPromise: isPromise,
626
+ isDeferred: isDeferred,
577
627
  isHash: isHash,
578
628
  ifGiven: ifGiven,
579
629
  unwrap: unwrap,
@@ -581,6 +631,7 @@ If you use them in your own code, you will get hurt.
581
631
  measure: measure,
582
632
  temporaryCss: temporaryCss,
583
633
  cssAnimate: cssAnimate,
634
+ finishCssAnimate: finishCssAnimate,
584
635
  forceCompositing: forceCompositing,
585
636
  prependGhost: prependGhost,
586
637
  escapePressed: escapePressed,
@@ -595,7 +646,9 @@ If you use them in your own code, you will get hurt.
595
646
  only: only,
596
647
  trim: trim,
597
648
  keys: keys,
598
- resolvedPromise: resolvedPromise
649
+ resolvedPromise: resolvedPromise,
650
+ resolvedDeferred: resolvedDeferred,
651
+ resolvableWhen: resolvableWhen
599
652
  };
600
653
  })();
601
654
 
@@ -612,7 +665,7 @@ Browser interface
612
665
  var __slice = [].slice;
613
666
 
614
667
  up.browser = (function() {
615
- var canCssAnimation, canPushState, ensureConsoleExists, isSupported, loadPage, memoize, u, url;
668
+ var canCssAnimation, canInputEvent, canPushState, ensureConsoleExists, isSupported, loadPage, memoize, u, url;
616
669
  u = up.util;
617
670
  loadPage = function(url, options) {
618
671
  var $form, csrfParam, csrfToken, metadataInput, method, target;
@@ -669,6 +722,9 @@ Browser interface
669
722
  canCssAnimation = memoize(function() {
670
723
  return 'transition' in document.documentElement.style;
671
724
  });
725
+ canInputEvent = memoize(function() {
726
+ return 'oninput' in document.createElement('input');
727
+ });
672
728
  isSupported = memoize(function() {
673
729
  return u.isDefined(document.addEventListener);
674
730
  });
@@ -678,6 +734,7 @@ Browser interface
678
734
  loadPage: loadPage,
679
735
  canPushState: canPushState,
680
736
  canCssAnimation: canCssAnimation,
737
+ canInputEvent: canInputEvent,
681
738
  isSupported: isSupported
682
739
  };
683
740
  })();
@@ -904,6 +961,7 @@ We need to work on this page:
904
961
  _results = [];
905
962
  for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
906
963
  step = _ref1[_i];
964
+ up.motion.finish(step.selector);
907
965
  $old = u.presence($(".up-popup " + step.selector)) || u.presence($(".up-modal " + step.selector)) || u.presence($(step.selector)) || u.error("Could not find selector (" + step.selector + ") in current body HTML");
908
966
  if (fragment = htmlElement.querySelector(step.selector)) {
909
967
  $new = $(fragment);
@@ -1388,7 +1446,7 @@ We need to work on this page:
1388
1446
 
1389
1447
  (function() {
1390
1448
  up.motion = (function() {
1391
- var animate, animation, animations, assertIsPromise, config, defaultAnimations, defaultTransitions, defaults, findAnimation, morph, none, reset, snapshot, transition, transitions, u, withGhosts;
1449
+ var GHOSTING_PROMISE_KEY, animate, animation, animations, assertIsDeferred, config, defaultAnimations, defaultTransitions, defaults, findAnimation, finish, finishGhosting, morph, none, reset, resolvableWhen, snapshot, transition, transitions, u, withGhosts;
1392
1450
  u = up.util;
1393
1451
  config = {
1394
1452
  duration: 300,
@@ -1413,6 +1471,9 @@ We need to work on this page:
1413
1471
  /**
1414
1472
  Animates an element.
1415
1473
 
1474
+ If the element is already being animated, the previous animation
1475
+ will instantly jump to its last frame before the new animation begins.
1476
+
1416
1477
  The following animations are pre-registered:
1417
1478
 
1418
1479
  - `fade-in`
@@ -1439,9 +1500,10 @@ We need to work on this page:
1439
1500
  animate = function(elementOrSelector, animation, options) {
1440
1501
  var $element;
1441
1502
  $element = $(elementOrSelector);
1503
+ finish($element);
1442
1504
  options = u.options(options, config);
1443
1505
  if (u.isFunction(animation)) {
1444
- return assertIsPromise(animation($element, options), ["Animation did not return a Promise", animation]);
1506
+ return assertIsDeferred(animation($element, options), animation);
1445
1507
  } else if (u.isString(animation)) {
1446
1508
  return animate($element, findAnimation(animation), options);
1447
1509
  } else if (u.isHash(animation)) {
@@ -1453,6 +1515,7 @@ We need to work on this page:
1453
1515
  findAnimation = function(name) {
1454
1516
  return animations[name] || u.error("Unknown animation", animation);
1455
1517
  };
1518
+ GHOSTING_PROMISE_KEY = 'up-ghosting-promise';
1456
1519
  withGhosts = function($old, $new, block) {
1457
1520
  var $newGhost, $oldGhost, newCssMemo, promise;
1458
1521
  $oldGhost = null;
@@ -1474,7 +1537,11 @@ We need to work on this page:
1474
1537
  display: 'none'
1475
1538
  });
1476
1539
  promise = block($oldGhost, $newGhost);
1477
- return promise.then(function() {
1540
+ $old.data(GHOSTING_PROMISE_KEY, promise);
1541
+ $new.data(GHOSTING_PROMISE_KEY, promise);
1542
+ promise.then(function() {
1543
+ $old.removeData(GHOSTING_PROMISE_KEY);
1544
+ $new.removeData(GHOSTING_PROMISE_KEY);
1478
1545
  $oldGhost.remove();
1479
1546
  $newGhost.remove();
1480
1547
  $old.css({
@@ -1482,10 +1549,39 @@ We need to work on this page:
1482
1549
  });
1483
1550
  return newCssMemo();
1484
1551
  });
1552
+ return promise;
1553
+ };
1554
+
1555
+ /*
1556
+ Completes all animations and transitions for the given element
1557
+ by jumping to the last animation frame instantly. All callbacks chained to
1558
+ the original animation's promise will be called.
1559
+
1560
+ Does nothing if the given element is not currently animating.
1561
+
1562
+ @param {Element|jQuery|String} elementOrSelector
1563
+ */
1564
+ finish = function(elementOrSelector) {
1565
+ return $(elementOrSelector).each(function() {
1566
+ var $element;
1567
+ $element = $(this);
1568
+ u.finishCssAnimate($element);
1569
+ return finishGhosting($element);
1570
+ });
1571
+ };
1572
+ finishGhosting = function($element) {
1573
+ var existingGhosting;
1574
+ if (existingGhosting = $element.data(GHOSTING_PROMISE_KEY)) {
1575
+ console.log("EXISTING", existingGhosting);
1576
+ return typeof existingGhosting.resolve === "function" ? existingGhosting.resolve() : void 0;
1577
+ }
1485
1578
  };
1486
- assertIsPromise = function(object, messageParts) {
1487
- u.isPromise(object) || u.error.apply(u, messageParts);
1488
- return object;
1579
+ assertIsDeferred = function(object, origin) {
1580
+ if (u.isDeferred(object)) {
1581
+ return object;
1582
+ } else {
1583
+ return u.error("Did not return a promise with .then and .resolve methods: ", origin);
1584
+ }
1489
1585
  };
1490
1586
 
1491
1587
  /**
@@ -1522,10 +1618,12 @@ We need to work on this page:
1522
1618
  options = u.options(config);
1523
1619
  $old = $(source);
1524
1620
  $new = $(target);
1621
+ finish($old);
1622
+ finish($new);
1525
1623
  transition = u.presence(transitionOrName, u.isFunction) || transitions[transitionOrName];
1526
1624
  if (transition) {
1527
1625
  return withGhosts($old, $new, function($oldGhost, $newGhost) {
1528
- return assertIsPromise(transition($oldGhost, $newGhost, options), ["Transition did not return a promise", transitionOrName]);
1626
+ return assertIsDeferred(transition($oldGhost, $newGhost, options), transitionOrName);
1529
1627
  });
1530
1628
  } else if (animation = animations[transitionOrName]) {
1531
1629
  $old.hide();
@@ -1533,14 +1631,14 @@ We need to work on this page:
1533
1631
  } else if (u.isString(transitionOrName) && transitionOrName.indexOf('/') >= 0) {
1534
1632
  parts = transitionOrName.split('/');
1535
1633
  transition = function($old, $new, options) {
1536
- return $.when(animate($old, parts[0], options), animate($new, parts[1], options));
1634
+ return resolvableWhen(animate($old, parts[0], options), animate($new, parts[1], options));
1537
1635
  };
1538
1636
  return morph($old, $new, transition, options);
1539
1637
  } else {
1540
1638
  return u.error("Unknown transition: " + transitionOrName);
1541
1639
  }
1542
1640
  } else {
1543
- return u.resolvedPromise();
1641
+ return u.resolvedDeferred();
1544
1642
  }
1545
1643
  };
1546
1644
 
@@ -1574,6 +1672,15 @@ We need to work on this page:
1574
1672
  return transitions = u.copy(defaultTransitions);
1575
1673
  };
1576
1674
 
1675
+ /**
1676
+ Returns a new promise that resolves once all promises in the given array resolve.
1677
+ Other then e.g. `$.then`, the combined promise will have a `resolve` method.
1678
+
1679
+ @method up.motion.when
1680
+ @param promises...
1681
+ */
1682
+ resolvableWhen = u.resolvableWhen;
1683
+
1577
1684
  /**
1578
1685
  Returns a no-op animation or transition which has no visual effects
1579
1686
  and completes instantly.
@@ -1582,7 +1689,7 @@ We need to work on this page:
1582
1689
  @return {Promise}
1583
1690
  A resolved promise
1584
1691
  */
1585
- none = u.resolvedPromise;
1692
+ none = u.resolvedDeferred;
1586
1693
  animation('none', none);
1587
1694
  animation('fade-in', function($ghost, options) {
1588
1695
  $ghost.css({
@@ -1701,29 +1808,31 @@ We need to work on this page:
1701
1808
  });
1702
1809
  transition('none', none);
1703
1810
  transition('move-left', function($old, $new, options) {
1704
- return $.when(animate($old, 'move-to-left', options), animate($new, 'move-from-right', options));
1811
+ return resolvableWhen(animate($old, 'move-to-left', options), animate($new, 'move-from-right', options));
1705
1812
  });
1706
1813
  transition('move-right', function($old, $new, options) {
1707
- return $.when(animate($old, 'move-to-right', options), animate($new, 'move-from-left', options));
1814
+ return resolvableWhen(animate($old, 'move-to-right', options), animate($new, 'move-from-left', options));
1708
1815
  });
1709
1816
  transition('move-up', function($old, $new, options) {
1710
- return $.when(animate($old, 'move-to-top', options), animate($new, 'move-from-bottom', options));
1817
+ return resolvableWhen(animate($old, 'move-to-top', options), animate($new, 'move-from-bottom', options));
1711
1818
  });
1712
1819
  transition('move-down', function($old, $new, options) {
1713
- return $.when(animate($old, 'move-to-bottom', options), animate($new, 'move-from-top', options));
1820
+ return resolvableWhen(animate($old, 'move-to-bottom', options), animate($new, 'move-from-top', options));
1714
1821
  });
1715
1822
  transition('cross-fade', function($old, $new, options) {
1716
- return $.when(animate($old, 'fade-out', options), animate($new, 'fade-in', options));
1823
+ return resolvableWhen(animate($old, 'fade-out', options), animate($new, 'fade-in', options));
1717
1824
  });
1718
1825
  up.bus.on('framework:ready', snapshot);
1719
1826
  up.bus.on('framework:reset', reset);
1720
1827
  return {
1721
1828
  morph: morph,
1722
1829
  animate: animate,
1830
+ finish: finish,
1723
1831
  transition: transition,
1724
1832
  animation: animation,
1725
1833
  defaults: defaults,
1726
- none: none
1834
+ none: none,
1835
+ when: resolvableWhen
1727
1836
  };
1728
1837
  })();
1729
1838
 
@@ -2044,8 +2153,7 @@ We need to work on this page:
2044
2153
  };
2045
2154
 
2046
2155
  /**
2047
- Observes an input field by periodic polling its value.
2048
- Executes code when the value changes.
2156
+ Observes an input field and executes code when its value changes.
2049
2157
 
2050
2158
  up.observe('input', { change: function(value, $input) {
2051
2159
  up.submit($input)
@@ -2062,17 +2170,20 @@ We need to work on this page:
2062
2170
  If given as a function, it must take two arguments (`value`, `$field`).
2063
2171
  If given as a string, it will be evaled as Javascript code in a context where
2064
2172
  (`value`, `$field`) are set.
2065
- @param {Number} [options.frequency=500]
2173
+ @param {Number} [options.delay=0]
2174
+ The number of miliseconds to wait before executing the callback
2175
+ after the input value changes. Use this to limit how often the callback
2176
+ will be invoked for a fast typist.
2066
2177
  */
2067
2178
  observe = function(fieldOrSelector, options) {
2068
- var $field, callback, check, clearTimer, codeOnChange, knownValue, resetTimer, startTimer, timer;
2179
+ var $field, callback, callbackPromise, callbackTimer, changeEvents, check, clearTimer, codeOnChange, delay, knownValue, nextCallback, runNextCallback;
2069
2180
  $field = $(fieldOrSelector);
2070
- options = u.options(options, {
2071
- frequency: 500
2072
- });
2181
+ options = u.options(options);
2182
+ delay = u.option($field.attr('up-delay'), options.delay, 0);
2183
+ delay = parseInt(delay);
2073
2184
  knownValue = null;
2074
- timer = null;
2075
2185
  callback = null;
2186
+ callbackTimer = null;
2076
2187
  if (codeOnChange = $field.attr('up-observe')) {
2077
2188
  callback = function(value, $field) {
2078
2189
  return eval(codeOnChange);
@@ -2082,6 +2193,16 @@ We need to work on this page:
2082
2193
  } else {
2083
2194
  u.error('observe: No change callback given');
2084
2195
  }
2196
+ callbackPromise = u.resolvedPromise();
2197
+ nextCallback = null;
2198
+ runNextCallback = function() {
2199
+ var returnValue;
2200
+ if (nextCallback) {
2201
+ returnValue = nextCallback();
2202
+ nextCallback = null;
2203
+ return returnValue;
2204
+ }
2205
+ };
2085
2206
  check = function() {
2086
2207
  var skipCallback, value;
2087
2208
  value = $field.val();
@@ -2089,26 +2210,30 @@ We need to work on this page:
2089
2210
  if (knownValue !== value) {
2090
2211
  knownValue = value;
2091
2212
  if (!skipCallback) {
2092
- return callback.apply($field.get(0), [value, $field]);
2213
+ clearTimer();
2214
+ nextCallback = function() {
2215
+ return callback.apply($field.get(0), [value, $field]);
2216
+ };
2217
+ return callbackTimer = setTimeout(function() {
2218
+ return callbackPromise.then(function() {
2219
+ var returnValue;
2220
+ returnValue = runNextCallback();
2221
+ if (u.isPromise(returnValue)) {
2222
+ return callbackPromise = returnValue;
2223
+ } else {
2224
+ return callbackPromise = u.resolvedPromise();
2225
+ }
2226
+ });
2227
+ }, delay);
2093
2228
  }
2094
2229
  }
2095
2230
  };
2096
- resetTimer = function() {
2097
- if (timer) {
2098
- clearTimer();
2099
- return startTimer();
2100
- }
2101
- };
2102
2231
  clearTimer = function() {
2103
- clearInterval(timer);
2104
- return timer = null;
2105
- };
2106
- startTimer = function() {
2107
- return timer = setInterval(check, options.frequency);
2232
+ return clearTimeout(callbackTimer);
2108
2233
  };
2109
- $field.bind("keyup click mousemove", resetTimer);
2234
+ changeEvents = up.browser.canInputEvent() ? 'input' : 'keypress paste cut change click propertychange';
2235
+ $field.on(changeEvents, check);
2110
2236
  check();
2111
- startTimer();
2112
2237
  return clearTimer;
2113
2238
  };
2114
2239
 
data/dist/up.min.js CHANGED
@@ -1 +1 @@
1
- (function(){window.up={}}).call(this),function(){var t=[].slice;up.util=function(){var n,e,r,o,i,u,a,s,c,p,l,f,m,d,h,v,g,y,b,w,k,S,C,T,x,P,E,A,F,U,O,j,z,D,H,L,M,W,G,I,X,q,N,V,R,B,J,Z,_,Q,K,Y,tn,nn;return w=function(t,n){return n=n||{},n.url=t,e(n)},e=function(t){return t.selector&&(t.headers={"X-Up-Selector":t.selector}),$.ajax(t)},D=function(t,n){return(""===n||"80"===n)&&"http:"===t||"443"===n&&"https:"===t},N=function(t,n){var e,r,o;return e=H(t)?$("<a>").attr({href:t}).get(0):nn(t),r=e.protocol+"//"+e.hostname,D(e.protocol,e.port)||(r+=":"+e.port),o=e.pathname,(null!=n?n.stripTrailingSlash:void 0)===!0&&(o=o.replace(/\/$/,"")),r+=o,(null!=n?n.hash:void 0)===!0&&(r+=e.hash),(null!=n?n.search:void 0)!==!1&&(r+=e.search),r},n=function(t){var n,e,r,o,i,u,a,s,c,p,l,f,m,d,h,v;for(l=t.split(/[ >]/),r=null,p=m=0,h=l.length;h>m;p=++m){for(u=l[p],i=u.match(/(^|\.|\#)[A-Za-z0-9\-_]+/g),f="div",o=[],c=null,d=0,v=i.length;v>d;d++)switch(a=i[d],a[0]){case".":o.push(a.substr(1));break;case"#":c=a.substr(1);break;default:f=a}s="<"+f,o.length&&(s+=' class="'+o.join(" ")+'"'),c&&(s+=' id="'+c+'"'),s+=">",n=$(s),e&&n.appendTo(e),0===p&&(r=n),e=n}return r},c=function(t,n){var e;return e=document.createElement(t),j(n)&&(e.innerHTML=n),e},h=function(){var n,e;throw n=1<=arguments.length?t.call(arguments,0):[],e=1===n.length&&up.util.isString(n[0])?n[0]:JSON.stringify(n),console.log.apply(console,["[UP] Error: "+e].concat(t.call(n))),alert(e),e},l=function(t){var n,e,r,o,i,u,a;for(console.log("Creating selector from element",t),e=(n=t.attr("class"))?n.split(" "):[],r=t.attr("id"),i=t.prop("tagName").toLowerCase(),r&&(i+="#"+r),u=0,a=e.length;a>u;u++)o=e[u],i+="."+o;return i},p=function(t){var n,e,r,o,i,u,a,s,p,l,f,m;return p=function(t){return"<"+t+"(?: [^>]*)?>"},u=function(t){return"</"+t+">"},n="(?:.|\\n)*?",i=function(t){return"("+t+")"},m=new RegExp(p("head")+n+p("title")+i(n)+u("title")+n+u("body"),"i"),o=new RegExp(p("body")+i(n)+u("body"),"i"),(r=t.match(o))?(s=document.createElement("html"),e=c("body",r[1]),s.appendChild(e),(f=t.match(m))&&(a=c("head"),s.appendChild(a),l=c("title",f[1]),a.appendChild(l)),s):c("div",t)},g=$.extend,tn=$.trim,M=Object.keys||function(t){var n,e,r,o;for(e=[],r=0,o=t.length;o>r;r++)n=t[r],t.hasOwnProperty(n)&&e.push(n);return e},d=function(t,n){var e,r,o,i,u;for(u=[],e=o=0,i=t.length;i>o;e=++o)r=t[e],u.push(n(r,e));return u},U=function(t){return null===t},L=function(t){return void 0===t},T=function(t){return!L(t)},F=function(t){return L(t)||U(t)},P=function(t){return!F(t)},C=function(t){return F(t)||O(t)&&0===M(t).length||0===t.length},Z=function(t,n){return null==n&&(n=j),n(t)?t:null},j=function(t){return!C(t)},x=function(t){return"function"==typeof t},H=function(t){return"string"==typeof t},E=function(t){return"object"==typeof t&&!!t},O=function(t){return E(t)||"function"==typeof t},A=function(t){return t instanceof jQuery},z=function(t){return x(t.then)},k=function(t){return P(t)?t:void 0},S=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},a=function(t){return S(t)?t.slice():g({},t)},nn=function(t){return A(t)?t.get(0):t},X=function(t,n){return g(a(t),n)},B=function(t,n){var e,r,o,i;if(o=t?a(t):{},n)for(r in n)e=n[r],i=o[r],P(i)?O(e)&&O(i)&&(o[r]=B(i,e)):o[r]=e;return o},R=function(){var n,e,r,o,i,u;for(e=1<=arguments.length?t.call(arguments,0):[],r=null,i=0,u=e.length;u>i;i++)if(n=e[i],o=n,x(o)&&(o=o()),j(o)){r=o;break}return r},m=function(t,n){var e,r,o,i;for(r=null,o=0,i=t.length;i>o;o++)if(e=t[o],n(e)){r=e;break}return r},K=function(t,n){var e;return e=[],d(t,function(t){return n(t)?e.push(t):void 0}),e},_=function(){var n,e,r,o;return n=arguments[0],r=2<=arguments.length?t.call(arguments,1):[],o=function(){var t,o,i;for(i=[],t=0,o=r.length;o>t;t++)e=r[t],i.push(n.attr(e));return i}(),m(o,j)},q=function(t){return setTimeout(t,0)},W=function(t){return t[t.length-1]},i=function(){var t;return t=document.documentElement,{width:t.clientWidth,height:t.clientHeight}},Y=function(t,n,e){var r,o;return o=t.css(M(n)),t.css(n),r=function(){return t.css(o)},e?(e(),r()):r},b=function(t){var n,e;return e=t.css(["transform","-webkit-transform"]),C(e)?(n=function(){return t.css(e)},t.css({transform:"translateZ(0)","-webkit-transform":"translateZ(0)"})):n=function(){},n},f=function(t,n,e){var r,o,i,u,a;return r=$(t),up.browser.canCssAnimation()?(e=B(e,{duration:300,delay:0,easing:"ease"}),o=$.Deferred(),i={"transition-property":M(n).join(", "),"transition-duration":e.duration+"ms","transition-delay":e.delay+"ms","transition-timing-function":e.easing},u=b(r),a=Y(r,i),r.css(n),o.then(u),o.then(a),setTimeout(function(){return o.resolve()},e.duration+e.delay),o.promise()):(r.css(n),Q())},I=function(t,n){var e,r,o;return r=(null!=n?n.relative:void 0)?t.position():t.offset(),e={left:r.left,top:r.top},(null!=n?n.inner:void 0)?(e.width=t.width(),e.height=t.height()):(e.width=t.outerWidth(),e.height=t.outerHeight()),(null!=n?n.full:void 0)&&(o=i(),e.right=o.width-(e.left+e.width),e.bottom=o.height-(e.top+e.height)),e},s=function(t,n){var e,r,o,i,u;for(i=t.get(0).attributes,u=[],r=0,o=i.length;o>r;r++)e=i[r],u.push(e.specified?n.attr(e.name,e.value):void 0);return u},J=function(t){var n,e;return e=I(t,{relative:!0,inner:!0}),n=t.clone(),n.find("script").remove(),n.css({right:"",bottom:"",position:"absolute"}),n.css(e),n.addClass("up-ghost"),n.insertBefore(t)},y=function(t,n){return t.find(n).addBack(n)},v=function(t){return 27===t.keyCode},u=function(t,n){return t.indexOf(n)>=0},o=function(t){return"true"===String(t)},r=function(t){return"false"===String(t)},G=function(t){return t.getResponseHeader("X-Up-Current-Location")},V=function(){var n,e,r,o,i,u;for(o=arguments[0],r=2<=arguments.length?t.call(arguments,1):[],n={},i=0,u=r.length;u>i;i++)e=r[i],o.hasOwnProperty(e)&&(n[e]=o[e]);return n},Q=function(){var t;return t=$.Deferred(),t.resolve(),t.promise()},{presentAttr:_,createElement:c,normalizeUrl:N,createElementFromHtml:p,$createElementFromSelector:n,createSelectorFromElement:l,get:w,ajax:e,extend:g,copy:a,merge:X,options:B,option:R,error:h,each:d,detect:m,select:K,last:W,isNull:U,isDefined:T,isUndefined:L,isGiven:P,isMissing:F,isPresent:j,isBlank:C,presence:Z,isObject:O,isFunction:x,isString:H,isJQuery:A,isPromise:z,isHash:E,ifGiven:k,unwrap:nn,nextFrame:q,measure:I,temporaryCss:Y,cssAnimate:f,forceCompositing:b,prependGhost:J,escapePressed:v,copyAttributes:s,findWithSelf:y,contains:u,isArray:S,castsToTrue:o,castsToFalse:r,locationFromXhr:G,clientSize:i,only:V,trim:tn,keys:M,resolvedPromise:Q}}()}.call(this),function(){var t=[].slice;up.browser=function(){var n,e,r,o,i,u,a,s;return a=up.util,i=function(t,n){var e,r,o,i,u,s;return null==n&&(n={}),u=a.option(n.method,"get").toLowerCase(),"get"===u?location.href=t:$.rails?(s=n.target,o=$.rails.csrfToken(),r=$.rails.csrfParam(),e=$("<form method='post' action='"+t+"'></form>"),i="<input name='_method' value='"+u+"' type='hidden' />",a.isDefined(r)&&a.isDefined(o)&&(i+="<input name='"+r+"' value='"+o+"' type='hidden' />"),s&&e.attr("target",s),e.hide().append(i).appendTo("body"),e.submit()):error("Can't fake a "+u.toUpperCase()+" request without Rails UJS")},s=function(){return location.href},r=function(){var t;return window.console||(window.console={}),(t=window.console).log||(t.log=function(){})},u=function(n){var e,r;return e=void 0,r=!1,function(){var o;return o=1<=arguments.length?t.call(arguments,0):[],r?e:(r=!0,e=n.apply(null,o))}},e=u(function(){return a.isDefined(history.pushState)}),n=u(function(){return"transition"in document.documentElement.style}),o=u(function(){return a.isDefined(document.addEventListener)}),{url:s,ensureConsoleExists:r,loadPage:i,canPushState:e,canCssAnimation:n,isSupported:o}}()}.call(this),function(){var t=[].slice;up.bus=function(){var n,e,r,o,i,u,a;return n={},r={},e=function(t){return n[t]||(n[t]=[])},a=function(){var t,e,o;r={},o=[];for(e in n)t=n[e],o.push(r[e]=up.util.copy(t));return o},u=function(){return n=up.util.copy(r)},i=function(t,n){return e(t).push(n)},o=function(){var n,r,o;return o=arguments[0],n=2<=arguments.length?t.call(arguments,1):[],console.log("bus emitting",o,n),r=e(o),up.util.each(r,function(t){return t.apply(null,n)})},i("framework:ready",a),i("framework:reset",u),{on:i,emit:o}}()}.call(this),function(){up.flow=function(){var t,n,e,r,o,i,u,a,s,c,p,l;return l=up.util,s=function(t,n){var e;return e=$(t),l.isPresent(n)&&(n=l.normalizeUrl(n)),e.attr("up-source",n)},c=function(t){var n;return n=$(t).closest("[up-source]"),l.presence(n.attr("up-source"))||up.browser.url()},u=function(t,n,e){var o;return e=l.options(e),o=l.presence(t)?t:l.createSelectorFromElement($(t)),up.browser.canPushState()||l.castsToFalse(e.history)?l.ajax({url:n,selector:o},l.only(e,"method")).done(function(t,i,u){var a;return(a=l.locationFromXhr(u))&&(n=a),(l.isMissing(e.history)||l.castsToTrue(e.history))&&(e.history=n),(l.isMissing(e.source)||l.castsToTrue(e.source))&&(e.source=n),r(o,t,e)}).fail(l.error):void up.browser.loadPage(n,l.only(e,"method"))},r=function(t,n,e){var r,i,u,a,s,c,f,m,d,h;for(e=l.options(e,{historyMethod:"push"}),"false"===e.history&&(e.history=null),e.source=l.option(e.source,e.history),a=l.createElementFromHtml(n),e.title||(e.title=null!=(m=a.querySelector("title"))?m.textContent:void 0),d=o(t,e),h=[],c=0,f=d.length;f>c;c++)s=d[c],i=l.presence($(".up-popup "+s.selector))||l.presence($(".up-modal "+s.selector))||l.presence($(s.selector))||l.error("Could not find selector ("+s.selector+") in current body HTML"),(u=a.querySelector(s.selector))?(r=$(u),h.push(p(i,r,s.pseudoClass,s.transition,e))):h.push(l.error("Could not find selector ("+s.selector+") in response ("+n+")"));return h},e=function(n,e){return"function"==typeof e.insert&&e.insert(n),e.history&&(e.title&&(document.title=e.title),up.history[e.historyMethod](e.history)),s(n,e.source),t(n),up.ready(n)},p=function(t,r,o,i,u){var a,s;return i||(i="none"),o?(s="before"===o?"prepend":"append",a=r.children(),t[s](r.contents()),l.copyAttributes(r,t),e(a,u),up.animate(r,i)):n(t,{animation:function(){return r.insertAfter(t),e(r,u),t.is("body")&&"none"!==i&&l.error("Cannot apply transitions to body-elements",i),up.morph(t,r,i)}})},o=function(t,n){var e,r,o,i,u,a,s,c,p,f,m;for(s=n.transition||n.animation||"none",e=/\ *,\ */,r=t.split(e),l.isPresent(s)&&(c=s.split(e)),m=[],o=p=0,f=r.length;f>p;o=++p)i=r[o],u=i.match(/^(.+?)(?:\:(before|after))?$/),a=c[o]||l.last(c),m.push({selector:u[1],pseudoClass:u[2],transition:a});return m},t=function(t){var n,e;return e="[autofocus]:last",n=l.findWithSelf(t,e),n.length&&n.get(0)!==document.activeElement?n.focus():void 0},n=function(t,n){var e,r;return e=$(t),n=l.options(n,{animation:"none"}),e.addClass("up-destroying"),l.isPresent(n.url)&&up.history.push(n.url),l.isPresent(n.title)&&(document.title=n.title),up.bus.emit("fragment:destroy",e),r=l.presence(n.animation,l.isPromise)||up.motion.animate(e,n.animation),r.then(function(){return e.remove()})},i=function(t){var n;return n=c(t),u(t,n)},a=function(){return up.bus.emit("framework:reset")},up.bus.on("app:ready",function(){return s(document.body,up.browser.url())}),{replace:u,reload:i,destroy:n,implant:r,reset:a}}(),up.replace=up.flow.replace,up.reload=up.flow.reload,up.destroy=up.flow.destroy,up.reset=up.flow.reset}.call(this),function(){var t=[].slice;up.magic=function(){var n,e,r,o,i,u,a,s,c,p,l,f,m,d,h,v;return v=up.util,n="up-destroyable",e="up-destroyer",l=[],s=null,p=function(t,n,e){var r,o;if(up.browser.isSupported())return r=[t,n,function(t){return e.apply(this,[t,$(this)])}],l.push(r),(o=$(document)).on.apply(o,r)},i=[],a=null,o=function(){var n,e,r,o;return o=arguments[0],n=2<=arguments.length?t.call(arguments,1):[],up.browser.isSupported()?(e=n.pop(),r=v.options(n[0],{batch:!1}),i.push({selector:o,callback:e,batch:r.batch})):void 0},r=function(t,r,o){var i;return i=t.callback.apply(o,[r]),v.isFunction(i)?(r.addClass(n),r.data(e,i)):void 0},u=function(t){var n,e,o,u,a;for(console.log("Compiling fragment",t),a=[],o=0,u=i.length;u>o;o++)e=i[o],n=v.findWithSelf(t,e.selector),a.push(n.length?e.batch?r(e,n,n.get()):n.each(function(){return r(e,$(this),this)}):void 0);return a},c=function(t){return v.findWithSelf(t,"."+n).each(function(){var t,n;return t=$(this),(n=t.data(e))()})},h=function(){return s=v.copy(l),a=v.copy(i)},d=function(){var t,n,e,r;for(n=0,e=l.length;e>n;n++)t=l[n],v.contains(s,t)||(r=$(document)).off.apply(r,t);return l=v.copy(s),i=v.copy(a)},m=function(t){var n;return n=$(t),up.bus.emit("fragment:ready",n),n},f=function(t){return p("keydown","body",function(n){return v.escapePressed(n)?t(n):void 0})},up.bus.on("app:ready",function(){return m(document.body)}),up.bus.on("fragment:ready",u),up.bus.on("fragment:destroy",c),up.bus.on("framework:ready",h),up.bus.on("framework:reset",d),{awaken:o,on:p,ready:m,onEscape:f}}(),up.awaken=up.magic.awaken,up.on=up.magic.on,up.ready=up.magic.ready}.call(this),function(){up.history=function(){var t,n,e,r,o,i;return i=up.util,t=function(t){return i.normalizeUrl(t,{hash:!0})===i.normalizeUrl(up.browser.url(),{hash:!0})},o=function(e,r){return r=i.options(r,{force:!1}),r.force||!t(e)?n("replace",e):void 0},r=function(e){return t(e)?void 0:n("push",e)},n=function(t,n){return up.browser.canPushState()?(t+="State",window.history[t]({fromUp:!0},"",n)):i.error("This browser doesn't support history.pushState")},e=function(t){var n;return n=t.originalEvent.state,console.log("popping state",n),console.log("current href",up.browser.url()),(null!=n?n.fromUp:void 0)?up.visit(up.browser.url(),{historyMethod:"replace"}):console.log("strange state",n)},up.browser.canPushState()&&setTimeout(function(){return $(window).on("popstate",e),o(up.browser.url(),{force:!0})},200),{push:r,replace:o}}()}.call(this),function(){up.motion=function(){var t,n,e,r,o,i,u,a,s,c,p,l,f,m,d,h,v;return h=up.util,o={duration:300,delay:0,easing:"ease"},e={},i={},d={},u={},a=function(t){return h.extend(o,t)},t=function(n,e,i){var u;return u=$(n),i=h.options(i,o),h.isFunction(e)?r(e(u,i),["Animation did not return a Promise",e]):h.isString(e)?t(u,s(e),i):h.isHash(e)?h.cssAnimate(u,e,i):h.error("Unknown animation type",e)},s=function(t){return e[t]||h.error("Unknown animation",n)},v=function(t,n,e){var r,o,i,u;return o=null,r=null,h.temporaryCss(n,{display:"none"},function(){return o=h.prependGhost(t).addClass("up-destroying")}),h.temporaryCss(t,{display:"none"},function(){return r=h.prependGhost(n)}),t.css({visibility:"hidden"}),i=h.temporaryCss(n,{display:"none"}),u=e(o,r),u.then(function(){return o.remove(),r.remove(),t.css({display:"none"}),i()})},r=function(t,n){return h.isPromise(t)||h.error.apply(h,n),t},c=function(n,i,u,a){var s,p,l,f,m;return up.browser.canCssAnimation()?(a=h.options(o),p=$(n),s=$(i),m=h.presence(u,h.isFunction)||d[u],m?v(p,s,function(t,n){return r(m(t,n,a),["Transition did not return a promise",u])}):(l=e[u])?(p.hide(),t(s,l,a)):h.isString(u)&&u.indexOf("/")>=0?(f=u.split("/"),m=function(n,e,r){return $.when(t(n,f[0],r),t(e,f[1],r))},c(p,s,m,a)):h.error("Unknown transition: "+u)):h.resolvedPromise()},m=function(t,n){return d[t]=n},n=function(t,n){return e[t]=n},f=function(){return i=h.copy(e),u=h.copy(d)},l=function(){return e=h.copy(i),d=h.copy(u)},p=h.resolvedPromise,n("none",p),n("fade-in",function(n,e){return n.css({opacity:0}),t(n,{opacity:1},e)}),n("fade-out",function(n,e){return n.css({opacity:1}),t(n,{opacity:0},e)}),n("move-to-top",function(n,e){var r,o;return r=h.measure(n),o=r.top+r.height,n.css({"margin-top":"0px"}),t(n,{"margin-top":"-"+o+"px"},e)}),n("move-from-top",function(n,e){var r,o;return r=h.measure(n),o=r.top+r.height,n.css({"margin-top":"-"+o+"px"}),t(n,{"margin-top":"0px"},e)}),n("move-to-bottom",function(n,e){var r,o;return r=h.measure(n),o=h.clientSize().height-r.top,n.css({"margin-top":"0px"}),t(n,{"margin-top":o+"px"},e)}),n("move-from-bottom",function(n,e){var r,o;return r=h.measure(n),o=h.clientSize().height-r.top,n.css({"margin-top":o+"px"}),t(n,{"margin-top":"0px"},e)}),n("move-to-left",function(n,e){var r,o;return r=h.measure(n),o=r.left+r.width,n.css({"margin-left":"0px"}),t(n,{"margin-left":"-"+o+"px"},e)}),n("move-from-left",function(n,e){var r,o;return r=h.measure(n),o=r.left+r.width,n.css({"margin-left":"-"+o+"px"}),t(n,{"margin-left":"0px"},e)}),n("move-to-right",function(n,e){var r,o;return r=h.measure(n),o=h.clientSize().width-r.left,n.css({"margin-left":"0px"}),t(n,{"margin-left":o+"px"},e)}),n("move-from-right",function(n,e){var r,o;return r=h.measure(n),o=h.clientSize().width-r.left,n.css({"margin-left":o+"px"}),t(n,{"margin-left":"0px"},e)}),n("roll-down",function(n,e){var r,o;return r=n.height(),o=h.temporaryCss(n,{height:"0px",overflow:"hidden"}),t(n,{height:r+"px"},e).then(o)}),m("none",p),m("move-left",function(n,e,r){return $.when(t(n,"move-to-left",r),t(e,"move-from-right",r))}),m("move-right",function(n,e,r){return $.when(t(n,"move-to-right",r),t(e,"move-from-left",r))}),m("move-up",function(n,e,r){return $.when(t(n,"move-to-top",r),t(e,"move-from-bottom",r))}),m("move-down",function(n,e,r){return $.when(t(n,"move-to-bottom",r),t(e,"move-from-top",r))}),m("cross-fade",function(n,e,r){return $.when(t(n,"fade-out",r),t(e,"fade-in",r))}),up.bus.on("framework:ready",f),up.bus.on("framework:reset",l),{morph:c,animate:t,transition:m,animation:n,defaults:a,none:p}}(),up.transition=up.motion.transition,up.animation=up.motion.animation,up.morph=up.motion.morph,up.animate=up.motion.animate}.call(this),function(){up.link=function(){var t,n,e,r,o;return r=up.util,o=function(t,n){return console.log("up.visit",t),up.replace("body",t,n)},t=function(t,n){var e,o,i;return e=$(t),n=r.options(n),i=r.option(e.attr("href"),e.attr("up-follow")),o=r.option(n.target,e.attr("up-target"),"body"),n.transition=r.option(n.transition,e.attr("up-transition"),e.attr("up-animation")),n.history=r.option(n.history,e.attr("up-history")),up.replace(o,i,n)},n=function(t){var n;return n=$(t),n.is("a")||r.presentAttr(n,"up-follow")?n:n.find("a:first")},e=function(t){var e;return(e=n(t))?r.option(e.attr("href"),e.attr("up-follow")):void 0},up.on("click","a[up-target]",function(n,e){return n.preventDefault(),t(e)}),up.on("click","[up-follow]",function(e,r){var o;return o=function(){var t,n;return t=$(e.target),n=t.closest("a, [up-follow]"),n.length&&r.find(n).length},o()?void 0:(e.preventDefault(),t(n(r)))}),{visit:o,follow:t,resolve:n,resolveUrl:e}}(),up.visit=up.link.visit,up.follow=up.link.follow}.call(this),function(){up.form=function(){var observe,submit,u;return u=up.util,submit=function(t,n){var e,r,o,i,a,s,c,p,l,f;return e=$(t).closest("form"),n=u.options(n),c=u.option(n.target,e.attr("up-target"),"body"),r=u.option(n.failTarget,e.attr("up-fail-target"),function(){return u.createSelectorFromElement(e)}),i=u.option(n.history,e.attr("up-history"),!0),p=u.option(n.transition,e.attr("up-transition")),o=u.option(n.failTransition,e.attr("up-fail-transition")),a=u.option(n.method,e.attr("up-method"),e.attr("data-method"),e.attr("method"),"post").toUpperCase(),f=u.option(n.url,e.attr("action"),up.browser.url()),e.addClass("up-active"),up.browser.canPushState()||u.castsToFalse(i)?(s={url:f,type:a,data:e.serialize(),selector:c},l=function(t){var n;return f=i?"false"===i?!1:u.isString(i)?i:(n=u.locationFromXhr(t))?n:"GET"===s.type?s.url+"?"+s.data:void 0:void 0,u.option(f,!1)},u.ajax(s).always(function(){return e.removeClass("up-active")}).done(function(t,n,e){return up.flow.implant(c,t,{history:l(e),transition:p})}).fail(function(t){var n;return n=t.responseText,up.flow.implant(r,n,{transition:o})})):void e.get(0).submit()},observe=function(fieldOrSelector,options){var $field,callback,check,clearTimer,codeOnChange,knownValue,resetTimer,startTimer,timer;return $field=$(fieldOrSelector),options=u.options(options,{frequency:500}),knownValue=null,timer=null,callback=null,(codeOnChange=$field.attr("up-observe"))?callback=function(value,$field){return eval(codeOnChange)}:options.change?callback=options.change:u.error("observe: No change callback given"),check=function(){var t,n;return n=$field.val(),t=_.isNull(knownValue),knownValue===n||(knownValue=n,t)?void 0:callback.apply($field.get(0),[n,$field])},resetTimer=function(){return timer?(clearTimer(),startTimer()):void 0},clearTimer=function(){return clearInterval(timer),timer=null},startTimer=function(){return timer=setInterval(check,options.frequency)},$field.bind("keyup click mousemove",resetTimer),check(),startTimer(),clearTimer},up.on("submit","form[up-target]",function(t,n){return t.preventDefault(),submit(n)}),up.awaken("[up-observe]",function(t){return observe(t)}),{submit:submit,observe:observe}}(),up.submit=up.form.submit,up.observe=up.form.observe}.call(this),function(){up.popup=function(){var t,n,e,r,o,i,u,a,s,c,p;return c=up.util,e={openAnimation:"fade-in",closeAnimation:"fade-out",origin:"bottom-right"},o=function(t){return c.extend(e,t)},a=function(t,n,e){var r,o;return o=c.measure(t,{full:!0}),r=function(){switch(e){case"bottom-right":return{right:o.right,top:o.top+o.height};case"bottom-left":return{left:o.left,top:o.bottom+o.height};case"top-right":return{right:o.right,bottom:o.top};case"top-left":return{left:o.left,bottom:o.top};default:return c.error("Unknown origin",e)}}(),n.attr("up-origin",e),n.css(r),i(n)},i=function(t){var n,e,r,o,i,u,a;if(e=c.measure(t,{full:!0}),r=null,o=null,e.right<0&&(r=-e.right),e.bottom<0&&(o=-e.bottom),e.left<0&&(r=e.left),e.top<0&&(o=e.top),r&&((i=parseInt(t.css("left")))?t.css("left",i-r):(u=parseInt(t.css("right")))&&t.css("right",u+r)),o){if(a=parseInt(t.css("top")))return t.css("top",a-o);if(n=parseInt(t.css("bottom")))return t.css("bottom",n+o)}},r=function(t,n,e){var r,o;return o=c.$createElementFromSelector(".up-popup"),e&&o.attr("up-sticky",""),o.attr("up-previous-url",up.browser.url()),o.attr("up-previous-title",document.title),r=c.$createElementFromSelector(n),r.appendTo(o),o.appendTo(document.body),o.hide(),o},p=function(t,n,e,r){return n.show(),a(t,n,e),up.animate(n,r)},u=function(t,o){var i,u,a,s,l,f,m,d;return i=$(t),o=c.options(o),d=c.option(i.attr("href")),f=c.option(o.target,i.attr("up-popup"),"body"),l=c.option(o.origin,i.attr("up-origin"),e.origin),a=c.option(o.animation,i.attr("up-animation"),e.openAnimation),m=c.option(o.sticky,i.is("[up-sticky]")),s=up.browser.canPushState()?c.option(o.history,i.attr("up-history"),!1):!1,n(),u=r(i,f,m),up.replace(f,d,{history:s,insert:function(){return p(i,u,l,a)}})},s=function(){var t;return t=$(".up-popup"),t.is(".up-destroying")?void 0:t.find("[up-source]").attr("up-source")},n=function(t){var n;return n=$(".up-popup"),n.length?(t=c.options(t,{animation:e.closeAnimation,url:n.attr("up-previous-url"),title:n.attr("up-previous-title")}),up.destroy(n,t)):void 0},t=function(){return $(".up-popup").is("[up-sticky]")?void 0:n()},up.on("click","a[up-popup]",function(t,e){return t.preventDefault(),e.is(".up-current")?n():u(e)}),up.on("click","body",function(t){var e;return e=$(t.target),e.closest(".up-popup").length||e.closest("[up-popup]").length?void 0:n()}),up.bus.on("fragment:ready",function(n){return n.closest(".up-popup").length?void 0:t()}),up.magic.onEscape(function(){return n()}),up.on("click","[up-close]",function(t,e){return e.closest(".up-popup")?n():void 0}),up.bus.on("framework:reset",n),{open:u,close:n,source:s,defaults:o}}()}.call(this),function(){up.modal=function(){var t,n,e,r,o,i,u,a,s,c;return s=up.util,e={width:"auto",height:"auto",openAnimation:"fade-in",closeAnimation:"fade-out",closeLabel:"X",template:function(t){return'<div class="up-modal">\n <div class="up-modal-dialog">\n <div class="up-modal-close" up-close>'+t.closeLabel+'</div>\n <div class="up-modal-content"></div>\n </div>\n</div>'}},o=function(t){return s.extend(e,t)},a=function(){var t;return t=e.template,s.isFunction(t)?t(e):t},r=function(t,n,e,r){var o,i,u,c;return u=$(a()),r&&u.attr("up-sticky",""),u.attr("up-previous-url",up.browser.url()),u.attr("up-previous-title",document.title),i=u.find(".up-modal-dialog"),s.isPresent(n)&&i.css("width",n),s.isPresent(e)&&i.css("height",e),o=i.find(".up-modal-content"),c=s.$createElementFromSelector(t),c.appendTo(o),u.appendTo(document.body),u.hide(),u},c=function(t,n){return t.show(),up.animate(t,n)},i=function(t,o){var i,u,a,p,l,f,m,d,h;return i=$(t),o=s.options(o),d=s.option(i.attr("href")),f=s.option(o.target,i.attr("up-modal"),"body"),h=s.option(o.width,i.attr("up-width"),e.width),p=s.option(o.height,i.attr("up-height"),e.height),a=s.option(o.animation,i.attr("up-animation"),e.openAnimation),m=s.option(o.sticky,i.is("[up-sticky]")),l=up.browser.canPushState()?s.option(o.history,i.attr("up-history"),!0):!1,n(),u=r(f,h,p,m),up.replace(f,d,{history:l,insert:function(){return c(u,a)}})},u=function(){var t;return t=$(".up-modal"),t.is(".up-destroying")?void 0:t.find("[up-source]").attr("up-source")},n=function(t){var n;return n=$(".up-modal"),n.length?(t=s.options(t,{animation:e.closeAnimation,url:n.attr("up-previous-url"),title:n.attr("up-previous-title")}),up.destroy(n,t)):void 0},t=function(){return $(".up-modal").is("[up-sticky]")?void 0:n()},up.on("click","a[up-modal]",function(t,e){return t.preventDefault(),e.is(".up-current")?n():i(e)}),up.on("click","body",function(t){var e;return e=$(t.target),e.closest(".up-modal-dialog").length||e.closest("[up-modal]").length?void 0:n()}),up.bus.on("fragment:ready",function(n){return n.closest(".up-modal").length?void 0:(console.log("fragment inserted",n,n.closest(".up-modal")),t())}),up.magic.onEscape(function(){return n()}),up.on("click","[up-close]",function(t,e){return e.closest(".up-modal")?n():void 0}),up.bus.on("framework:reset",n),{open:i,close:n,source:u,defaults:o}}()}.call(this),function(){up.tooltip=function(){var t,n,e,r,o;return o=up.util,r=function(t,n,e){var r,i,u;return i=o.measure(t),u=o.measure(n),r=function(){switch(e){case"top":return{left:i.left+.5*(i.width-u.width),top:i.top-u.height};case"bottom":return{left:i.left+.5*(i.width-u.width),top:i.top+i.height};default:return o.error("Unknown origin",e)}}(),n.attr("up-origin",e),n.css(r)},n=function(t){return o.$createElementFromSelector(".up-tooltip").html(t).appendTo(document.body)},e=function(e,i){var u,a,s,c,p;return null==i&&(i={}),u=$(e),c=o.option(i.html,u.attr("up-tooltip")),p=o.option(i.origin,u.attr("up-origin"),"top"),s=o.option(i.animation,u.attr("up-animation"),"fade-in"),t(),a=n(c),r(u,a,p),up.animate(a,s,i)},t=function(t){var n;return n=$(".up-tooltip"),n.length?(t=o.options(t,{animation:"fade-out"}),up.destroy(n,t)):void 0},up.awaken("[up-tooltip]",function(n){return n.on("mouseover",function(){return e(n)}),n.on("mouseout",function(){return t()})}),up.on("click","body",function(){return t()}),up.bus.on("framework:reset",t),up.magic.onEscape(function(){return t()}),{open:e,close:t}}()}.call(this),function(){up.navigation=function(){var t,n,e,r,o,i,u,a,s,c;return s=up.util,t="up-active",n="up-current",r="a[href], a[up-target], [up-follow], [up-modal], [up-popup]",e="."+t,u=function(t){return s.isPresent(t)?s.normalizeUrl(t,{search:!1,stripTrailingSlash:!0}):void 0},i=function(){var t,e,o;return o=u(up.browser.url()),t=u(up.modal.source()),e=u(up.popup.source()),s.each($(r),function(r){var i,a;return i=$(r),a=up.link.resolveUrl(i),a=u(a),a===o||a===t||a===e?i.addClass(n):i.removeClass(n)})},a=function(n){return c(),n=o(n),n.addClass(t)},o=function(t){return s.presence(t.parents(r))||t},c=function(){return $(e).removeClass(t)},up.on("click",r,function(t,n){return a(n)}),up.bus.on("fragment:ready",function(){return c(),i()}),up.bus.on("fragment:destroy",function(t){return t.is(".up-modal, .up-popup")?i():void 0})}()}.call(this),function(){up.marker=function(){var t,n,e;return e=up.util,n=function(t){return""!==e.trim(t.html())},t=function(t){return e.findWithSelf(t,"[up-marker]").each(function(){var t;return t=$(this),n(t)?void 0:t.hide()})},up.bus.on("fragment:ready",t)}()}.call(this),function(){up.browser.isSupported()&&(up.browser.ensureConsoleExists(),up.bus.emit("framework:ready"),$(document).on("ready",function(){return up.bus.emit("app:ready")}))}.call(this);
1
+ (function(){window.up={}}).call(this),function(){var t=[].slice;up.util=function(){var n,e,r,o,u,i,a,s,c,l,p,f,d,m,h,v,g,y,b,w,k,C,S,x,T,E,P,A,F,D,U,O,j,z,H,I,N,W,L,M,G,X,V,R,q,B,J,Z,_,Q,K,Y,tn,nn,en,rn,on,un,an;return C=function(t,n){return n=n||{},n.url=t,r(n)},r=function(t){return t.selector&&(t.headers={"X-Up-Selector":t.selector}),$.ajax(t)},N=function(t,n){return(""===n||"80"===n)&&"http:"===t||"443"===n&&"https:"===t},B=function(t,n){var e,r,o;return e=W(t)?$("<a>").attr({href:t}).get(0):an(t),r=e.protocol+"//"+e.hostname,N(e.protocol,e.port)||(r+=":"+e.port),o=e.pathname,(null!=n?n.stripTrailingSlash:void 0)===!0&&(o=o.replace(/\/$/,"")),r+=o,(null!=n?n.hash:void 0)===!0&&(r+=e.hash),(null!=n?n.search:void 0)!==!1&&(r+=e.search),r},n=function(t){var n,e,r,o,u,i,a,s,c,l,p,f,d,m,h,v;for(p=t.split(/[ >]/),r=null,l=d=0,h=p.length;h>d;l=++d){for(i=p[l],u=i.match(/(^|\.|\#)[A-Za-z0-9\-_]+/g),f="div",o=[],c=null,m=0,v=u.length;v>m;m++)switch(a=u[m],a[0]){case".":o.push(a.substr(1));break;case"#":c=a.substr(1);break;default:f=a}s="<"+f,o.length&&(s+=' class="'+o.join(" ")+'"'),c&&(s+=' id="'+c+'"'),s+=">",n=$(s),e&&n.appendTo(e),0===l&&(r=n),e=n}return r},l=function(t,n){var e;return e=document.createElement(t),H(n)&&(e.innerHTML=n),e},v=function(){var n,e;throw n=1<=arguments.length?t.call(arguments,0):[],console.log.apply(console,["[UP] Error"].concat(t.call(n))),e=1===n.length&&up.util.isString(n[0])?n[0]:JSON.stringify(n),alert(e),e},f=function(t){var n,e,r,o,u,i,a;for(console.log("Creating selector from element",t),e=(n=t.attr("class"))?n.split(" "):[],r=t.attr("id"),u=t.prop("tagName").toLowerCase(),r&&(u+="#"+r),i=0,a=e.length;a>i;i++)o=e[i],u+="."+o;return u},p=function(t){var n,e,r,o,u,i,a,s,c,p,f,d;return c=function(t){return"<"+t+"(?: [^>]*)?>"},i=function(t){return"</"+t+">"},n="(?:.|\\n)*?",u=function(t){return"("+t+")"},d=new RegExp(c("head")+n+c("title")+u(n)+i("title")+n+i("body"),"i"),o=new RegExp(c("body")+u(n)+i("body"),"i"),(r=t.match(o))?(s=document.createElement("html"),e=l("body",r[1]),s.appendChild(e),(f=t.match(d))&&(a=l("head"),s.appendChild(a),p=l("title",f[1]),a.appendChild(p)),s):l("div",t)},y=$.extend,un=$.trim,M=Object.keys||function(t){var n,e,r,o;for(e=[],r=0,o=t.length;o>r;r++)n=t[r],t.hasOwnProperty(n)&&e.push(n);return e},h=function(t,n){var e,r,o,u,i;for(i=[],e=o=0,u=t.length;u>o;e=++o)r=t[e],i.push(n(r,e));return i},j=function(t){return null===t},L=function(t){return void 0===t},P=function(t){return!L(t)},O=function(t){return L(t)||j(t)},F=function(t){return!O(t)},T=function(t){return O(t)||z(t)&&0===M(t).length||0===t.length},K=function(t,n){return null==n&&(n=H),n(t)?t:null},H=function(t){return!T(t)},A=function(t){return"function"==typeof t},W=function(t){return"string"==typeof t},D=function(t){return"object"==typeof t&&!!t},z=function(t){return D(t)||"function"==typeof t},U=function(t){return t instanceof jQuery},I=function(t){return z(t)&&A(t.then)},E=function(t){return I(t)&&A(t.resolve)},S=function(t){return F(t)?t:void 0},x=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},s=function(t){return x(t)?t.slice():y({},t)},an=function(t){return U(t)?t.get(0):t},R=function(t,n){return y(s(t),n)},_=function(t,n){var e,r,o,u;if(o=t?s(t):{},n)for(r in n)e=n[r],u=o[r],F(u)?z(e)&&z(u)&&(o[r]=_(u,e)):o[r]=e;return o},Z=function(){var n,e,r,o,u,i;for(e=1<=arguments.length?t.call(arguments,0):[],r=null,u=0,i=e.length;i>u;u++)if(n=e[u],o=n,A(o)&&(o=o()),H(o)){r=o;break}return r},m=function(t,n){var e,r,o,u;for(r=null,o=0,u=t.length;u>o;o++)if(e=t[o],n(e)){r=e;break}return r},rn=function(t,n){var e;return e=[],h(t,function(t){return n(t)?e.push(t):void 0}),e},Y=function(){var n,e,r,o;return n=arguments[0],r=2<=arguments.length?t.call(arguments,1):[],o=function(){var t,o,u;for(u=[],t=0,o=r.length;o>t;t++)e=r[t],u.push(n.attr(e));return u}(),m(o,H)},q=function(t){return setTimeout(t,0)},G=function(t){return t[t.length-1]},i=function(){var t;return t=document.documentElement,{width:t.clientWidth,height:t.clientHeight}},on=function(t,n,e){var r,o;return o=t.css(M(n)),t.css(n),r=function(){return t.css(o)},e?(e(),r()):r},k=function(t){var n,e;return e=t.css(["transform","-webkit-transform"]),T(e)?(n=function(){return t.css(e)},t.css({transform:"translateZ(0)","-webkit-transform":"translateZ(0)"})):n=function(){},n},d=function(t,n,r){var o,u,i,a,s,c;return o=$(t),up.browser.canCssAnimation()?(r=_(r,{duration:300,delay:0,easing:"ease"}),u=$.Deferred(),a={"transition-property":M(n).join(", "),"transition-duration":r.duration+"ms","transition-delay":r.delay+"ms","transition-timing-function":r.easing},s=k(o),c=on(o,a),o.css(n),u.then(s),u.then(c),o.data(e,u),u.then(function(){return o.removeData(e)}),i=setTimeout(function(){return u.resolve()},r.duration+r.delay),u.then(function(){return clearTimeout(i)}),u):(o.css(n),en())},e="up-animation-promise",w=function(t){return $(t).each(function(){var t;return(t=$(this).data(e))?t.resolve():void 0})},V=function(t,n){var e,r,o;return r=(null!=n?n.relative:void 0)?t.position():t.offset(),e={left:r.left,top:r.top},(null!=n?n.inner:void 0)?(e.width=t.width(),e.height=t.height()):(e.width=t.outerWidth(),e.height=t.outerHeight()),(null!=n?n.full:void 0)&&(o=i(),e.right=o.width-(e.left+e.width),e.bottom=o.height-(e.top+e.height)),e},c=function(t,n){var e,r,o,u,i;for(u=t.get(0).attributes,i=[],r=0,o=u.length;o>r;r++)e=u[r],i.push(e.specified?n.attr(e.name,e.value):void 0);return i},Q=function(t){var n,e;return e=V(t,{relative:!0,inner:!0}),n=t.clone(),n.find("script").remove(),n.css({right:"",bottom:"",position:"absolute"}),n.css(e),n.addClass("up-ghost"),n.insertBefore(t)},b=function(t,n){return t.find(n).addBack(n)},g=function(t){return 27===t.keyCode},a=function(t,n){return t.indexOf(n)>=0},u=function(t){return"true"===String(t)},o=function(t){return"false"===String(t)},X=function(t){return t.getResponseHeader("X-Up-Current-Location")},J=function(){var n,e,r,o,u,i;for(o=arguments[0],r=2<=arguments.length?t.call(arguments,1):[],n={},u=0,i=r.length;i>u;u++)e=r[u],o.hasOwnProperty(e)&&(n[e]=o[e]);return n},nn=function(){var t;return t=$.Deferred(),t.resolve(),t},en=function(){return nn().promise()},tn=function(){var n,e;return n=1<=arguments.length?t.call(arguments,0):[],e=$.when.apply($,n),e.resolve=function(){return h(n,function(t){return"function"==typeof t.resolve?t.resolve():void 0})},e},{presentAttr:Y,createElement:l,normalizeUrl:B,createElementFromHtml:p,$createElementFromSelector:n,createSelectorFromElement:f,get:C,ajax:r,extend:y,copy:s,merge:R,options:_,option:Z,error:v,each:h,detect:m,select:rn,last:G,isNull:j,isDefined:P,isUndefined:L,isGiven:F,isMissing:O,isPresent:H,isBlank:T,presence:K,isObject:z,isFunction:A,isString:W,isJQuery:U,isPromise:I,isDeferred:E,isHash:D,ifGiven:S,unwrap:an,nextFrame:q,measure:V,temporaryCss:on,cssAnimate:d,finishCssAnimate:w,forceCompositing:k,prependGhost:Q,escapePressed:g,copyAttributes:c,findWithSelf:b,contains:a,isArray:x,castsToTrue:u,castsToFalse:o,locationFromXhr:X,clientSize:i,only:J,trim:un,keys:M,resolvedPromise:en,resolvedDeferred:nn,resolvableWhen:tn}}()}.call(this),function(){var t=[].slice;up.browser=function(){var n,e,r,o,u,i,a,s,c;return s=up.util,i=function(t,n){var e,r,o,u,i,a;return null==n&&(n={}),i=s.option(n.method,"get").toLowerCase(),"get"===i?location.href=t:$.rails?(a=n.target,o=$.rails.csrfToken(),r=$.rails.csrfParam(),e=$("<form method='post' action='"+t+"'></form>"),u="<input name='_method' value='"+i+"' type='hidden' />",s.isDefined(r)&&s.isDefined(o)&&(u+="<input name='"+r+"' value='"+o+"' type='hidden' />"),a&&e.attr("target",a),e.hide().append(u).appendTo("body"),e.submit()):error("Can't fake a "+i.toUpperCase()+" request without Rails UJS")},c=function(){return location.href},o=function(){var t;return window.console||(window.console={}),(t=window.console).log||(t.log=function(){})},a=function(n){var e,r;return e=void 0,r=!1,function(){var o;return o=1<=arguments.length?t.call(arguments,0):[],r?e:(r=!0,e=n.apply(null,o))}},r=a(function(){return s.isDefined(history.pushState)}),n=a(function(){return"transition"in document.documentElement.style}),e=a(function(){return"oninput"in document.createElement("input")}),u=a(function(){return s.isDefined(document.addEventListener)}),{url:c,ensureConsoleExists:o,loadPage:i,canPushState:r,canCssAnimation:n,canInputEvent:e,isSupported:u}}()}.call(this),function(){var t=[].slice;up.bus=function(){var n,e,r,o,u,i,a;return n={},r={},e=function(t){return n[t]||(n[t]=[])},a=function(){var t,e,o;r={},o=[];for(e in n)t=n[e],o.push(r[e]=up.util.copy(t));return o},i=function(){return n=up.util.copy(r)},u=function(t,n){return e(t).push(n)},o=function(){var n,r,o;return o=arguments[0],n=2<=arguments.length?t.call(arguments,1):[],console.log("bus emitting",o,n),r=e(o),up.util.each(r,function(t){return t.apply(null,n)})},u("framework:ready",a),u("framework:reset",i),{on:u,emit:o}}()}.call(this),function(){up.flow=function(){var t,n,e,r,o,u,i,a,s,c,l,p;return p=up.util,s=function(t,n){var e;return e=$(t),p.isPresent(n)&&(n=p.normalizeUrl(n)),e.attr("up-source",n)},c=function(t){var n;return n=$(t).closest("[up-source]"),p.presence(n.attr("up-source"))||up.browser.url()},i=function(t,n,e){var o;return e=p.options(e),o=p.presence(t)?t:p.createSelectorFromElement($(t)),up.browser.canPushState()||p.castsToFalse(e.history)?p.ajax({url:n,selector:o},p.only(e,"method")).done(function(t,u,i){var a;return(a=p.locationFromXhr(i))&&(n=a),(p.isMissing(e.history)||p.castsToTrue(e.history))&&(e.history=n),(p.isMissing(e.source)||p.castsToTrue(e.source))&&(e.source=n),r(o,t,e)}).fail(p.error):void up.browser.loadPage(n,p.only(e,"method"))},r=function(t,n,e){var r,u,i,a,s,c,f,d,m,h;for(e=p.options(e,{historyMethod:"push"}),"false"===e.history&&(e.history=null),e.source=p.option(e.source,e.history),a=p.createElementFromHtml(n),e.title||(e.title=null!=(d=a.querySelector("title"))?d.textContent:void 0),m=o(t,e),h=[],c=0,f=m.length;f>c;c++)s=m[c],up.motion.finish(s.selector),u=p.presence($(".up-popup "+s.selector))||p.presence($(".up-modal "+s.selector))||p.presence($(s.selector))||p.error("Could not find selector ("+s.selector+") in current body HTML"),(i=a.querySelector(s.selector))?(r=$(i),h.push(l(u,r,s.pseudoClass,s.transition,e))):h.push(p.error("Could not find selector ("+s.selector+") in response ("+n+")"));return h},e=function(n,e){return"function"==typeof e.insert&&e.insert(n),e.history&&(e.title&&(document.title=e.title),up.history[e.historyMethod](e.history)),s(n,e.source),t(n),up.ready(n)},l=function(t,r,o,u,i){var a,s;return u||(u="none"),o?(s="before"===o?"prepend":"append",a=r.children(),t[s](r.contents()),p.copyAttributes(r,t),e(a,i),up.animate(r,u)):n(t,{animation:function(){return r.insertAfter(t),e(r,i),t.is("body")&&"none"!==u&&p.error("Cannot apply transitions to body-elements",u),up.morph(t,r,u)}})},o=function(t,n){var e,r,o,u,i,a,s,c,l,f,d;for(s=n.transition||n.animation||"none",e=/\ *,\ */,r=t.split(e),p.isPresent(s)&&(c=s.split(e)),d=[],o=l=0,f=r.length;f>l;o=++l)u=r[o],i=u.match(/^(.+?)(?:\:(before|after))?$/),a=c[o]||p.last(c),d.push({selector:i[1],pseudoClass:i[2],transition:a});return d},t=function(t){var n,e;return e="[autofocus]:last",n=p.findWithSelf(t,e),n.length&&n.get(0)!==document.activeElement?n.focus():void 0},n=function(t,n){var e,r;return e=$(t),n=p.options(n,{animation:"none"}),e.addClass("up-destroying"),p.isPresent(n.url)&&up.history.push(n.url),p.isPresent(n.title)&&(document.title=n.title),up.bus.emit("fragment:destroy",e),r=p.presence(n.animation,p.isPromise)||up.motion.animate(e,n.animation),r.then(function(){return e.remove()})},u=function(t){var n;return n=c(t),i(t,n)},a=function(){return up.bus.emit("framework:reset")},up.bus.on("app:ready",function(){return s(document.body,up.browser.url())}),{replace:i,reload:u,destroy:n,implant:r,reset:a}}(),up.replace=up.flow.replace,up.reload=up.flow.reload,up.destroy=up.flow.destroy,up.reset=up.flow.reset}.call(this),function(){var t=[].slice;up.magic=function(){var n,e,r,o,u,i,a,s,c,l,p,f,d,m,h,v;return v=up.util,n="up-destroyable",e="up-destroyer",p=[],s=null,l=function(t,n,e){var r,o;if(up.browser.isSupported())return r=[t,n,function(t){return e.apply(this,[t,$(this)])}],p.push(r),(o=$(document)).on.apply(o,r)},u=[],a=null,o=function(){var n,e,r,o;return o=arguments[0],n=2<=arguments.length?t.call(arguments,1):[],up.browser.isSupported()?(e=n.pop(),r=v.options(n[0],{batch:!1}),u.push({selector:o,callback:e,batch:r.batch})):void 0},r=function(t,r,o){var u;return u=t.callback.apply(o,[r]),v.isFunction(u)?(r.addClass(n),r.data(e,u)):void 0},i=function(t){var n,e,o,i,a;for(console.log("Compiling fragment",t),a=[],o=0,i=u.length;i>o;o++)e=u[o],n=v.findWithSelf(t,e.selector),a.push(n.length?e.batch?r(e,n,n.get()):n.each(function(){return r(e,$(this),this)}):void 0);return a},c=function(t){return v.findWithSelf(t,"."+n).each(function(){var t,n;return t=$(this),(n=t.data(e))()})},h=function(){return s=v.copy(p),a=v.copy(u)},m=function(){var t,n,e,r;for(n=0,e=p.length;e>n;n++)t=p[n],v.contains(s,t)||(r=$(document)).off.apply(r,t);return p=v.copy(s),u=v.copy(a)},d=function(t){var n;return n=$(t),up.bus.emit("fragment:ready",n),n},f=function(t){return l("keydown","body",function(n){return v.escapePressed(n)?t(n):void 0})},up.bus.on("app:ready",function(){return d(document.body)}),up.bus.on("fragment:ready",i),up.bus.on("fragment:destroy",c),up.bus.on("framework:ready",h),up.bus.on("framework:reset",m),{awaken:o,on:l,ready:d,onEscape:f}}(),up.awaken=up.magic.awaken,up.on=up.magic.on,up.ready=up.magic.ready}.call(this),function(){up.history=function(){var t,n,e,r,o,u;return u=up.util,t=function(t){return u.normalizeUrl(t,{hash:!0})===u.normalizeUrl(up.browser.url(),{hash:!0})},o=function(e,r){return r=u.options(r,{force:!1}),r.force||!t(e)?n("replace",e):void 0},r=function(e){return t(e)?void 0:n("push",e)},n=function(t,n){return up.browser.canPushState()?(t+="State",window.history[t]({fromUp:!0},"",n)):u.error("This browser doesn't support history.pushState")},e=function(t){var n;return n=t.originalEvent.state,console.log("popping state",n),console.log("current href",up.browser.url()),(null!=n?n.fromUp:void 0)?up.visit(up.browser.url(),{historyMethod:"replace"}):console.log("strange state",n)},up.browser.canPushState()&&setTimeout(function(){return $(window).on("popstate",e),o(up.browser.url(),{force:!0})},200),{push:r,replace:o}}()}.call(this),function(){up.motion=function(){var t,n,e,r,o,u,i,a,s,c,l,p,f,d,m,h,v,g,y,b,w;return b=up.util,u={duration:300,delay:0,easing:"ease"},r={},i={},y={},a={},s=function(t){return b.extend(u,t)},n=function(t,e,r){var i;return i=$(t),l(i),r=b.options(r,u),b.isFunction(e)?o(e(i,r),e):b.isString(e)?n(i,c(e),r):b.isHash(e)?b.cssAnimate(i,e,r):b.error("Unknown animation type",e)},c=function(t){return r[t]||b.error("Unknown animation",e)},t="up-ghosting-promise",w=function(n,e,r){var o,u,i,a;return u=null,o=null,b.temporaryCss(e,{display:"none"},function(){return u=b.prependGhost(n).addClass("up-destroying")}),b.temporaryCss(n,{display:"none"},function(){return o=b.prependGhost(e)}),n.css({visibility:"hidden"}),i=b.temporaryCss(e,{display:"none"}),a=r(u,o),n.data(t,a),e.data(t,a),a.then(function(){return n.removeData(t),e.removeData(t),u.remove(),o.remove(),n.css({display:"none"}),i()}),a},l=function(t){return $(t).each(function(){var t;return t=$(this),b.finishCssAnimate(t),p(t)})},p=function(n){var e;return(e=n.data(t))?(console.log("EXISTING",e),"function"==typeof e.resolve?e.resolve():void 0):void 0},o=function(t,n){return b.isDeferred(t)?t:b.error("Did not return a promise with .then and .resolve methods: ",n)},f=function(t,e,i,a){var s,c,p,d,m;return up.browser.canCssAnimation()?(a=b.options(u),c=$(t),s=$(e),l(c),l(s),m=b.presence(i,b.isFunction)||y[i],m?w(c,s,function(t,n){return o(m(t,n,a),i)}):(p=r[i])?(c.hide(),n(s,p,a)):b.isString(i)&&i.indexOf("/")>=0?(d=i.split("/"),m=function(t,e,r){return h(n(t,d[0],r),n(e,d[1],r))},f(c,s,m,a)):b.error("Unknown transition: "+i)):b.resolvedDeferred()},g=function(t,n){return y[t]=n},e=function(t,n){return r[t]=n},v=function(){return i=b.copy(r),a=b.copy(y)},m=function(){return r=b.copy(i),y=b.copy(a)},h=b.resolvableWhen,d=b.resolvedDeferred,e("none",d),e("fade-in",function(t,e){return t.css({opacity:0}),n(t,{opacity:1},e)}),e("fade-out",function(t,e){return t.css({opacity:1}),n(t,{opacity:0},e)}),e("move-to-top",function(t,e){var r,o;return r=b.measure(t),o=r.top+r.height,t.css({"margin-top":"0px"}),n(t,{"margin-top":"-"+o+"px"},e)}),e("move-from-top",function(t,e){var r,o;return r=b.measure(t),o=r.top+r.height,t.css({"margin-top":"-"+o+"px"}),n(t,{"margin-top":"0px"},e)}),e("move-to-bottom",function(t,e){var r,o;return r=b.measure(t),o=b.clientSize().height-r.top,t.css({"margin-top":"0px"}),n(t,{"margin-top":o+"px"},e)}),e("move-from-bottom",function(t,e){var r,o;return r=b.measure(t),o=b.clientSize().height-r.top,t.css({"margin-top":o+"px"}),n(t,{"margin-top":"0px"},e)}),e("move-to-left",function(t,e){var r,o;return r=b.measure(t),o=r.left+r.width,t.css({"margin-left":"0px"}),n(t,{"margin-left":"-"+o+"px"},e)}),e("move-from-left",function(t,e){var r,o;return r=b.measure(t),o=r.left+r.width,t.css({"margin-left":"-"+o+"px"}),n(t,{"margin-left":"0px"},e)}),e("move-to-right",function(t,e){var r,o;return r=b.measure(t),o=b.clientSize().width-r.left,t.css({"margin-left":"0px"}),n(t,{"margin-left":o+"px"},e)}),e("move-from-right",function(t,e){var r,o;return r=b.measure(t),o=b.clientSize().width-r.left,t.css({"margin-left":o+"px"}),n(t,{"margin-left":"0px"},e)}),e("roll-down",function(t,e){var r,o;return r=t.height(),o=b.temporaryCss(t,{height:"0px",overflow:"hidden"}),n(t,{height:r+"px"},e).then(o)}),g("none",d),g("move-left",function(t,e,r){return h(n(t,"move-to-left",r),n(e,"move-from-right",r))}),g("move-right",function(t,e,r){return h(n(t,"move-to-right",r),n(e,"move-from-left",r))}),g("move-up",function(t,e,r){return h(n(t,"move-to-top",r),n(e,"move-from-bottom",r))}),g("move-down",function(t,e,r){return h(n(t,"move-to-bottom",r),n(e,"move-from-top",r))}),g("cross-fade",function(t,e,r){return h(n(t,"fade-out",r),n(e,"fade-in",r))}),up.bus.on("framework:ready",v),up.bus.on("framework:reset",m),{morph:f,animate:n,finish:l,transition:g,animation:e,defaults:s,none:d,when:h}}(),up.transition=up.motion.transition,up.animation=up.motion.animation,up.morph=up.motion.morph,up.animate=up.motion.animate}.call(this),function(){up.link=function(){var t,n,e,r,o;return r=up.util,o=function(t,n){return console.log("up.visit",t),up.replace("body",t,n)},t=function(t,n){var e,o,u;return e=$(t),n=r.options(n),u=r.option(e.attr("href"),e.attr("up-follow")),o=r.option(n.target,e.attr("up-target"),"body"),n.transition=r.option(n.transition,e.attr("up-transition"),e.attr("up-animation")),n.history=r.option(n.history,e.attr("up-history")),up.replace(o,u,n)},n=function(t){var n;return n=$(t),n.is("a")||r.presentAttr(n,"up-follow")?n:n.find("a:first")},e=function(t){var e;return(e=n(t))?r.option(e.attr("href"),e.attr("up-follow")):void 0},up.on("click","a[up-target]",function(n,e){return n.preventDefault(),t(e)}),up.on("click","[up-follow]",function(e,r){var o;return o=function(){var t,n;return t=$(e.target),n=t.closest("a, [up-follow]"),n.length&&r.find(n).length},o()?void 0:(e.preventDefault(),t(n(r)))}),{visit:o,follow:t,resolve:n,resolveUrl:e}}(),up.visit=up.link.visit,up.follow=up.link.follow}.call(this),function(){up.form=function(){var observe,submit,u;return u=up.util,submit=function(t,n){var e,r,o,i,a,s,c,l,p,f;return e=$(t).closest("form"),n=u.options(n),c=u.option(n.target,e.attr("up-target"),"body"),r=u.option(n.failTarget,e.attr("up-fail-target"),function(){return u.createSelectorFromElement(e)}),i=u.option(n.history,e.attr("up-history"),!0),l=u.option(n.transition,e.attr("up-transition")),o=u.option(n.failTransition,e.attr("up-fail-transition")),a=u.option(n.method,e.attr("up-method"),e.attr("data-method"),e.attr("method"),"post").toUpperCase(),f=u.option(n.url,e.attr("action"),up.browser.url()),e.addClass("up-active"),up.browser.canPushState()||u.castsToFalse(i)?(s={url:f,type:a,data:e.serialize(),selector:c},p=function(t){var n;return f=i?"false"===i?!1:u.isString(i)?i:(n=u.locationFromXhr(t))?n:"GET"===s.type?s.url+"?"+s.data:void 0:void 0,u.option(f,!1)},u.ajax(s).always(function(){return e.removeClass("up-active")}).done(function(t,n,e){return up.flow.implant(c,t,{history:p(e),transition:l})}).fail(function(t){var n;return n=t.responseText,up.flow.implant(r,n,{transition:o})})):void e.get(0).submit()},observe=function(fieldOrSelector,options){var $field,callback,callbackPromise,callbackTimer,changeEvents,check,clearTimer,codeOnChange,delay,knownValue,nextCallback,runNextCallback;return $field=$(fieldOrSelector),options=u.options(options),delay=u.option($field.attr("up-delay"),options.delay,0),delay=parseInt(delay),knownValue=null,callback=null,callbackTimer=null,(codeOnChange=$field.attr("up-observe"))?callback=function(value,$field){return eval(codeOnChange)}:options.change?callback=options.change:u.error("observe: No change callback given"),callbackPromise=u.resolvedPromise(),nextCallback=null,runNextCallback=function(){var t;return nextCallback?(t=nextCallback(),nextCallback=null,t):void 0},check=function(){var t,n;return n=$field.val(),t=_.isNull(knownValue),knownValue===n||(knownValue=n,t)?void 0:(clearTimer(),nextCallback=function(){return callback.apply($field.get(0),[n,$field])},callbackTimer=setTimeout(function(){return callbackPromise.then(function(){var t;return t=runNextCallback(),callbackPromise=u.isPromise(t)?t:u.resolvedPromise()})},delay))},clearTimer=function(){return clearTimeout(callbackTimer)},changeEvents=up.browser.canInputEvent()?"input":"keypress paste cut change click propertychange",$field.on(changeEvents,check),check(),clearTimer},up.on("submit","form[up-target]",function(t,n){return t.preventDefault(),submit(n)}),up.awaken("[up-observe]",function(t){return observe(t)}),{submit:submit,observe:observe}}(),up.submit=up.form.submit,up.observe=up.form.observe}.call(this),function(){up.popup=function(){var t,n,e,r,o,u,i,a,s,c,l;return c=up.util,e={openAnimation:"fade-in",closeAnimation:"fade-out",origin:"bottom-right"},o=function(t){return c.extend(e,t)},a=function(t,n,e){var r,o;return o=c.measure(t,{full:!0}),r=function(){switch(e){case"bottom-right":return{right:o.right,top:o.top+o.height};case"bottom-left":return{left:o.left,top:o.bottom+o.height};case"top-right":return{right:o.right,bottom:o.top};case"top-left":return{left:o.left,bottom:o.top};default:return c.error("Unknown origin",e)}}(),n.attr("up-origin",e),n.css(r),u(n)},u=function(t){var n,e,r,o,u,i,a;if(e=c.measure(t,{full:!0}),r=null,o=null,e.right<0&&(r=-e.right),e.bottom<0&&(o=-e.bottom),e.left<0&&(r=e.left),e.top<0&&(o=e.top),r&&((u=parseInt(t.css("left")))?t.css("left",u-r):(i=parseInt(t.css("right")))&&t.css("right",i+r)),o){if(a=parseInt(t.css("top")))return t.css("top",a-o);if(n=parseInt(t.css("bottom")))return t.css("bottom",n+o)}},r=function(t,n,e){var r,o;return o=c.$createElementFromSelector(".up-popup"),e&&o.attr("up-sticky",""),o.attr("up-previous-url",up.browser.url()),o.attr("up-previous-title",document.title),r=c.$createElementFromSelector(n),r.appendTo(o),o.appendTo(document.body),o.hide(),o},l=function(t,n,e,r){return n.show(),a(t,n,e),up.animate(n,r)},i=function(t,o){var u,i,a,s,p,f,d,m;return u=$(t),o=c.options(o),m=c.option(u.attr("href")),f=c.option(o.target,u.attr("up-popup"),"body"),p=c.option(o.origin,u.attr("up-origin"),e.origin),a=c.option(o.animation,u.attr("up-animation"),e.openAnimation),d=c.option(o.sticky,u.is("[up-sticky]")),s=up.browser.canPushState()?c.option(o.history,u.attr("up-history"),!1):!1,n(),i=r(u,f,d),up.replace(f,m,{history:s,insert:function(){return l(u,i,p,a)}})},s=function(){var t;return t=$(".up-popup"),t.is(".up-destroying")?void 0:t.find("[up-source]").attr("up-source")},n=function(t){var n;return n=$(".up-popup"),n.length?(t=c.options(t,{animation:e.closeAnimation,url:n.attr("up-previous-url"),title:n.attr("up-previous-title")}),up.destroy(n,t)):void 0},t=function(){return $(".up-popup").is("[up-sticky]")?void 0:n()},up.on("click","a[up-popup]",function(t,e){return t.preventDefault(),e.is(".up-current")?n():i(e)}),up.on("click","body",function(t){var e;return e=$(t.target),e.closest(".up-popup").length||e.closest("[up-popup]").length?void 0:n()}),up.bus.on("fragment:ready",function(n){return n.closest(".up-popup").length?void 0:t()}),up.magic.onEscape(function(){return n()}),up.on("click","[up-close]",function(t,e){return e.closest(".up-popup")?n():void 0}),up.bus.on("framework:reset",n),{open:i,close:n,source:s,defaults:o}}()}.call(this),function(){up.modal=function(){var t,n,e,r,o,u,i,a,s,c;return s=up.util,e={width:"auto",height:"auto",openAnimation:"fade-in",closeAnimation:"fade-out",closeLabel:"X",template:function(t){return'<div class="up-modal">\n <div class="up-modal-dialog">\n <div class="up-modal-close" up-close>'+t.closeLabel+'</div>\n <div class="up-modal-content"></div>\n </div>\n</div>'}},o=function(t){return s.extend(e,t)},a=function(){var t;return t=e.template,s.isFunction(t)?t(e):t},r=function(t,n,e,r){var o,u,i,c;return i=$(a()),r&&i.attr("up-sticky",""),i.attr("up-previous-url",up.browser.url()),i.attr("up-previous-title",document.title),u=i.find(".up-modal-dialog"),s.isPresent(n)&&u.css("width",n),s.isPresent(e)&&u.css("height",e),o=u.find(".up-modal-content"),c=s.$createElementFromSelector(t),c.appendTo(o),i.appendTo(document.body),i.hide(),i},c=function(t,n){return t.show(),up.animate(t,n)},u=function(t,o){var u,i,a,l,p,f,d,m,h;return u=$(t),o=s.options(o),m=s.option(u.attr("href")),f=s.option(o.target,u.attr("up-modal"),"body"),h=s.option(o.width,u.attr("up-width"),e.width),l=s.option(o.height,u.attr("up-height"),e.height),a=s.option(o.animation,u.attr("up-animation"),e.openAnimation),d=s.option(o.sticky,u.is("[up-sticky]")),p=up.browser.canPushState()?s.option(o.history,u.attr("up-history"),!0):!1,n(),i=r(f,h,l,d),up.replace(f,m,{history:p,insert:function(){return c(i,a)}})},i=function(){var t;return t=$(".up-modal"),t.is(".up-destroying")?void 0:t.find("[up-source]").attr("up-source")},n=function(t){var n;return n=$(".up-modal"),n.length?(t=s.options(t,{animation:e.closeAnimation,url:n.attr("up-previous-url"),title:n.attr("up-previous-title")}),up.destroy(n,t)):void 0},t=function(){return $(".up-modal").is("[up-sticky]")?void 0:n()},up.on("click","a[up-modal]",function(t,e){return t.preventDefault(),e.is(".up-current")?n():u(e)}),up.on("click","body",function(t){var e;return e=$(t.target),e.closest(".up-modal-dialog").length||e.closest("[up-modal]").length?void 0:n()}),up.bus.on("fragment:ready",function(n){return n.closest(".up-modal").length?void 0:(console.log("fragment inserted",n,n.closest(".up-modal")),t())}),up.magic.onEscape(function(){return n()}),up.on("click","[up-close]",function(t,e){return e.closest(".up-modal")?n():void 0}),up.bus.on("framework:reset",n),{open:u,close:n,source:i,defaults:o}}()}.call(this),function(){up.tooltip=function(){var t,n,e,r,o;return o=up.util,r=function(t,n,e){var r,u,i;return u=o.measure(t),i=o.measure(n),r=function(){switch(e){case"top":return{left:u.left+.5*(u.width-i.width),top:u.top-i.height};case"bottom":return{left:u.left+.5*(u.width-i.width),top:u.top+u.height};default:return o.error("Unknown origin",e)}}(),n.attr("up-origin",e),n.css(r)},n=function(t){return o.$createElementFromSelector(".up-tooltip").html(t).appendTo(document.body)},e=function(e,u){var i,a,s,c,l;return null==u&&(u={}),i=$(e),c=o.option(u.html,i.attr("up-tooltip")),l=o.option(u.origin,i.attr("up-origin"),"top"),s=o.option(u.animation,i.attr("up-animation"),"fade-in"),t(),a=n(c),r(i,a,l),up.animate(a,s,u)},t=function(t){var n;return n=$(".up-tooltip"),n.length?(t=o.options(t,{animation:"fade-out"}),up.destroy(n,t)):void 0},up.awaken("[up-tooltip]",function(n){return n.on("mouseover",function(){return e(n)}),n.on("mouseout",function(){return t()})}),up.on("click","body",function(){return t()}),up.bus.on("framework:reset",t),up.magic.onEscape(function(){return t()}),{open:e,close:t}}()}.call(this),function(){up.navigation=function(){var t,n,e,r,o,u,i,a,s,c;return s=up.util,t="up-active",n="up-current",r="a[href], a[up-target], [up-follow], [up-modal], [up-popup]",e="."+t,i=function(t){return s.isPresent(t)?s.normalizeUrl(t,{search:!1,stripTrailingSlash:!0}):void 0},u=function(){var t,e,o;return o=i(up.browser.url()),t=i(up.modal.source()),e=i(up.popup.source()),s.each($(r),function(r){var u,a;return u=$(r),a=up.link.resolveUrl(u),a=i(a),a===o||a===t||a===e?u.addClass(n):u.removeClass(n)})},a=function(n){return c(),n=o(n),n.addClass(t)},o=function(t){return s.presence(t.parents(r))||t},c=function(){return $(e).removeClass(t)},up.on("click",r,function(t,n){return a(n)}),up.bus.on("fragment:ready",function(){return c(),u()}),up.bus.on("fragment:destroy",function(t){return t.is(".up-modal, .up-popup")?u():void 0})}()}.call(this),function(){up.marker=function(){var t,n,e;return e=up.util,n=function(t){return""!==e.trim(t.html())},t=function(t){return e.findWithSelf(t,"[up-marker]").each(function(){var t;return t=$(this),n(t)?void 0:t.hide()})},up.bus.on("fragment:ready",t)}()}.call(this),function(){up.browser.isSupported()&&(up.browser.ensureConsoleExists(),up.bus.emit("framework:ready"),$(document).on("ready",function(){return up.bus.emit("app:ready")}))}.call(this);
@@ -66,6 +66,9 @@ up.browser = (->
66
66
 
67
67
  canCssAnimation = memoize ->
68
68
  'transition' of document.documentElement.style
69
+
70
+ canInputEvent = memoize ->
71
+ 'oninput' of document.createElement('input')
69
72
 
70
73
  isSupported = memoize ->
71
74
  # This is the most concise way to exclude IE8 and lower
@@ -77,6 +80,7 @@ up.browser = (->
77
80
  loadPage: loadPage
78
81
  canPushState: canPushState
79
82
  canCssAnimation: canCssAnimation
83
+ canInputEvent: canInputEvent
80
84
  isSupported: isSupported
81
85
 
82
86
  )()
@@ -113,8 +113,15 @@ up.flow = (->
113
113
 
114
114
  # TODO: extract title from HTTP header
115
115
  options.title ||= htmlElement.querySelector("title")?.textContent
116
-
116
+
117
117
  for step in implantSteps(selector, options)
118
+
119
+ # Before we select a replacement target, ensure that all transitions
120
+ # and animations have been run. Finishing a transition usually removes
121
+ # the element that is being morphed, so it will affect further selections
122
+ # using the same selector.
123
+ up.motion.finish(step.selector)
124
+
118
125
  $old =
119
126
  # always prefer to replace content in popups or modals
120
127
  u.presence($(".up-popup " + step.selector)) ||
@@ -107,8 +107,7 @@ up.form = (->
107
107
  )
108
108
 
109
109
  ###*
110
- Observes an input field by periodic polling its value.
111
- Executes code when the value changes.
110
+ Observes an input field and executes code when its value changes.
112
111
 
113
112
  up.observe('input', { change: function(value, $input) {
114
113
  up.submit($input)
@@ -125,15 +124,22 @@ up.form = (->
125
124
  If given as a function, it must take two arguments (`value`, `$field`).
126
125
  If given as a string, it will be evaled as Javascript code in a context where
127
126
  (`value`, `$field`) are set.
128
- @param {Number} [options.frequency=500]
127
+ @param {Number} [options.delay=0]
128
+ The number of miliseconds to wait before executing the callback
129
+ after the input value changes. Use this to limit how often the callback
130
+ will be invoked for a fast typist.
129
131
  ###
130
132
  observe = (fieldOrSelector, options) ->
131
133
 
132
134
  $field = $(fieldOrSelector)
133
- options = u.options(options, frequency: 500)
135
+ options = u.options(options)
136
+ delay = u.option($field.attr('up-delay'), options.delay, 0)
137
+ delay = parseInt(delay)
138
+
134
139
  knownValue = null
135
- timer = null
136
140
  callback = null
141
+ callbackTimer = null
142
+
137
143
  if codeOnChange = $field.attr('up-observe')
138
144
  callback = (value, $field) ->
139
145
  eval(codeOnChange)
@@ -142,30 +148,51 @@ up.form = (->
142
148
  else
143
149
  u.error('observe: No change callback given')
144
150
 
151
+ callbackPromise = u.resolvedPromise()
152
+
153
+ # This holds the next callback function, curried with `value` and `$field`.
154
+ # Since we're waiting for callback promises to resolve before running
155
+ # another callback, this might be overwritten while we're waiting for a
156
+ # previous callback to finish.
157
+ nextCallback = null
158
+
159
+ runNextCallback = ->
160
+ if nextCallback
161
+ returnValue = nextCallback()
162
+ nextCallback = null
163
+ returnValue
164
+
145
165
  check = ->
146
166
  value = $field.val()
147
- skipCallback = _.isNull(knownValue) # don't run the callback for the check during initialization
167
+ # don't run the callback for the check during initialization
168
+ skipCallback = _.isNull(knownValue)
148
169
  if knownValue != value
149
170
  knownValue = value
150
- callback.apply($field.get(0), [value, $field]) unless skipCallback
151
-
152
- resetTimer = ->
153
- if timer
154
- clearTimer()
155
- startTimer()
171
+ unless skipCallback
172
+ clearTimer()
173
+ nextCallback = -> callback.apply($field.get(0), [value, $field])
174
+ callbackTimer = setTimeout(
175
+ ->
176
+ # Only run the callback once the previous callback's
177
+ # promise resolves.
178
+ callbackPromise.then ->
179
+ returnValue = runNextCallback()
180
+ # If the callback returns a promise, we will remember it
181
+ # and chain additional callback invocations to it.
182
+ if u.isPromise(returnValue)
183
+ callbackPromise = returnValue
184
+ else
185
+ callbackPromise = u.resolvedPromise()
186
+ , delay
187
+ )
156
188
 
157
189
  clearTimer = ->
158
- clearInterval(timer)
159
- timer = null
160
-
161
- startTimer = ->
162
- timer = setInterval(check, options.frequency)
190
+ clearTimeout(callbackTimer)
163
191
 
164
- # reset counter after user interaction
165
- $field.bind "keyup click mousemove", resetTimer # mousemove is for selects
192
+ changeEvents = if up.browser.canInputEvent() then 'input' else 'keypress paste cut change click propertychange'
193
+ $field.on changeEvents, check
166
194
 
167
195
  check()
168
- startTimer()
169
196
 
170
197
  # return destructor
171
198
  return clearTimer
@@ -45,6 +45,9 @@ up.motion = (->
45
45
  ###*
46
46
  Animates an element.
47
47
 
48
+ If the element is already being animated, the previous animation
49
+ will instantly jump to its last frame before the new animation begins.
50
+
48
51
  The following animations are pre-registered:
49
52
 
50
53
  - `fade-in`
@@ -70,12 +73,10 @@ up.motion = (->
70
73
  ###
71
74
  animate = (elementOrSelector, animation, options) ->
72
75
  $element = $(elementOrSelector)
76
+ finish($element)
73
77
  options = u.options(options, config)
74
78
  if u.isFunction(animation)
75
- assertIsPromise(
76
- animation($element, options),
77
- ["Animation did not return a Promise", animation]
78
- )
79
+ assertIsDeferred(animation($element, options), animation)
79
80
  else if u.isString(animation)
80
81
  animate($element, findAnimation(animation), options)
81
82
  else if u.isHash(animation)
@@ -85,6 +86,8 @@ up.motion = (->
85
86
 
86
87
  findAnimation = (name) ->
87
88
  animations[name] or u.error("Unknown animation", animation)
89
+
90
+ GHOSTING_PROMISE_KEY = 'up-ghosting-promise'
88
91
 
89
92
  withGhosts = ($old, $new, block) ->
90
93
  $oldGhost = null
@@ -98,7 +101,12 @@ up.motion = (->
98
101
 
99
102
  newCssMemo = u.temporaryCss($new, display: 'none')
100
103
  promise = block($oldGhost, $newGhost)
104
+ $old.data(GHOSTING_PROMISE_KEY, promise)
105
+ $new.data(GHOSTING_PROMISE_KEY, promise)
106
+
101
107
  promise.then ->
108
+ $old.removeData(GHOSTING_PROMISE_KEY)
109
+ $new.removeData(GHOSTING_PROMISE_KEY)
102
110
  $oldGhost.remove()
103
111
  $newGhost.remove()
104
112
  # Now that the transition is over we show $new again.
@@ -106,10 +114,34 @@ up.motion = (->
106
114
  # $new should take up space
107
115
  $old.css(display: 'none')
108
116
  newCssMemo()
117
+
118
+ promise
119
+
120
+ ###
121
+ Completes all animations and transitions for the given element
122
+ by jumping to the last animation frame instantly. All callbacks chained to
123
+ the original animation's promise will be called.
124
+
125
+ Does nothing if the given element is not currently animating.
126
+
127
+ @param {Element|jQuery|String} elementOrSelector
128
+ ###
129
+ finish = (elementOrSelector) ->
130
+ $(elementOrSelector).each ->
131
+ $element = $(this)
132
+ u.finishCssAnimate($element)
133
+ finishGhosting($element)
134
+
135
+ finishGhosting = ($element) ->
136
+ if existingGhosting = $element.data(GHOSTING_PROMISE_KEY)
137
+ console.log("EXISTING", existingGhosting)
138
+ existingGhosting.resolve?()
109
139
 
110
- assertIsPromise = (object, messageParts) ->
111
- u.isPromise(object) or u.error(messageParts...)
112
- object
140
+ assertIsDeferred = (object, origin) ->
141
+ if u.isDeferred(object)
142
+ object
143
+ else
144
+ u.error("Did not return a promise with .then and .resolve methods: ", origin)
113
145
 
114
146
  ###*
115
147
  Performs a transition between two elements.
@@ -144,20 +176,19 @@ up.motion = (->
144
176
  options = u.options(config)
145
177
  $old = $(source)
146
178
  $new = $(target)
179
+ finish($old)
180
+ finish($new)
147
181
  transition = u.presence(transitionOrName, u.isFunction) || transitions[transitionOrName]
148
182
  if transition
149
183
  withGhosts $old, $new, ($oldGhost, $newGhost) ->
150
- assertIsPromise(
151
- transition($oldGhost, $newGhost, options),
152
- ["Transition did not return a promise", transitionOrName]
153
- )
184
+ assertIsDeferred(transition($oldGhost, $newGhost, options), transitionOrName)
154
185
  else if animation = animations[transitionOrName]
155
186
  $old.hide()
156
187
  animate($new, animation, options)
157
188
  else if u.isString(transitionOrName) && transitionOrName.indexOf('/') >= 0
158
189
  parts = transitionOrName.split('/')
159
190
  transition = ($old, $new, options) ->
160
- $.when(
191
+ resolvableWhen(
161
192
  animate($old, parts[0], options),
162
193
  animate($new, parts[1], options)
163
194
  )
@@ -167,11 +198,11 @@ up.motion = (->
167
198
  else
168
199
  # Skip ghosting and all the other stuff that can go wrong
169
200
  # in ancient browsers
170
- u.resolvedPromise()
201
+ u.resolvedDeferred()
171
202
 
172
203
  ###*
173
204
  Defines a named transition.
174
-
205
+
175
206
  @method up.transition
176
207
  @param {String} name
177
208
  @param {Function} transition
@@ -181,100 +212,109 @@ up.motion = (->
181
212
 
182
213
  ###*
183
214
  Defines a named animation.
184
-
215
+
185
216
  @method up.animation
186
217
  @param {String} name
187
218
  @param {Function} animation
188
219
  ###
189
220
  animation = (name, animation) ->
190
221
  animations[name] = animation
191
-
222
+
192
223
  snapshot = ->
193
224
  defaultAnimations = u.copy(animations)
194
225
  defaultTransitions = u.copy(transitions)
195
-
226
+
196
227
  reset = ->
197
228
  animations = u.copy(defaultAnimations)
198
229
  transitions = u.copy(defaultTransitions)
199
-
230
+
231
+ ###*
232
+ Returns a new promise that resolves once all promises in the given array resolve.
233
+ Other then e.g. `$.then`, the combined promise will have a `resolve` method.
234
+
235
+ @method up.motion.when
236
+ @param promises...
237
+ ###
238
+ resolvableWhen = u.resolvableWhen
239
+
200
240
  ###*
201
241
  Returns a no-op animation or transition which has no visual effects
202
242
  and completes instantly.
203
-
243
+
204
244
  @method up.motion.none
205
245
  @return {Promise}
206
- A resolved promise
246
+ A resolved promise
207
247
  ###
208
- none = u.resolvedPromise
209
-
248
+ none = u.resolvedDeferred
249
+
210
250
  animation('none', none)
211
251
 
212
252
  animation('fade-in', ($ghost, options) ->
213
253
  $ghost.css(opacity: 0)
214
254
  animate($ghost, { opacity: 1 }, options)
215
255
  )
216
-
256
+
217
257
  animation('fade-out', ($ghost, options) ->
218
258
  $ghost.css(opacity: 1)
219
259
  animate($ghost, { opacity: 0 }, options)
220
260
  )
221
-
261
+
222
262
  animation('move-to-top', ($ghost, options) ->
223
263
  box = u.measure($ghost)
224
264
  travelDistance = box.top + box.height
225
265
  $ghost.css('margin-top': '0px')
226
266
  animate($ghost, { 'margin-top': "-#{travelDistance}px" }, options)
227
267
  )
228
-
268
+
229
269
  animation('move-from-top', ($ghost, options) ->
230
270
  box = u.measure($ghost)
231
271
  travelDistance = box.top + box.height
232
272
  $ghost.css('margin-top': "-#{travelDistance}px")
233
273
  animate($ghost, { 'margin-top': '0px' }, options)
234
274
  )
235
-
275
+
236
276
  animation('move-to-bottom', ($ghost, options) ->
237
277
  box = u.measure($ghost)
238
278
  travelDistance = u.clientSize().height - box.top
239
279
  $ghost.css('margin-top': '0px')
240
280
  animate($ghost, { 'margin-top': "#{travelDistance}px" }, options)
241
281
  )
242
-
282
+
243
283
  animation('move-from-bottom', ($ghost, options) ->
244
284
  box = u.measure($ghost)
245
285
  travelDistance = u.clientSize().height - box.top
246
286
  $ghost.css('margin-top': "#{travelDistance}px")
247
287
  animate($ghost, { 'margin-top': '0px' }, options)
248
288
  )
249
-
289
+
250
290
  animation('move-to-left', ($ghost, options) ->
251
291
  box = u.measure($ghost)
252
292
  travelDistance = box.left + box.width
253
293
  $ghost.css('margin-left': '0px')
254
294
  animate($ghost, { 'margin-left': "-#{travelDistance}px" }, options)
255
295
  )
256
-
296
+
257
297
  animation('move-from-left', ($ghost, options) ->
258
298
  box = u.measure($ghost)
259
299
  travelDistance = box.left + box.width
260
300
  $ghost.css('margin-left': "-#{travelDistance}px")
261
301
  animate($ghost, { 'margin-left': '0px' }, options)
262
302
  )
263
-
303
+
264
304
  animation('move-to-right', ($ghost, options) ->
265
305
  box = u.measure($ghost)
266
306
  travelDistance = u.clientSize().width - box.left
267
307
  $ghost.css('margin-left': '0px')
268
308
  animate($ghost, { 'margin-left': "#{travelDistance}px" }, options)
269
309
  )
270
-
310
+
271
311
  animation('move-from-right', ($ghost, options) ->
272
312
  box = u.measure($ghost)
273
313
  travelDistance = u.clientSize().width - box.left
274
314
  $ghost.css('margin-left': "#{travelDistance}px")
275
315
  animate($ghost, { 'margin-left': '0px' }, options)
276
316
  )
277
-
317
+
278
318
  animation('roll-down', ($ghost, options) ->
279
319
  fullHeight = $ghost.height()
280
320
  styleMemo = u.temporaryCss($ghost,
@@ -283,39 +323,39 @@ up.motion = (->
283
323
  )
284
324
  animate($ghost, { height: "#{fullHeight}px" }, options).then(styleMemo)
285
325
  )
286
-
326
+
287
327
  transition('none', none)
288
-
328
+
289
329
  transition('move-left', ($old, $new, options) ->
290
- $.when(
330
+ resolvableWhen(
291
331
  animate($old, 'move-to-left', options),
292
332
  animate($new, 'move-from-right', options)
293
333
  )
294
334
  )
295
-
335
+
296
336
  transition('move-right', ($old, $new, options) ->
297
- $.when(
337
+ resolvableWhen(
298
338
  animate($old, 'move-to-right', options),
299
339
  animate($new, 'move-from-left', options)
300
340
  )
301
341
  )
302
-
342
+
303
343
  transition('move-up', ($old, $new, options) ->
304
- $.when(
344
+ resolvableWhen(
305
345
  animate($old, 'move-to-top', options),
306
346
  animate($new, 'move-from-bottom', options)
307
347
  )
308
348
  )
309
-
349
+
310
350
  transition('move-down', ($old, $new, options) ->
311
- $.when(
351
+ resolvableWhen(
312
352
  animate($old, 'move-to-bottom', options),
313
353
  animate($new, 'move-from-top', options)
314
354
  )
315
355
  )
316
-
356
+
317
357
  transition('cross-fade', ($old, $new, options) ->
318
- $.when(
358
+ resolvableWhen(
319
359
  animate($old, 'fade-out', options),
320
360
  animate($new, 'fade-in', options)
321
361
  )
@@ -326,10 +366,12 @@ up.motion = (->
326
366
 
327
367
  morph: morph
328
368
  animate: animate
369
+ finish: finish
329
370
  transition: transition
330
371
  animation: animation
331
372
  defaults: defaults
332
373
  none: none
374
+ when: resolvableWhen
333
375
 
334
376
  )()
335
377
 
@@ -89,10 +89,10 @@ up.util = (->
89
89
  element
90
90
 
91
91
  error = (args...) ->
92
- message = if args.length == 1 && up.util.isString(args[0]) then args[0] else JSON.stringify(args)
93
- console.log("[UP] Error: #{message}", args...)
94
- alert message
95
- throw message
92
+ console.log("[UP] Error", args...)
93
+ asString = if args.length == 1 && up.util.isString(args[0]) then args[0] else JSON.stringify(args)
94
+ alert asString
95
+ throw asString
96
96
 
97
97
  createSelectorFromElement = ($element) ->
98
98
  console.log("Creating selector from element", $element)
@@ -205,8 +205,11 @@ up.util = (->
205
205
  object instanceof jQuery
206
206
 
207
207
  isPromise = (object) ->
208
- isFunction(object.then)
209
-
208
+ isObject(object) && isFunction(object.then)
209
+
210
+ isDeferred = (object) ->
211
+ isPromise(object) && isFunction(object.resolve)
212
+
210
213
  ifGiven = (object) ->
211
214
  object if isGiven(object)
212
215
 
@@ -317,6 +320,12 @@ up.util = (->
317
320
 
318
321
  ###*
319
322
  Animates the given element's CSS properties using CSS transitions.
323
+
324
+ If the element is already being animated, the previous animation
325
+ will instantly jump to its last frame before the new animation begins.
326
+
327
+ To improve performance, the element will be forced into compositing for
328
+ the duration of the animation.
320
329
 
321
330
  @method up.util.cssAnimate
322
331
  @param {Element|jQuery|String} elementOrSelector
@@ -343,6 +352,8 @@ up.util = (->
343
352
  delay: 0,
344
353
  easing: 'ease'
345
354
  )
355
+ # We don't finish an existing animation here, since
356
+ # the public API `up.motion.animate` already does this.
346
357
  deferred = $.Deferred()
347
358
  transition =
348
359
  'transition-property': keys(lastFrame).join(', ')
@@ -354,12 +365,34 @@ up.util = (->
354
365
  $element.css(lastFrame)
355
366
  deferred.then(withoutCompositing)
356
367
  deferred.then(withoutTransition)
357
- setTimeout((-> deferred.resolve()), opts.duration + opts.delay)
358
- deferred.promise()
368
+ $element.data(ANIMATION_PROMISE_KEY, deferred)
369
+ deferred.then(-> $element.removeData(ANIMATION_PROMISE_KEY))
370
+ endTimeout = setTimeout((-> deferred.resolve()), opts.duration + opts.delay)
371
+ deferred.then(-> clearTimeout(endTimeout)) # clean up in case we're canceled
372
+ # Return the whole deferred and not just return a thenable.
373
+ # Other code will need the possibility to cancel the animation
374
+ # by resolving the deferred.
375
+ deferred
359
376
  else
360
377
  $element.css(lastFrame)
361
378
  resolvedPromise()
362
-
379
+
380
+ ANIMATION_PROMISE_KEY = 'up-animation-promise'
381
+
382
+ ###
383
+ Completes the animation for the given element by jumping
384
+ to the last frame instantly. All callbacks chained to
385
+ the original animation's promise will be called.
386
+
387
+ Does nothing if the given element is not currently animating.
388
+
389
+ @param {Element|jQuery|String} elementOrSelector
390
+ ###
391
+ finishCssAnimate = (elementOrSelector) ->
392
+ $(elementOrSelector).each ->
393
+ if existingAnimation = $(this).data(ANIMATION_PROMISE_KEY)
394
+ existingAnimation.resolve()
395
+
363
396
  measure = ($element, options) ->
364
397
  coordinates = if options?.relative
365
398
  $element.position()
@@ -430,10 +463,19 @@ up.util = (->
430
463
  filtered[key] = object[key]
431
464
  filtered
432
465
 
433
- resolvedPromise = ->
466
+ resolvedDeferred = ->
434
467
  deferred = $.Deferred()
435
468
  deferred.resolve()
436
- deferred.promise()
469
+ deferred
470
+
471
+ resolvedPromise = ->
472
+ resolvedDeferred().promise()
473
+
474
+ resolvableWhen = (deferreds...) ->
475
+ joined = $.when(deferreds...)
476
+ joined.resolve = ->
477
+ each deferreds, (deferred) -> deferred.resolve?()
478
+ joined
437
479
 
438
480
  # memoArray = ->
439
481
  # array = []
@@ -482,6 +524,7 @@ up.util = (->
482
524
  isString: isString
483
525
  isJQuery: isJQuery
484
526
  isPromise: isPromise
527
+ isDeferred: isDeferred
485
528
  isHash: isHash
486
529
  ifGiven: ifGiven
487
530
  unwrap: unwrap
@@ -489,6 +532,7 @@ up.util = (->
489
532
  measure: measure
490
533
  temporaryCss: temporaryCss
491
534
  cssAnimate: cssAnimate
535
+ finishCssAnimate: finishCssAnimate
492
536
  forceCompositing: forceCompositing
493
537
  prependGhost: prependGhost
494
538
  escapePressed: escapePressed
@@ -504,5 +548,7 @@ up.util = (->
504
548
  trim: trim
505
549
  keys: keys
506
550
  resolvedPromise: resolvedPromise
551
+ resolvedDeferred: resolvedDeferred
552
+ resolvableWhen: resolvableWhen
507
553
 
508
554
  )()
@@ -1,5 +1,5 @@
1
1
  module Upjs
2
2
  module Rails
3
- VERSION = "0.3.2"
3
+ VERSION = "0.3.3"
4
4
  end
5
5
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- upjs-rails (0.3.0)
4
+ upjs-rails (0.3.2)
5
5
  rails (>= 3)
6
6
 
7
7
  GEM
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: upjs-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Henning Koch
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-25 00:00:00.000000000 Z
11
+ date: 2015-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails