upjs-rails 0.10.5 → 0.11.0

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: ac1e8625e8dd7456aee85627dade6303c19d20ff
4
- data.tar.gz: 29efdf5cf17321841c6921361f763da2a065cec6
3
+ metadata.gz: 9612554166f5b3f84f42b54fc24d3f01a82f309a
4
+ data.tar.gz: 8329cce83bf85a136b387b24c17f8d0a0ce76c7c
5
5
  SHA512:
6
- metadata.gz: 87bc620fe93824215f348b97b4ecccdcdc4570e9b51c5ffb1220c5c2a62b26bd1de96623b4e95906d301117e117728a5ff0ab1ecca59830c96bc2d093a8c5073
7
- data.tar.gz: b9f734a256b2c1a8be04076c051739922f24e2d34d681fd70ba54fd494746c7a81f29d2d7b9f08650c5dc7d633832c7a18d5c160b48347e544d9588ff84fa73d
6
+ metadata.gz: 4f7c9f36a603dca57417c2efff60487fcea9a003b5951119687629c04f8f291f0273409be8d2bb608e6d3c9ec59991d6b6c63c51541dea30caecd27285c2c1bb
7
+ data.tar.gz: bcd6e73b1d9ef5a8a581de35287d25fd1893a8649f51810831649fb2d6d1a47d6ddd1b6b33ed9da2cc72d3f10302d9993e0ba09258eba68c4b5dbae2bf5d5538
data/CHANGELOG.md CHANGED
@@ -5,6 +5,38 @@ All notable changes to this project will be documented in this file.
5
5
  This project mostly adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
7
 
8
+ 0.11.0
9
+ ------
10
+
11
+ ### Compatible changes
12
+
13
+ - Rework the scrolling implementation so we don't need to scroll elements to the top before replacing them.
14
+ - `up.ajax` now only caches responses with a status code of `200 OK`
15
+ - When a link with an `[up-close]` attribute is clicked, the link's default action will only be prevented
16
+ if the link was actually within a modal or popup.
17
+ - When revealing an element, Up will now compute the correct element position if there are
18
+ additional positioning contexts between the viewport and the element
19
+ - New option "top" for `up.reveal`: Whether to scroll the viewport so that the first element row aligns with
20
+ the top edge of the viewport. Without this option, `up.reveal` scrolls as little as possible.
21
+ - Allow to animate scrolling when the `document` is the viewport.
22
+ - New `up.layout` setting `fixedRight` that contains selectors for elements that are anchored to
23
+ the right edge of the screen. When opening a modal, these elements will be prevented from jumping
24
+ around. If you're using `up-bootstrap.js`, this will default to `['.navbar-fixed-top', '.navbar-fixed-bottom', '.footer']`.
25
+ - Fix a bug in `upjs-rails` where the gem would fail to `include` itself in some versions
26
+ of Ruby and Rails.
27
+
28
+
29
+ ### Incompatible changes
30
+
31
+ - Interactions that would result in an URL change ("pushState") now fall back to a full page load
32
+ if Up.js was booted from a non-GET request. [More information about the reasons for this](https://github.com/makandra/upjs/commit/d81d9007aa3bfae0fca8c55a71d180d1044acae5).
33
+
34
+ This currently works out of the box if you're using Up.js via the `upjs-rails` Rubygem.
35
+ If you're integrating Up.js with Bower or manually, you need to have your server app
36
+ set an `_up_request_method` cookie with the current request method on every request.
37
+
38
+
39
+
8
40
  0.10.5
9
41
  ------
10
42
 
data/dist/up-bootstrap.js CHANGED
@@ -5,7 +5,8 @@
5
5
 
6
6
  up.layout.defaults({
7
7
  fixedTop: defaults.fixedTop.concat(['.navbar-fixed-top']),
8
- fixedBottom: defaults.fixedBottom.concat(['.navbar-fixed-bottom'])
8
+ fixedBottom: defaults.fixedBottom.concat(['.navbar-fixed-bottom']),
9
+ anchoredRight: defaults.anchoredRight.concat(['.navbar-fixed-top', '.navbar-fixed-bottom', '.footer'])
9
10
  });
10
11
 
11
12
  }).call(this);
