upjs-rails 0.8.2 → 0.9.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 +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) : [];
|