upjs-rails 0.10.5 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 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);