upjs-rails 0.18.1 → 0.19.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/CHANGELOG.md +13 -0
- data/dist/up.js +906 -453
- data/dist/up.min.js +3 -2
- data/lib/assets/javascripts/up/browser.js.coffee +3 -1
- data/lib/assets/javascripts/up/flow.js.coffee +277 -67
- data/lib/assets/javascripts/up/log.js.coffee +1 -0
- data/lib/assets/javascripts/up/motion.js.coffee +12 -3
- data/lib/assets/javascripts/up/proxy.js.coffee +8 -5
- data/lib/assets/javascripts/up/syntax.js.coffee +41 -57
- data/lib/assets/javascripts/up/util.js.coffee +38 -21
- data/lib/upjs/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +1 -4
- data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +1 -2
- data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +5 -0
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +269 -18
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +5 -5
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +5 -5
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +36 -36
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +43 -2
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +150 -6
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 77dcd1a1f7e464a6f108d1fb3fafcc34c1c6c06e
|
4
|
+
data.tar.gz: 63001606276d007e811562e6c1e26d078a45fa63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43e602670030b82cb89e564dfa223bfa3a602872ff55225f09915b066c3e0588e620affd0fbe670c6eb4f9a9648b0adc37c8f4186c244842e3ac37f7b9b8b175
|
7
|
+
data.tar.gz: 00c7bfc420e1f6397f18c9f7bb703a406e6ef3bfbf7d5881a72104514220e323cf47b0c6307de7c91123174eed84fc75516c4d5a12334c143cac914b559612c8
|
data/CHANGELOG.md
CHANGED
@@ -10,9 +10,22 @@ Unreleased
|
|
10
10
|
|
11
11
|
### Compatible changes
|
12
12
|
|
13
|
+
### Breaking changes
|
14
|
+
|
15
|
+
|
16
|
+
0.19.0
|
17
|
+
------
|
18
|
+
|
19
|
+
### Compatible changes
|
20
|
+
|
21
|
+
- Elements can now be persisted during page updates using the [`up-keep`](/up-keep) attribute.
|
22
|
+
- `up.proxy.ajax` is now available as [`up.ajax`](/up.ajax).
|
23
|
+
- `up.ajax` can now handle nested objects as `{ data }` option (used to pass form parameters).
|
13
24
|
|
14
25
|
### Breaking changes
|
15
26
|
|
27
|
+
- `up.implant` has been renamed to [`up.extract`](/up.extract).
|
28
|
+
|
16
29
|
|
17
30
|
0.18.1
|
18
31
|
------
|
data/dist/up.js
CHANGED
@@ -27,7 +27,7 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
27
27
|
@function up.util.memoize
|
28
28
|
@internal
|
29
29
|
*/
|
30
|
-
var $createElementFromSelector, ANIMATION_PROMISE_KEY,
|
30
|
+
var $createElementFromSelector, $createPlaceholder, ANIMATION_PROMISE_KEY, all, any, cache, castedAttr, clientSize, compact, config, contains, copy, copyAttributes, createElement, createElementFromHtml, cssAnimate, detect, each, error, escapePressed, except, extend, findWithSelf, finishCssAnimate, fixedToAbsolute, forceCompositing, intersect, isArray, isBlank, isDeferred, isDefined, isElement, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isNumber, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, last, locationFromXhr, map, measure, memoize, merge, methodFromXhr, multiSelector, nextFrame, nonUpClasses, normalizeMethod, normalizeUrl, nullJQuery, offsetParent, once, only, option, options, parseUrl, presence, presentAttr, reject, remove, requestDataAsArray, requestDataAsQuery, resolvableWhen, resolvedDeferred, resolvedPromise, scrollbarWidth, select, selectorForElement, setMissingAttrs, temporaryCss, times, titleFromXhr, toArray, trim, unJQuery, uniq, unresolvableDeferred, unresolvablePromise, unwrapElement;
|
31
31
|
memoize = function(func) {
|
32
32
|
var cache, cached;
|
33
33
|
cache = void 0;
|
@@ -140,17 +140,17 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
140
140
|
@internal
|
141
141
|
*/
|
142
142
|
$createElementFromSelector = function(selector) {
|
143
|
-
var $element, $parent, $root, classes, conjunction, depthSelector, expression, html, id, iteration, j,
|
143
|
+
var $element, $parent, $root, classes, conjunction, depthSelector, expression, html, i, id, iteration, j, len, len1, path, tag;
|
144
144
|
path = selector.split(/[ >]/);
|
145
145
|
$root = null;
|
146
|
-
for (iteration =
|
146
|
+
for (iteration = i = 0, len = path.length; i < len; iteration = ++i) {
|
147
147
|
depthSelector = path[iteration];
|
148
148
|
conjunction = depthSelector.match(/(^|\.|\#)[A-Za-z0-9\-_]+/g);
|
149
149
|
tag = "div";
|
150
150
|
classes = [];
|
151
151
|
id = null;
|
152
|
-
for (
|
153
|
-
expression = conjunction[
|
152
|
+
for (j = 0, len1 = conjunction.length; j < len1; j++) {
|
153
|
+
expression = conjunction[j];
|
154
154
|
switch (expression[0]) {
|
155
155
|
case ".":
|
156
156
|
classes.push(expression.substr(1));
|
@@ -191,90 +191,17 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
191
191
|
};
|
192
192
|
|
193
193
|
/**
|
194
|
-
|
195
|
-
|
196
|
-
@function up.debug
|
197
|
-
@param {String} message
|
198
|
-
@param {Array} args...
|
199
|
-
@internal
|
200
|
-
*/
|
201
|
-
debug = function() {
|
202
|
-
var args, message, ref;
|
203
|
-
message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
204
|
-
message = "[UP] " + message;
|
205
|
-
return (ref = up.browser).puts.apply(ref, ['debug', message].concat(slice.call(args)));
|
206
|
-
};
|
207
|
-
|
208
|
-
/**
|
209
|
-
@function up.warn
|
210
|
-
@internal
|
211
|
-
*/
|
212
|
-
warn = function() {
|
213
|
-
var args, message, ref;
|
214
|
-
message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
215
|
-
message = "[UP] " + message;
|
216
|
-
return (ref = up.browser).puts.apply(ref, ['warn', message].concat(slice.call(args)));
|
217
|
-
};
|
218
|
-
|
219
|
-
/**
|
220
|
-
Throws a fatal error with the given message.
|
221
|
-
|
222
|
-
- The error will be printed to the [error console](https://developer.mozilla.org/en-US/docs/Web/API/Console/error)
|
223
|
-
- An [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) (exception) will be thrown, unwinding the current call stack
|
224
|
-
- The error message will be printed in a corner of the screen
|
225
|
-
|
226
|
-
\#\#\#\# Examples
|
227
|
-
|
228
|
-
up.error('Division by zero')
|
229
|
-
up.error('Unexpected result %o', result)
|
230
|
-
|
231
|
-
@function up.error
|
232
|
-
@internal
|
194
|
+
@function $create
|
233
195
|
*/
|
234
|
-
|
235
|
-
var $
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
$
|
241
|
-
$
|
242
|
-
$
|
243
|
-
throw new Error(asString);
|
244
|
-
};
|
245
|
-
CONSOLE_PLACEHOLDERS = /\%[odisf]/g;
|
246
|
-
evalConsoleTemplate = function() {
|
247
|
-
var args, i, maxLength, message;
|
248
|
-
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
249
|
-
message = args[0];
|
250
|
-
i = 0;
|
251
|
-
maxLength = 80;
|
252
|
-
return message.replace(CONSOLE_PLACEHOLDERS, function() {
|
253
|
-
var arg, argType;
|
254
|
-
i += 1;
|
255
|
-
arg = args[i];
|
256
|
-
argType = typeof arg;
|
257
|
-
if (argType === 'string') {
|
258
|
-
arg = arg.replace(/\s+/g, ' ');
|
259
|
-
if (arg.length > maxLength) {
|
260
|
-
arg = (arg.substr(0, maxLength)) + "…";
|
261
|
-
}
|
262
|
-
arg = "\"" + arg + "\"";
|
263
|
-
} else if (argType === 'undefined') {
|
264
|
-
arg = 'undefined';
|
265
|
-
} else if (argType === 'number' || argType === 'function') {
|
266
|
-
arg = arg.toString();
|
267
|
-
} else {
|
268
|
-
arg = JSON.stringify(arg);
|
269
|
-
}
|
270
|
-
if (arg.length > maxLength) {
|
271
|
-
arg = (arg.substr(0, maxLength)) + " …";
|
272
|
-
if (argType === 'object' || argType === 'function') {
|
273
|
-
arg += " }";
|
274
|
-
}
|
275
|
-
}
|
276
|
-
return arg;
|
277
|
-
});
|
196
|
+
$createPlaceholder = function(selector, container) {
|
197
|
+
var $placeholder;
|
198
|
+
if (container == null) {
|
199
|
+
container = document.body;
|
200
|
+
}
|
201
|
+
$placeholder = $createElementFromSelector(selector);
|
202
|
+
$placeholder.addClass('up-placeholder');
|
203
|
+
$placeholder.appendTo(container);
|
204
|
+
return $placeholder;
|
278
205
|
};
|
279
206
|
|
280
207
|
/**
|
@@ -294,10 +221,10 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
294
221
|
@experimental
|
295
222
|
*/
|
296
223
|
selectorForElement = function(element) {
|
297
|
-
var $element, classes,
|
224
|
+
var $element, classes, i, id, klass, len, name, selector, upId;
|
298
225
|
$element = $(element);
|
299
226
|
selector = void 0;
|
300
|
-
|
227
|
+
up.puts("Creating selector from element %o", $element.get(0));
|
301
228
|
if (upId = presence($element.attr("up-id"))) {
|
302
229
|
selector = "[up-id='" + upId + "']";
|
303
230
|
} else if (id = presence($element.attr("id"))) {
|
@@ -305,10 +232,9 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
305
232
|
} else if (name = presence($element.attr("name"))) {
|
306
233
|
selector = "[name='" + name + "']";
|
307
234
|
} else if (classes = presence(nonUpClasses($element))) {
|
308
|
-
console.log("using klass!", classes);
|
309
235
|
selector = '';
|
310
|
-
for (
|
311
|
-
klass = classes[
|
236
|
+
for (i = 0, len = classes.length; i < len; i++) {
|
237
|
+
klass = classes[i];
|
312
238
|
selector += "." + klass;
|
313
239
|
}
|
314
240
|
} else {
|
@@ -387,9 +313,9 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
387
313
|
@stable
|
388
314
|
*/
|
389
315
|
each = function(array, block) {
|
390
|
-
var index, item,
|
316
|
+
var i, index, item, len, results;
|
391
317
|
results = [];
|
392
|
-
for (index =
|
318
|
+
for (index = i = 0, len = array.length; i < len; index = ++i) {
|
393
319
|
item = array[index];
|
394
320
|
results.push(block(item, index));
|
395
321
|
}
|
@@ -418,9 +344,9 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
418
344
|
@stable
|
419
345
|
*/
|
420
346
|
times = function(count, block) {
|
421
|
-
var
|
347
|
+
var i, iteration, ref, results;
|
422
348
|
results = [];
|
423
|
-
for (iteration =
|
349
|
+
for (iteration = i = 0, ref = count - 1; 0 <= ref ? i <= ref : i >= ref; iteration = 0 <= ref ? ++i : --i) {
|
424
350
|
results.push(block(iteration));
|
425
351
|
}
|
426
352
|
return results;
|
@@ -797,10 +723,10 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
797
723
|
@stable
|
798
724
|
*/
|
799
725
|
detect = function(array, tester) {
|
800
|
-
var element,
|
726
|
+
var element, i, len, match;
|
801
727
|
match = void 0;
|
802
|
-
for (
|
803
|
-
element = array[
|
728
|
+
for (i = 0, len = array.length; i < len; i++) {
|
729
|
+
element = array[i];
|
804
730
|
if (tester(element)) {
|
805
731
|
match = element;
|
806
732
|
break;
|
@@ -820,10 +746,10 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
820
746
|
@experimental
|
821
747
|
*/
|
822
748
|
any = function(array, tester) {
|
823
|
-
var element,
|
749
|
+
var element, i, len, match;
|
824
750
|
match = false;
|
825
|
-
for (
|
826
|
-
element = array[
|
751
|
+
for (i = 0, len = array.length; i < len; i++) {
|
752
|
+
element = array[i];
|
827
753
|
if (tester(element)) {
|
828
754
|
match = true;
|
829
755
|
break;
|
@@ -832,6 +758,29 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
832
758
|
return match;
|
833
759
|
};
|
834
760
|
|
761
|
+
/**
|
762
|
+
Returns whether the given function returns a truthy value
|
763
|
+
for all elements in the given array.
|
764
|
+
|
765
|
+
@function up.util.all
|
766
|
+
@param {Array<T>} array
|
767
|
+
@param {Function<T>} tester
|
768
|
+
@return {Boolean}
|
769
|
+
@experimental
|
770
|
+
*/
|
771
|
+
all = function(array, tester) {
|
772
|
+
var element, i, len, match;
|
773
|
+
match = true;
|
774
|
+
for (i = 0, len = array.length; i < len; i++) {
|
775
|
+
element = array[i];
|
776
|
+
if (!tester(element)) {
|
777
|
+
match = false;
|
778
|
+
break;
|
779
|
+
}
|
780
|
+
}
|
781
|
+
return match;
|
782
|
+
};
|
783
|
+
|
835
784
|
/**
|
836
785
|
Returns all elements from the given array that are
|
837
786
|
neither `null` or `undefined`.
|
@@ -925,10 +874,10 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
925
874
|
var $element, attrName, attrNames, values;
|
926
875
|
$element = arguments[0], attrNames = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
927
876
|
values = (function() {
|
928
|
-
var
|
877
|
+
var i, len, results;
|
929
878
|
results = [];
|
930
|
-
for (
|
931
|
-
attrName = attrNames[
|
879
|
+
for (i = 0, len = attrNames.length; i < len; i++) {
|
880
|
+
attrName = attrNames[i];
|
932
881
|
results.push($element.attr(attrName));
|
933
882
|
}
|
934
883
|
return results;
|
@@ -1212,11 +1161,11 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1212
1161
|
@internal
|
1213
1162
|
*/
|
1214
1163
|
copyAttributes = function($source, $target) {
|
1215
|
-
var attr,
|
1164
|
+
var attr, i, len, ref, results;
|
1216
1165
|
ref = $source.get(0).attributes;
|
1217
1166
|
results = [];
|
1218
|
-
for (
|
1219
|
-
attr = ref[
|
1167
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
1168
|
+
attr = ref[i];
|
1220
1169
|
if (attr.specified) {
|
1221
1170
|
results.push($target.attr(attr.name, attr.value));
|
1222
1171
|
} else {
|
@@ -1311,11 +1260,11 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1311
1260
|
@stable
|
1312
1261
|
*/
|
1313
1262
|
only = function() {
|
1314
|
-
var filtered,
|
1263
|
+
var filtered, i, len, object, properties, property;
|
1315
1264
|
object = arguments[0], properties = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
1316
1265
|
filtered = {};
|
1317
|
-
for (
|
1318
|
-
property = properties[
|
1266
|
+
for (i = 0, len = properties.length; i < len; i++) {
|
1267
|
+
property = properties[i];
|
1319
1268
|
if (object.hasOwnProperty(property)) {
|
1320
1269
|
filtered[property] = object[property];
|
1321
1270
|
}
|
@@ -1333,11 +1282,11 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1333
1282
|
@stable
|
1334
1283
|
*/
|
1335
1284
|
except = function() {
|
1336
|
-
var filtered,
|
1285
|
+
var filtered, i, len, object, properties, property;
|
1337
1286
|
object = arguments[0], properties = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
1338
1287
|
filtered = copy(object);
|
1339
|
-
for (
|
1340
|
-
property = properties[
|
1288
|
+
for (i = 0, len = properties.length; i < len; i++) {
|
1289
|
+
property = properties[i];
|
1341
1290
|
delete filtered[property];
|
1342
1291
|
}
|
1343
1292
|
return filtered;
|
@@ -1484,12 +1433,12 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1484
1433
|
@internal
|
1485
1434
|
*/
|
1486
1435
|
multiSelector = function(parts) {
|
1487
|
-
var combinedSelector, elements,
|
1436
|
+
var combinedSelector, elements, i, len, obj, part, selectors;
|
1488
1437
|
obj = {};
|
1489
1438
|
selectors = [];
|
1490
1439
|
elements = [];
|
1491
|
-
for (
|
1492
|
-
part = parts[
|
1440
|
+
for (i = 0, len = parts.length; i < len; i++) {
|
1441
|
+
part = parts[i];
|
1493
1442
|
if (isString(part)) {
|
1494
1443
|
selectors.push(part);
|
1495
1444
|
} else {
|
@@ -1505,11 +1454,11 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1505
1454
|
return obj.find(void 0);
|
1506
1455
|
};
|
1507
1456
|
obj.find = function($root) {
|
1508
|
-
var $matches, $result,
|
1457
|
+
var $matches, $result, j, len1, ref, selector;
|
1509
1458
|
$result = nullJQuery();
|
1510
1459
|
ref = obj.parsed;
|
1511
|
-
for (
|
1512
|
-
selector = ref[
|
1460
|
+
for (j = 0, len1 = ref.length; j < len1; j++) {
|
1461
|
+
selector = ref[j];
|
1513
1462
|
$matches = $root ? $root.find(selector) : $(selector);
|
1514
1463
|
$result = $result.add($matches);
|
1515
1464
|
}
|
@@ -1577,7 +1526,7 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1577
1526
|
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
1578
1527
|
if (config.log) {
|
1579
1528
|
args[0] = "[" + config.log + "] " + args[0];
|
1580
|
-
return
|
1529
|
+
return up.puts.apply(up, args);
|
1581
1530
|
}
|
1582
1531
|
};
|
1583
1532
|
keys = function() {
|
@@ -1635,7 +1584,9 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1635
1584
|
};
|
1636
1585
|
alias = function(oldKey, newKey) {
|
1637
1586
|
var value;
|
1638
|
-
value = get(oldKey
|
1587
|
+
value = get(oldKey, {
|
1588
|
+
silent: true
|
1589
|
+
});
|
1639
1590
|
if (isDefined(value)) {
|
1640
1591
|
return set(newKey, value);
|
1641
1592
|
}
|
@@ -1666,24 +1617,30 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1666
1617
|
return true;
|
1667
1618
|
}
|
1668
1619
|
};
|
1669
|
-
get = function(key,
|
1620
|
+
get = function(key, options) {
|
1670
1621
|
var entry, storeKey;
|
1671
|
-
if (
|
1672
|
-
|
1622
|
+
if (options == null) {
|
1623
|
+
options = {};
|
1673
1624
|
}
|
1674
1625
|
storeKey = normalizeStoreKey(key);
|
1675
1626
|
if (entry = store[storeKey]) {
|
1676
1627
|
if (isFresh(entry)) {
|
1677
|
-
|
1628
|
+
if (!options.silent) {
|
1629
|
+
log("Cache hit for '%s'", key);
|
1630
|
+
}
|
1678
1631
|
return entry.value;
|
1679
1632
|
} else {
|
1680
|
-
|
1633
|
+
if (!options.silent) {
|
1634
|
+
log("Discarding stale cache entry for '%s'", key);
|
1635
|
+
}
|
1681
1636
|
remove(key);
|
1682
|
-
return
|
1637
|
+
return void 0;
|
1683
1638
|
}
|
1684
1639
|
} else {
|
1685
|
-
|
1686
|
-
|
1640
|
+
if (!options.silent) {
|
1641
|
+
log("Cache miss for '%s'", key);
|
1642
|
+
}
|
1643
|
+
return void 0;
|
1687
1644
|
}
|
1688
1645
|
};
|
1689
1646
|
return {
|
@@ -1774,51 +1731,68 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1774
1731
|
@internal
|
1775
1732
|
*/
|
1776
1733
|
requestDataAsArray = function(data) {
|
1777
|
-
var
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
value: value
|
1734
|
+
var array, i, len, pair, part, query, ref;
|
1735
|
+
query = requestDataAsQuery(data);
|
1736
|
+
array = [];
|
1737
|
+
ref = query.split('&');
|
1738
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
1739
|
+
part = ref[i];
|
1740
|
+
if (isPresent(part)) {
|
1741
|
+
pair = part.split('=');
|
1742
|
+
array.push({
|
1743
|
+
name: decodeURIComponent(pair[0]),
|
1744
|
+
value: decodeURIComponent(pair[1])
|
1789
1745
|
});
|
1790
1746
|
}
|
1791
|
-
return results;
|
1792
|
-
} else {
|
1793
|
-
return error('Unknown options.data type for %o', data);
|
1794
1747
|
}
|
1748
|
+
return array;
|
1795
1749
|
};
|
1796
1750
|
|
1797
1751
|
/**
|
1798
1752
|
Returns an URL-encoded query string for the given params object.
|
1799
1753
|
|
1800
|
-
@function up.util.
|
1754
|
+
@function up.util.requestDataAsQuery
|
1801
1755
|
@param {Object|Array|Undefined|Null} data
|
1802
1756
|
@internal
|
1803
1757
|
*/
|
1804
|
-
|
1805
|
-
var
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
1809
|
-
query
|
1810
|
-
|
1811
|
-
|
1812
|
-
query += '&';
|
1813
|
-
}
|
1814
|
-
return query += encodeURIComponent(field.name) + '=' + encodeURIComponent(field.value);
|
1815
|
-
});
|
1758
|
+
requestDataAsQuery = function(data) {
|
1759
|
+
var query;
|
1760
|
+
if (data) {
|
1761
|
+
query = $.param(data);
|
1762
|
+
query = query.replace(/\+/g, '%20');
|
1763
|
+
return query;
|
1764
|
+
} else {
|
1765
|
+
return "";
|
1816
1766
|
}
|
1817
|
-
|
1767
|
+
};
|
1768
|
+
|
1769
|
+
/**
|
1770
|
+
Throws a fatal error with the given message.
|
1771
|
+
|
1772
|
+
- The error will be printed to the [error console](https://developer.mozilla.org/en-US/docs/Web/API/Console/error)
|
1773
|
+
- An [`Error`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error) (exception) will be thrown, unwinding the current call stack
|
1774
|
+
- The error message will be printed in a corner of the screen
|
1775
|
+
|
1776
|
+
\#\#\#\# Examples
|
1777
|
+
|
1778
|
+
up.error('Division by zero')
|
1779
|
+
up.error('Unexpected result %o', result)
|
1780
|
+
|
1781
|
+
@experimental
|
1782
|
+
*/
|
1783
|
+
error = function() {
|
1784
|
+
var $error, args, asString, ref, ref1;
|
1785
|
+
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
1786
|
+
(ref = up.log).error.apply(ref, args);
|
1787
|
+
asString = (ref1 = up.browser).sprintf.apply(ref1, args);
|
1788
|
+
$error = presence($('.up-error')) || $('<div class="up-error"></div>').prependTo('body');
|
1789
|
+
$error.addClass('up-error');
|
1790
|
+
$error.text(asString);
|
1791
|
+
throw new Error(asString);
|
1818
1792
|
};
|
1819
1793
|
return {
|
1820
1794
|
requestDataAsArray: requestDataAsArray,
|
1821
|
-
|
1795
|
+
requestDataAsQuery: requestDataAsQuery,
|
1822
1796
|
offsetParent: offsetParent,
|
1823
1797
|
fixedToAbsolute: fixedToAbsolute,
|
1824
1798
|
presentAttr: presentAttr,
|
@@ -1828,6 +1802,7 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1828
1802
|
normalizeMethod: normalizeMethod,
|
1829
1803
|
createElementFromHtml: createElementFromHtml,
|
1830
1804
|
$createElementFromSelector: $createElementFromSelector,
|
1805
|
+
$createPlaceholder: $createPlaceholder,
|
1831
1806
|
selectorForElement: selectorForElement,
|
1832
1807
|
extend: extend,
|
1833
1808
|
copy: copy,
|
@@ -1835,12 +1810,11 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1835
1810
|
options: options,
|
1836
1811
|
option: option,
|
1837
1812
|
error: error,
|
1838
|
-
debug: debug,
|
1839
|
-
warn: warn,
|
1840
1813
|
each: each,
|
1841
1814
|
map: map,
|
1842
1815
|
times: times,
|
1843
1816
|
any: any,
|
1817
|
+
all: all,
|
1844
1818
|
detect: detect,
|
1845
1819
|
select: select,
|
1846
1820
|
reject: reject,
|
@@ -1901,15 +1875,112 @@ that might save you from loading something like [Underscore.js](http://underscor
|
|
1901
1875
|
cache: cache,
|
1902
1876
|
unwrapElement: unwrapElement,
|
1903
1877
|
multiSelector: multiSelector,
|
1904
|
-
|
1878
|
+
error: error
|
1905
1879
|
};
|
1906
1880
|
})($);
|
1907
1881
|
|
1908
1882
|
up.error = up.util.error;
|
1909
1883
|
|
1910
|
-
|
1884
|
+
}).call(this);
|
1885
|
+
(function() {
|
1886
|
+
var slice = [].slice;
|
1887
|
+
|
1888
|
+
up.log = (function($) {
|
1889
|
+
var debug, error, group, prefix, puts, warn;
|
1890
|
+
prefix = function(message) {
|
1891
|
+
return "ᴜᴘ " + message;
|
1892
|
+
};
|
1893
|
+
|
1894
|
+
/**
|
1895
|
+
Prints a debugging message to the browser console.
|
1896
|
+
|
1897
|
+
@function up.debug
|
1898
|
+
@param {String} message
|
1899
|
+
@param {Array} args...
|
1900
|
+
@internal
|
1901
|
+
*/
|
1902
|
+
debug = function() {
|
1903
|
+
var args, message, ref;
|
1904
|
+
message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
1905
|
+
if (message) {
|
1906
|
+
return (ref = up.browser).puts.apply(ref, ['debug', prefix(message)].concat(slice.call(args)));
|
1907
|
+
}
|
1908
|
+
};
|
1909
|
+
|
1910
|
+
/**
|
1911
|
+
Prints a logging message to the browser console.
|
1912
|
+
|
1913
|
+
@function up.puts
|
1914
|
+
@param {String} message
|
1915
|
+
@param {Array} args...
|
1916
|
+
@internal
|
1917
|
+
*/
|
1918
|
+
puts = function() {
|
1919
|
+
var args, message, ref;
|
1920
|
+
message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
1921
|
+
if (message) {
|
1922
|
+
return (ref = up.browser).puts.apply(ref, ['log', prefix(message)].concat(slice.call(args)));
|
1923
|
+
}
|
1924
|
+
};
|
1911
1925
|
|
1912
|
-
|
1926
|
+
/**
|
1927
|
+
@function up.log.warn
|
1928
|
+
@internal
|
1929
|
+
*/
|
1930
|
+
warn = function() {
|
1931
|
+
var args, message, ref;
|
1932
|
+
message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
1933
|
+
if (message) {
|
1934
|
+
return (ref = up.browser).puts.apply(ref, ['warn', prefix(message)].concat(slice.call(args)));
|
1935
|
+
}
|
1936
|
+
};
|
1937
|
+
|
1938
|
+
/**
|
1939
|
+
- Makes sure the group always closes
|
1940
|
+
- Does not make a group if the message is nil
|
1941
|
+
|
1942
|
+
@function up.log.group
|
1943
|
+
@internal
|
1944
|
+
*/
|
1945
|
+
group = function() {
|
1946
|
+
var args, block, message, ref;
|
1947
|
+
message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
1948
|
+
block = args.pop();
|
1949
|
+
if (message) {
|
1950
|
+
(ref = up.browser).puts.apply(ref, ['groupCollapsed', prefix(message)].concat(slice.call(args)));
|
1951
|
+
try {
|
1952
|
+
return block();
|
1953
|
+
} finally {
|
1954
|
+
if (message) {
|
1955
|
+
console.groupEnd();
|
1956
|
+
}
|
1957
|
+
}
|
1958
|
+
} else {
|
1959
|
+
return block();
|
1960
|
+
}
|
1961
|
+
};
|
1962
|
+
|
1963
|
+
/**
|
1964
|
+
@function up.log.error
|
1965
|
+
@internal
|
1966
|
+
*/
|
1967
|
+
error = function() {
|
1968
|
+
var args, message, ref;
|
1969
|
+
message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
1970
|
+
if (message) {
|
1971
|
+
return (ref = up.browser).puts.apply(ref, ['error', prefix(message)].concat(slice.call(args)));
|
1972
|
+
}
|
1973
|
+
};
|
1974
|
+
return {
|
1975
|
+
puts: puts,
|
1976
|
+
debug: debug,
|
1977
|
+
error: error,
|
1978
|
+
warn: warn,
|
1979
|
+
group: group
|
1980
|
+
};
|
1981
|
+
})(jQuery);
|
1982
|
+
|
1983
|
+
up.puts = up.log.puts;
|
1913
1984
|
|
1914
1985
|
}).call(this);
|
1915
1986
|
|
@@ -1927,7 +1998,7 @@ we can't currently get rid off.
|
|
1927
1998
|
var slice = [].slice;
|
1928
1999
|
|
1929
2000
|
up.browser = (function($) {
|
1930
|
-
var canCssTransition, canInputEvent, canLogSubstitution, canPushState, confirm, initialRequestMethod, isIE8OrWorse, isIE9OrWorse, isRecentJQuery, isSupported, loadPage, popCookie, puts, u, url;
|
2001
|
+
var CONSOLE_PLACEHOLDERS, canCssTransition, canInputEvent, canLogSubstitution, canPushState, confirm, initialRequestMethod, installPolyfills, isIE8OrWorse, isIE9OrWorse, isRecentJQuery, isSupported, loadPage, popCookie, puts, sprintf, u, url;
|
1931
2002
|
u = up.util;
|
1932
2003
|
|
1933
2004
|
/**
|
@@ -1938,13 +2009,17 @@ we can't currently get rid off.
|
|
1938
2009
|
@internal
|
1939
2010
|
*/
|
1940
2011
|
loadPage = function(url, options) {
|
1941
|
-
var $form, addField, csrfField, method;
|
2012
|
+
var $form, addField, csrfField, method, query;
|
1942
2013
|
if (options == null) {
|
1943
2014
|
options = {};
|
1944
2015
|
}
|
1945
2016
|
method = u.option(options.method, 'get').toLowerCase();
|
1946
2017
|
if (method === 'get') {
|
1947
|
-
|
2018
|
+
query = u.requestDataAsQuery(options.data);
|
2019
|
+
if (query) {
|
2020
|
+
url = url + "?" + query;
|
2021
|
+
}
|
2022
|
+
return location.href = url;
|
1948
2023
|
} else {
|
1949
2024
|
$form = $("<form method='post' action='" + url + "'></form>");
|
1950
2025
|
addField = function(field) {
|
@@ -1988,10 +2063,50 @@ we can't currently get rid off.
|
|
1988
2063
|
if (canLogSubstitution()) {
|
1989
2064
|
return console[stream].apply(console, args);
|
1990
2065
|
} else {
|
1991
|
-
message =
|
2066
|
+
message = sprintf.apply(null, args);
|
1992
2067
|
return console[stream](message);
|
1993
2068
|
}
|
1994
2069
|
};
|
2070
|
+
CONSOLE_PLACEHOLDERS = /\%[odisf]/g;
|
2071
|
+
|
2072
|
+
/**
|
2073
|
+
See https://developer.mozilla.org/en-US/docs/Web/API/Console#Using_string_substitutions
|
2074
|
+
|
2075
|
+
@function up.browser.sprintf
|
2076
|
+
@internal
|
2077
|
+
*/
|
2078
|
+
sprintf = function() {
|
2079
|
+
var args, i, maxLength, message;
|
2080
|
+
message = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
2081
|
+
i = 0;
|
2082
|
+
maxLength = 80;
|
2083
|
+
return message.replace(CONSOLE_PLACEHOLDERS, function() {
|
2084
|
+
var arg, argType;
|
2085
|
+
arg = args[i];
|
2086
|
+
argType = typeof arg;
|
2087
|
+
if (argType === 'string') {
|
2088
|
+
arg = arg.replace(/\s+/g, ' ');
|
2089
|
+
if (arg.length > maxLength) {
|
2090
|
+
arg = (arg.substr(0, maxLength)) + "…";
|
2091
|
+
}
|
2092
|
+
arg = "\"" + arg + "\"";
|
2093
|
+
} else if (argType === 'undefined') {
|
2094
|
+
arg = 'undefined';
|
2095
|
+
} else if (argType === 'number' || argType === 'function') {
|
2096
|
+
arg = arg.toString();
|
2097
|
+
} else {
|
2098
|
+
arg = JSON.stringify(arg);
|
2099
|
+
}
|
2100
|
+
if (arg.length > maxLength) {
|
2101
|
+
arg = (arg.substr(0, maxLength)) + " …";
|
2102
|
+
if (argType === 'object' || argType === 'function') {
|
2103
|
+
arg += " }";
|
2104
|
+
}
|
2105
|
+
}
|
2106
|
+
i += 1;
|
2107
|
+
return arg;
|
2108
|
+
});
|
2109
|
+
};
|
1995
2110
|
url = function() {
|
1996
2111
|
return location.href;
|
1997
2112
|
};
|
@@ -2113,6 +2228,27 @@ we can't currently get rid off.
|
|
2113
2228
|
isSupported = function() {
|
2114
2229
|
return (!isIE8OrWorse()) && isRecentJQuery();
|
2115
2230
|
};
|
2231
|
+
|
2232
|
+
/**
|
2233
|
+
@internal
|
2234
|
+
*/
|
2235
|
+
installPolyfills = function() {
|
2236
|
+
console.group || (console.group = function() {
|
2237
|
+
var args;
|
2238
|
+
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
2239
|
+
return puts.apply(null, ['group'].concat(slice.call(args)));
|
2240
|
+
});
|
2241
|
+
console.groupCollapsed || (console.groupCollapsed = function() {
|
2242
|
+
var args;
|
2243
|
+
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
2244
|
+
return puts.apply(null, ['groupCollapsed'].concat(slice.call(args)));
|
2245
|
+
});
|
2246
|
+
return console.groupEnd || (console.groupEnd = function() {
|
2247
|
+
var args;
|
2248
|
+
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
2249
|
+
return puts.apply(null, ['groupEnd'].concat(slice.call(args)));
|
2250
|
+
});
|
2251
|
+
};
|
2116
2252
|
return {
|
2117
2253
|
url: url,
|
2118
2254
|
loadPage: loadPage,
|
@@ -2122,7 +2258,9 @@ we can't currently get rid off.
|
|
2122
2258
|
canInputEvent: canInputEvent,
|
2123
2259
|
canLogSubstitution: canLogSubstitution,
|
2124
2260
|
isSupported: isSupported,
|
2125
|
-
|
2261
|
+
installPolyfills: installPolyfills,
|
2262
|
+
puts: puts,
|
2263
|
+
sprintf: sprintf
|
2126
2264
|
};
|
2127
2265
|
})(jQuery);
|
2128
2266
|
|
@@ -2173,7 +2311,7 @@ and call `preventDefault()` on the `event` object:
|
|
2173
2311
|
var slice = [].slice;
|
2174
2312
|
|
2175
2313
|
up.bus = (function($) {
|
2176
|
-
var boot, emit, emitReset, forgetUpDescription, live, liveUpDescriptions, nextUpDescriptionNumber, nobodyPrevents, onEscape, rememberUpDescription, restoreSnapshot, snapshot, u, unbind, upDescriptionNumber, upDescriptionToJqueryDescription, upListenerToJqueryListener;
|
2314
|
+
var boot, emit, emitReset, forgetUpDescription, live, liveUpDescriptions, logEmission, nextUpDescriptionNumber, nobodyPrevents, onEscape, rememberUpDescription, restoreSnapshot, snapshot, u, unbind, upDescriptionNumber, upDescriptionToJqueryDescription, upListenerToJqueryListener;
|
2177
2315
|
u = up.util;
|
2178
2316
|
liveUpDescriptions = {};
|
2179
2317
|
nextUpDescriptionNumber = 0;
|
@@ -2372,6 +2510,10 @@ and call `preventDefault()` on the `event` object:
|
|
2372
2510
|
or `stopPropagation()`.
|
2373
2511
|
@param {jQuery} [eventProps.$element=$(document)]
|
2374
2512
|
The element on which the event is triggered.
|
2513
|
+
@param {String|Array} [eventProps.message]
|
2514
|
+
A message to print to the console when the event is emitted.
|
2515
|
+
If omitted, a default message is printed.
|
2516
|
+
Set this to `false` to prevent any console output.
|
2375
2517
|
@experimental
|
2376
2518
|
*/
|
2377
2519
|
emit = function(eventName, eventProps) {
|
@@ -2380,11 +2522,40 @@ and call `preventDefault()` on the `event` object:
|
|
2380
2522
|
eventProps = {};
|
2381
2523
|
}
|
2382
2524
|
event = $.Event(eventName, eventProps);
|
2383
|
-
$target = eventProps.$element
|
2384
|
-
|
2525
|
+
if ($target = eventProps.$element) {
|
2526
|
+
delete eventProps.$element;
|
2527
|
+
} else {
|
2528
|
+
$target = $(document);
|
2529
|
+
}
|
2530
|
+
logEmission(eventName, eventProps);
|
2385
2531
|
$target.trigger(event);
|
2386
2532
|
return event;
|
2387
2533
|
};
|
2534
|
+
logEmission = function(eventName, eventProps) {
|
2535
|
+
var niceMessage, niceMessageArgs, ref;
|
2536
|
+
if (eventProps.hasOwnProperty('message')) {
|
2537
|
+
niceMessage = eventProps.message;
|
2538
|
+
delete eventProps.message;
|
2539
|
+
if (u.isArray(niceMessage)) {
|
2540
|
+
ref = niceMessage, niceMessage = ref[0], niceMessageArgs = 2 <= ref.length ? slice.call(ref, 1) : [];
|
2541
|
+
} else {
|
2542
|
+
niceMessageArgs = [];
|
2543
|
+
}
|
2544
|
+
if (niceMessage) {
|
2545
|
+
if (u.isPresent(eventProps)) {
|
2546
|
+
return up.puts.apply(up, [niceMessage + " (%s (%o))"].concat(slice.call(niceMessageArgs), [eventName], [eventProps]));
|
2547
|
+
} else {
|
2548
|
+
return up.puts.apply(up, [niceMessage + " (%s)"].concat(slice.call(niceMessageArgs), [eventName]));
|
2549
|
+
}
|
2550
|
+
}
|
2551
|
+
} else {
|
2552
|
+
if (u.isPresent(eventProps)) {
|
2553
|
+
return up.puts('Emitted event %s (%o)', eventName, eventProps);
|
2554
|
+
} else {
|
2555
|
+
return up.puts('Emitted event %s', eventName);
|
2556
|
+
}
|
2557
|
+
}
|
2558
|
+
};
|
2388
2559
|
|
2389
2560
|
/**
|
2390
2561
|
[Emits an event](/up.emit) and returns whether any listener
|
@@ -2393,13 +2564,19 @@ and call `preventDefault()` on the `event` object:
|
|
2393
2564
|
@function up.bus.nobodyPrevents
|
2394
2565
|
@param {String} eventName
|
2395
2566
|
@param {Object} eventProps
|
2567
|
+
@param {String|Array} [eventProps.message]
|
2396
2568
|
@experimental
|
2397
2569
|
*/
|
2398
2570
|
nobodyPrevents = function() {
|
2399
2571
|
var args, event;
|
2400
2572
|
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
2401
2573
|
event = emit.apply(null, args);
|
2402
|
-
|
2574
|
+
if (event.isDefaultPrevented()) {
|
2575
|
+
up.puts("An observer prevented the event %s", args[0]);
|
2576
|
+
return false;
|
2577
|
+
} else {
|
2578
|
+
return true;
|
2579
|
+
}
|
2403
2580
|
};
|
2404
2581
|
|
2405
2582
|
/**
|
@@ -2432,7 +2609,7 @@ and call `preventDefault()` on the `event` object:
|
|
2432
2609
|
results = [];
|
2433
2610
|
for (i = 0, len = liveUpDescriptions.length; i < len; i++) {
|
2434
2611
|
description = liveUpDescriptions[i];
|
2435
|
-
results.push(description.
|
2612
|
+
results.push(description.isDefault = true);
|
2436
2613
|
}
|
2437
2614
|
return results;
|
2438
2615
|
};
|
@@ -2446,7 +2623,7 @@ and call `preventDefault()` on the `event` object:
|
|
2446
2623
|
restoreSnapshot = function() {
|
2447
2624
|
var description, doomedDescriptions, i, len, results;
|
2448
2625
|
doomedDescriptions = u.reject(liveUpDescriptions, function(description) {
|
2449
|
-
return description.
|
2626
|
+
return description.isDefault;
|
2450
2627
|
});
|
2451
2628
|
results = [];
|
2452
2629
|
for (i = 0, len = doomedDescriptions.length; i < len; i++) {
|
@@ -2468,7 +2645,9 @@ and call `preventDefault()` on the `event` object:
|
|
2468
2645
|
@experimental
|
2469
2646
|
*/
|
2470
2647
|
emitReset = function() {
|
2471
|
-
return up.emit('up:framework:reset'
|
2648
|
+
return up.emit('up:framework:reset', {
|
2649
|
+
message: 'Resetting framework'
|
2650
|
+
});
|
2472
2651
|
};
|
2473
2652
|
|
2474
2653
|
/**
|
@@ -2493,7 +2672,10 @@ and call `preventDefault()` on the `event` object:
|
|
2493
2672
|
*/
|
2494
2673
|
boot = function() {
|
2495
2674
|
if (up.browser.isSupported()) {
|
2496
|
-
|
2675
|
+
up.browser.installPolyfills();
|
2676
|
+
return up.emit('up:framework:boot', {
|
2677
|
+
message: 'Booting framework'
|
2678
|
+
});
|
2497
2679
|
}
|
2498
2680
|
};
|
2499
2681
|
|
@@ -2568,7 +2750,7 @@ later.
|
|
2568
2750
|
var slice = [].slice;
|
2569
2751
|
|
2570
2752
|
up.syntax = (function($) {
|
2571
|
-
var DESTROYABLE_CLASS, DESTROYER_KEY, applyCompiler, compile, compiler, compilers, data,
|
2753
|
+
var DESTROYABLE_CLASS, DESTROYER_KEY, applyCompiler, clean, compile, compiler, compilers, data, reset, snapshot, u;
|
2572
2754
|
u = up.util;
|
2573
2755
|
DESTROYABLE_CLASS = 'up-destroyable';
|
2574
2756
|
DESTROYER_KEY = 'up-destroyer';
|
@@ -2714,6 +2896,11 @@ later.
|
|
2714
2896
|
If set to `true` and a fragment insertion contains multiple
|
2715
2897
|
elements matching the selector, `compiler` is only called once
|
2716
2898
|
with a jQuery collection containing all matching elements.
|
2899
|
+
@param {Boolean} [options.keep=false]
|
2900
|
+
If set to `true` compiled fragment will be [persisted](/up-keep) during
|
2901
|
+
[page updates](/a-up-target).
|
2902
|
+
|
2903
|
+
This has the same effect as setting an `up-keep` attribute on the element.
|
2717
2904
|
@param {Function($element, data)} compiler
|
2718
2905
|
The function to call when a matching element is inserted.
|
2719
2906
|
The function takes the new element as the first argument (as a jQuery object).
|
@@ -2728,7 +2915,6 @@ later.
|
|
2728
2915
|
@stable
|
2729
2916
|
*/
|
2730
2917
|
compilers = [];
|
2731
|
-
defaultCompilers = null;
|
2732
2918
|
compiler = function() {
|
2733
2919
|
var args, options, selector;
|
2734
2920
|
selector = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
@@ -2736,46 +2922,81 @@ later.
|
|
2736
2922
|
return;
|
2737
2923
|
}
|
2738
2924
|
compiler = args.pop();
|
2739
|
-
options = u.options(args[0]
|
2740
|
-
batch: false
|
2741
|
-
});
|
2925
|
+
options = u.options(args[0]);
|
2742
2926
|
return compilers.push({
|
2743
2927
|
selector: selector,
|
2744
2928
|
callback: compiler,
|
2745
|
-
batch: options.batch
|
2929
|
+
batch: options.batch,
|
2930
|
+
keep: options.keep
|
2746
2931
|
});
|
2747
2932
|
};
|
2748
2933
|
applyCompiler = function(compiler, $jqueryElement, nativeElement) {
|
2749
|
-
var destroyer;
|
2750
|
-
|
2934
|
+
var destroyer, value;
|
2935
|
+
up.puts((!compiler.isDefault ? "Compiling '%s' on %o" : void 0), compiler.selector, nativeElement);
|
2936
|
+
if (compiler.keep) {
|
2937
|
+
value = u.isString(compiler.keep) ? compiler.keep : '';
|
2938
|
+
$jqueryElement.attr('up-keep', value);
|
2939
|
+
}
|
2751
2940
|
destroyer = compiler.callback.apply(nativeElement, [$jqueryElement, data($jqueryElement)]);
|
2752
2941
|
if (u.isFunction(destroyer)) {
|
2753
2942
|
$jqueryElement.addClass(DESTROYABLE_CLASS);
|
2754
2943
|
return $jqueryElement.data(DESTROYER_KEY, destroyer);
|
2755
|
-
}
|
2756
|
-
};
|
2757
|
-
|
2758
|
-
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2762
|
-
|
2763
|
-
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
2769
|
-
|
2944
|
+
}
|
2945
|
+
};
|
2946
|
+
|
2947
|
+
/**
|
2948
|
+
Applies all compilers on the given element and its descendants.
|
2949
|
+
Unlike [`up.hello`](/up.hello), this doesn't emit any events.
|
2950
|
+
|
2951
|
+
@function up.syntax.compile
|
2952
|
+
@param {Array<Element>} [options.skip]
|
2953
|
+
A list of elements whose subtrees should not be compiled.
|
2954
|
+
@internal
|
2955
|
+
*/
|
2956
|
+
compile = function($fragment, options) {
|
2957
|
+
var $skipSubtrees;
|
2958
|
+
options = u.options(options);
|
2959
|
+
$skipSubtrees = $(options.skip);
|
2960
|
+
return up.log.group("Compiling fragment %o", $fragment.get(0), function() {
|
2961
|
+
var $matches, i, len, results;
|
2962
|
+
results = [];
|
2963
|
+
for (i = 0, len = compilers.length; i < len; i++) {
|
2964
|
+
compiler = compilers[i];
|
2965
|
+
$matches = u.findWithSelf($fragment, compiler.selector);
|
2966
|
+
$matches = $matches.filter(function() {
|
2967
|
+
var $match;
|
2968
|
+
$match = $(this);
|
2969
|
+
return u.all($skipSubtrees, function(element) {
|
2970
|
+
return $match.closest(element).length === 0;
|
2971
|
+
});
|
2972
|
+
});
|
2973
|
+
if ($matches.length) {
|
2974
|
+
results.push(up.log.group((!compiler.isDefault ? "Compiling '%s' on %d element(s)" : void 0), compiler.selector, $matches.length, function() {
|
2975
|
+
if (compiler.batch) {
|
2976
|
+
return applyCompiler(compiler, $matches, $matches.get());
|
2977
|
+
} else {
|
2978
|
+
return $matches.each(function() {
|
2979
|
+
return applyCompiler(compiler, $(this), this);
|
2980
|
+
});
|
2981
|
+
}
|
2770
2982
|
}));
|
2983
|
+
} else {
|
2984
|
+
results.push(void 0);
|
2771
2985
|
}
|
2772
|
-
} else {
|
2773
|
-
results.push(void 0);
|
2774
2986
|
}
|
2775
|
-
|
2776
|
-
|
2987
|
+
return results;
|
2988
|
+
});
|
2777
2989
|
};
|
2778
|
-
|
2990
|
+
|
2991
|
+
/**
|
2992
|
+
Runs any destroyers on the given fragment and its descendants.
|
2993
|
+
Unlike [`up.destroy`](/up.destroy), this doesn't emit any events
|
2994
|
+
and does not remove the element from the DOM.
|
2995
|
+
|
2996
|
+
@function up.syntax.clean
|
2997
|
+
@internal
|
2998
|
+
*/
|
2999
|
+
clean = function($fragment) {
|
2779
3000
|
return u.findWithSelf($fragment, "." + DESTROYABLE_CLASS).each(function() {
|
2780
3001
|
var $element, destroyer;
|
2781
3002
|
$element = $(this);
|
@@ -2831,7 +3052,13 @@ later.
|
|
2831
3052
|
@internal
|
2832
3053
|
*/
|
2833
3054
|
snapshot = function() {
|
2834
|
-
|
3055
|
+
var i, len, results;
|
3056
|
+
results = [];
|
3057
|
+
for (i = 0, len = compilers.length; i < len; i++) {
|
3058
|
+
compiler = compilers[i];
|
3059
|
+
results.push(compiler.isDefault = true);
|
3060
|
+
}
|
3061
|
+
return results;
|
2835
3062
|
};
|
2836
3063
|
|
2837
3064
|
/**
|
@@ -2841,80 +3068,22 @@ later.
|
|
2841
3068
|
@internal
|
2842
3069
|
*/
|
2843
3070
|
reset = function() {
|
2844
|
-
return compilers = u.
|
2845
|
-
|
2846
|
-
|
2847
|
-
/**
|
2848
|
-
Compiles a page fragment that has been inserted into the DOM
|
2849
|
-
without Up.js.
|
2850
|
-
|
2851
|
-
**As long as you manipulate the DOM using Up.js, you will never
|
2852
|
-
need to call this method.** You only need to use `up.hello` if the
|
2853
|
-
DOM is manipulated without Up.js' involvement, e.g. by setting
|
2854
|
-
the `innerHTML` property or calling jQuery methods like
|
2855
|
-
`html`, `insertAfter` or `appendTo`:
|
2856
|
-
|
2857
|
-
$element = $('.element');
|
2858
|
-
$element.html('<div>...</div>');
|
2859
|
-
up.hello($element);
|
2860
|
-
|
2861
|
-
This function emits the [`up:fragment:inserted`](/up:fragment:inserted)
|
2862
|
-
event.
|
2863
|
-
|
2864
|
-
@function up.hello
|
2865
|
-
@param {String|Element|jQuery} selectorOrElement
|
2866
|
-
@param {String|Element|jQuery} [options.origin]
|
2867
|
-
@return {jQuery}
|
2868
|
-
The compiled element
|
2869
|
-
@stable
|
2870
|
-
*/
|
2871
|
-
hello = function(selectorOrElement, options) {
|
2872
|
-
var $element, eventAttrs;
|
2873
|
-
$element = $(selectorOrElement);
|
2874
|
-
eventAttrs = u.options(options, {
|
2875
|
-
$element: $element
|
3071
|
+
return compilers = u.select(compilers, function(compiler) {
|
3072
|
+
return compiler.isDefault;
|
2876
3073
|
});
|
2877
|
-
up.emit('up:fragment:inserted', eventAttrs);
|
2878
|
-
return $element;
|
2879
3074
|
};
|
2880
|
-
|
2881
|
-
/**
|
2882
|
-
When a page fragment has been [inserted or updated](/up.replace),
|
2883
|
-
this event is [emitted](/up.emit) on the fragment.
|
2884
|
-
|
2885
|
-
\#\#\#\# Example
|
2886
|
-
|
2887
|
-
up.on('up:fragment:inserted', function(event, $fragment) {
|
2888
|
-
console.log("Looks like we have a new %o!", $fragment);
|
2889
|
-
});
|
2890
|
-
|
2891
|
-
@event up:fragment:inserted
|
2892
|
-
@param {jQuery} event.$element
|
2893
|
-
The fragment that has been inserted or updated.
|
2894
|
-
@stable
|
2895
|
-
*/
|
2896
|
-
up.on('ready', (function() {
|
2897
|
-
return hello(document.body);
|
2898
|
-
}));
|
2899
|
-
up.on('up:fragment:inserted', function(event, $element) {
|
2900
|
-
return compile($element);
|
2901
|
-
});
|
2902
|
-
up.on('up:fragment:destroy', function(event, $element) {
|
2903
|
-
return runDestroyers($element);
|
2904
|
-
});
|
2905
3075
|
up.on('up:framework:boot', snapshot);
|
2906
3076
|
up.on('up:framework:reset', reset);
|
2907
3077
|
return {
|
2908
3078
|
compiler: compiler,
|
2909
|
-
|
3079
|
+
compile: compile,
|
3080
|
+
clean: clean,
|
2910
3081
|
data: data
|
2911
3082
|
};
|
2912
3083
|
})(jQuery);
|
2913
3084
|
|
2914
3085
|
up.compiler = up.syntax.compiler;
|
2915
3086
|
|
2916
|
-
up.hello = up.syntax.hello;
|
2917
|
-
|
2918
3087
|
up.ready = function() {
|
2919
3088
|
return up.util.error('up.ready no longer exists. Please use up.hello instead.');
|
2920
3089
|
};
|
@@ -3041,6 +3210,7 @@ We need to work on this page:
|
|
3041
3210
|
@experimental
|
3042
3211
|
*/
|
3043
3212
|
push = function(url, options) {
|
3213
|
+
up.puts("Current location is now %s", url);
|
3044
3214
|
return manipulate('push', url, options);
|
3045
3215
|
};
|
3046
3216
|
manipulate = function(method, url, options) {
|
@@ -3052,7 +3222,6 @@ We need to work on this page:
|
|
3052
3222
|
if (up.browser.canPushState()) {
|
3053
3223
|
fullMethod = method + "State";
|
3054
3224
|
state = buildState();
|
3055
|
-
u.debug("Changing history to URL %o (%o)", url, method);
|
3056
3225
|
window.history[fullMethod](state, '', url);
|
3057
3226
|
return observeNewUrl(currentUrl());
|
3058
3227
|
} else {
|
@@ -3066,32 +3235,35 @@ We need to work on this page:
|
|
3066
3235
|
};
|
3067
3236
|
};
|
3068
3237
|
restoreStateOnPop = function(state) {
|
3069
|
-
var
|
3070
|
-
url = currentUrl();
|
3071
|
-
u.debug("Restoring state %o (now on " + url + ")", state);
|
3072
|
-
popSelector = config.popTargets.join(', ');
|
3073
|
-
return up.replace(popSelector, url, {
|
3074
|
-
history: false,
|
3075
|
-
reveal: false,
|
3076
|
-
transition: 'none',
|
3077
|
-
saveScroll: false,
|
3078
|
-
restoreScroll: config.restoreScroll
|
3079
|
-
});
|
3080
|
-
};
|
3081
|
-
pop = function(event) {
|
3082
|
-
var state;
|
3083
|
-
u.debug("History state popped to URL %o", currentUrl());
|
3084
|
-
observeNewUrl(currentUrl());
|
3085
|
-
up.layout.saveScroll({
|
3086
|
-
url: previousUrl
|
3087
|
-
});
|
3088
|
-
state = event.originalEvent.state;
|
3238
|
+
var url;
|
3089
3239
|
if (state != null ? state.fromUp : void 0) {
|
3090
|
-
|
3240
|
+
url = currentUrl();
|
3241
|
+
return up.log.group("Restoring URL %s", url, function() {
|
3242
|
+
var popSelector;
|
3243
|
+
popSelector = config.popTargets.join(', ');
|
3244
|
+
return up.replace(popSelector, url, {
|
3245
|
+
history: false,
|
3246
|
+
reveal: false,
|
3247
|
+
transition: 'none',
|
3248
|
+
saveScroll: false,
|
3249
|
+
restoreScroll: config.restoreScroll
|
3250
|
+
});
|
3251
|
+
});
|
3091
3252
|
} else {
|
3092
|
-
return
|
3253
|
+
return up.puts('Ignoring a state not pushed by Up.js (%o)', state);
|
3093
3254
|
}
|
3094
3255
|
};
|
3256
|
+
pop = function(event) {
|
3257
|
+
return up.log.group("History state popped to URL %s", currentUrl(), function() {
|
3258
|
+
var state;
|
3259
|
+
observeNewUrl(currentUrl());
|
3260
|
+
up.layout.saveScroll({
|
3261
|
+
url: previousUrl
|
3262
|
+
});
|
3263
|
+
state = event.originalEvent.state;
|
3264
|
+
return restoreStateOnPop(state);
|
3265
|
+
});
|
3266
|
+
};
|
3095
3267
|
if (up.browser.canPushState()) {
|
3096
3268
|
register = function() {
|
3097
3269
|
$(window).on("popstate", pop);
|
@@ -3324,7 +3496,7 @@ This modules contains functions to scroll the viewport and reveal contained elem
|
|
3324
3496
|
$obstructor = $(obstructor);
|
3325
3497
|
anchorPosition = $obstructor.css(cssAttr);
|
3326
3498
|
if (!u.isPresent(anchorPosition)) {
|
3327
|
-
u.error("Fixed element %o must have a CSS attribute %
|
3499
|
+
u.error("Fixed element %o must have a CSS attribute %s", $obstructor.get(0), cssAttr);
|
3328
3500
|
}
|
3329
3501
|
return parseInt(anchorPosition) + $obstructor.height();
|
3330
3502
|
};
|
@@ -3399,9 +3571,9 @@ This modules contains functions to scroll the viewport and reveal contained elem
|
|
3399
3571
|
*/
|
3400
3572
|
reveal = function(elementOrSelector, options) {
|
3401
3573
|
var $element, $viewport, elementDims, firstElementRow, lastElementRow, newScrollPos, obstruction, offsetShift, originalScrollPos, predictFirstVisibleRow, predictLastVisibleRow, snap, viewportHeight, viewportIsDocument;
|
3402
|
-
u.debug('Revealing %o', elementOrSelector);
|
3403
|
-
options = u.options(options);
|
3404
3574
|
$element = $(elementOrSelector);
|
3575
|
+
up.puts('Revealing fragment %o', elementOrSelector.get(0));
|
3576
|
+
options = u.options(options);
|
3405
3577
|
$viewport = options.viewport ? $(options.viewport) : viewportOf($element);
|
3406
3578
|
snap = u.option(options.snap, config.snap);
|
3407
3579
|
viewportIsDocument = $viewport.is(document);
|
@@ -3566,7 +3738,7 @@ This modules contains functions to scroll the viewport and reveal contained elem
|
|
3566
3738
|
}
|
3567
3739
|
url = u.option(options.url, up.history.url());
|
3568
3740
|
tops = u.option(options.tops, scrollTops());
|
3569
|
-
|
3741
|
+
up.puts('Saving scroll positions for URL %s (%o)', url, tops);
|
3570
3742
|
return lastScrollTops.set(url, tops);
|
3571
3743
|
};
|
3572
3744
|
|
@@ -3584,7 +3756,7 @@ This modules contains functions to scroll the viewport and reveal contained elem
|
|
3584
3756
|
@experimental
|
3585
3757
|
*/
|
3586
3758
|
restoreScroll = function(options) {
|
3587
|
-
var $ancestorViewports, $descendantViewports, $
|
3759
|
+
var $ancestorViewports, $descendantViewports, $viewports, tops, url;
|
3588
3760
|
if (options == null) {
|
3589
3761
|
options = {};
|
3590
3762
|
}
|
@@ -3598,16 +3770,18 @@ This modules contains functions to scroll the viewport and reveal contained elem
|
|
3598
3770
|
$viewports = viewports();
|
3599
3771
|
}
|
3600
3772
|
tops = lastScrollTops.get(url);
|
3601
|
-
|
3602
|
-
|
3603
|
-
|
3604
|
-
|
3605
|
-
|
3606
|
-
|
3607
|
-
|
3608
|
-
|
3609
|
-
|
3610
|
-
|
3773
|
+
return up.log.group('Restoring scroll positions for URL %s to %o', url, tops, function() {
|
3774
|
+
var $matchingViewport, key, right, scrollTop;
|
3775
|
+
for (key in tops) {
|
3776
|
+
scrollTop = tops[key];
|
3777
|
+
right = key === 'document' ? document : key;
|
3778
|
+
$matchingViewport = $viewports.filter(right);
|
3779
|
+
scroll($matchingViewport, scrollTop, {
|
3780
|
+
duration: 0
|
3781
|
+
});
|
3782
|
+
}
|
3783
|
+
return u.resolvedDeferred();
|
3784
|
+
});
|
3611
3785
|
};
|
3612
3786
|
|
3613
3787
|
/**
|
@@ -3765,7 +3939,7 @@ are based on this module.
|
|
3765
3939
|
|
3766
3940
|
(function() {
|
3767
3941
|
up.flow = (function($) {
|
3768
|
-
var autofocus, destroy,
|
3942
|
+
var autofocus, destroy, emitFragmentInserted, emitFragmentKept, extract, findKeepPlan, findOldFragment, first, hello, isRealElement, oldFragmentNotFound, parseImplantSteps, parseResponse, processResponse, reload, replace, resolveSelector, setSource, source, swapElements, transferKeepableElements, u, updateHistory;
|
3769
3943
|
u = up.util;
|
3770
3944
|
setSource = function(element, sourceUrl) {
|
3771
3945
|
var $element;
|
@@ -3809,7 +3983,7 @@ are based on this module.
|
|
3809
3983
|
originSelector = u.selectorForElement(origin);
|
3810
3984
|
selector = selector.replace(/\&/, originSelector);
|
3811
3985
|
} else {
|
3812
|
-
u.error("Found origin reference %
|
3986
|
+
u.error("Found origin reference (%s) in selector %s, but options.origin is missing", '&', selector);
|
3813
3987
|
}
|
3814
3988
|
}
|
3815
3989
|
} else {
|
@@ -3822,7 +3996,9 @@ are based on this module.
|
|
3822
3996
|
Replaces elements on the current page with corresponding elements
|
3823
3997
|
from a new page fetched from the server.
|
3824
3998
|
|
3825
|
-
The current and new elements must
|
3999
|
+
The current and new elements must both match the given CSS selector.
|
4000
|
+
|
4001
|
+
The UJS variant of this is the [`a[up-target]`](/a-up-target) selector.
|
3826
4002
|
|
3827
4003
|
\#\#\#\# Example
|
3828
4004
|
|
@@ -3840,7 +4016,7 @@ are based on this module.
|
|
3840
4016
|
<div class="one">new one</div>
|
3841
4017
|
<div class="two">new two</div>
|
3842
4018
|
|
3843
|
-
Up.js looks for the selector `.two` in the response and [implants](/up.
|
4019
|
+
Up.js looks for the selector `.two` in the response and [implants](/up.extract) it into
|
3844
4020
|
the current page. The current page now looks like this:
|
3845
4021
|
|
3846
4022
|
<div class="one">old one</div>
|
@@ -3942,7 +4118,7 @@ are based on this module.
|
|
3942
4118
|
*/
|
3943
4119
|
replace = function(selectorOrElement, url, options) {
|
3944
4120
|
var failTarget, promise, request, target;
|
3945
|
-
|
4121
|
+
up.puts("Replacing %s from %s (%o)", selectorOrElement, url, options);
|
3946
4122
|
options = u.options(options);
|
3947
4123
|
target = resolveSelector(selectorOrElement, options.origin);
|
3948
4124
|
failTarget = u.option(options.failTarget, 'body');
|
@@ -3963,7 +4139,7 @@ are based on this module.
|
|
3963
4139
|
preload: options.preload,
|
3964
4140
|
headers: options.headers
|
3965
4141
|
};
|
3966
|
-
promise = up.
|
4142
|
+
promise = up.ajax(request);
|
3967
4143
|
promise.done(function(html, textStatus, xhr) {
|
3968
4144
|
return processResponse(true, target, url, request, xhr, options);
|
3969
4145
|
});
|
@@ -3977,7 +4153,7 @@ are based on this module.
|
|
3977
4153
|
@internal
|
3978
4154
|
*/
|
3979
4155
|
processResponse = function(isSuccess, selector, url, request, xhr, options) {
|
3980
|
-
var isReloadable, newRequest, urlFromServer;
|
4156
|
+
var isReloadable, newRequest, query, urlFromServer;
|
3981
4157
|
options.method = u.normalizeMethod(u.option(u.methodFromXhr(xhr), options.method));
|
3982
4158
|
options.title = u.option(u.titleFromXhr(xhr), options.title);
|
3983
4159
|
isReloadable = options.method === 'GET';
|
@@ -3992,7 +4168,9 @@ are based on this module.
|
|
3992
4168
|
up.proxy.alias(request, newRequest);
|
3993
4169
|
}
|
3994
4170
|
} else if (isReloadable) {
|
3995
|
-
|
4171
|
+
if (query = u.requestDataAsQuery(options.data)) {
|
4172
|
+
url = url + "?" + query;
|
4173
|
+
}
|
3996
4174
|
}
|
3997
4175
|
if (isSuccess) {
|
3998
4176
|
if (isReloadable) {
|
@@ -4028,7 +4206,7 @@ are based on this module.
|
|
4028
4206
|
if (options.preload) {
|
4029
4207
|
return u.resolvedPromise();
|
4030
4208
|
} else {
|
4031
|
-
return
|
4209
|
+
return extract(selector, xhr.responseText, options);
|
4032
4210
|
}
|
4033
4211
|
};
|
4034
4212
|
|
@@ -4049,7 +4227,7 @@ are based on this module.
|
|
4049
4227
|
html = '<div class="one">new one</div>' +
|
4050
4228
|
'<div class="two">new two</div>';
|
4051
4229
|
|
4052
|
-
up.
|
4230
|
+
up.extract('.two', html);
|
4053
4231
|
|
4054
4232
|
Up.js looks for the selector `.two` in the strings and updates its
|
4055
4233
|
contents in the current page. The current page now looks like this:
|
@@ -4060,7 +4238,7 @@ are based on this module.
|
|
4060
4238
|
Note how only `.two` has changed. The update for `.one` was
|
4061
4239
|
discarded, since it didn't match the selector.
|
4062
4240
|
|
4063
|
-
@function up.
|
4241
|
+
@function up.extract
|
4064
4242
|
@param {String|Element|jQuery} selectorOrElement
|
4065
4243
|
@param {String} html
|
4066
4244
|
@param {Object} [options]
|
@@ -4070,36 +4248,43 @@ are based on this module.
|
|
4070
4248
|
and all animation has finished.
|
4071
4249
|
@experimental
|
4072
4250
|
*/
|
4073
|
-
|
4074
|
-
|
4075
|
-
|
4076
|
-
|
4077
|
-
|
4078
|
-
|
4079
|
-
|
4080
|
-
|
4081
|
-
|
4082
|
-
|
4083
|
-
|
4084
|
-
|
4085
|
-
|
4086
|
-
options.beforeSwap($old, $new);
|
4087
|
-
}
|
4088
|
-
deferreds = [];
|
4089
|
-
ref = parseImplantSteps(selector, options);
|
4090
|
-
for (j = 0, len = ref.length; j < len; j++) {
|
4091
|
-
step = ref[j];
|
4092
|
-
$old = findOldFragment(step.selector, options);
|
4093
|
-
$new = (ref1 = response.find(step.selector)) != null ? ref1.first() : void 0;
|
4094
|
-
if ($old && $new) {
|
4095
|
-
deferred = swapElements($old, $new, step.pseudoClass, step.transition, options);
|
4096
|
-
deferreds.push(deferred);
|
4251
|
+
extract = function(selectorOrElement, html, options) {
|
4252
|
+
return up.log.group('Extracting %s from %d bytes of HTML', selectorOrElement, html != null ? html.length : void 0, function() {
|
4253
|
+
var deferreds, j, len, ref, ref1, response, selector, step;
|
4254
|
+
options = u.options(options, {
|
4255
|
+
historyMethod: 'push',
|
4256
|
+
requireMatch: true,
|
4257
|
+
keep: true
|
4258
|
+
});
|
4259
|
+
selector = resolveSelector(selectorOrElement, options.origin);
|
4260
|
+
response = parseResponse(html, options);
|
4261
|
+
options.title || (options.title = response.title());
|
4262
|
+
if (options.saveScroll !== false) {
|
4263
|
+
up.layout.saveScroll();
|
4097
4264
|
}
|
4098
|
-
|
4099
|
-
|
4100
|
-
|
4101
|
-
|
4102
|
-
|
4265
|
+
if (typeof options.beforeSwap === "function") {
|
4266
|
+
options.beforeSwap();
|
4267
|
+
}
|
4268
|
+
deferreds = [];
|
4269
|
+
updateHistory(options);
|
4270
|
+
ref = parseImplantSteps(selector, options);
|
4271
|
+
for (j = 0, len = ref.length; j < len; j++) {
|
4272
|
+
step = ref[j];
|
4273
|
+
up.log.group('Updating %s', step.selector, function() {
|
4274
|
+
var $new, $old, deferred, ref1;
|
4275
|
+
$old = findOldFragment(step.selector, options);
|
4276
|
+
$new = (ref1 = response.find(step.selector)) != null ? ref1.first() : void 0;
|
4277
|
+
if ($old && $new) {
|
4278
|
+
deferred = swapElements($old, $new, step.pseudoClass, step.transition, options);
|
4279
|
+
return deferreds.push(deferred);
|
4280
|
+
}
|
4281
|
+
});
|
4282
|
+
}
|
4283
|
+
if (typeof options.afterSwap === "function") {
|
4284
|
+
options.afterSwap();
|
4285
|
+
}
|
4286
|
+
return (ref1 = up.motion).when.apply(ref1, deferreds);
|
4287
|
+
});
|
4103
4288
|
};
|
4104
4289
|
findOldFragment = function(selector, options) {
|
4105
4290
|
return first(".up-popup " + selector) || first(".up-modal " + selector) || first(selector) || oldFragmentNotFound(selector, options);
|
@@ -4107,7 +4292,7 @@ are based on this module.
|
|
4107
4292
|
oldFragmentNotFound = function(selector, options) {
|
4108
4293
|
var message;
|
4109
4294
|
if (options.requireMatch) {
|
4110
|
-
message = 'Could not find selector %
|
4295
|
+
message = 'Could not find selector %s in current body HTML';
|
4111
4296
|
if (message[0] === '#') {
|
4112
4297
|
message += ' (avoid using IDs)';
|
4113
4298
|
}
|
@@ -4127,28 +4312,21 @@ are based on this module.
|
|
4127
4312
|
if (child = $.find(selector, htmlElement)[0]) {
|
4128
4313
|
return $(child);
|
4129
4314
|
} else if (options.requireMatch) {
|
4130
|
-
return u.error("Could not find selector %
|
4315
|
+
return u.error("Could not find selector %s in response %o", selector, html);
|
4131
4316
|
}
|
4132
4317
|
}
|
4133
4318
|
};
|
4134
4319
|
};
|
4135
|
-
|
4320
|
+
updateHistory = function(options) {
|
4136
4321
|
if (options.history) {
|
4137
4322
|
if (options.title) {
|
4138
4323
|
document.title = options.title;
|
4139
4324
|
}
|
4140
|
-
up.history[options.historyMethod](options.history);
|
4325
|
+
return up.history[options.historyMethod](options.history);
|
4141
4326
|
}
|
4142
|
-
if (options.source !== false) {
|
4143
|
-
setSource($new, options.source);
|
4144
|
-
}
|
4145
|
-
autofocus($new);
|
4146
|
-
return up.hello($new, {
|
4147
|
-
origin: options.origin
|
4148
|
-
});
|
4149
4327
|
};
|
4150
4328
|
swapElements = function($old, $new, pseudoClass, transition, options) {
|
4151
|
-
var $wrapper,
|
4329
|
+
var $wrapper, keepPlan, promise, replacement;
|
4152
4330
|
transition || (transition = 'none');
|
4153
4331
|
if (options.source === 'keep') {
|
4154
4332
|
options = u.merge(options, {
|
@@ -4157,11 +4335,13 @@ are based on this module.
|
|
4157
4335
|
}
|
4158
4336
|
up.motion.finish($old);
|
4159
4337
|
if (pseudoClass) {
|
4160
|
-
insertionMethod = pseudoClass === 'before' ? 'prepend' : 'append';
|
4161
4338
|
$wrapper = $new.contents().wrap('<span class="up-insertion"></span>').parent();
|
4162
|
-
|
4163
|
-
|
4164
|
-
|
4339
|
+
if (pseudoClass === 'before') {
|
4340
|
+
$old.prepend($wrapper);
|
4341
|
+
} else {
|
4342
|
+
$old.append($wrapper);
|
4343
|
+
}
|
4344
|
+
hello($wrapper.children(), options);
|
4165
4345
|
promise = up.layout.revealOrRestoreScroll($wrapper, options);
|
4166
4346
|
promise = promise.then(function() {
|
4167
4347
|
return up.animate($wrapper, transition, options);
|
@@ -4169,34 +4349,179 @@ are based on this module.
|
|
4169
4349
|
promise = promise.then(function() {
|
4170
4350
|
return u.unwrapElement($wrapper);
|
4171
4351
|
});
|
4172
|
-
|
4352
|
+
} else if (keepPlan = findKeepPlan($old, $new, options)) {
|
4353
|
+
emitFragmentKept(keepPlan);
|
4354
|
+
promise = u.resolvedPromise();
|
4173
4355
|
} else {
|
4174
4356
|
replacement = function() {
|
4357
|
+
options.keepPlans = transferKeepableElements($old, $new, options);
|
4175
4358
|
$new.insertBefore($old);
|
4176
|
-
|
4177
|
-
|
4178
|
-
u.error('Cannot apply transitions to body-elements (%o)', transition);
|
4359
|
+
if (options.source !== false) {
|
4360
|
+
setSource($new, options.source);
|
4179
4361
|
}
|
4362
|
+
autofocus($new);
|
4363
|
+
hello($new, options);
|
4180
4364
|
return up.morph($old, $new, transition, options);
|
4181
4365
|
};
|
4182
|
-
|
4366
|
+
promise = destroy($old, {
|
4183
4367
|
animation: replacement
|
4184
4368
|
});
|
4185
4369
|
}
|
4370
|
+
return promise;
|
4371
|
+
};
|
4372
|
+
transferKeepableElements = function($old, $new, options) {
|
4373
|
+
var $keepable, $keepableClone, j, keepPlans, keepable, len, plan, ref;
|
4374
|
+
keepPlans = [];
|
4375
|
+
if (options.keep) {
|
4376
|
+
ref = $old.find('[up-keep]');
|
4377
|
+
for (j = 0, len = ref.length; j < len; j++) {
|
4378
|
+
keepable = ref[j];
|
4379
|
+
$keepable = $(keepable);
|
4380
|
+
if (plan = findKeepPlan($keepable, $new, u.merge(options, {
|
4381
|
+
descendantsOnly: true
|
4382
|
+
}))) {
|
4383
|
+
$keepableClone = $keepable.clone();
|
4384
|
+
$keepable.replaceWith($keepableClone);
|
4385
|
+
plan.$newElement.replaceWith($keepable);
|
4386
|
+
keepPlans.push(plan);
|
4387
|
+
}
|
4388
|
+
}
|
4389
|
+
}
|
4390
|
+
return keepPlans;
|
4391
|
+
};
|
4392
|
+
findKeepPlan = function($element, $new, options) {
|
4393
|
+
var $keepable, $partner, description, keepEventArgs, partnerSelector;
|
4394
|
+
if (options.keep) {
|
4395
|
+
$keepable = $element;
|
4396
|
+
if (partnerSelector = u.castedAttr($keepable, 'up-keep')) {
|
4397
|
+
u.isString(partnerSelector) || (partnerSelector = '&');
|
4398
|
+
partnerSelector = resolveSelector(partnerSelector, $keepable);
|
4399
|
+
if (options.descendantsOnly) {
|
4400
|
+
$partner = $new.find(partnerSelector);
|
4401
|
+
} else {
|
4402
|
+
$partner = u.findWithSelf($new, partnerSelector);
|
4403
|
+
}
|
4404
|
+
$partner = $partner.first();
|
4405
|
+
if ($partner.length && $partner.is('[up-keep]')) {
|
4406
|
+
description = {
|
4407
|
+
$element: $keepable,
|
4408
|
+
$newElement: $partner,
|
4409
|
+
newData: up.syntax.data($partner)
|
4410
|
+
};
|
4411
|
+
keepEventArgs = u.merge(description, {
|
4412
|
+
message: ['Keeping element %o', $keepable.get(0)]
|
4413
|
+
});
|
4414
|
+
if (up.bus.nobodyPrevents('up:fragment:keep', keepEventArgs)) {
|
4415
|
+
return description;
|
4416
|
+
}
|
4417
|
+
}
|
4418
|
+
}
|
4419
|
+
}
|
4186
4420
|
};
|
4421
|
+
|
4422
|
+
/**
|
4423
|
+
Elements with an `up-keep` attribute will be persisted during
|
4424
|
+
[fragment updates](/a-up-target).
|
4425
|
+
|
4426
|
+
For example:
|
4427
|
+
|
4428
|
+
<audio up-keep src="song.mp3"></audio>
|
4429
|
+
|
4430
|
+
The element you're keeping should have an umambiguous class name, ID or `up-id`
|
4431
|
+
attribute so Up.js can find its new position within the page update.
|
4432
|
+
|
4433
|
+
Emits events [`up:fragment:keep`](/up:fragment:keep) and [`up:fragment:kept`](/up:fragment:kept).
|
4434
|
+
|
4435
|
+
\#\#\#\# Controlling if an element will be kept
|
4436
|
+
|
4437
|
+
Up.js will **only** keep an existing element if:
|
4438
|
+
|
4439
|
+
- The existing element has an `up-keep` attribute
|
4440
|
+
- The response contains an element matching the CSS selector of the existing element
|
4441
|
+
- The matching element *also* has an `up-keep` attribute
|
4442
|
+
- The [`up:fragment:keep`](/up:fragment:keep) event that is [emitted](/up.emit) on the existing element
|
4443
|
+
is not prevented by a event listener.
|
4444
|
+
|
4445
|
+
Let's say we want only keep an `<audio>` element as long as it plays
|
4446
|
+
the same song (as identified by the tag's `src` attribute).
|
4447
|
+
|
4448
|
+
On the client we can achieve this by listening to an `up:keep:fragment` event
|
4449
|
+
and preventing it if the `src` attribute of the old and new element differ:
|
4450
|
+
|
4451
|
+
up.compiler('audio', function($element) {
|
4452
|
+
$element.on('up:fragment:keep', function(event) {
|
4453
|
+
if $element.attr('src') !== event.$newElement.attr('src') {
|
4454
|
+
event.preventDefault();
|
4455
|
+
}
|
4456
|
+
});
|
4457
|
+
});
|
4458
|
+
|
4459
|
+
If we don't want to solve this on the client, we can achieve the same effect
|
4460
|
+
on the server. By setting the value of the `up-keep` attribute we can
|
4461
|
+
define the CSS selector used for matching elements.
|
4462
|
+
|
4463
|
+
<audio up-keep="audio[src='song.mp3']" src="song.mp3"></audio>
|
4464
|
+
|
4465
|
+
Now, if a response no longer contains an `<audio src="song.mp3">` tag, the existing
|
4466
|
+
element will be destroyed and replaced by a fragment from the response.
|
4467
|
+
|
4468
|
+
@selector [up-keep]
|
4469
|
+
@stable
|
4470
|
+
*/
|
4471
|
+
|
4472
|
+
/**
|
4473
|
+
This event is [emitted](/up.emit) before an existing element is [kept](/up-keep) during
|
4474
|
+
a page update.
|
4475
|
+
|
4476
|
+
Event listeners can call `event.preventDefault()` on an `up:fragment:keep` event
|
4477
|
+
to prevent the element from being persisted. If the event is prevented, the element
|
4478
|
+
will be replaced by a fragment from the response.
|
4479
|
+
|
4480
|
+
@event up:fragment:keep
|
4481
|
+
@param event.preventDefault()
|
4482
|
+
Event listeners may call this method to prevent the element from being preserved.
|
4483
|
+
@param {jQuery} event.$element
|
4484
|
+
The fragment that will be kept.
|
4485
|
+
@param {jqQuery} event.$newElement
|
4486
|
+
The discarded element.
|
4487
|
+
@param {jQuery} event.newData
|
4488
|
+
The value of the [`up-data`](/up-data) attribute of the discarded element,
|
4489
|
+
parsed as a JSON object.
|
4490
|
+
@stable
|
4491
|
+
*/
|
4492
|
+
|
4493
|
+
/**
|
4494
|
+
This event is [emitted](/up.emit) when an existing element has been [kept](/up-keep)
|
4495
|
+
during a page update.
|
4496
|
+
|
4497
|
+
Event listeners can inspect the discarded update through `event.$newElement`
|
4498
|
+
and `event.newData` and then modify the preserved element when necessary.
|
4499
|
+
|
4500
|
+
@event up:fragment:kept
|
4501
|
+
@param {jQuery} event.$element
|
4502
|
+
The fragment that has been kept.
|
4503
|
+
@param {jqQuery} event.$newElement
|
4504
|
+
The discarded element.
|
4505
|
+
@param {jQuery} event.newData
|
4506
|
+
The value of the [`up-data`](/up-data) attribute of the discarded element,
|
4507
|
+
parsed as a JSON object.
|
4508
|
+
@stable
|
4509
|
+
*/
|
4187
4510
|
parseImplantSteps = function(selector, options) {
|
4188
|
-
var comma, disjunction, i, j, len, pseudoClass, results, selectorAtom, selectorParts, transition,
|
4189
|
-
|
4511
|
+
var comma, disjunction, i, j, len, pseudoClass, results, selectorAtom, selectorParts, transition, transitionArg, transitions;
|
4512
|
+
transitionArg = options.transition || options.animation || 'none';
|
4190
4513
|
comma = /\ *,\ */;
|
4191
4514
|
disjunction = selector.split(comma);
|
4192
|
-
if (u.
|
4193
|
-
transitions =
|
4515
|
+
if (u.isString(transitions)) {
|
4516
|
+
transitions = transitionArg.split(comma);
|
4517
|
+
} else {
|
4518
|
+
transitions = [transitionArg];
|
4194
4519
|
}
|
4195
4520
|
results = [];
|
4196
4521
|
for (i = j = 0, len = disjunction.length; j < len; i = ++j) {
|
4197
4522
|
selectorAtom = disjunction[i];
|
4198
4523
|
selectorParts = selectorAtom.match(/^(.+?)(?:\:(before|after))?$/);
|
4199
|
-
selectorParts || u.error('Could not parse selector atom %
|
4524
|
+
selectorParts || u.error('Could not parse selector atom "%s"', selectorAtom);
|
4200
4525
|
selector = selectorParts[1];
|
4201
4526
|
if (selector === 'html') {
|
4202
4527
|
selector = 'body';
|
@@ -4211,6 +4536,83 @@ are based on this module.
|
|
4211
4536
|
}
|
4212
4537
|
return results;
|
4213
4538
|
};
|
4539
|
+
|
4540
|
+
/**
|
4541
|
+
Compiles a page fragment that has been inserted into the DOM
|
4542
|
+
without Up.js.
|
4543
|
+
|
4544
|
+
**As long as you manipulate the DOM using Up.js, you will never
|
4545
|
+
need to call this method.** You only need to use `up.hello` if the
|
4546
|
+
DOM is manipulated without Up.js' involvement, e.g. by setting
|
4547
|
+
the `innerHTML` property or calling jQuery methods like
|
4548
|
+
`html`, `insertAfter` or `appendTo`:
|
4549
|
+
|
4550
|
+
$element = $('.element');
|
4551
|
+
$element.html('<div>...</div>');
|
4552
|
+
up.hello($element);
|
4553
|
+
|
4554
|
+
This function emits the [`up:fragment:inserted`](/up:fragment:inserted)
|
4555
|
+
event.
|
4556
|
+
|
4557
|
+
@function up.hello
|
4558
|
+
@param {String|Element|jQuery} selectorOrElement
|
4559
|
+
@param {String|Element|jQuery} [options.origin]
|
4560
|
+
@param {String|Element|jQuery} [options.kept]
|
4561
|
+
@return {jQuery}
|
4562
|
+
The compiled element
|
4563
|
+
@stable
|
4564
|
+
*/
|
4565
|
+
hello = function(selectorOrElement, options) {
|
4566
|
+
var $element, j, keptElements, len, plan, ref;
|
4567
|
+
$element = $(selectorOrElement);
|
4568
|
+
options = u.options(options, {
|
4569
|
+
keepPlans: []
|
4570
|
+
});
|
4571
|
+
keptElements = [];
|
4572
|
+
ref = options.keepPlans;
|
4573
|
+
for (j = 0, len = ref.length; j < len; j++) {
|
4574
|
+
plan = ref[j];
|
4575
|
+
emitFragmentKept(plan);
|
4576
|
+
keptElements.push(plan.$element);
|
4577
|
+
}
|
4578
|
+
up.syntax.compile($element, {
|
4579
|
+
skip: keptElements
|
4580
|
+
});
|
4581
|
+
emitFragmentInserted($element, options);
|
4582
|
+
return $element;
|
4583
|
+
};
|
4584
|
+
|
4585
|
+
/**
|
4586
|
+
When a page fragment has been [inserted or updated](/up.replace),
|
4587
|
+
this event is [emitted](/up.emit) on the fragment.
|
4588
|
+
|
4589
|
+
\#\#\#\# Example
|
4590
|
+
|
4591
|
+
up.on('up:fragment:inserted', function(event, $fragment) {
|
4592
|
+
console.log("Looks like we have a new %o!", $fragment);
|
4593
|
+
});
|
4594
|
+
|
4595
|
+
@event up:fragment:inserted
|
4596
|
+
@param {jQuery} event.$element
|
4597
|
+
The fragment that has been inserted or updated.
|
4598
|
+
@stable
|
4599
|
+
*/
|
4600
|
+
emitFragmentInserted = function(fragment, options) {
|
4601
|
+
var $fragment;
|
4602
|
+
$fragment = $(fragment);
|
4603
|
+
return up.emit('up:fragment:inserted', {
|
4604
|
+
$element: $fragment,
|
4605
|
+
message: ['Inserted fragment %o', $fragment.get(0)],
|
4606
|
+
origin: options.origin
|
4607
|
+
});
|
4608
|
+
};
|
4609
|
+
emitFragmentKept = function(keepPlan) {
|
4610
|
+
var eventAttrs;
|
4611
|
+
eventAttrs = u.merge(keepPlan, {
|
4612
|
+
message: ['Kept fragment %o', keepPlan.$element.get(0)]
|
4613
|
+
});
|
4614
|
+
return up.emit('up:fragment:kept', eventAttrs);
|
4615
|
+
};
|
4214
4616
|
autofocus = function($element) {
|
4215
4617
|
var $control, selector;
|
4216
4618
|
selector = '[autofocus]:last';
|
@@ -4290,10 +4692,15 @@ are based on this module.
|
|
4290
4692
|
@stable
|
4291
4693
|
*/
|
4292
4694
|
destroy = function(selectorOrElement, options) {
|
4293
|
-
var $element, animateOptions, animationDeferred;
|
4695
|
+
var $element, animateOptions, animationDeferred, destroyMessage, destroyedMessage;
|
4294
4696
|
$element = $(selectorOrElement);
|
4697
|
+
if (!$element.is('.up-placeholder, .up-tooltip, .up-modal, .up-popup')) {
|
4698
|
+
destroyMessage = ['Destroying fragment %o', $element.get(0)];
|
4699
|
+
destroyedMessage = ['Destroyed fragment %o', $element.get(0)];
|
4700
|
+
}
|
4295
4701
|
if (up.bus.nobodyPrevents('up:fragment:destroy', {
|
4296
|
-
$element: $element
|
4702
|
+
$element: $element,
|
4703
|
+
message: destroyMessage
|
4297
4704
|
})) {
|
4298
4705
|
options = u.options(options, {
|
4299
4706
|
animation: false
|
@@ -4308,8 +4715,10 @@ are based on this module.
|
|
4308
4715
|
}
|
4309
4716
|
animationDeferred = u.presence(options.animation, u.isDeferred) || up.motion.animate($element, options.animation, animateOptions);
|
4310
4717
|
animationDeferred.then(function() {
|
4718
|
+
up.syntax.clean($element);
|
4311
4719
|
up.emit('up:fragment:destroyed', {
|
4312
|
-
$element: $element
|
4720
|
+
$element: $element,
|
4721
|
+
message: destroyedMessage
|
4313
4722
|
});
|
4314
4723
|
return $element.remove();
|
4315
4724
|
});
|
@@ -4377,23 +4786,27 @@ are based on this module.
|
|
4377
4786
|
return replace(selectorOrElement, sourceUrl, options);
|
4378
4787
|
};
|
4379
4788
|
up.on('ready', function() {
|
4380
|
-
|
4789
|
+
var $body;
|
4790
|
+
$body = $(document.body);
|
4791
|
+
setSource($body, up.browser.url());
|
4792
|
+
return hello($body);
|
4381
4793
|
});
|
4382
4794
|
return {
|
4383
4795
|
knife: eval(typeof Knife !== "undefined" && Knife !== null ? Knife.point : void 0),
|
4384
4796
|
replace: replace,
|
4385
4797
|
reload: reload,
|
4386
4798
|
destroy: destroy,
|
4387
|
-
|
4799
|
+
extract: extract,
|
4388
4800
|
first: first,
|
4389
4801
|
source: source,
|
4390
|
-
resolveSelector: resolveSelector
|
4802
|
+
resolveSelector: resolveSelector,
|
4803
|
+
hello: hello
|
4391
4804
|
};
|
4392
4805
|
})(jQuery);
|
4393
4806
|
|
4394
4807
|
up.replace = up.flow.replace;
|
4395
4808
|
|
4396
|
-
up.
|
4809
|
+
up.extract = up.flow.extract;
|
4397
4810
|
|
4398
4811
|
up.reload = up.flow.reload;
|
4399
4812
|
|
@@ -4401,6 +4814,8 @@ are based on this module.
|
|
4401
4814
|
|
4402
4815
|
up.first = up.flow.first;
|
4403
4816
|
|
4817
|
+
up.hello = up.flow.hello;
|
4818
|
+
|
4404
4819
|
}).call(this);
|
4405
4820
|
|
4406
4821
|
/**
|
@@ -4436,7 +4851,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
4436
4851
|
|
4437
4852
|
(function() {
|
4438
4853
|
up.motion = (function($) {
|
4439
|
-
var GHOSTING_PROMISE_KEY, animate, animateOptions, animation, animations, assertIsDeferred, config, defaultAnimations, defaultTransitions, findAnimation, finish, finishGhosting, isEnabled, morph, none, prependCopy, reset, resolvableWhen, skipMorph, snapshot, transition, transitions, u, withGhosts;
|
4854
|
+
var GHOSTING_PROMISE_KEY, animate, animateOptions, animation, animations, assertIsDeferred, config, defaultAnimations, defaultTransitions, ensureMorphable, findAnimation, finish, finishGhosting, isEnabled, morph, none, prependCopy, reset, resolvableWhen, skipMorph, snapshot, transition, transitions, u, withGhosts;
|
4440
4855
|
u = up.util;
|
4441
4856
|
animations = {};
|
4442
4857
|
defaultAnimations = {};
|
@@ -4668,7 +5083,7 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
4668
5083
|
finishGhosting = function($element) {
|
4669
5084
|
var existingGhosting;
|
4670
5085
|
if (existingGhosting = $element.data(GHOSTING_PROMISE_KEY)) {
|
4671
|
-
|
5086
|
+
up.puts('Canceling existing ghosting on %o', $element);
|
4672
5087
|
return typeof existingGhosting.resolve === "function" ? existingGhosting.resolve() : void 0;
|
4673
5088
|
}
|
4674
5089
|
};
|
@@ -4744,37 +5159,51 @@ or [transitions](/up.transition) using Javascript or CSS.
|
|
4744
5159
|
@stable
|
4745
5160
|
*/
|
4746
5161
|
morph = function(source, target, transitionOrName, options) {
|
4747
|
-
var $new, $old
|
4748
|
-
|
5162
|
+
var $new, $old;
|
5163
|
+
if (transitionOrName === 'none') {
|
5164
|
+
transitionOrName = false;
|
5165
|
+
}
|
4749
5166
|
$old = $(source);
|
4750
5167
|
$new = $(target);
|
4751
|
-
|
4752
|
-
|
4753
|
-
|
4754
|
-
|
4755
|
-
|
4756
|
-
|
4757
|
-
|
4758
|
-
|
4759
|
-
|
4760
|
-
|
4761
|
-
|
4762
|
-
|
4763
|
-
|
4764
|
-
|
4765
|
-
|
4766
|
-
|
4767
|
-
|
4768
|
-
|
4769
|
-
|
4770
|
-
|
4771
|
-
}
|
4772
|
-
|
5168
|
+
ensureMorphable($old, transitionOrName);
|
5169
|
+
ensureMorphable($new, transitionOrName);
|
5170
|
+
return up.log.group((transitionOrName ? 'Morphing %o to %o (using %o)' : void 0), source, target, transitionOrName, function() {
|
5171
|
+
var animation, parsedOptions, parts, transition;
|
5172
|
+
parsedOptions = u.only(options, 'reveal', 'restoreScroll', 'source');
|
5173
|
+
parsedOptions = u.extend(parsedOptions, animateOptions(options));
|
5174
|
+
if (isEnabled()) {
|
5175
|
+
finish($old);
|
5176
|
+
finish($new);
|
5177
|
+
if (!transitionOrName) {
|
5178
|
+
return skipMorph($old, $new, parsedOptions);
|
5179
|
+
} else if (animation = animations[transitionOrName]) {
|
5180
|
+
skipMorph($old, $new, parsedOptions);
|
5181
|
+
return animate($new, animation, parsedOptions);
|
5182
|
+
} else if (transition = u.presence(transitionOrName, u.isFunction) || transitions[transitionOrName]) {
|
5183
|
+
return withGhosts($old, $new, parsedOptions, function($oldGhost, $newGhost) {
|
5184
|
+
var transitionPromise;
|
5185
|
+
transitionPromise = transition($oldGhost, $newGhost, parsedOptions);
|
5186
|
+
return assertIsDeferred(transitionPromise, transitionOrName);
|
5187
|
+
});
|
5188
|
+
} else if (u.isString(transitionOrName) && transitionOrName.indexOf('/') >= 0) {
|
5189
|
+
parts = transitionOrName.split('/');
|
5190
|
+
transition = function($old, $new, options) {
|
5191
|
+
return resolvableWhen(animate($old, parts[0], options), animate($new, parts[1], options));
|
5192
|
+
};
|
5193
|
+
return morph($old, $new, transition, parsedOptions);
|
5194
|
+
} else {
|
5195
|
+
return u.error("Unknown transition %o", transitionOrName);
|
5196
|
+
}
|
4773
5197
|
} else {
|
4774
|
-
return
|
5198
|
+
return skipMorph($old, $new, parsedOptions);
|
4775
5199
|
}
|
4776
|
-
}
|
4777
|
-
|
5200
|
+
});
|
5201
|
+
};
|
5202
|
+
ensureMorphable = function($element, transition) {
|
5203
|
+
var element;
|
5204
|
+
if (transition && $element.parents('body').length === 0) {
|
5205
|
+
element = $element.get(0);
|
5206
|
+
return u.error("Can't morph a <%s> element (%o)", element.tagName, element);
|
4778
5207
|
}
|
4779
5208
|
};
|
4780
5209
|
|
@@ -5161,7 +5590,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5161
5590
|
var slice = [].slice;
|
5162
5591
|
|
5163
5592
|
up.proxy = (function($) {
|
5164
|
-
var $waitingLink, ajax, alias, busy, busyDelayTimer, busyEventEmitted, cache, cacheKey, cancelBusyDelay, cancelPreloadDelay, checkPreload, clear, config, get, idle, isIdempotent, load, loadEnded, loadOrQueue, loadStarted, normalizeRequest, pendingCount, pokeQueue, preload, preloadDelayTimer, queue, queuedRequests, remove, reset, set, startPreloadDelay, u;
|
5593
|
+
var $waitingLink, ajax, alias, busy, busyDelayTimer, busyEventEmitted, cache, cacheKey, cancelBusyDelay, cancelPreloadDelay, checkPreload, clear, config, get, idle, isIdempotent, load, loadEnded, loadOrQueue, loadStarted, normalizeRequest, pendingCount, pokeQueue, preload, preloadDelayTimer, queue, queuedRequests, remove, reset, responseReceived, set, startPreloadDelay, u;
|
5165
5594
|
u = up.util;
|
5166
5595
|
$waitingLink = void 0;
|
5167
5596
|
preloadDelayTimer = void 0;
|
@@ -5226,8 +5655,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5226
5655
|
expiry: function() {
|
5227
5656
|
return config.cacheExpiry;
|
5228
5657
|
},
|
5229
|
-
key: cacheKey
|
5230
|
-
log: 'up.proxy'
|
5658
|
+
key: cacheKey
|
5231
5659
|
});
|
5232
5660
|
|
5233
5661
|
/**
|
@@ -5349,7 +5777,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5349
5777
|
Once the response is received, a `up:proxy:receive` event will
|
5350
5778
|
be emitted.
|
5351
5779
|
|
5352
|
-
@function up.
|
5780
|
+
@function up.ajax
|
5353
5781
|
@param {String} request.url
|
5354
5782
|
@param {String} [request.method='GET']
|
5355
5783
|
@param {String} [request.target='body']
|
@@ -5371,11 +5799,13 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5371
5799
|
forceCache = options.cache === true;
|
5372
5800
|
ignoreCache = options.cache === false;
|
5373
5801
|
request = u.only(options, 'url', 'method', 'data', 'target', 'headers', '_normalized');
|
5802
|
+
request = normalizeRequest(request);
|
5374
5803
|
pending = true;
|
5375
5804
|
if (!isIdempotent(request) && !forceCache) {
|
5376
5805
|
clear();
|
5377
5806
|
promise = loadOrQueue(request);
|
5378
5807
|
} else if ((promise = get(request)) && !ignoreCache) {
|
5808
|
+
up.puts('Re-using cached response for %s %s', request.method, request.url);
|
5379
5809
|
pending = promise.state() === 'pending';
|
5380
5810
|
} else {
|
5381
5811
|
promise = loadOrQueue(request);
|
@@ -5388,6 +5818,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5388
5818
|
loadStarted();
|
5389
5819
|
promise.always(loadEnded);
|
5390
5820
|
}
|
5821
|
+
console.groupEnd();
|
5391
5822
|
return promise;
|
5392
5823
|
};
|
5393
5824
|
|
@@ -5429,7 +5860,9 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5429
5860
|
if (wasIdle) {
|
5430
5861
|
emission = function() {
|
5431
5862
|
if (busy()) {
|
5432
|
-
up.emit('up:proxy:busy'
|
5863
|
+
up.emit('up:proxy:busy', {
|
5864
|
+
message: 'Proxy is busy'
|
5865
|
+
});
|
5433
5866
|
return busyEventEmitted = true;
|
5434
5867
|
}
|
5435
5868
|
};
|
@@ -5442,7 +5875,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5442
5875
|
};
|
5443
5876
|
|
5444
5877
|
/**
|
5445
|
-
This event is [emitted]/(up.emit) when [AJAX requests](/up.
|
5878
|
+
This event is [emitted]/(up.emit) when [AJAX requests](/up.ajax)
|
5446
5879
|
are taking long to finish.
|
5447
5880
|
|
5448
5881
|
By default Up.js will wait 300 ms for an AJAX request to finish
|
@@ -5462,13 +5895,15 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5462
5895
|
loadEnded = function() {
|
5463
5896
|
pendingCount -= 1;
|
5464
5897
|
if (idle() && busyEventEmitted) {
|
5465
|
-
up.emit('up:proxy:idle'
|
5898
|
+
up.emit('up:proxy:idle', {
|
5899
|
+
message: 'Proxy is idle'
|
5900
|
+
});
|
5466
5901
|
return busyEventEmitted = false;
|
5467
5902
|
}
|
5468
5903
|
};
|
5469
5904
|
|
5470
5905
|
/**
|
5471
|
-
This event is [emitted]/(up.emit) when [AJAX requests](/up.
|
5906
|
+
This event is [emitted]/(up.emit) when [AJAX requests](/up.ajax)
|
5472
5907
|
have [taken long to finish](/up:proxy:busy), but have finished now.
|
5473
5908
|
|
5474
5909
|
@event up:proxy:idle
|
@@ -5483,7 +5918,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5483
5918
|
};
|
5484
5919
|
queue = function(request) {
|
5485
5920
|
var deferred, entry;
|
5486
|
-
|
5921
|
+
up.puts('Queuing request for %s %s', request.method, request.url);
|
5487
5922
|
deferred = $.Deferred();
|
5488
5923
|
entry = {
|
5489
5924
|
deferred: deferred,
|
@@ -5494,8 +5929,9 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5494
5929
|
};
|
5495
5930
|
load = function(request) {
|
5496
5931
|
var promise;
|
5497
|
-
|
5498
|
-
|
5932
|
+
up.emit('up:proxy:load', u.merge(request, {
|
5933
|
+
message: ['Loading %s %s', request.method, request.url]
|
5934
|
+
}));
|
5499
5935
|
request = u.copy(request);
|
5500
5936
|
request.headers || (request.headers = {});
|
5501
5937
|
request.headers['X-Up-Target'] = request.target;
|
@@ -5508,12 +5944,21 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5508
5944
|
request.method = 'POST';
|
5509
5945
|
}
|
5510
5946
|
promise = $.ajax(request);
|
5511
|
-
promise.
|
5512
|
-
|
5513
|
-
|
5947
|
+
promise.done(function(data, textStatus, xhr) {
|
5948
|
+
return responseReceived(request, xhr);
|
5949
|
+
});
|
5950
|
+
promise.fail(function(xhr, textStatus, errorThrown) {
|
5951
|
+
return responseReceived(request, xhr);
|
5514
5952
|
});
|
5515
5953
|
return promise;
|
5516
5954
|
};
|
5955
|
+
responseReceived = function(request, xhr) {
|
5956
|
+
var ref;
|
5957
|
+
up.emit('up:proxy:received', u.merge(request, {
|
5958
|
+
message: ['Server responded with %s %s (%d bytes)', xhr.status, xhr.statusText, (ref = xhr.responseText) != null ? ref.length : void 0]
|
5959
|
+
}));
|
5960
|
+
return pokeQueue();
|
5961
|
+
};
|
5517
5962
|
pokeQueue = function() {
|
5518
5963
|
var entry, promise;
|
5519
5964
|
if (entry = queuedRequests.shift()) {
|
@@ -5532,7 +5977,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5532
5977
|
};
|
5533
5978
|
|
5534
5979
|
/**
|
5535
|
-
This event is [emitted]/(up.emit) before an [AJAX request](/up.
|
5980
|
+
This event is [emitted]/(up.emit) before an [AJAX request](/up.ajax)
|
5536
5981
|
is starting to load.
|
5537
5982
|
|
5538
5983
|
@event up:proxy:load
|
@@ -5543,7 +5988,7 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5543
5988
|
*/
|
5544
5989
|
|
5545
5990
|
/**
|
5546
|
-
This event is [emitted]/(up.emit) when the response to an [AJAX request](/up.
|
5991
|
+
This event is [emitted]/(up.emit) when the response to an [AJAX request](/up.ajax)
|
5547
5992
|
has been received.
|
5548
5993
|
|
5549
5994
|
@event up:proxy:received
|
@@ -5589,11 +6034,12 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5589
6034
|
if (isIdempotent({
|
5590
6035
|
method: method
|
5591
6036
|
})) {
|
5592
|
-
|
5593
|
-
|
5594
|
-
|
6037
|
+
return up.log.group("Preloading link %o", $link, function() {
|
6038
|
+
options.preload = true;
|
6039
|
+
return up.follow($link, options);
|
6040
|
+
});
|
5595
6041
|
} else {
|
5596
|
-
|
6042
|
+
up.puts("Won't preload %o due to unsafe method %s", $link, method);
|
5597
6043
|
return u.resolvedPromise();
|
5598
6044
|
}
|
5599
6045
|
};
|
@@ -5634,6 +6080,8 @@ You can change (or remove) this delay by [configuring `up.proxy`](/up.proxy.conf
|
|
5634
6080
|
};
|
5635
6081
|
})(jQuery);
|
5636
6082
|
|
6083
|
+
up.ajax = up.proxy.ajax;
|
6084
|
+
|
5637
6085
|
}).call(this);
|
5638
6086
|
|
5639
6087
|
/**
|
@@ -6384,7 +6832,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
6384
6832
|
delay = parseInt(delay);
|
6385
6833
|
callback = null;
|
6386
6834
|
if (u.isGiven(options.change)) {
|
6387
|
-
|
6835
|
+
u.error('up.observe now takes the change callback as the last argument');
|
6388
6836
|
}
|
6389
6837
|
rawCallback = u.option(u.presentAttr($element, 'op-observe'), callbackArg);
|
6390
6838
|
if (u.isString(rawCallback)) {
|
@@ -6510,7 +6958,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
6510
6958
|
}));
|
6511
6959
|
}
|
6512
6960
|
if (u.isBlank(target)) {
|
6513
|
-
error('Could not find default validation target for %o (tried ancestors %o)', $field, config.validateTargets);
|
6961
|
+
u.error('Could not find default validation target for %o (tried ancestors %o)', $field.get(0), config.validateTargets);
|
6514
6962
|
}
|
6515
6963
|
if (!u.isString(target)) {
|
6516
6964
|
target = u.selectorForElement(target);
|
@@ -6567,17 +7015,13 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
6567
7015
|
values = [':unchecked', ':blank'];
|
6568
7016
|
}
|
6569
7017
|
} else if ($field.is('input[type=radio]')) {
|
6570
|
-
console.log('-- it is a radio button --');
|
6571
7018
|
$checkedButton = $field.closest('form, body').find("input[type='radio'][name='" + ($field.attr('name')) + "']:checked");
|
6572
|
-
console.log('checked button is %o', $checkedButton);
|
6573
|
-
console.log('checked button val is %o', $checkedButton.val());
|
6574
7019
|
if ($checkedButton.length) {
|
6575
7020
|
values = [':checked', ':present', $checkedButton.val()];
|
6576
7021
|
} else {
|
6577
7022
|
values = [':unchecked', ':blank'];
|
6578
7023
|
}
|
6579
7024
|
} else {
|
6580
|
-
console.log('-- else -- for %o', $field);
|
6581
7025
|
value = $field.val();
|
6582
7026
|
if (u.isPresent(value)) {
|
6583
7027
|
values = [':present', value];
|
@@ -6641,7 +7085,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
6641
7085
|
$field = $(fieldOrSelector);
|
6642
7086
|
options = u.options(options);
|
6643
7087
|
targets = u.option(options.target, $field.attr('up-toggle'));
|
6644
|
-
u.isPresent(targets) || u.error("No toggle target given for %o", $field);
|
7088
|
+
u.isPresent(targets) || u.error("No toggle target given for %o", $field.get(0));
|
6645
7089
|
fieldValues = currentValuesForToggle($field);
|
6646
7090
|
return $(targets).each(function() {
|
6647
7091
|
var $target, hideValues, show, showValues;
|
@@ -6976,7 +7420,7 @@ open dialogs with sub-forms, etc. all without losing form state.
|
|
6976
7420
|
|
6977
7421
|
@selector [up-hide-for]
|
6978
7422
|
@param up-hide-for
|
6979
|
-
A space-separated list of values for which to
|
7423
|
+
A space-separated list of values for which to hide this element.
|
6980
7424
|
@stable
|
6981
7425
|
*/
|
6982
7426
|
up.on('change', '[up-toggle]', function(event, $field) {
|
@@ -7198,7 +7642,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7198
7642
|
bottom: linkBox.top
|
7199
7643
|
};
|
7200
7644
|
default:
|
7201
|
-
return u.error("Unknown position %
|
7645
|
+
return u.error("Unknown position option '%s'", position);
|
7202
7646
|
}
|
7203
7647
|
})();
|
7204
7648
|
$popup = $('.up-popup');
|
@@ -7247,15 +7691,14 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7247
7691
|
return $popup.removeAttr('up-covered-title');
|
7248
7692
|
};
|
7249
7693
|
createFrame = function(target, options) {
|
7250
|
-
var $
|
7694
|
+
var $popup;
|
7251
7695
|
$popup = u.$createElementFromSelector('.up-popup');
|
7252
7696
|
if (options.sticky) {
|
7253
7697
|
$popup.attr('up-sticky', '');
|
7254
7698
|
}
|
7255
7699
|
$popup.attr('up-covered-url', up.browser.url());
|
7256
7700
|
$popup.attr('up-covered-title', document.title);
|
7257
|
-
|
7258
|
-
$placeholder.appendTo($popup);
|
7701
|
+
u.$createPlaceholder(target, $popup);
|
7259
7702
|
$popup.appendTo(document.body);
|
7260
7703
|
return $popup;
|
7261
7704
|
};
|
@@ -7318,7 +7761,8 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7318
7761
|
return up.browser.confirm(options.confirm).then(function() {
|
7319
7762
|
var promise, wasOpen;
|
7320
7763
|
if (up.bus.nobodyPrevents('up:popup:open', {
|
7321
|
-
url: url
|
7764
|
+
url: url,
|
7765
|
+
message: 'Opening popup'
|
7322
7766
|
})) {
|
7323
7767
|
wasOpen = isOpen();
|
7324
7768
|
if (wasOpen) {
|
@@ -7341,7 +7785,9 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7341
7785
|
});
|
7342
7786
|
}
|
7343
7787
|
promise = promise.then(function() {
|
7344
|
-
return up.emit('up:popup:opened'
|
7788
|
+
return up.emit('up:popup:opened', {
|
7789
|
+
message: 'Popup opened'
|
7790
|
+
});
|
7345
7791
|
});
|
7346
7792
|
return promise;
|
7347
7793
|
} else {
|
@@ -7396,7 +7842,9 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7396
7842
|
currentUrl = void 0;
|
7397
7843
|
deferred = up.destroy($popup, options);
|
7398
7844
|
deferred.then(function() {
|
7399
|
-
return up.emit('up:popup:closed'
|
7845
|
+
return up.emit('up:popup:closed', {
|
7846
|
+
message: 'Popup closed'
|
7847
|
+
});
|
7400
7848
|
});
|
7401
7849
|
return deferred;
|
7402
7850
|
} else {
|
@@ -7703,7 +8151,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7703
8151
|
return $modal.removeAttr('up-covered-title');
|
7704
8152
|
};
|
7705
8153
|
createFrame = function(target, options) {
|
7706
|
-
var $content, $dialog, $modal
|
8154
|
+
var $content, $dialog, $modal;
|
7707
8155
|
shiftElements();
|
7708
8156
|
$modal = $(templateHtml());
|
7709
8157
|
if (options.sticky) {
|
@@ -7722,8 +8170,7 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7722
8170
|
$dialog.css('height', options.height);
|
7723
8171
|
}
|
7724
8172
|
$content = $modal.find('.up-modal-content');
|
7725
|
-
|
7726
|
-
$placeholder.appendTo($content);
|
8173
|
+
u.$createPlaceholder(target, $content);
|
7727
8174
|
$modal.appendTo(document.body);
|
7728
8175
|
return $modal;
|
7729
8176
|
};
|
@@ -7868,7 +8315,8 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7868
8315
|
return up.browser.confirm(options.confirm).then(function() {
|
7869
8316
|
var promise, wasOpen;
|
7870
8317
|
if (up.bus.nobodyPrevents('up:modal:open', {
|
7871
|
-
url: url
|
8318
|
+
url: url,
|
8319
|
+
message: 'Opening modal'
|
7872
8320
|
})) {
|
7873
8321
|
wasOpen = isOpen();
|
7874
8322
|
if (wasOpen) {
|
@@ -7888,7 +8336,9 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7888
8336
|
});
|
7889
8337
|
}
|
7890
8338
|
promise = promise.then(function() {
|
7891
|
-
return up.emit('up:modal:opened'
|
8339
|
+
return up.emit('up:modal:opened', {
|
8340
|
+
message: 'Modal opened'
|
8341
|
+
});
|
7892
8342
|
});
|
7893
8343
|
return promise;
|
7894
8344
|
} else {
|
@@ -7933,7 +8383,8 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7933
8383
|
$modal = $('.up-modal');
|
7934
8384
|
if ($modal.length) {
|
7935
8385
|
if (up.bus.nobodyPrevents('up:modal:close', {
|
7936
|
-
$element: $modal
|
8386
|
+
$element: $modal,
|
8387
|
+
message: 'Closing modal'
|
7937
8388
|
})) {
|
7938
8389
|
options = u.options(options, {
|
7939
8390
|
animation: config.closeAnimation,
|
@@ -7944,7 +8395,9 @@ To disable this behavior, give the opening link an `up-sticky` attribute:
|
|
7944
8395
|
promise = up.destroy($modal, options);
|
7945
8396
|
promise = promise.then(function() {
|
7946
8397
|
unshiftElements();
|
7947
|
-
return up.emit('up:modal:closed'
|
8398
|
+
return up.emit('up:modal:closed', {
|
8399
|
+
message: 'Modal closed'
|
8400
|
+
});
|
7948
8401
|
});
|
7949
8402
|
return promise;
|
7950
8403
|
} else {
|
@@ -8170,7 +8623,7 @@ The tooltip element is appended to the end of `<body>`.
|
|
8170
8623
|
top: linkBox.top + linkBox.height
|
8171
8624
|
};
|
8172
8625
|
default:
|
8173
|
-
return u.error("Unknown position %
|
8626
|
+
return u.error("Unknown position option '%s'", position);
|
8174
8627
|
}
|
8175
8628
|
})();
|
8176
8629
|
$tooltip.attr('up-position', position);
|