@@ -1 +1 @@
1
- (function(){var a;a=up.layout.defaults(),up.layout.defaults({fixedTop:a.fixedTop.concat([".navbar-fixed-top"]),fixedBottom:a.fixedBottom.concat([".navbar-fixed-bottom"])})}).call(this),function(){up.modal.defaults({template:'<div class="up-modal">\n <div class="up-modal-dialog modal-dialog">\n <div class="up-modal-content modal-content"></div>\n </div>\n</div>'})}.call(this),function(){var a;a=up.navigation.defaults(),up.navigation.defaults({currentClasses:a.currentClasses.concat(["active"])})}.call(this),function(){}.call(this);
1
+ (function(){var a;a=up.layout.defaults(),up.layout.defaults({fixedTop:a.fixedTop.concat([".navbar-fixed-top"]),fixedBottom:a.fixedBottom.concat([".navbar-fixed-bottom"]),anchoredRight:a.anchoredRight.concat([".navbar-fixed-top",".navbar-fixed-bottom",".footer"])})}).call(this),function(){up.modal.defaults({template:'<div class="up-modal">\n <div class="up-modal-dialog modal-dialog">\n <div class="up-modal-content modal-content"></div>\n </div>\n</div>'})}.call(this),function(){var a;a=up.navigation.defaults(),up.navigation.defaults({currentClasses:a.currentClasses.concat(["active"])})}.call(this),function(){}.call(this);
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, ANIMATION_PROMISE_KEY, CONSOLE_PLACEHOLDERS, ajax, any, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, debug, detect, each, emptyJQuery, endsWith, error, escapePressed, extend, findWithSelf, finishCssAnimate, forceCompositing, identity, ifGiven, isArray, isBlank, isDeferred, isDefined, isElement, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isNumber, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, keys, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, multiSelector, nextFrame, normalizeMethod, normalizeUrl, nullJquery, once, only, option, options, presence, presentAttr, remove, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, setMissingAttrs, startsWith, stringifyConsoleArgs, temporaryCss, times, toArray, trim, unJquery, uniq, unwrapElement, warn;
28
+ var $createElementFromSelector, ANIMATION_PROMISE_KEY, CONSOLE_PLACEHOLDERS, ajax, any, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, debug, detect, each, emptyJQuery, endsWith, error, escapePressed, extend, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, identity, ifGiven, isArray, isBlank, isDeferred, isDefined, isElement, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isNumber, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, keys, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, multiSelector, nextFrame, normalizeMethod, normalizeUrl, nullJquery, offsetParent, once, only, option, options, presence, presentAttr, remove, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, setMissingAttrs, startsWith, stringifyConsoleArgs, temporaryCss, times, toArray, trim, unJquery, uniq, unwrapElement, warn;
29
29
  memoize = function(func) {
30
30
  var cache, cached;
31
31
  cache = void 0;
@@ -656,21 +656,44 @@ If you use them in your own code, you will get hurt.
656
656
  }
657
657
  });
658
658
  };
