upjs-rails 0.8.2 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dist/up-bootstrap.js +13 -0
- data/dist/up-bootstrap.min.js +1 -1
- data/dist/up.js +342 -108
- data/dist/up.min.js +2 -2
- data/lib/assets/javascripts/up-bootstrap/layout-ext.js.coffee +5 -0
- data/lib/assets/javascripts/up-bootstrap/modal-ext.js.coffee +0 -5
- data/lib/assets/javascripts/up-bootstrap/navigation-ext.js.coffee +4 -0
- data/lib/assets/javascripts/up.js.coffee +1 -1
- data/lib/assets/javascripts/up/flow.js.coffee +54 -40
- data/lib/assets/javascripts/up/layout.js.coffee +330 -0
- data/lib/assets/javascripts/up/link.js.coffee +6 -3
- data/lib/assets/javascripts/up/modal.js.coffee +21 -12
- data/lib/assets/javascripts/up/util.js.coffee +35 -9
- data/lib/upjs/rails/version.rb +1 -1
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +47 -3
- data/spec_app/spec/javascripts/up/layout_spec.js.coffee +240 -0
- data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +0 -1
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +6 -0
- metadata +6 -4
- data/lib/assets/javascripts/up/viewport.js.coffee +0 -174
- data/spec_app/spec/javascripts/up/viewport_spec.js.coffee +0 -122
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc09b20d83f04c7aab8c11e39ee0eb4f7eb6f9e3
|
4
|
+
data.tar.gz: 0f6e623d66e8d2bd8a5ec25aa906e3999eaf5cc3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0adae829accb44dd0fea004cd41bd27169a9c8cc33ea4cbb4ce9639bd81639506d617eb49206a11917b6e0851e9d2d9d1c2ff6b4ead30c987ea53d9aeaabfea6
|
7
|
+
data.tar.gz: 688bf765d4cf1dde1aeb9193f17f41c253c9788b66c8e54cdb73ea1027102f4356c551d46c1aab5b161bf407ba4f3b88ca9d185d3ad6f56d94f88f9c3b8a98d7
|
data/dist/up-bootstrap.js
CHANGED
@@ -1,8 +1,21 @@
|
|
1
|
+
(function() {
|
2
|
+
var defaults;
|
3
|
+
|
4
|
+
defaults = up.layout.defaults();
|
5
|
+
|
6
|
+
up.layout.defaults({
|
7
|
+
fixedTop: defaults.fixedTop + ", .navbar-fixed-top",
|
8
|
+
fixedBottom: defaults.fixedBottom + ", .navbar-fixed-bottom"
|
9
|
+
});
|
10
|
+
|
11
|
+
}).call(this);
|
1
12
|
(function() {
|
2
13
|
up.modal.defaults({
|
3
14
|
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>"
|
4
15
|
});
|
5
16
|
|
17
|
+
}).call(this);
|
18
|
+
(function() {
|
6
19
|
up.navigation.defaults({
|
7
20
|
currentClass: 'active'
|
8
21
|
});
|
data/dist/up-bootstrap.min.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
(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>'}),up.navigation.defaults({currentClass:"active"})}
|
1
|
+
(function(){var a;a=up.layout.defaults(),up.layout.defaults({fixedTop:a.fixedTop+", .navbar-fixed-top",fixedBottom:a.fixedBottom+", .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(){up.navigation.defaults({currentClass:"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, castsToFalse, castsToTrue, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, debug, detect, each, error, escapePressed, extend, findWithSelf, finishCssAnimate, forceCompositing, get, ifGiven, isArray, isBlank, isDeferred, isDefined, isElement, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, keys, last, locationFromXhr, measure, memoize, merge, methodFromXhr, nextFrame, normalizeMethod, normalizeUrl, nullJquery, once, only, option, options, prependGhost, presence, presentAttr, remove, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, setMissingAttrs, stringifyConsoleArgs, temporaryCss, times, toArray, trim, uniq,
|
28
|
+
var $createElementFromSelector, ANIMATION_PROMISE_KEY, CONSOLE_PLACEHOLDERS, ajax, castsToFalse, castsToTrue, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, debug, detect, each, endsWith, error, escapePressed, extend, findWithSelf, finishCssAnimate, forceCompositing, get, identity, ifGiven, isArray, isBlank, isDeferred, isDefined, isElement, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, keys, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, nextFrame, normalizeMethod, normalizeUrl, nullJquery, once, only, option, options, prependGhost, 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;
|
@@ -85,7 +85,7 @@ If you use them in your own code, you will get hurt.
|
|
85
85
|
anchor.href = anchor.href;
|
86
86
|
}
|
87
87
|
} else {
|
88
|
-
anchor =
|
88
|
+
anchor = unJquery(urlOrAnchor);
|
89
89
|
}
|
90
90
|
normalized = anchor.protocol + "//" + anchor.hostname;
|
91
91
|
if (!isStandardPort(anchor.protocol, anchor.port)) {
|
@@ -197,7 +197,7 @@ If you use them in your own code, you will get hurt.
|
|
197
197
|
var i, maxLength, message;
|
198
198
|
message = args[0];
|
199
199
|
i = 0;
|
200
|
-
maxLength =
|
200
|
+
maxLength = 50;
|
201
201
|
return message.replace(CONSOLE_PLACEHOLDERS, function() {
|
202
202
|
var arg, argType;
|
203
203
|
i += 1;
|
@@ -208,12 +208,16 @@ If you use them in your own code, you will get hurt.
|
|
208
208
|
if (arg.length > maxLength) {
|
209
209
|
arg = (arg.substr(0, maxLength)) + "…";
|
210
210
|
}
|
211
|
-
|
211
|
+
arg = "\"" + arg + "\"";
|
212
212
|
} else if (argType === 'number') {
|
213
|
-
|
213
|
+
arg = arg.toString();
|
214
214
|
} else {
|
215
|
-
|
215
|
+
arg = JSON.stringify(arg);
|
216
|
+
if (arg.length > maxLength) {
|
217
|
+
arg = (arg.substr(0, maxLength)) + "…";
|
218
|
+
}
|
216
219
|
}
|
220
|
+
return arg;
|
217
221
|
});
|
218
222
|
};
|
219
223
|
createSelectorFromElement = function($element) {
|
@@ -282,6 +286,10 @@ If you use them in your own code, you will get hurt.
|
|
282
286
|
}
|
283
287
|
return results;
|
284
288
|
};
|
289
|
+
map = each;
|
290
|
+
identity = function(x) {
|
291
|
+
return x;
|
292
|
+
};
|
285
293
|
times = function(count, block) {
|
286
294
|
var iteration, j, ref, results;
|
287
295
|
results = [];
|
@@ -363,7 +371,7 @@ If you use them in your own code, you will get hurt.
|
|
363
371
|
return extend({}, object);
|
364
372
|
}
|
365
373
|
};
|
366
|
-
|
374
|
+
unJquery = function(object) {
|
367
375
|
if (isJQuery(object)) {
|
368
376
|
return object.get(0);
|
369
377
|
} else {
|
@@ -691,6 +699,12 @@ If you use them in your own code, you will get hurt.
|
|
691
699
|
escapePressed = function(event) {
|
692
700
|
return event.keyCode === 27;
|
693
701
|
};
|
702
|
+
startsWith = function(string, element) {
|
703
|
+
return string.indexOf(element) === 0;
|
704
|
+
};
|
705
|
+
endsWith = function(string, element) {
|
706
|
+
return string.indexOf(element) === string.length - element.length;
|
707
|
+
};
|
694
708
|
contains = function(stringOrArray, element) {
|
695
709
|
return stringOrArray.indexOf(element) >= 0;
|
696
710
|
};
|
@@ -796,23 +810,35 @@ If you use them in your own code, you will get hurt.
|
|
796
810
|
return hash.update(copy(factoryOptions));
|
797
811
|
},
|
798
812
|
update: function(options) {
|
799
|
-
var key,
|
800
|
-
|
813
|
+
var key, value;
|
814
|
+
if (options == null) {
|
815
|
+
options = {};
|
816
|
+
}
|
801
817
|
for (key in options) {
|
802
818
|
value = options[key];
|
803
819
|
if (factoryOptions.hasOwnProperty(key)) {
|
804
|
-
|
820
|
+
hash[key] = value;
|
805
821
|
} else {
|
806
|
-
|
822
|
+
error("Unknown setting %o", key);
|
807
823
|
}
|
808
824
|
}
|
809
|
-
return
|
825
|
+
return hash;
|
810
826
|
}
|
811
827
|
};
|
812
828
|
apiKeys = Object.getOwnPropertyNames(hash);
|
813
829
|
hash.reset();
|
814
830
|
return hash;
|
815
831
|
};
|
832
|
+
unwrapElement = function(wrapper) {
|
833
|
+
var parent, wrappedNodes;
|
834
|
+
wrapper = unJquery(wrapper);
|
835
|
+
parent = wrapper.parentNode;
|
836
|
+
wrappedNodes = toArray(wrapper.childNodes);
|
837
|
+
each(wrappedNodes, function(wrappedNode) {
|
838
|
+
return parent.insertBefore(wrappedNode, wrapper);
|
839
|
+
});
|
840
|
+
return parent.removeChild(wrapper);
|
841
|
+
};
|
816
842
|
return {
|
817
843
|
presentAttr: presentAttr,
|
818
844
|
createElement: createElement,
|
@@ -832,6 +858,8 @@ If you use them in your own code, you will get hurt.
|
|
832
858
|
debug: debug,
|
833
859
|
warn: warn,
|
834
860
|
each: each,
|
861
|
+
map: map,
|
862
|
+
identity: identity,
|
835
863
|
times: times,
|
836
864
|
detect: detect,
|
837
865
|
select: select,
|
@@ -858,7 +886,7 @@ If you use them in your own code, you will get hurt.
|
|
858
886
|
isUnmodifiedKeyEvent: isUnmodifiedKeyEvent,
|
859
887
|
isUnmodifiedMouseEvent: isUnmodifiedMouseEvent,
|
860
888
|
nullJquery: nullJquery,
|
861
|
-
|
889
|
+
unJquery: unJquery,
|
862
890
|
nextFrame: nextFrame,
|
863
891
|
measure: measure,
|
864
892
|
temporaryCss: temporaryCss,
|
@@ -870,6 +898,8 @@ If you use them in your own code, you will get hurt.
|
|
870
898
|
copyAttributes: copyAttributes,
|
871
899
|
findWithSelf: findWithSelf,
|
872
900
|
contains: contains,
|
901
|
+
startsWith: startsWith,
|
902
|
+
endsWith: endsWith,
|
873
903
|
isArray: isArray,
|
874
904
|
toArray: toArray,
|
875
905
|
castsToTrue: castsToTrue,
|
@@ -887,7 +917,8 @@ If you use them in your own code, you will get hurt.
|
|
887
917
|
remove: remove,
|
888
918
|
memoize: memoize,
|
889
919
|
scrollbarWidth: scrollbarWidth,
|
890
|
-
config: config
|
920
|
+
config: config,
|
921
|
+
unwrapElement: unwrapElement
|
891
922
|
};
|
892
923
|
})();
|
893
924
|
|
@@ -1164,32 +1195,33 @@ Viewport scrolling
|
|
1164
1195
|
|
1165
1196
|
This modules contains functions to scroll the viewport and reveal contained elements.
|
1166
1197
|
|
1167
|
-
|
1168
|
-
|
1169
|
-
The container that will be scrolled is the closest parent of the element that is either:
|
1170
|
-
|
1171
|
-
- The currently open [modal](/up.modal)
|
1172
|
-
- An element with the attribute `[up-viewport]`
|
1173
|
-
- The `<body>` element
|
1174
|
-
- An element matching the selector you have configured using `up.viewport.defaults({ viewSelector: 'my-custom-selector' })`.
|
1175
|
-
|
1176
|
-
@class up.viewport
|
1198
|
+
@class up.layout
|
1177
1199
|
*/
|
1178
1200
|
|
1179
1201
|
(function() {
|
1180
|
-
|
1181
|
-
|
1202
|
+
var slice = [].slice;
|
1203
|
+
|
1204
|
+
up.layout = (function() {
|
1205
|
+
var SCROLL_PROMISE_KEY, config, findViewport, finishScrolling, measureObstruction, reset, reveal, scroll, u;
|
1182
1206
|
u = up.util;
|
1183
1207
|
|
1184
1208
|
/**
|
1185
|
-
|
1209
|
+
|
1210
|
+
|
1211
|
+
@method up.layout.defaults
|
1212
|
+
@param {String} [options.viewport]
|
1213
|
+
@param {String} [options.fixedTop]
|
1214
|
+
@param {String} [options.fixedBottom]
|
1186
1215
|
@param {Number} [options.duration]
|
1187
1216
|
@param {String} [options.easing]
|
1188
|
-
@param {
|
1217
|
+
@param {Number} [options.snap]
|
1189
1218
|
*/
|
1190
1219
|
config = u.config({
|
1191
1220
|
duration: 0,
|
1192
|
-
|
1221
|
+
viewport: 'body, .up-modal, [up-viewport]',
|
1222
|
+
fixedTop: '[up-fixed~=top]',
|
1223
|
+
fixedBottom: '[up-fixed~=bottom]',
|
1224
|
+
snap: 50,
|
1193
1225
|
easing: 'swing'
|
1194
1226
|
});
|
1195
1227
|
reset = function() {
|
@@ -1198,17 +1230,46 @@ The container that will be scrolled is the closest parent of the element that is
|
|
1198
1230
|
SCROLL_PROMISE_KEY = 'up-scroll-promise';
|
1199
1231
|
|
1200
1232
|
/**
|
1233
|
+
Scrolls the given viewport to the given Y-position.
|
1234
|
+
|
1235
|
+
A "viewport" is an element that has scrollbars, e.g. `<body>` or
|
1236
|
+
a container with `overflow-x: scroll`.
|
1237
|
+
|
1238
|
+
\#\#\#\# Example
|
1239
|
+
|
1240
|
+
This will scroll a `<div class="main">...</div>` to a Y-position of 100 pixels:
|
1241
|
+
|
1242
|
+
up.scoll('.main', 100);
|
1243
|
+
|
1244
|
+
\#\#\#\# Animating the scrolling motion
|
1245
|
+
|
1246
|
+
The scrolling can (optionally) be animated.
|
1247
|
+
|
1248
|
+
up.scoll('.main', 100, {
|
1249
|
+
easing: 'swing',
|
1250
|
+
duration: 250
|
1251
|
+
});
|
1252
|
+
|
1253
|
+
If the given viewport is already in a scroll animation when `up.scroll`
|
1254
|
+
is called a second time, the previous animation will instantly jump to the
|
1255
|
+
last frame before the next animation is started.
|
1256
|
+
|
1257
|
+
@protected
|
1201
1258
|
@method up.scroll
|
1202
|
-
@param {String|Element|jQuery}
|
1259
|
+
@param {String|Element|jQuery} viewport
|
1260
|
+
The container element to scroll.
|
1203
1261
|
@param {Number} scrollPos
|
1204
|
-
|
1262
|
+
The absolute number of pixels to set the scroll position to.
|
1263
|
+
@param {Number}[options.duration]
|
1264
|
+
The number of miliseconds for the scrolling's animation.
|
1205
1265
|
@param {String}[options.easing]
|
1266
|
+
The timing function that controls the acceleration for the scrolling's animation.
|
1206
1267
|
@return {Deferred}
|
1207
|
-
|
1268
|
+
A promise that will be resolved when the scrolling ends.
|
1208
1269
|
*/
|
1209
|
-
scroll = function(
|
1270
|
+
scroll = function(viewport, scrollTop, options) {
|
1210
1271
|
var $view, deferred, duration, easing, targetProps;
|
1211
|
-
$view = $(
|
1272
|
+
$view = $(viewport);
|
1212
1273
|
options = u.options(options);
|
1213
1274
|
duration = u.option(options.duration, config.duration);
|
1214
1275
|
easing = u.option(options.easing, config.easing);
|
@@ -1249,45 +1310,124 @@ The container that will be scrolled is the closest parent of the element that is
|
|
1249
1310
|
}
|
1250
1311
|
});
|
1251
1312
|
};
|
1313
|
+
measureObstruction = function() {
|
1314
|
+
var fixedBottomTops, fixedTopBottoms, measurePosition, obstructor;
|
1315
|
+
measurePosition = function(obstructor, cssAttr) {
|
1316
|
+
var $obstructor, anchorPosition;
|
1317
|
+
$obstructor = $(obstructor);
|
1318
|
+
anchorPosition = $obstructor.css(cssAttr);
|
1319
|
+
if (!(anchorPosition === '0' || u.endsWith(anchorPosition, 'px'))) {
|
1320
|
+
u.error("Fixed element must have an anchor position in px, but was %o", anchorPosition);
|
1321
|
+
}
|
1322
|
+
return parseInt(anchorPosition) + $obstructor.height();
|
1323
|
+
};
|
1324
|
+
fixedTopBottoms = (function() {
|
1325
|
+
var i, len, ref, results;
|
1326
|
+
ref = $(config.fixedTop);
|
1327
|
+
results = [];
|
1328
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
1329
|
+
obstructor = ref[i];
|
1330
|
+
results.push(measurePosition(obstructor, 'top'));
|
1331
|
+
}
|
1332
|
+
return results;
|
1333
|
+
})();
|
1334
|
+
fixedBottomTops = (function() {
|
1335
|
+
var i, len, ref, results;
|
1336
|
+
ref = $(config.fixedBottom);
|
1337
|
+
results = [];
|
1338
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
1339
|
+
obstructor = ref[i];
|
1340
|
+
results.push(measurePosition(obstructor, 'bottom'));
|
1341
|
+
}
|
1342
|
+
return results;
|
1343
|
+
})();
|
1344
|
+
return {
|
1345
|
+
top: Math.max.apply(Math, [0].concat(slice.call(fixedTopBottoms))),
|
1346
|
+
bottom: Math.max.apply(Math, [0].concat(slice.call(fixedBottomTops)))
|
1347
|
+
};
|
1348
|
+
};
|
1252
1349
|
|
1253
1350
|
/**
|
1351
|
+
Scroll's the given element's viewport so the element
|
1352
|
+
is visible for the user.
|
1353
|
+
|
1354
|
+
By default Up.js will always reveal an element before
|
1355
|
+
updating it with Javascript functions like [`up.replace`](/up.flow#up.replace)
|
1356
|
+
or UJS behavior like [`[up-target]`](/up.link#up-target).
|
1357
|
+
|
1358
|
+
\#\#\#\# How Up.js finds the viewport
|
1359
|
+
|
1360
|
+
The viewport (the container that is going to be scrolled)
|
1361
|
+
is the closest parent of the element that is either:
|
1362
|
+
|
1363
|
+
- the currently open [modal](/up.modal)
|
1364
|
+
- an element with the attribute `[up-viewport]`
|
1365
|
+
- the `<body>` element
|
1366
|
+
- an element matching the selector you have configured using `up.viewport.defaults({ viewSelector: 'my-custom-selector' })`
|
1367
|
+
|
1368
|
+
\#\#\#\# Fixed elements obstruction the viewport
|
1369
|
+
|
1370
|
+
Many applications have a navigation bar fixed to the top or bottom,
|
1371
|
+
obstructing the view on an element.
|
1372
|
+
|
1373
|
+
To make `up.aware` of these fixed elements you can either:
|
1374
|
+
|
1375
|
+
- give the element an attribute [`up-fixed="top"`](#up-fixed-top) or [`up-fixed="bottom"`](up-fixed-bottom)
|
1376
|
+
- [configure default options](#up.layout.defaults) for `fixedTop` or `fixedBottom`
|
1377
|
+
|
1254
1378
|
@method up.reveal
|
1255
1379
|
@param {String|Element|jQuery} element
|
1256
|
-
@param {String|Element|jQuery} [options.
|
1380
|
+
@param {String|Element|jQuery} [options.viewport]
|
1257
1381
|
@param {Number} [options.duration]
|
1258
1382
|
@param {String} [options.easing]
|
1383
|
+
@param {String} [options.snap]
|
1259
1384
|
@return {Deferred}
|
1260
|
-
|
1385
|
+
A promise that will be resolved when the element is revealed.
|
1261
1386
|
*/
|
1262
1387
|
reveal = function(elementOrSelector, options) {
|
1263
|
-
var $element, $
|
1388
|
+
var $element, $viewport, elementDims, firstElementRow, lastElementRow, newScrollPos, obstruction, offsetShift, originalScrollPos, predictFirstVisibleRow, predictLastVisibleRow, snap, viewportHeight, viewportIsBody;
|
1264
1389
|
options = u.options(options);
|
1265
1390
|
$element = $(elementOrSelector);
|
1266
|
-
$
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1391
|
+
$viewport = findViewport($element, options.viewport);
|
1392
|
+
snap = u.option(options.snap, config.snap);
|
1393
|
+
viewportIsBody = $viewport.is('body');
|
1394
|
+
viewportHeight = viewportIsBody ? u.clientSize().height : $viewport.height();
|
1395
|
+
originalScrollPos = $viewport.scrollTop();
|
1270
1396
|
newScrollPos = originalScrollPos;
|
1271
|
-
offsetShift =
|
1272
|
-
|
1273
|
-
|
1397
|
+
offsetShift = void 0;
|
1398
|
+
obstruction = void 0;
|
1399
|
+
if (viewportIsBody) {
|
1400
|
+
obstruction = measureObstruction();
|
1401
|
+
offsetShift = 0;
|
1402
|
+
} else {
|
1403
|
+
obstruction = {
|
1404
|
+
top: 0,
|
1405
|
+
bottom: 0
|
1406
|
+
};
|
1407
|
+
offsetShift = originalScrollPos;
|
1408
|
+
}
|
1409
|
+
predictFirstVisibleRow = function() {
|
1410
|
+
return newScrollPos + obstruction.top;
|
1274
1411
|
};
|
1275
|
-
|
1276
|
-
return newScrollPos +
|
1412
|
+
predictLastVisibleRow = function() {
|
1413
|
+
return newScrollPos + viewportHeight - obstruction.bottom - 1;
|
1277
1414
|
};
|
1278
1415
|
elementDims = u.measure($element, {
|
1279
1416
|
relative: true
|
1280
1417
|
});
|
1281
1418
|
firstElementRow = elementDims.top + offsetShift;
|
1282
1419
|
lastElementRow = firstElementRow + elementDims.height - 1;
|
1283
|
-
if (lastElementRow >
|
1284
|
-
newScrollPos += lastElementRow -
|
1420
|
+
if (lastElementRow > predictLastVisibleRow()) {
|
1421
|
+
newScrollPos += lastElementRow - predictLastVisibleRow();
|
1285
1422
|
}
|
1286
|
-
if (firstElementRow <
|
1287
|
-
newScrollPos = firstElementRow;
|
1423
|
+
if (firstElementRow < predictFirstVisibleRow()) {
|
1424
|
+
newScrollPos = firstElementRow - obstruction.top;
|
1425
|
+
}
|
1426
|
+
if (newScrollPos < snap) {
|
1427
|
+
newScrollPos = 0;
|
1288
1428
|
}
|
1289
1429
|
if (newScrollPos !== originalScrollPos) {
|
1290
|
-
return scroll($
|
1430
|
+
return scroll($viewport, newScrollPos, options);
|
1291
1431
|
} else {
|
1292
1432
|
return u.resolvedDeferred();
|
1293
1433
|
}
|
@@ -1295,27 +1435,99 @@ The container that will be scrolled is the closest parent of the element that is
|
|
1295
1435
|
|
1296
1436
|
/**
|
1297
1437
|
@private
|
1298
|
-
@method up.viewport.
|
1438
|
+
@method up.viewport.findViewport
|
1299
1439
|
*/
|
1300
|
-
|
1301
|
-
var $
|
1302
|
-
$
|
1303
|
-
if (u.isJQuery(
|
1304
|
-
$
|
1440
|
+
findViewport = function($element, viewportSelectorOrElement) {
|
1441
|
+
var $viewport, vieportSelector;
|
1442
|
+
$viewport = void 0;
|
1443
|
+
if (u.isJQuery(viewportSelectorOrElement)) {
|
1444
|
+
$viewport = viewportSelectorOrElement;
|
1305
1445
|
} else {
|
1306
|
-
|
1307
|
-
$
|
1446
|
+
vieportSelector = u.presence(viewportSelectorOrElement) || config.viewport;
|
1447
|
+
$viewport = $element.closest(vieportSelector);
|
1308
1448
|
}
|
1309
|
-
$
|
1310
|
-
return $
|
1449
|
+
$viewport.length || u.error("Could not find viewport for %o", $element);
|
1450
|
+
return $viewport;
|
1311
1451
|
};
|
1312
1452
|
|
1313
1453
|
/**
|
1314
|
-
Marks this element as a scrolling container.
|
1315
|
-
|
1316
|
-
|
1454
|
+
Marks this element as a scrolling container. Apply this ttribute if your app uses
|
1455
|
+
a custom panel layout with fixed positioning instead of scrolling `<body>`.
|
1456
|
+
|
1457
|
+
[`up.reveal`](/up.reveal) will always try to scroll the viewport closest
|
1458
|
+
to the element that is being revealed. By default this is the `<body>` element.
|
1459
|
+
|
1460
|
+
\#\#\#\# Example
|
1461
|
+
|
1462
|
+
Here is an example for a layout for an e-mail client, showing a list of e-mails
|
1463
|
+
on the left side and the e-mail text on the right side:
|
1464
|
+
|
1465
|
+
.side {
|
1466
|
+
position: fixed;
|
1467
|
+
top: 0;
|
1468
|
+
bottom: 0;
|
1469
|
+
left: 0;
|
1470
|
+
width: 100px;
|
1471
|
+
overflow-y: scroll;
|
1472
|
+
}
|
1473
|
+
|
1474
|
+
.main {
|
1475
|
+
position: fixed;
|
1476
|
+
top: 0;
|
1477
|
+
bottom: 0;
|
1478
|
+
left: 100px;
|
1479
|
+
right: 0;
|
1480
|
+
overflow-y: scroll;
|
1481
|
+
}
|
1482
|
+
|
1483
|
+
This would be the HTML (notice the `up-viewport` attribute):
|
1484
|
+
|
1485
|
+
<div class=".side" up-viewport>
|
1486
|
+
<a href="/emails/5001" up-target=".main">Re: Your invoice</a>
|
1487
|
+
<a href="/emails/2023" up-target=".main">Quote for services</a>
|
1488
|
+
<a href="/emails/9002" up-target=".main">Fwd: Room reservation</a>
|
1489
|
+
</div>
|
1490
|
+
|
1491
|
+
<div class="main" up-viewport>
|
1492
|
+
<h1>Re: Your Invoice</h1>
|
1493
|
+
<p>
|
1494
|
+
Lorem ipsum dolor sit amet, consetetur sadipscing elitr.
|
1495
|
+
Stet clita kasd gubergren, no sea takimata sanctus est.
|
1496
|
+
</p>
|
1497
|
+
</div>
|
1317
1498
|
|
1318
1499
|
@method [up-viewport]
|
1500
|
+
@ujs
|
1501
|
+
*/
|
1502
|
+
|
1503
|
+
/**
|
1504
|
+
Marks this element as a navigation fixed to the top edge of the screen
|
1505
|
+
using `position: fixed`.
|
1506
|
+
|
1507
|
+
[`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
|
1508
|
+
the viewport far enough so the revealed element is fully visible.
|
1509
|
+
|
1510
|
+
Example:
|
1511
|
+
|
1512
|
+
<div class="top-nav" up-fixed="top">...</div>
|
1513
|
+
|
1514
|
+
@method [up-fixed=top]
|
1515
|
+
@ujs
|
1516
|
+
*/
|
1517
|
+
|
1518
|
+
/**
|
1519
|
+
Marks this element as a navigation fixed to the bottom edge of the screen
|
1520
|
+
using `position: fixed`.
|
1521
|
+
|
1522
|
+
[`up.reveal`](/up.reveal) is aware of fixed elements and will scroll
|
1523
|
+
the viewport far enough so the revealed element is fully visible.
|
1524
|
+
|
1525
|
+
Example:
|
1526
|
+
|
1527
|
+
<div class="bottom-nav" up-fixed="bottom">...</div>
|
1528
|
+
|
1529
|
+
@method [up-fixed=bottom]
|
1530
|
+
@ujs
|
1319
1531
|
*/
|
1320
1532
|
up.bus.on('framework:reset', reset);
|
1321
1533
|
return {
|
@@ -1326,9 +1538,9 @@ The container that will be scrolled is the closest parent of the element that is
|
|
1326
1538
|
};
|
1327
1539
|
})();
|
1328
1540
|
|
1329
|
-
up.scroll = up.
|
1541
|
+
up.scroll = up.layout.scroll;
|
1330
1542
|
|
1331
|
-
up.reveal = up.
|
1543
|
+
up.reveal = up.layout.reveal;
|
1332
1544
|
|
1333
1545
|
}).call(this);
|
1334
1546
|
|
@@ -1352,7 +1564,7 @@ We need to work on this page:
|
|
1352
1564
|
|
1353
1565
|
(function() {
|
1354
1566
|
up.flow = (function() {
|
1355
|
-
var autofocus, destroy, elementsInserted, findOldFragment, first, fragmentNotFound, implant, isRealElement, parseImplantSteps, parseResponse,
|
1567
|
+
var autofocus, destroy, elementsInserted, findOldFragment, first, fragmentNotFound, implant, isRealElement, parseImplantSteps, parseResponse, reload, replace, reset, reveal, setSource, source, swapElements, u;
|
1356
1568
|
u = up.util;
|
1357
1569
|
setSource = function(element, sourceUrl) {
|
1358
1570
|
var $element;
|
@@ -1388,7 +1600,11 @@ We need to work on this page:
|
|
1388
1600
|
If omitted or true, the `url` argument will be used.
|
1389
1601
|
If set to `false`, the history will remain unchanged.
|
1390
1602
|
@param {String|Boolean} [options.source=true]
|
1391
|
-
@param {String} [options.scroll
|
1603
|
+
@param {String} [options.scroll]
|
1604
|
+
Up.js will try to [reveal](/up.layout#up.reveal) the element being updated, by
|
1605
|
+
scrolling its containing viewport. Set this option to `false` to prevent any scrolling.
|
1606
|
+
|
1607
|
+
If omitted, this will use the [default from `up.layout`](/up.layout#up.layout.defaults).
|
1392
1608
|
@param {Boolean} [options.cache]
|
1393
1609
|
Whether to use a [cached response](/up.proxy) if available.
|
1394
1610
|
@param {String} [options.historyMethod='push']
|
@@ -1471,7 +1687,7 @@ We need to work on this page:
|
|
1471
1687
|
options.history = null;
|
1472
1688
|
}
|
1473
1689
|
if (u.castsToFalse(options.scroll)) {
|
1474
|
-
options.scroll =
|
1690
|
+
options.scroll = false;
|
1475
1691
|
}
|
1476
1692
|
options.source = u.option(options.source, options.history);
|
1477
1693
|
response = parseResponse(html);
|
@@ -1481,10 +1697,8 @@ We need to work on this page:
|
|
1481
1697
|
for (j = 0, len = ref.length; j < len; j++) {
|
1482
1698
|
step = ref[j];
|
1483
1699
|
$old = findOldFragment(step.selector);
|
1484
|
-
$new = response.find(step.selector);
|
1485
|
-
results.push(
|
1486
|
-
return swapElements($old, $new, step.pseudoClass, step.transition, options);
|
1487
|
-
}));
|
1700
|
+
$new = response.find(step.selector).first();
|
1701
|
+
results.push(swapElements($old, $new, step.pseudoClass, step.transition, options));
|
1488
1702
|
}
|
1489
1703
|
return results;
|
1490
1704
|
};
|
@@ -1517,14 +1731,12 @@ We need to work on this page:
|
|
1517
1731
|
}
|
1518
1732
|
};
|
1519
1733
|
};
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
reveal = function($element, view) {
|
1525
|
-
if (view) {
|
1734
|
+
reveal = function($element, options) {
|
1735
|
+
var viewport;
|
1736
|
+
viewport = options.scroll;
|
1737
|
+
if (viewport !== false) {
|
1526
1738
|
return up.reveal($element, {
|
1527
|
-
|
1739
|
+
viewport: viewport
|
1528
1740
|
});
|
1529
1741
|
} else {
|
1530
1742
|
return u.resolvedDeferred();
|
@@ -1545,25 +1757,32 @@ We need to work on this page:
|
|
1545
1757
|
return up.ready($new);
|
1546
1758
|
};
|
1547
1759
|
swapElements = function($old, $new, pseudoClass, transition, options) {
|
1548
|
-
var $
|
1760
|
+
var $wrapper, insertionMethod;
|
1549
1761
|
transition || (transition = 'none');
|
1762
|
+
up.motion.finish($old);
|
1550
1763
|
if (pseudoClass) {
|
1551
1764
|
insertionMethod = pseudoClass === 'before' ? 'prepend' : 'append';
|
1552
|
-
$
|
1553
|
-
$old[insertionMethod]($
|
1765
|
+
$wrapper = $new.contents().wrap('<span class="up-insertion"></span>').parent();
|
1766
|
+
$old[insertionMethod]($wrapper);
|
1554
1767
|
u.copyAttributes($new, $old);
|
1555
|
-
elementsInserted($
|
1556
|
-
return
|
1768
|
+
elementsInserted($wrapper.children(), options);
|
1769
|
+
return reveal($wrapper, options).then(function() {
|
1770
|
+
return up.animate($wrapper, transition, options);
|
1771
|
+
}).then(function() {
|
1772
|
+
u.unwrapElement($wrapper);
|
1773
|
+
});
|
1557
1774
|
} else {
|
1558
|
-
return
|
1559
|
-
|
1560
|
-
|
1561
|
-
|
1562
|
-
|
1563
|
-
|
1775
|
+
return reveal($old, options).then(function() {
|
1776
|
+
return destroy($old, {
|
1777
|
+
animation: function() {
|
1778
|
+
$new.insertBefore($old);
|
1779
|
+
elementsInserted($new, options);
|
1780
|
+
if ($old.is('body') && transition !== 'none') {
|
1781
|
+
u.error('Cannot apply transitions to body-elements (%o)', transition);
|
1782
|
+
}
|
1783
|
+
return up.morph($old, $new, transition, options);
|
1564
1784
|
}
|
1565
|
-
|
1566
|
-
}
|
1785
|
+
});
|
1567
1786
|
});
|
1568
1787
|
}
|
1569
1788
|
};
|
@@ -1662,9 +1881,10 @@ We need to work on this page:
|
|
1662
1881
|
}
|
1663
1882
|
up.bus.emit('fragment:destroy', $element);
|
1664
1883
|
animationPromise = u.presence(options.animation, u.isPromise) || up.motion.animate($element, options.animation, animateOptions);
|
1665
|
-
|
1884
|
+
animationPromise.then(function() {
|
1666
1885
|
return $element.remove();
|
1667
1886
|
});
|
1887
|
+
return animationPromise;
|
1668
1888
|
};
|
1669
1889
|
|
1670
1890
|
/**
|
@@ -3273,12 +3493,17 @@ Read on
|
|
3273
3493
|
@method up.visit
|
3274
3494
|
@param {String} url
|
3275
3495
|
The URL to visit.
|
3496
|
+
@param {String} [options.target='body']
|
3497
|
+
The selector to replace.
|
3498
|
+
See options for [`up.replace`](/up.flow#up.replace)
|
3276
3499
|
@param {Object} options
|
3277
3500
|
See options for [`up.replace`](/up.flow#up.replace)
|
3278
3501
|
*/
|
3279
3502
|
visit = function(url, options) {
|
3280
|
-
|
3281
|
-
|
3503
|
+
var selector;
|
3504
|
+
options = u.options(options);
|
3505
|
+
selector = u.option(options.target, 'body');
|
3506
|
+
return up.replace(selector, url, options);
|
3282
3507
|
};
|
3283
3508
|
|
3284
3509
|
/**
|
@@ -4338,13 +4563,6 @@ For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead.
|
|
4338
4563
|
|
4339
4564
|
Any option attributes for [`a[up-modal]`](#a.up-modal) will be honored.
|
4340
4565
|
|
4341
|
-
You can also open a URL directly like this:
|
4342
|
-
|
4343
|
-
up.modal.open({ url: '/foo', target: '.list' })
|
4344
|
-
|
4345
|
-
This will request `/foo`, extract the `.list` selector from the response
|
4346
|
-
and open the selected container in a modal dialog.
|
4347
|
-
|
4348
4566
|
\#\#\#\# Events
|
4349
4567
|
|
4350
4568
|
- Emits an [event](/up.bus) `modal:open` when the modal
|
@@ -4353,12 +4571,8 @@ For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead.
|
|
4353
4571
|
animation has finished and the modal contents are fully visible.
|
4354
4572
|
|
4355
4573
|
@method up.modal.open
|
4356
|
-
@param {Element|jQuery|String}
|
4574
|
+
@param {Element|jQuery|String} elementOrSelector
|
4357
4575
|
The link to follow.
|
4358
|
-
Can be omitted if you give `options.url` instead.
|
4359
|
-
@param {String} [options.url]
|
4360
|
-
The URL to open.
|
4361
|
-
Can be omitted if you give `elementOrSelector` instead.
|
4362
4576
|
@param {String} [options.target]
|
4363
4577
|
The selector to extract from the response and open in a modal dialog.
|
4364
4578
|
@param {Number} [options.width]
|
@@ -4383,6 +4597,26 @@ For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead.
|
|
4383
4597
|
@return {Promise}
|
4384
4598
|
A promise that will be resolved when the modal has finished loading.
|
4385
4599
|
*/
|
4600
|
+
|
4601
|
+
/**
|
4602
|
+
Opens a modal for the given URL.
|
4603
|
+
|
4604
|
+
Example:
|
4605
|
+
|
4606
|
+
up.modal.open({ url: '/foo', target: '.list' })
|
4607
|
+
|
4608
|
+
This will request `/foo`, extract the `.list` selector from the response
|
4609
|
+
and open the selected container in a modal dialog.
|
4610
|
+
|
4611
|
+
@method up.modal.open
|
4612
|
+
@param {String} options.url
|
4613
|
+
The URL to load.
|
4614
|
+
@param {String} options.target
|
4615
|
+
The CSS selector to extract from the response.
|
4616
|
+
The extracted content will be placed into the dialog window.
|
4617
|
+
@param {Object} options
|
4618
|
+
See options for [previous `up.modal.open` variant](#up.modal.open).
|
4619
|
+
*/
|
4386
4620
|
open = function() {
|
4387
4621
|
var $link, $modal, animateOptions, animation, args, height, history, maxWidth, options, selector, sticky, url, width;
|
4388
4622
|
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|