upjs-rails 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
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