659
- measure = function($element, options) {
660
- var box, coordinates, viewport;
661
- coordinates = (options != null ? options.relative : void 0) ? $element.position() : $element.offset();
659
+ measure = function($element, opts) {
660
+ var $context, box, contextCoords, coordinates, elementCoords, viewport;
661
+ opts = options(opts, {
662
+ relative: false,
663
+ inner: false,
664
+ full: false
665
+ });
666
+ if (opts.relative) {
667
+ if (opts.relative === true) {
668
+ coordinates = $element.position();
669
+ } else {
670
+ $context = $(opts.relative);
671
+ elementCoords = $element.offset();
672
+ if ($context.is(document)) {
673
+ coordinates = elementCoords;
674
+ } else {
675
+ contextCoords = $context.offset();
676
+ coordinates = {
677
+ left: elementCoords.left - contextCoords.left,
678
+ top: elementCoords.top - contextCoords.top
679
+ };
680
+ }
681
+ }
682
+ } else {
683
+ coordinates = $element.offset();
684
+ }
662
685
  box = {
663
686
  left: coordinates.left,
664
687
  top: coordinates.top
665
688
  };
666
- if (options != null ? options.inner : void 0) {
689
+ if (opts.inner) {
667
690
  box.width = $element.width();
668
691
  box.height = $element.height();
669
692
  } else {
670
693
  box.width = $element.outerWidth();
671
694
  box.height = $element.outerHeight();
672
695
  }
673
- if (options != null ? options.full : void 0) {
696
+ if (opts.full) {
674
697
  viewport = clientSize();
675
698
  box.right = viewport.width - (box.left + box.width);
676
699
  box.bottom = viewport.height - (box.top + box.height);
@@ -1056,7 +1079,36 @@ If you use them in your own code, you will get hurt.
1056
1079
  });
1057
1080
  return parent.removeChild(wrapper);
1058
1081
  };
1082
+ offsetParent = function($element) {
1083
+ var $match, position;
1084
+ $match = void 0;
1085
+ while (($element = $element.parent()) && $element.length) {
1086
+ position = $element.css('position');
1087
+ console.log("Iteration element is %o with position %o", $element, position);
1088
+ if (position === 'absolute' || position === 'relative' || $element.is('body')) {
1089
+ $match = $element;
1090
+ break;
1091
+ }
1092
+ }
1093
+ return $match;
1094
+ };
1095
+ fixedToAbsolute = function(element, $viewport) {
1096
+ var $element, $futureOffsetParent, elementCoords, futureParentCoords;
1097
+ $element = $(element);
1098
+ $futureOffsetParent = offsetParent($element);
1099
+ elementCoords = $element.position();
1100
+ futureParentCoords = $futureOffsetParent.offset();
1101
+ return $element.css({
1102
+ position: 'absolute',
1103
+ left: elementCoords.left - futureParentCoords.left,
1104
+ top: elementCoords.top - futureParentCoords.top + $viewport.scrollTop(),
1105
+ right: '',
1106
+ bottom: ''
1107
+ });
1108
+ };
1059
1109
  return {
1110
+ offsetParent: offsetParent,
1111
+ fixedToAbsolute: fixedToAbsolute,
1060
1112
  presentAttr: presentAttr,
1061
1113
  createElement: createElement,
1062
1114
  normalizeUrl: normalizeUrl,
@@ -1155,7 +1207,7 @@ we can't currently get rid off.
1155
1207
 
1156
1208
  (function() {
1157
1209
  up.browser = (function() {
1158
- var canCssAnimation, canInputEvent, canPushState, ensureConsoleExists, ensureRecentJquery, isSupported, loadPage, u, url;
1210
+ var canCssAnimation, canInputEvent, canPushState, ensureConsoleExists, ensureRecentJquery, initialRequestMethod, isSupported, loadPage, popCookie, u, url;
1159
1211
  u = up.util;
1160
1212
  loadPage = function(url, options) {
1161
1213
  var $form, csrfParam, csrfToken, metadataInput, method, target;
@@ -1200,7 +1252,7 @@ we can't currently get rid off.
1200
1252
  return (base7 = window.console).groupEnd || (base7.groupEnd = noop);
1201
1253
  };
1202
1254
  canPushState = u.memoize(function() {
1203
- return u.isDefined(history.pushState);
1255
+ return u.isDefined(history.pushState) && initialRequestMethod === 'get';
1204
1256
  });
1205
1257
  canCssAnimation = u.memoize(function() {
1206
1258
  return 'transition' in document.documentElement.style;
@@ -1217,6 +1269,15 @@ we can't currently get rid off.
1217
1269
  compatible = major >= 2 || (major === 1 && minor >= 9);
1218
1270
  return compatible || u.error("jQuery %o found, but Up.js requires 1.9+", version);
1219
1271
  };
1272
+ popCookie = function(name) {
1273
+ var ref, value;
1274
+ value = (ref = document.cookie.match(new RegExp(name + "=(\\w+)"))) != null ? ref[1] : void 0;
1275
+ if (u.isPresent(value)) {
1276
+ document.cookie = name + '=; expires=Thu, 01-Jan-70 00:00:01 GMT; path=/';
1277
+ }
1278
+ return value;
1279
+ };
1280
+ initialRequestMethod = (popCookie('_up_request_method') || 'get').toLowerCase();
1220
1281
  isSupported = u.memoize(function() {
1221
1282
  return u.isDefined(document.addEventListener);
1222
1283
  });
@@ -1885,7 +1946,6 @@ We need to work on this page:
1885
1946
  return normalizeUrl(url) === currentUrl();
1886
1947
  };
1887
1948
  observeNewUrl = function(url) {
1888
- console.log("observing new url %o", url);
1889
1949
  if (nextPreviousUrl) {
1890
1950
  previousUrl = nextPreviousUrl;
1891
1951
  nextPreviousUrl = void 0;
@@ -2036,7 +2096,7 @@ This modules contains functions to scroll the viewport and reveal contained elem
2036
2096
  var slice = [].slice;
2037
2097
 
2038
2098
  up.layout = (function() {
2039
- var SCROLL_PROMISE_KEY, config, finishScrolling, lastScrollTops, measureObstruction, reset, restoreScroll, reveal, saveScroll, scroll, scrollTops, u, viewportOf, viewportSelector, viewports, viewportsWithin;
2099
+ var SCROLL_PROMISE_KEY, anchoredRight, config, finishScrolling, fixedChildren, lastScrollTops, measureObstruction, reset, restoreScroll, reveal, saveScroll, scroll, scrollTops, u, viewportOf, viewportSelector, viewports, viewportsWithin;
2040
2100
  u = up.util;
2041
2101
 
2042
2102
  /**
@@ -2052,6 +2112,9 @@ This modules contains functions to scroll the viewport and reveal contained elem
2052
2112
  @param {Array<String>} [options.fixedBottom]
2053
2113
  An array of CSS selectors that find elements fixed to the
2054
2114
  bottom edge of the screen (using `position: fixed`).
2115
+ @param {Array<String>} [options.anchoredRight]
2116
+ An array of CSS selectors that find elements anchored to the
2117
+ right edge of the screen (using `position: fixed` or `position: absolute`).
2055
2118
  @param {Number} [options.duration]
2056
2119
  The duration of the scrolling animation in milliseconds.
2057
2120
  Setting this to `0` will disable scrolling animations.
@@ -2070,6 +2133,7 @@ This modules contains functions to scroll the viewport and reveal contained elem
2070
2133
  viewports: [document, '.up-modal', '[up-viewport]'],
2071
2134
  fixedTop: ['[up-fixed~=top]'],
2072
2135
  fixedBottom: ['[up-fixed~=bottom]'],
2136
+ anchoredRight: ['[up-anchored~=right]', '[up-fixed~=top]', '[up-fixed~=bottom]', '[up-fixed~=right]'],
2073
2137
  snap: 50,
2074
2138
  substance: 150,
2075
2139
  easing: 'swing'
@@ -2139,6 +2203,9 @@ This modules contains functions to scroll the viewport and reveal contained elem
2139
2203
  targetProps = {
2140
2204
  scrollTop: scrollTop
2141
2205
  };
2206
+ if ($viewport.get(0) === document) {
2207
+ $viewport = $('html, body');
2208
+ }
2142
2209
  $viewport.animate(targetProps, {
2143
2210
  duration: duration,
2144
2211
  easing: easing,
@@ -2165,6 +2232,14 @@ This modules contains functions to scroll the viewport and reveal contained elem
2165
2232
  }
2166
2233
  });
2167
2234
  };
2235
+
2236
+ /**
2237
+ @method up.viewport.anchoredRight
2238
+ @private
2239
+ */
2240
+ anchoredRight = function() {
2241
+ return u.multiSelector(config.anchoredRight).select();
2242
+ };
2168
2243
  measureObstruction = function() {
2169
2244
  var fixedBottomTops, fixedTopBottoms, measurePosition, obstructor;
2170
2245
  measurePosition = function(obstructor, cssAttr) {
@@ -2236,6 +2311,9 @@ This modules contains functions to scroll the viewport and reveal contained elem
2236
2311
  @param {String} [options.easing]
2237
2312
  @param {String} [options.snap]
2238
2313
  @param {String|Element|jQuery} [options.viewport]
2314
+ @param {Boolean} [options.top=false]
2315
+ Whether to scroll the viewport so that the first element row aligns
2316
+ with the top edge of the viewport.
2239
2317
  @return {Deferred}
2240
2318
  A promise that will be resolved when the element is revealed.
2241
2319
  */
@@ -2268,14 +2346,14 @@ This modules contains functions to scroll the viewport and reveal contained elem
2268
2346
  return newScrollPos + viewportHeight - obstruction.bottom - 1;
2269
2347
  };
2270
2348
  elementDims = u.measure($element, {
2271
- relative: true
2349
+ relative: $viewport
2272
2350
  });
2273
2351
  firstElementRow = elementDims.top + offsetShift;
2274
2352
  lastElementRow = firstElementRow + Math.min(elementDims.height, config.substance) - 1;
2275
2353
  if (lastElementRow > predictLastVisibleRow()) {
2276
2354
  newScrollPos += lastElementRow - predictLastVisibleRow();
2277
2355
  }
2278
- if (firstElementRow < predictFirstVisibleRow()) {
2356
+ if (firstElementRow < predictFirstVisibleRow() || options.top) {
2279
2357
  newScrollPos = firstElementRow - obstruction.top;
2280
2358
  }
2281
2359
  if (newScrollPos < snap) {
@@ -2342,9 +2420,9 @@ This modules contains functions to scroll the viewport and reveal contained elem
2342
2420
  up.layout.scrollTops()
2343
2421
  => { '.main': 0, '.sidebar': 73 }
2344
2422
 
2345
- @protected
2346
2423
  @method up.layout.scrollTops
2347
2424
  @return Object<String, Number>
2425
+ @protected
2348
2426
  */
2349
2427
  scrollTops = function() {
2350
2428
  var $viewport, i, key, len, ref, topsBySelector, viewport;
@@ -2364,6 +2442,27 @@ This modules contains functions to scroll the viewport and reveal contained elem
2364
2442
  return topsBySelector;
2365
2443
  };
2366
2444
 
2445
+ /**
2446
+ @method up.layout.fixedChildren
2447
+ @protected
2448
+ */
2449
+ fixedChildren = function(root) {
2450
+ var $elements, $root;
2451
+ if (root == null) {
2452
+ root = void 0;
2453
+ }
2454
+ root || (root = document.body);
2455
+ $root = $(root);
2456
+ $elements = $root.find('[up-fixed]');
2457
+ if (u.isPresent(config.fixedTop)) {
2458
+ $elements = $elements.add($root.find(config.fixedTop.join(', ')));
2459
+ }
2460
+ if (u.isPresent(config.fixedBottom)) {
2461
+ $elements = $elements.add($root.find(config.fixedBottom.join(', ')));
2462
+ }
2463
+ return $elements;
2464
+ };
2465
+
2367
2466
  /**
2368
2467
  Saves the top scroll positions of all the
2369
2468
  viewports configured in `up.layout.defaults('viewports').
@@ -2511,7 +2610,9 @@ This modules contains functions to scroll the viewport and reveal contained elem
2511
2610
  viewports: viewports,
2512
2611
  scrollTops: scrollTops,
2513
2612
  saveScroll: saveScroll,
2514
- restoreScroll: restoreScroll
2613
+ restoreScroll: restoreScroll,
2614
+ anchoredRight: anchoredRight,
2615
+ fixedChildren: fixedChildren
2515
2616
  };
2516
2617
  })();
2517
2618
 
@@ -2593,7 +2694,7 @@ We need to work on this page:
2593
2694
  */
2594
2695
  replace = function(selectorOrElement, url, options) {
2595
2696
  var promise, request, selector;
2596
- u.debug("Replace %o with %o", selectorOrElement, url);
2697
+ u.debug("Replace %o with %o (options %o)", selectorOrElement, url, options);
2597
2698
  options = u.options(options);
2598
2699
  selector = u.presence(selectorOrElement) ? selectorOrElement : u.createSelectorFromElement($(selectorOrElement));
2599
2700
  if (!up.browser.canPushState() && options.history !== false) {
@@ -2749,17 +2850,15 @@ We need to work on this page:
2749
2850
  u.unwrapElement($wrapper);
2750
2851
  });
2751
2852
  } else {
2752
- return reveal($old, options).then(function() {
2753
- return destroy($old, {
2754
- animation: function() {
2755
- $new.insertBefore($old);
2756
- elementsInserted($new, options);
2757
- if ($old.is('body') && transition !== 'none') {
2758
- u.error('Cannot apply transitions to body-elements (%o)', transition);
2759
- }
2760
- return up.morph($old, $new, transition, options);
2853
+ return destroy($old, {
2854
+ animation: function() {
2855
+ $new.insertBefore($old);
2856
+ elementsInserted($new, options);
2857
+ if ($old.is('body') && transition !== 'none') {
2858
+ u.error('Cannot apply transitions to body-elements (%o)', transition);
2761
2859
  }
2762
- });
2860
+ return up.morph($old, $new, transition, options);
2861
+ }
2763
2862
  });
2764
2863
  }
2765
2864
  };
@@ -2954,7 +3053,7 @@ We need to work on this page:
2954
3053
 
2955
3054
  (function() {
2956
3055
  up.motion = (function() {
2957
- var GHOSTING_PROMISE_KEY, animate, animateOptions, animation, animations, assertIsDeferred, config, defaultAnimations, defaultTransitions, findAnimation, finish, finishGhosting, morph, none, prependGhost, reset, resolvableWhen, snapshot, transition, transitions, u, withGhosts;
3056
+ var GHOSTING_PROMISE_KEY, animate, animateOptions, animation, animations, assertIsDeferred, config, defaultAnimations, defaultTransitions, findAnimation, finish, finishGhosting, morph, none, prependCopy, reset, resolvableWhen, snapshot, transition, transitions, u, withGhosts;
2958
3057
  u = up.util;
2959
3058
  animations = {};
2960
3059
  defaultAnimations = {};
@@ -3090,27 +3189,36 @@ We need to work on this page:
3090
3189
  return animations[name] || u.error("Unknown animation %o", animation);
3091
3190
  };
3092
3191
  GHOSTING_PROMISE_KEY = 'up-ghosting-promise';
3093
- withGhosts = function($old, $new, block) {
3094
- var newCopy, oldCopy, promise, showNew;
3095
- oldCopy = null;
3096
- newCopy = null;
3192
+ withGhosts = function($old, $new, options, block) {
3193
+ var $viewport, newCopy, newScrollTop, oldCopy, oldScrollTop, promise, showNew;
3194
+ oldCopy = void 0;
3195
+ newCopy = void 0;
3196
+ oldScrollTop = void 0;
3197
+ newScrollTop = void 0;
3198
+ $viewport = up.layout.viewportOf($old);
3097
3199
  u.temporaryCss($new, {
3098
3200
  display: 'none'
3099
3201
  }, function() {
3100
- oldCopy = prependGhost($old);
3202
+ oldCopy = prependCopy($old, $viewport);
3101
3203
  oldCopy.$ghost.addClass('up-destroying');
3102
- return oldCopy.$bounds.addClass('up-destroying');
3204
+ oldCopy.$bounds.addClass('up-destroying');
3205
+ return oldScrollTop = $viewport.scrollTop();
3103
3206
  });
3104
3207
  u.temporaryCss($old, {
3105
3208
  display: 'none'
3106
3209
  }, function() {
3107
- return newCopy = prependGhost($new);
3108
- });
3109
- $old.css({
3110
- visibility: 'hidden'
3210
+ if (options.reveal) {
3211
+ up.reveal($new, {
3212
+ viewport: $viewport
3213
+ });
3214
+ }
3215
+ newCopy = prependCopy($new, $viewport);
3216
+ return newScrollTop = $viewport.scrollTop();
3111
3217
  });
3218
+ oldCopy.moveTop(newScrollTop - oldScrollTop);
3219
+ $old.hide();
3112
3220
  showNew = u.temporaryCss($new, {
3113
- display: 'none'
3221
+ visibility: 'hidden'
3114
3222
  });
3115
3223
  promise = block(oldCopy.$ghost, newCopy.$ghost);
3116
3224
  $old.data(GHOSTING_PROMISE_KEY, promise);
@@ -3120,9 +3228,6 @@ We need to work on this page:
3120
3228
  $new.removeData(GHOSTING_PROMISE_KEY);
3121
3229
  oldCopy.$bounds.remove();
3122
3230
  newCopy.$bounds.remove();
3123
- $old.css({
3124
- display: 'none'
3125
- });
3126
3231
  return showNew();
3127
3232
  });
3128
3233
  return promise;
@@ -3153,11 +3258,11 @@ We need to work on this page:
3153
3258
  return typeof existingGhosting.resolve === "function" ? existingGhosting.resolve() : void 0;
3154
3259
  }
3155
3260
  };
3156
- assertIsDeferred = function(object, origin) {
3261
+ assertIsDeferred = function(object, source) {
3157
3262
  if (u.isDeferred(object)) {
3158
3263
  return object;
3159
3264
  } else {
3160
- return u.error("Did not return a promise with .then and .resolve methods: %o", origin);
3265
+ return u.error("Did not return a promise with .then and .resolve methods: %o", source);
3161
3266
  }
3162
3267
  };
3163
3268
 
@@ -3200,32 +3305,38 @@ We need to work on this page:
3200
3305
  The timing function that controls the transition's acceleration.
3201
3306
  See [W3C documentation](http://www.w3.org/TR/css3-transitions/#transition-timing-function)
3202
3307
  for a list of pre-defined timing functions.
3308
+ @param {Boolean} [options.reveal=false]
3309
+ Whether to reveal the new element by scrolling its parent viewport.
3203
3310
  @return {Promise}
3204
3311
  A promise for the transition's end.
3205
3312
  */
3206
3313
  morph = function(source, target, transitionOrName, options) {
3207
- var $new, $old, animation, parts, transition;
3314
+ var $new, $old, animation, parsedOptions, parts, transition;
3208
3315
  if (up.browser.canCssAnimation()) {
3209
- options = animateOptions(options);
3316
+ parsedOptions = u.only(options, 'reveal');
3317
+ parsedOptions = u.extend(parsedOptions, animateOptions(options));
3210
3318
  $old = $(source);
3211
3319
  $new = $(target);
3212
3320
  finish($old);
3213
3321
  finish($new);
3214
- if (transitionOrName === 'none' || transitionOrName === false) {
3215
- return none();
3322
+ if (transitionOrName === 'none' || transitionOrName === false || (animation = animations[transitionOrName])) {
3323
+ $old.hide();
3324
+ if (options.reveal) {
3325
+ up.reveal($new);
3326
+ }
3327
+ return animate($new, animation || 'none', options);
3216
3328
  } else if (transition = u.presence(transitionOrName, u.isFunction) || transitions[transitionOrName]) {
3217
- return withGhosts($old, $new, function($oldGhost, $newGhost) {
3218
- return assertIsDeferred(transition($oldGhost, $newGhost, options), transitionOrName);
3329
+ return withGhosts($old, $new, parsedOptions, function($oldGhost, $newGhost) {
3330
+ var transitionPromise;
3331
+ transitionPromise = transition($oldGhost, $newGhost, parsedOptions);
3332
+ return assertIsDeferred(transitionPromise, transitionOrName);
3219
3333
  });
3220
- } else if (animation = animations[transitionOrName]) {
3221
- $old.hide();
3222
- return animate($new, animation, options);
3223
3334
  } else if (u.isString(transitionOrName) && transitionOrName.indexOf('/') >= 0) {
3224
3335
  parts = transitionOrName.split('/');
3225
3336
  transition = function($old, $new, options) {
3226
3337
  return resolvableWhen(animate($old, parts[0], options), animate($new, parts[1], options));
3227
3338
  };
3228
- return morph($old, $new, transition, options);
3339
+ return morph($old, $new, transition, parsedOptions);
3229
3340
  } else {
3230
3341
  return u.error("Unknown transition %o", transitionOrName);
3231
3342
  }
@@ -3237,8 +3348,8 @@ We need to work on this page:
3237
3348
  /**
3238
3349
  @private
3239
3350
  */
3240
- prependGhost = function($element) {
3241
- var $bounds, $ghost, diff, elementDims;
3351
+ prependCopy = function($element, $viewport) {
3352
+ var $bounds, $fixedElements, $ghost, elementDims, fixedElement, i, len, moveTop, top;
3242
3353
  elementDims = u.measure($element, {
3243
3354
  relative: true,
3244
3355
  inner: true
@@ -3260,17 +3371,27 @@ We need to work on this page:
3260
3371
  position: 'absolute'
3261
3372
  });
3262
3373
  $bounds.css(elementDims);
3374
+ top = elementDims.top;
3375
+ moveTop = function(diff) {
3376
+ if (diff !== 0) {
3377
+ top += diff;
3378
+ return $bounds.css({
3379
+ top: top
3380
+ });
3381
+ }
3382
+ };
3263
3383
  $ghost.appendTo($bounds);
3264
3384
  $bounds.insertBefore($element);
3265
- diff = $ghost.offset().top - $element.offset().top;
3266
- if (diff !== 0) {
3267
- $bounds.css({
3268
- top: elementDims.top - diff
3269
- });
3385
+ moveTop($element.offset().top - $ghost.offset().top);
3386
+ $fixedElements = up.layout.fixedChildren($ghost);
3387
+ for (i = 0, len = $fixedElements.length; i < len; i++) {
3388
+ fixedElement = $fixedElements[i];
3389
+ u.fixedToAbsolute(fixedElement, $viewport);
3270
3390
  }
3271
3391
  return {
3272
3392
  $ghost: $ghost,
3273
- $bounds: $bounds
3393
+ $bounds: $bounds,
3394
+ moveTop: moveTop
3274
3395
  };
3275
3396
  };
3276
3397
 
@@ -3512,7 +3633,7 @@ We need to work on this page:
3512
3633
  defaults: config.update,
3513
3634
  none: none,
3514
3635
  when: resolvableWhen,
3515
- prependGhost: prependGhost
3636
+ prependCopy: prependCopy
3516
3637
  };
3517
3638
  })();
3518
3639
 
@@ -3714,6 +3835,9 @@ You can change (or remove) this delay like this:
3714
3835
  } else {
3715
3836
  promise = load(request);
3716
3837
  set(request, promise);
3838
+ promise.fail(function() {
3839
+ return remove(request);
3840
+ });
3717
3841
  }
3718
3842
  if (pending && !options.preload) {
3719
3843
  loadStarted();
@@ -4938,8 +5062,9 @@ We need to work on this page:
4938
5062
  @ujs
4939
5063
  */
4940
5064
  up.on('click', '[up-close]', function(event, $element) {
4941
- if ($element.closest('.up-popup')) {
4942
- return close();
5065
+ if ($element.closest('.up-popup').length) {
5066
+ close();
5067
+ return event.preventDefault();
4943
5068
  }
4944
5069
  });
4945
5070
  up.bus.on('framework:reset', reset);
@@ -4970,7 +5095,7 @@ For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead.
4970
5095
  var slice = [].slice;
4971
5096
 
4972
5097
  up.modal = (function() {
4973
- var autoclose, close, config, contains, createHiddenModal, currentSource, discardHistory, open, rememberHistory, reset, shiftBody, source, templateHtml, u, unshiftBody, updated;
5098
+ var autoclose, close, config, contains, createHiddenModal, currentSource, discardHistory, open, rememberHistory, reset, shiftElements, source, templateHtml, u, unshiftElements, updated;
4974
5099
  u = up.util;
4975
5100
 
4976
5101
  /**
@@ -4982,7 +5107,7 @@ For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead.
4982
5107
 
4983
5108
  Defaults to `undefined`, meaning that the dialog will grow to fit its contents
4984
5109
  until it reaches `options.maxWidth`. Leaving this as `undefined` will
4985
- also allow you to control the width using CSS.
5110
+ also allow you to control the width using CSS on `.up-modal-dialog´.
4986
5111
  @param {Number} [options.maxWidth]
4987
5112
  The width of the dialog as a CSS value like `'400px'` or `50%`.
4988
5113
  You can set this to `undefined` to make the dialog fit its contents.
@@ -5074,21 +5199,32 @@ For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead.
5074
5199
  $modal.hide();
5075
5200
  return $modal;
5076
5201
  };
5077
- unshiftBody = void 0;
5078
- shiftBody = function() {
5079
- var bodyRightPadding, bodyRightShift, scrollbarWidth;
5202
+ unshiftElements = [];
5203
+ shiftElements = function() {
5204
+ var bodyRightPadding, bodyRightShift, scrollbarWidth, unshiftBody;
5080
5205
  scrollbarWidth = u.scrollbarWidth();
5081
5206
  bodyRightPadding = parseInt($('body').css('padding-right'));
5082
5207
  bodyRightShift = scrollbarWidth + bodyRightPadding;
5083
- return unshiftBody = u.temporaryCss($('body'), {
5208
+ unshiftBody = u.temporaryCss($('body'), {
5084
5209
  'padding-right': bodyRightShift + "px",
5085
5210
  'overflow-y': 'hidden'
5086
5211
  });
5212
+ unshiftElements.push(unshiftBody);
5213
+ return up.layout.anchoredRight().each(function() {
5214
+ var $element, elementRight, elementRightShift, unshiftElement;
5215
+ $element = $(this);
5216
+ elementRight = parseInt($element.css('right'));
5217
+ elementRightShift = scrollbarWidth + elementRight;
5218
+ unshiftElement = u.temporaryCss($element, {
5219
+ 'right': elementRightShift
5220
+ });
5221
+ return unshiftElements.push(unshiftElement);
5222
+ });
5087
5223
  };
5088
5224
  updated = function($modal, animation, animateOptions) {
5089
5225
  var promise;
5090
5226
  up.bus.emit('modal:open');
5091
- shiftBody();
5227
+ shiftElements();
5092
5228
  $modal.show();
5093
5229
  promise = up.animate($modal, animation, animateOptions);
5094
5230
  promise.then(function() {
@@ -5235,7 +5371,10 @@ For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead.
5235
5371
  up.bus.emit('modal:close');
5236
5372
  promise = up.destroy($modal, options);
5237
5373
  promise.then(function() {
5238
- unshiftBody();
5374
+ var unshifter;
5375
+ while (unshifter = unshiftElements.pop()) {
5376
+ unshifter();
5377
+ }
5239
5378
  return up.bus.emit('modal:closed');
5240
5379
  });
5241
5380
  return promise;
@@ -5365,8 +5504,9 @@ For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead.
5365
5504
  @ujs
5366
5505
  */
5367
5506
  up.on('click', '[up-close]', function(event, $element) {
5368
- if ($element.closest('.up-modal')) {
5369
- return close();
5507
+ if ($element.closest('.up-modal').length) {
5508
+ close();
5509
+ return event.preventDefault();
5370
5510
  }
5371
5511
  });
5372
5512
  up.bus.on('framework:reset', reset);