upjs-rails 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dist/up.css +16 -1
- data/dist/up.js +499 -88
- data/dist/up.min.css +1 -1
- data/dist/up.min.js +2 -1
- data/lib/assets/javascripts/up/browser.js.coffee +17 -1
- data/lib/assets/javascripts/up/bus.js.coffee +6 -4
- data/lib/assets/javascripts/up/flow.js.coffee +25 -16
- data/lib/assets/javascripts/up/form.js.coffee +11 -3
- data/lib/assets/javascripts/up/history.js.coffee +3 -4
- data/lib/assets/javascripts/up/link.js.coffee +47 -17
- data/lib/assets/javascripts/up/magic.js.coffee +36 -8
- data/lib/assets/javascripts/up/modal.js.coffee +6 -8
- data/lib/assets/javascripts/up/motion.js.coffee +9 -7
- data/lib/assets/javascripts/up/navigation.js.coffee +17 -7
- data/lib/assets/javascripts/up/popup.js.coffee +2 -4
- data/lib/assets/javascripts/up/proxy.js.coffee +179 -0
- data/lib/assets/javascripts/up/tooltip.js.coffee +6 -2
- data/lib/assets/javascripts/up/util.js.coffee +92 -6
- data/lib/assets/javascripts/up.js.coffee +4 -1
- data/lib/assets/stylesheets/up/error.css.sass +15 -0
- data/lib/assets/stylesheets/up/tooltip.css.sass +1 -0
- data/lib/upjs/rails/current_location.rb +2 -1
- data/lib/upjs/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +38 -9
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +2 -2
- data/spec_app/spec/javascripts/up/magic_spec.js.coffee +25 -1
- data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +2 -2
- metadata +4 -2
data/dist/up.js
CHANGED
@@ -25,7 +25,7 @@ If you use them in your own code, you will get hurt.
|
|
25
25
|
var __slice = [].slice;
|
26
26
|
|
27
27
|
up.util = (function() {
|
28
|
-
var $createElementFromSelector, ANIMATION_PROMISE_KEY, ajax, castsToFalse, castsToTrue, clientSize, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, detect, each, error, escapePressed, extend, findWithSelf, finishCssAnimate, forceCompositing, get, ifGiven, isArray, isBlank, isDeferred, isDefined, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, keys, last, locationFromXhr, measure, merge, nextFrame, normalizeUrl, only, option, options, prependGhost, presence, presentAttr, resolvableWhen, resolvedDeferred, resolvedPromise, select, temporaryCss, trim, unwrap;
|
28
|
+
var $createElementFromSelector, ANIMATION_PROMISE_KEY, CONSOLE_PLACEHOLDERS, ajax, castsToFalse, castsToTrue, clientSize, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, debug, detect, each, error, escapePressed, extend, findWithSelf, finishCssAnimate, forceCompositing, get, ifGiven, isArray, isBlank, isDeferred, isDefined, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, keys, last, locationFromXhr, measure, merge, methodFromXhr, nextFrame, normalizeMethod, normalizeUrl, only, option, options, prependGhost, presence, presentAttr, resolvableWhen, resolvedDeferred, resolvedPromise, select, stringSet, stringifyConsoleArgs, temporaryCss, toArray, trim, unwrap;
|
29
29
|
get = function(url, options) {
|
30
30
|
options = options || {};
|
31
31
|
options.url = url;
|
@@ -81,6 +81,18 @@ If you use them in your own code, you will get hurt.
|
|
81
81
|
}
|
82
82
|
return normalized;
|
83
83
|
};
|
84
|
+
|
85
|
+
/*
|
86
|
+
@method up.util.normalizeMethod
|
87
|
+
@protected
|
88
|
+
*/
|
89
|
+
normalizeMethod = function(method) {
|
90
|
+
if (method) {
|
91
|
+
return method.toUpperCase();
|
92
|
+
} else {
|
93
|
+
return 'GET';
|
94
|
+
}
|
95
|
+
};
|
84
96
|
$createElementFromSelector = function(selector) {
|
85
97
|
var $element, $parent, $root, classes, conjunction, depthSelector, expression, html, id, iteration, path, tag, _i, _j, _len, _len1;
|
86
98
|
path = selector.split(/[ >]/);
|
@@ -131,17 +143,65 @@ If you use them in your own code, you will get hurt.
|
|
131
143
|
}
|
132
144
|
return element;
|
133
145
|
};
|
146
|
+
debug = function() {
|
147
|
+
var args, group, message, placeHolderCount, value, _ref;
|
148
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
149
|
+
args = toArray(args);
|
150
|
+
message = args.shift();
|
151
|
+
message = "[UP] " + message;
|
152
|
+
placeHolderCount = ((_ref = message.match(CONSOLE_PLACEHOLDERS)) != null ? _ref.length : void 0) || 0;
|
153
|
+
if (isFunction(last(args)) && placeHolderCount < args.length) {
|
154
|
+
group = args.pop();
|
155
|
+
}
|
156
|
+
value = console.debug.apply(console, [message].concat(__slice.call(args)));
|
157
|
+
if (group) {
|
158
|
+
console.groupCollapsed();
|
159
|
+
try {
|
160
|
+
value = group();
|
161
|
+
} finally {
|
162
|
+
console.groupEnd();
|
163
|
+
}
|
164
|
+
}
|
165
|
+
return value;
|
166
|
+
};
|
134
167
|
error = function() {
|
135
|
-
var args, asString;
|
168
|
+
var $error, args, asString;
|
136
169
|
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
137
|
-
|
138
|
-
|
139
|
-
|
170
|
+
args[0] = "[UP] " + args[0];
|
171
|
+
console.error.apply(console, args);
|
172
|
+
asString = stringifyConsoleArgs(args);
|
173
|
+
$error = presence($('.up-error')) || $('<div class="up-error"></div>').prependTo('body');
|
174
|
+
$error.addClass('up-error');
|
175
|
+
$error.text(asString);
|
140
176
|
throw asString;
|
141
177
|
};
|
178
|
+
CONSOLE_PLACEHOLDERS = /\%[odisf]/g;
|
179
|
+
stringifyConsoleArgs = function(args) {
|
180
|
+
var i, maxLength, message;
|
181
|
+
message = args[0];
|
182
|
+
i = 0;
|
183
|
+
maxLength = 30;
|
184
|
+
return message.replace(CONSOLE_PLACEHOLDERS, function() {
|
185
|
+
var arg, argType;
|
186
|
+
i += 1;
|
187
|
+
arg = args[i];
|
188
|
+
argType = typeof arg;
|
189
|
+
if (argType === 'string') {
|
190
|
+
arg = arg.replace(/\s+/g, ' ');
|
191
|
+
if (arg.length > maxLength) {
|
192
|
+
arg = (arg.substr(0, maxLength)) + "…";
|
193
|
+
}
|
194
|
+
return "\"" + arg + "\"";
|
195
|
+
} else if (argType === 'number') {
|
196
|
+
return arg.toString();
|
197
|
+
} else {
|
198
|
+
return "(" + argType + ")";
|
199
|
+
}
|
200
|
+
});
|
201
|
+
};
|
142
202
|
createSelectorFromElement = function($element) {
|
143
203
|
var classString, classes, id, klass, selector, _i, _len;
|
144
|
-
|
204
|
+
debug("Creating selector from element %o", $element);
|
145
205
|
classes = (classString = $element.attr("class")) ? classString.split(" ") : [];
|
146
206
|
id = $element.attr("id");
|
147
207
|
selector = $element.prop("tagName").toLowerCase();
|
@@ -265,6 +325,9 @@ If you use them in your own code, you will get hurt.
|
|
265
325
|
isArray = Array.isArray || function(object) {
|
266
326
|
return Object.prototype.toString.call(object) === '[object Array]';
|
267
327
|
};
|
328
|
+
toArray = function(object) {
|
329
|
+
return Array.prototype.slice.call(object);
|
330
|
+
};
|
268
331
|
copy = function(object) {
|
269
332
|
if (isArray(object)) {
|
270
333
|
return object.slice();
|
@@ -557,7 +620,10 @@ If you use them in your own code, you will get hurt.
|
|
557
620
|
return String(object) === "false";
|
558
621
|
};
|
559
622
|
locationFromXhr = function(xhr) {
|
560
|
-
return xhr.getResponseHeader('X-Up-
|
623
|
+
return xhr.getResponseHeader('X-Up-Location');
|
624
|
+
};
|
625
|
+
methodFromXhr = function(xhr) {
|
626
|
+
return xhr.getResponseHeader('X-Up-Method');
|
561
627
|
};
|
562
628
|
only = function() {
|
563
629
|
var filtered, key, keys, object, _i, _len;
|
@@ -591,10 +657,36 @@ If you use them in your own code, you will get hurt.
|
|
591
657
|
};
|
592
658
|
return joined;
|
593
659
|
};
|
660
|
+
stringSet = function(array) {
|
661
|
+
var includes, includesAny, key, put, set, string, _i, _len;
|
662
|
+
set = {};
|
663
|
+
includes = function(string) {
|
664
|
+
return set[key(string)];
|
665
|
+
};
|
666
|
+
includesAny = function(strings) {
|
667
|
+
return detect(strings, includes);
|
668
|
+
};
|
669
|
+
put = function(string) {
|
670
|
+
return set[key(string)] = true;
|
671
|
+
};
|
672
|
+
key = function(string) {
|
673
|
+
return "_" + string;
|
674
|
+
};
|
675
|
+
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
676
|
+
string = array[_i];
|
677
|
+
put(string);
|
678
|
+
}
|
679
|
+
return {
|
680
|
+
put: put,
|
681
|
+
includes: includes,
|
682
|
+
includesAny: includesAny
|
683
|
+
};
|
684
|
+
};
|
594
685
|
return {
|
595
686
|
presentAttr: presentAttr,
|
596
687
|
createElement: createElement,
|
597
688
|
normalizeUrl: normalizeUrl,
|
689
|
+
normalizeMethod: normalizeMethod,
|
598
690
|
createElementFromHtml: createElementFromHtml,
|
599
691
|
$createElementFromSelector: $createElementFromSelector,
|
600
692
|
createSelectorFromElement: createSelectorFromElement,
|
@@ -606,6 +698,7 @@ If you use them in your own code, you will get hurt.
|
|
606
698
|
options: options,
|
607
699
|
option: option,
|
608
700
|
error: error,
|
701
|
+
debug: debug,
|
609
702
|
each: each,
|
610
703
|
detect: detect,
|
611
704
|
select: select,
|
@@ -639,16 +732,19 @@ If you use them in your own code, you will get hurt.
|
|
639
732
|
findWithSelf: findWithSelf,
|
640
733
|
contains: contains,
|
641
734
|
isArray: isArray,
|
735
|
+
toArray: toArray,
|
642
736
|
castsToTrue: castsToTrue,
|
643
737
|
castsToFalse: castsToFalse,
|
644
738
|
locationFromXhr: locationFromXhr,
|
739
|
+
methodFromXhr: methodFromXhr,
|
645
740
|
clientSize: clientSize,
|
646
741
|
only: only,
|
647
742
|
trim: trim,
|
648
743
|
keys: keys,
|
649
744
|
resolvedPromise: resolvedPromise,
|
650
745
|
resolvedDeferred: resolvedDeferred,
|
651
|
-
resolvableWhen: resolvableWhen
|
746
|
+
resolvableWhen: resolvableWhen,
|
747
|
+
stringSet: stringSet
|
652
748
|
};
|
653
749
|
})();
|
654
750
|
|
@@ -665,7 +761,7 @@ Browser interface
|
|
665
761
|
var __slice = [].slice;
|
666
762
|
|
667
763
|
up.browser = (function() {
|
668
|
-
var canCssAnimation, canInputEvent, canPushState, ensureConsoleExists, isSupported, loadPage, memoize, u, url;
|
764
|
+
var canCssAnimation, canInputEvent, canPushState, ensureConsoleExists, ensureRecentJquery, isSupported, loadPage, memoize, u, url;
|
669
765
|
u = up.util;
|
670
766
|
loadPage = function(url, options) {
|
671
767
|
var $form, csrfParam, csrfToken, metadataInput, method, target;
|
@@ -697,9 +793,16 @@ Browser interface
|
|
697
793
|
return location.href;
|
698
794
|
};
|
699
795
|
ensureConsoleExists = function() {
|
700
|
-
var _base;
|
796
|
+
var noop, _base, _base1, _base2, _base3, _base4, _base5, _base6;
|
701
797
|
window.console || (window.console = {});
|
702
|
-
|
798
|
+
noop = function() {};
|
799
|
+
(_base = window.console).log || (_base.log = noop);
|
800
|
+
(_base1 = window.console).info || (_base1.info = noop);
|
801
|
+
(_base2 = window.console).error || (_base2.error = noop);
|
802
|
+
(_base3 = window.console).debug || (_base3.debug = noop);
|
803
|
+
(_base4 = window.console).group || (_base4.group = noop);
|
804
|
+
(_base5 = window.console).groupCollapsed || (_base5.groupCollapsed = noop);
|
805
|
+
return (_base6 = window.console).groupEnd || (_base6.groupEnd = noop);
|
703
806
|
};
|
704
807
|
memoize = function(func) {
|
705
808
|
var cache, cached;
|
@@ -725,6 +828,15 @@ Browser interface
|
|
725
828
|
canInputEvent = memoize(function() {
|
726
829
|
return 'oninput' in document.createElement('input');
|
727
830
|
});
|
831
|
+
ensureRecentJquery = function() {
|
832
|
+
var compatible, major, minor, parts, version;
|
833
|
+
version = $.fn.jquery;
|
834
|
+
parts = version.split('.');
|
835
|
+
major = parseInt(parts[0]);
|
836
|
+
minor = parseInt(parts[1]);
|
837
|
+
compatible = major >= 2 || (major === 1 && minor >= 9);
|
838
|
+
return compatible || u.error("jQuery %o found, but Up.js requires 1.9+", version);
|
839
|
+
};
|
728
840
|
isSupported = memoize(function() {
|
729
841
|
return u.isDefined(document.addEventListener);
|
730
842
|
});
|
@@ -735,7 +847,8 @@ Browser interface
|
|
735
847
|
canPushState: canPushState,
|
736
848
|
canCssAnimation: canCssAnimation,
|
737
849
|
canInputEvent: canInputEvent,
|
738
|
-
isSupported: isSupported
|
850
|
+
isSupported: isSupported,
|
851
|
+
ensureRecentJquery: ensureRecentJquery
|
739
852
|
};
|
740
853
|
})();
|
741
854
|
|
@@ -771,7 +884,8 @@ We need to work on this page:
|
|
771
884
|
var __slice = [].slice;
|
772
885
|
|
773
886
|
up.bus = (function() {
|
774
|
-
var callbacksByEvent, callbacksFor, defaultCallbacksByEvent, emit, listen, reset, snapshot;
|
887
|
+
var callbacksByEvent, callbacksFor, defaultCallbacksByEvent, emit, listen, reset, snapshot, u;
|
888
|
+
u = up.util;
|
775
889
|
callbacksByEvent = {};
|
776
890
|
defaultCallbacksByEvent = {};
|
777
891
|
callbacksFor = function(event) {
|
@@ -791,7 +905,7 @@ We need to work on this page:
|
|
791
905
|
_results = [];
|
792
906
|
for (event in callbacksByEvent) {
|
793
907
|
callbacks = callbacksByEvent[event];
|
794
|
-
_results.push(defaultCallbacksByEvent[event] =
|
908
|
+
_results.push(defaultCallbacksByEvent[event] = u.copy(callbacks));
|
795
909
|
}
|
796
910
|
return _results;
|
797
911
|
};
|
@@ -804,7 +918,7 @@ We need to work on this page:
|
|
804
918
|
@method up.bus.reset
|
805
919
|
*/
|
806
920
|
reset = function() {
|
807
|
-
return callbacksByEvent =
|
921
|
+
return callbacksByEvent = u.copy(defaultCallbacksByEvent);
|
808
922
|
};
|
809
923
|
|
810
924
|
/**
|
@@ -833,9 +947,9 @@ We need to work on this page:
|
|
833
947
|
emit = function() {
|
834
948
|
var args, callbacks, eventName;
|
835
949
|
eventName = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
836
|
-
|
950
|
+
u.debug("Emitting event %o with args %o", eventName, args);
|
837
951
|
callbacks = callbacksFor(eventName);
|
838
|
-
return
|
952
|
+
return u.each(callbacks, function(callback) {
|
839
953
|
return callback.apply(null, args);
|
840
954
|
});
|
841
955
|
};
|
@@ -908,19 +1022,31 @@ We need to work on this page:
|
|
908
1022
|
@param {String} [options.historyMethod='push']
|
909
1023
|
*/
|
910
1024
|
replace = function(selectorOrElement, url, options) {
|
911
|
-
var selector;
|
1025
|
+
var promise, request, selector;
|
912
1026
|
options = u.options(options);
|
913
1027
|
selector = u.presence(selectorOrElement) ? selectorOrElement : u.createSelectorFromElement($(selectorOrElement));
|
914
1028
|
if (!up.browser.canPushState() && !u.castsToFalse(options.history)) {
|
915
|
-
|
1029
|
+
if (!options.preload) {
|
1030
|
+
up.browser.loadPage(url, u.only(options, 'method'));
|
1031
|
+
}
|
916
1032
|
return;
|
917
1033
|
}
|
918
|
-
|
1034
|
+
request = {
|
919
1035
|
url: url,
|
1036
|
+
method: options.method,
|
920
1037
|
selector: selector
|
921
|
-
}
|
922
|
-
|
1038
|
+
};
|
1039
|
+
promise = up.proxy.ajax(request);
|
1040
|
+
promise.done(function(html, textStatus, xhr) {
|
1041
|
+
var currentLocation, newRequest;
|
923
1042
|
if (currentLocation = u.locationFromXhr(xhr)) {
|
1043
|
+
u.debug('Location from server: %o', currentLocation);
|
1044
|
+
newRequest = {
|
1045
|
+
url: currentLocation,
|
1046
|
+
method: u.methodFromXhr(xhr),
|
1047
|
+
selector: selector
|
1048
|
+
};
|
1049
|
+
up.proxy.alias(request, newRequest);
|
924
1050
|
url = currentLocation;
|
925
1051
|
}
|
926
1052
|
if (u.isMissing(options.history) || u.castsToTrue(options.history)) {
|
@@ -929,8 +1055,12 @@ We need to work on this page:
|
|
929
1055
|
if (u.isMissing(options.source) || u.castsToTrue(options.source)) {
|
930
1056
|
options.source = url;
|
931
1057
|
}
|
932
|
-
|
933
|
-
|
1058
|
+
if (!options.preload) {
|
1059
|
+
return implant(selector, html, options);
|
1060
|
+
}
|
1061
|
+
});
|
1062
|
+
promise.fail(u.error);
|
1063
|
+
return promise;
|
934
1064
|
};
|
935
1065
|
|
936
1066
|
/**
|
@@ -962,12 +1092,12 @@ We need to work on this page:
|
|
962
1092
|
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
963
1093
|
step = _ref1[_i];
|
964
1094
|
up.motion.finish(step.selector);
|
965
|
-
$old = u.presence($(".up-popup " + step.selector)) || u.presence($(".up-modal " + step.selector)) || u.presence($(step.selector)) || u.error(
|
1095
|
+
$old = u.presence($(".up-popup " + step.selector)) || u.presence($(".up-modal " + step.selector)) || u.presence($(step.selector)) || u.error('Could not find selector %o in current body HTML', step.selector);
|
966
1096
|
if (fragment = htmlElement.querySelector(step.selector)) {
|
967
1097
|
$new = $(fragment);
|
968
1098
|
_results.push(swapElements($old, $new, step.pseudoClass, step.transition, options));
|
969
1099
|
} else {
|
970
|
-
_results.push(u.error("Could not find selector
|
1100
|
+
_results.push(u.error("Could not find selector %o in response %o", step.selector, html));
|
971
1101
|
}
|
972
1102
|
}
|
973
1103
|
return _results;
|
@@ -1002,7 +1132,7 @@ We need to work on this page:
|
|
1002
1132
|
$new.insertAfter($old);
|
1003
1133
|
elementsInserted($new, options);
|
1004
1134
|
if ($old.is('body') && transition !== 'none') {
|
1005
|
-
u.error('Cannot apply transitions to body-elements', transition);
|
1135
|
+
u.error('Cannot apply transitions to body-elements (%o)', transition);
|
1006
1136
|
}
|
1007
1137
|
return up.morph($old, $new, transition);
|
1008
1138
|
}
|
@@ -1143,7 +1273,7 @@ We need to work on this page:
|
|
1143
1273
|
var __slice = [].slice;
|
1144
1274
|
|
1145
1275
|
up.magic = (function() {
|
1146
|
-
var DESTROYABLE_CLASS, DESTROYER_KEY, applyAwakener, awaken, awakeners, compile, defaultAwakeners, defaultLiveDescriptions, destroy, live, liveDescriptions, onEscape, ready, reset, snapshot, u;
|
1276
|
+
var DESTROYABLE_CLASS, DESTROYER_KEY, applyAwakener, awaken, awakeners, compile, data, defaultAwakeners, defaultLiveDescriptions, destroy, live, liveDescriptions, onEscape, ready, reset, snapshot, u;
|
1147
1277
|
u = up.util;
|
1148
1278
|
DESTROYABLE_CLASS = 'up-destroyable';
|
1149
1279
|
DESTROYER_KEY = 'up-destroyer';
|
@@ -1158,8 +1288,11 @@ We need to work on this page:
|
|
1158
1288
|
A space-separated list of event names to bind.
|
1159
1289
|
@param {String} selector
|
1160
1290
|
The selector an on which the event must be triggered.
|
1161
|
-
@param {Function(event, $element)} behavior
|
1291
|
+
@param {Function(event, $element, data)} behavior
|
1162
1292
|
The handler that should be called.
|
1293
|
+
The function takes the affected element as the first argument (as a jQuery object).
|
1294
|
+
If the element has an `up-data` attribute, its value is parsed as JSON
|
1295
|
+
and passed as a second argument.
|
1163
1296
|
*/
|
1164
1297
|
liveDescriptions = [];
|
1165
1298
|
defaultLiveDescriptions = null;
|
@@ -1170,7 +1303,7 @@ We need to work on this page:
|
|
1170
1303
|
}
|
1171
1304
|
description = [
|
1172
1305
|
events, selector, function(event) {
|
1173
|
-
return behavior.apply(this, [event, $(this)]);
|
1306
|
+
return behavior.apply(this, [event, $(this), data(this)]);
|
1174
1307
|
}
|
1175
1308
|
];
|
1176
1309
|
liveDescriptions.push(description);
|
@@ -1188,9 +1321,11 @@ We need to work on this page:
|
|
1188
1321
|
If set to `true` and a fragment insertion contains multiple
|
1189
1322
|
elements matching the selector, `awakener` is only called once
|
1190
1323
|
with a jQuery collection containing all matching elements.
|
1191
|
-
@param {Function($element)} awakener
|
1324
|
+
@param {Function($element, data)} awakener
|
1192
1325
|
The function to call when a matching element is inserted.
|
1193
1326
|
The function takes the new element as the first argument (as a jQuery object).
|
1327
|
+
If the element has an `up-data` attribute, its value is parsed as JSON
|
1328
|
+
and passed as a second argument.
|
1194
1329
|
|
1195
1330
|
The function may return another function that destroys the awakened
|
1196
1331
|
object when it is removed from the DOM, by clearing global state such as
|
@@ -1216,7 +1351,8 @@ We need to work on this page:
|
|
1216
1351
|
};
|
1217
1352
|
applyAwakener = function(awakener, $jqueryElement, nativeElement) {
|
1218
1353
|
var destroyer;
|
1219
|
-
|
1354
|
+
u.debug("Applying awakener %o on %o", awakener.selector, nativeElement);
|
1355
|
+
destroyer = awakener.callback.apply(nativeElement, [$jqueryElement, data($jqueryElement)]);
|
1220
1356
|
if (u.isFunction(destroyer)) {
|
1221
1357
|
$jqueryElement.addClass(DESTROYABLE_CLASS);
|
1222
1358
|
return $jqueryElement.data(DESTROYER_KEY, destroyer);
|
@@ -1224,7 +1360,7 @@ We need to work on this page:
|
|
1224
1360
|
};
|
1225
1361
|
compile = function($fragment) {
|
1226
1362
|
var $matches, awakener, _i, _len, _results;
|
1227
|
-
|
1363
|
+
u.debug("Compiling fragment %o", $fragment);
|
1228
1364
|
_results = [];
|
1229
1365
|
for (_i = 0, _len = awakeners.length; _i < _len; _i++) {
|
1230
1366
|
awakener = awakeners[_i];
|
@@ -1252,6 +1388,30 @@ We need to work on this page:
|
|
1252
1388
|
});
|
1253
1389
|
};
|
1254
1390
|
|
1391
|
+
/*
|
1392
|
+
Checks if the given element has an `up-data` attribute.
|
1393
|
+
If yes, parses the attribute value as JSON and returns the parsed object.
|
1394
|
+
|
1395
|
+
Returns an empty object if the element has no `up-data` attribute.
|
1396
|
+
|
1397
|
+
The API of this method is likely to change in the future, so
|
1398
|
+
we can support getting or setting individual keys.
|
1399
|
+
|
1400
|
+
@protected
|
1401
|
+
@method up.magic.data
|
1402
|
+
@param {String|Element|jQuery} elementOrSelector
|
1403
|
+
*/
|
1404
|
+
data = function(elementOrSelector) {
|
1405
|
+
var $element, json;
|
1406
|
+
$element = $(elementOrSelector);
|
1407
|
+
json = $element.attr('up-data');
|
1408
|
+
if (u.isString(json) && u.trim(json) !== '') {
|
1409
|
+
return JSON.parse(json);
|
1410
|
+
} else {
|
1411
|
+
return {};
|
1412
|
+
}
|
1413
|
+
};
|
1414
|
+
|
1255
1415
|
/**
|
1256
1416
|
Makes a snapshot of the currently registered event listeners,
|
1257
1417
|
to later be restored through [`up.bus.reset`](/up.bus#up.bus.reset).
|
@@ -1319,7 +1479,8 @@ We need to work on this page:
|
|
1319
1479
|
awaken: awaken,
|
1320
1480
|
on: live,
|
1321
1481
|
ready: ready,
|
1322
|
-
onEscape: onEscape
|
1482
|
+
onEscape: onEscape,
|
1483
|
+
data: data
|
1323
1484
|
};
|
1324
1485
|
})();
|
1325
1486
|
|
@@ -1396,14 +1557,13 @@ We need to work on this page:
|
|
1396
1557
|
pop = function(event) {
|
1397
1558
|
var state;
|
1398
1559
|
state = event.originalEvent.state;
|
1399
|
-
console.log("popping state", state);
|
1400
|
-
console.log("current href", up.browser.url());
|
1401
1560
|
if (state != null ? state.fromUp : void 0) {
|
1561
|
+
u.debug("Restoring state %o (now on " + (up.browser.url()) + ")", state);
|
1402
1562
|
return up.visit(up.browser.url(), {
|
1403
1563
|
historyMethod: 'replace'
|
1404
1564
|
});
|
1405
1565
|
} else {
|
1406
|
-
return
|
1566
|
+
return u.debug('Discarding unknown state %o', state);
|
1407
1567
|
}
|
1408
1568
|
};
|
1409
1569
|
if (up.browser.canPushState()) {
|
@@ -1509,11 +1669,11 @@ We need to work on this page:
|
|
1509
1669
|
} else if (u.isHash(animation)) {
|
1510
1670
|
return u.cssAnimate($element, animation, options);
|
1511
1671
|
} else {
|
1512
|
-
return u.error("Unknown animation type", animation);
|
1672
|
+
return u.error("Unknown animation type %o", animation);
|
1513
1673
|
}
|
1514
1674
|
};
|
1515
1675
|
findAnimation = function(name) {
|
1516
|
-
return animations[name] || u.error("Unknown animation", animation);
|
1676
|
+
return animations[name] || u.error("Unknown animation %o", animation);
|
1517
1677
|
};
|
1518
1678
|
GHOSTING_PROMISE_KEY = 'up-ghosting-promise';
|
1519
1679
|
withGhosts = function($old, $new, block) {
|
@@ -1572,7 +1732,7 @@ We need to work on this page:
|
|
1572
1732
|
finishGhosting = function($element) {
|
1573
1733
|
var existingGhosting;
|
1574
1734
|
if (existingGhosting = $element.data(GHOSTING_PROMISE_KEY)) {
|
1575
|
-
|
1735
|
+
u.debug('Canceling existing ghosting on %o', $element);
|
1576
1736
|
return typeof existingGhosting.resolve === "function" ? existingGhosting.resolve() : void 0;
|
1577
1737
|
}
|
1578
1738
|
};
|
@@ -1580,7 +1740,7 @@ We need to work on this page:
|
|
1580
1740
|
if (u.isDeferred(object)) {
|
1581
1741
|
return object;
|
1582
1742
|
} else {
|
1583
|
-
return u.error("Did not return a promise with .then and .resolve methods: ", origin);
|
1743
|
+
return u.error("Did not return a promise with .then and .resolve methods: %o", origin);
|
1584
1744
|
}
|
1585
1745
|
};
|
1586
1746
|
|
@@ -1620,8 +1780,9 @@ We need to work on this page:
|
|
1620
1780
|
$new = $(target);
|
1621
1781
|
finish($old);
|
1622
1782
|
finish($new);
|
1623
|
-
|
1624
|
-
|
1783
|
+
if (transitionOrName === 'none') {
|
1784
|
+
return none();
|
1785
|
+
} else if (transition = u.presence(transitionOrName, u.isFunction) || transitions[transitionOrName]) {
|
1625
1786
|
return withGhosts($old, $new, function($oldGhost, $newGhost) {
|
1626
1787
|
return assertIsDeferred(transition($oldGhost, $newGhost, options), transitionOrName);
|
1627
1788
|
});
|
@@ -1635,7 +1796,7 @@ We need to work on this page:
|
|
1635
1796
|
};
|
1636
1797
|
return morph($old, $new, transition, options);
|
1637
1798
|
} else {
|
1638
|
-
return u.error("Unknown transition
|
1799
|
+
return u.error("Unknown transition %o", transitionOrName);
|
1639
1800
|
}
|
1640
1801
|
} else {
|
1641
1802
|
return u.resolvedDeferred();
|
@@ -1846,6 +2007,208 @@ We need to work on this page:
|
|
1846
2007
|
|
1847
2008
|
}).call(this);
|
1848
2009
|
|
2010
|
+
/**
|
2011
|
+
Caching and preloading
|
2012
|
+
======================
|
2013
|
+
|
2014
|
+
Document me.
|
2015
|
+
|
2016
|
+
@class up.proxy
|
2017
|
+
*/
|
2018
|
+
|
2019
|
+
(function() {
|
2020
|
+
up.proxy = (function() {
|
2021
|
+
var $waitingLink, ajax, alias, cache, cacheKey, cancelDelay, checkPreload, clear, config, defaults, delayTimer, ensureIsIdempotent, get, isFresh, isIdempotent, normalizeRequest, preload, remove, reset, set, startDelay, timestamp, touch, trim, u;
|
2022
|
+
config = {
|
2023
|
+
preloadDelay: 50,
|
2024
|
+
cacheSize: 70,
|
2025
|
+
cacheExpiry: 1000 * 60 * 5
|
2026
|
+
};
|
2027
|
+
|
2028
|
+
/**
|
2029
|
+
@method up.proxy.defaults
|
2030
|
+
@param {Number} [preloadDelay]
|
2031
|
+
@param {Number} [cacheSize]
|
2032
|
+
@param {Number} [cacheExpiry]
|
2033
|
+
The number of milliseconds until a cache entry expires.
|
2034
|
+
*/
|
2035
|
+
defaults = function(options) {
|
2036
|
+
return u.extend(config, options);
|
2037
|
+
};
|
2038
|
+
cache = {};
|
2039
|
+
u = up.util;
|
2040
|
+
$waitingLink = null;
|
2041
|
+
delayTimer = null;
|
2042
|
+
cacheKey = function(request) {
|
2043
|
+
normalizeRequest(request);
|
2044
|
+
return [request.url, request.method, request.selector].join('|');
|
2045
|
+
};
|
2046
|
+
trim = function() {
|
2047
|
+
var keys, oldestKey, oldestTimestamp;
|
2048
|
+
keys = u.keys(cache);
|
2049
|
+
if (keys.length > config.cacheSize) {
|
2050
|
+
oldestKey = null;
|
2051
|
+
oldestTimestamp = null;
|
2052
|
+
u.each(keys, function(key) {
|
2053
|
+
var promise, timestamp;
|
2054
|
+
promise = cache[key];
|
2055
|
+
timestamp = promise.timestamp;
|
2056
|
+
if (!oldestTimestamp || oldestTimestamp > timestamp) {
|
2057
|
+
oldestKey = key;
|
2058
|
+
return oldestTimestamp = timestamp;
|
2059
|
+
}
|
2060
|
+
});
|
2061
|
+
if (oldestKey) {
|
2062
|
+
return delete cache[oldestKey];
|
2063
|
+
}
|
2064
|
+
}
|
2065
|
+
};
|
2066
|
+
timestamp = function() {
|
2067
|
+
return (new Date()).valueOf();
|
2068
|
+
};
|
2069
|
+
normalizeRequest = function(request) {
|
2070
|
+
if (!u.isHash(request)) {
|
2071
|
+
debugger;
|
2072
|
+
}
|
2073
|
+
if (!request._requestNormalized) {
|
2074
|
+
request.method = u.normalizeMethod(request.method);
|
2075
|
+
if (request.url) {
|
2076
|
+
request.url = u.normalizeUrl(request.url);
|
2077
|
+
}
|
2078
|
+
request.selector || (request.selector = 'body');
|
2079
|
+
request._requestNormalized = true;
|
2080
|
+
}
|
2081
|
+
return request;
|
2082
|
+
};
|
2083
|
+
alias = function(oldRequest, newRequest) {
|
2084
|
+
var promise;
|
2085
|
+
u.debug("Aliasing %o to %o", oldRequest, newRequest);
|
2086
|
+
if (promise = get(oldRequest)) {
|
2087
|
+
return set(newRequest, promise);
|
2088
|
+
}
|
2089
|
+
};
|
2090
|
+
|
2091
|
+
/*
|
2092
|
+
@method up.proxy.ajax
|
2093
|
+
@param {String} options.url
|
2094
|
+
@param {String} [options.method='GET']
|
2095
|
+
@param {String} [options.selector]
|
2096
|
+
*/
|
2097
|
+
ajax = function(request) {
|
2098
|
+
var promise;
|
2099
|
+
if (!isIdempotent(request)) {
|
2100
|
+
clear();
|
2101
|
+
promise = u.ajax(request);
|
2102
|
+
} else if (promise = get(request)) {
|
2103
|
+
touch(promise);
|
2104
|
+
} else {
|
2105
|
+
promise = u.ajax(request);
|
2106
|
+
set(request, promise);
|
2107
|
+
}
|
2108
|
+
return promise;
|
2109
|
+
};
|
2110
|
+
isIdempotent = function(request) {
|
2111
|
+
normalizeRequest(request);
|
2112
|
+
return request.method === 'GET';
|
2113
|
+
};
|
2114
|
+
ensureIsIdempotent = function(request) {
|
2115
|
+
return isIdempotent(request) || u.error("Won't preload non-GET request %o", request);
|
2116
|
+
};
|
2117
|
+
isFresh = function(promise) {
|
2118
|
+
var timeSinceTouch;
|
2119
|
+
timeSinceTouch = timestamp() - promise.timestamp;
|
2120
|
+
return timeSinceTouch < config.cacheExpiry;
|
2121
|
+
};
|
2122
|
+
touch = function(promise) {
|
2123
|
+
return promise.timestamp = timestamp();
|
2124
|
+
};
|
2125
|
+
get = function(request) {
|
2126
|
+
var key, promise;
|
2127
|
+
key = cacheKey(request);
|
2128
|
+
if (promise = cache[key]) {
|
2129
|
+
if (!isFresh(promise)) {
|
2130
|
+
u.debug("Discarding stale cache entry for %o (%o)", request.url, request);
|
2131
|
+
remove(request);
|
2132
|
+
return void 0;
|
2133
|
+
} else {
|
2134
|
+
u.debug("Cache hit for %o (%o)", request.url, request);
|
2135
|
+
return promise;
|
2136
|
+
}
|
2137
|
+
} else {
|
2138
|
+
u.debug("Cache miss for %o (%o)", request.url, request);
|
2139
|
+
return void 0;
|
2140
|
+
}
|
2141
|
+
};
|
2142
|
+
set = function(request, promise) {
|
2143
|
+
var key;
|
2144
|
+
trim();
|
2145
|
+
key = cacheKey(request);
|
2146
|
+
cache[key] = promise;
|
2147
|
+
touch(promise);
|
2148
|
+
return promise;
|
2149
|
+
};
|
2150
|
+
remove = function(request) {
|
2151
|
+
var key;
|
2152
|
+
key = cacheKey(request);
|
2153
|
+
return delete cache[key];
|
2154
|
+
};
|
2155
|
+
clear = function() {
|
2156
|
+
return cache = {};
|
2157
|
+
};
|
2158
|
+
checkPreload = function($link) {
|
2159
|
+
var curriedPreload, delay;
|
2160
|
+
delay = parseInt(u.presentAttr($link, 'up-delay')) || config.preloadDelay;
|
2161
|
+
if (!$link.is($waitingLink)) {
|
2162
|
+
$waitingLink = $link;
|
2163
|
+
cancelDelay();
|
2164
|
+
curriedPreload = function() {
|
2165
|
+
return preload($link);
|
2166
|
+
};
|
2167
|
+
return startDelay(curriedPreload, delay);
|
2168
|
+
}
|
2169
|
+
};
|
2170
|
+
startDelay = function(block, delay) {
|
2171
|
+
return delayTimer = setTimeout(block, delay);
|
2172
|
+
};
|
2173
|
+
cancelDelay = function() {
|
2174
|
+
clearTimeout(delayTimer);
|
2175
|
+
return delayTimer = null;
|
2176
|
+
};
|
2177
|
+
preload = function(link, options) {
|
2178
|
+
options = u.options();
|
2179
|
+
ensureIsIdempotent(options);
|
2180
|
+
u.debug("Preloading %o", link);
|
2181
|
+
options.preload = true;
|
2182
|
+
return up.link.follow(link, options);
|
2183
|
+
};
|
2184
|
+
reset = function() {
|
2185
|
+
cancelDelay();
|
2186
|
+
return cache = {};
|
2187
|
+
};
|
2188
|
+
up.bus.on('framework:reset', reset);
|
2189
|
+
|
2190
|
+
/*
|
2191
|
+
@method [up-preload]
|
2192
|
+
@ujs
|
2193
|
+
*/
|
2194
|
+
up.on('mouseover mousedown touchstart', '[up-preload]', function(event, $element) {
|
2195
|
+
if (!up.link.childClicked(event, $element)) {
|
2196
|
+
return checkPreload(up.link.resolve($element));
|
2197
|
+
}
|
2198
|
+
});
|
2199
|
+
return {
|
2200
|
+
preload: preload,
|
2201
|
+
ajax: ajax,
|
2202
|
+
get: get,
|
2203
|
+
set: set,
|
2204
|
+
alias: alias,
|
2205
|
+
clear: clear,
|
2206
|
+
defaults: defaults
|
2207
|
+
};
|
2208
|
+
})();
|
2209
|
+
|
2210
|
+
}).call(this);
|
2211
|
+
|
1849
2212
|
/**
|
1850
2213
|
Linking to page fragments
|
1851
2214
|
=========================
|
@@ -1923,7 +2286,7 @@ Read on
|
|
1923
2286
|
|
1924
2287
|
(function() {
|
1925
2288
|
up.link = (function() {
|
1926
|
-
var follow, resolve,
|
2289
|
+
var childClicked, follow, resolve, u, visit;
|
1927
2290
|
u = up.util;
|
1928
2291
|
|
1929
2292
|
/**
|
@@ -1940,7 +2303,7 @@ Read on
|
|
1940
2303
|
up.visit('/users')
|
1941
2304
|
*/
|
1942
2305
|
visit = function(url, options) {
|
1943
|
-
|
2306
|
+
u.debug("Visiting " + url);
|
1944
2307
|
return up.replace('body', url, options);
|
1945
2308
|
};
|
1946
2309
|
|
@@ -1970,36 +2333,63 @@ Read on
|
|
1970
2333
|
return up.replace(selector, url, options);
|
1971
2334
|
};
|
1972
2335
|
resolve = function(element) {
|
1973
|
-
var $element;
|
2336
|
+
var $element, followAttr;
|
1974
2337
|
$element = $(element);
|
1975
|
-
|
2338
|
+
followAttr = $element.attr('up-follow');
|
2339
|
+
if ($element.is('a') || (u.isPresent(followAttr) && !u.castsToTrue(followAttr))) {
|
1976
2340
|
return $element;
|
1977
2341
|
} else {
|
1978
2342
|
return $element.find('a:first');
|
1979
2343
|
}
|
1980
2344
|
};
|
1981
|
-
resolveUrl = function(element) {
|
1982
|
-
var $link;
|
1983
|
-
if ($link = resolve(element)) {
|
1984
|
-
return u.option($link.attr('href'), $link.attr('up-follow'));
|
1985
|
-
}
|
1986
|
-
};
|
1987
2345
|
|
1988
2346
|
/**
|
1989
2347
|
Follows this link via AJAX and replaces a CSS selector in the current page
|
1990
|
-
with corresponding elements from a new page fetched from the server
|
2348
|
+
with corresponding elements from a new page fetched from the server:
|
1991
2349
|
|
1992
2350
|
<a href="/users" up-target=".main">User list</a>
|
1993
2351
|
|
2352
|
+
By also adding an `up-instant` attribute, the page will be fetched
|
2353
|
+
on `mousedown` instead of `click`, making the interaction even faster:
|
2354
|
+
|
2355
|
+
<a href="/users" up-target=".main" up-instant>User list</a>
|
2356
|
+
|
2357
|
+
Note that using `[up-instant]` will prevent a user from canceling a link
|
2358
|
+
click by moving the mouse away from the interaction area. However, for
|
2359
|
+
navigation actions this isn't needed. E.g. popular operation
|
2360
|
+
systems switch tabs on `mousedown`.
|
2361
|
+
|
1994
2362
|
@method a[up-target]
|
1995
2363
|
@ujs
|
1996
2364
|
@param {String} up-target
|
1997
2365
|
The CSS selector to replace
|
2366
|
+
@param up-instant
|
2367
|
+
If set, fetches the element on `mousedown` instead of `click`.
|
2368
|
+
This makes the interaction faster.
|
1998
2369
|
*/
|
1999
2370
|
up.on('click', 'a[up-target]', function(event, $link) {
|
2000
2371
|
event.preventDefault();
|
2001
|
-
|
2372
|
+
if (!$link.is('[up-instant]')) {
|
2373
|
+
return follow($link);
|
2374
|
+
}
|
2002
2375
|
});
|
2376
|
+
up.on('mousedown', 'a[up-target][up-instant]', function(event, $link) {
|
2377
|
+
if (event.which === 1) {
|
2378
|
+
event.preventDefault();
|
2379
|
+
return follow($link);
|
2380
|
+
}
|
2381
|
+
});
|
2382
|
+
|
2383
|
+
/*
|
2384
|
+
@method up.link.childClicked
|
2385
|
+
@private
|
2386
|
+
*/
|
2387
|
+
childClicked = function(event, $link) {
|
2388
|
+
var $target, $targetLink;
|
2389
|
+
$target = $(event.target);
|
2390
|
+
$targetLink = $target.closest('a, [up-follow]');
|
2391
|
+
return $targetLink.length && $link.find($targetLink).length;
|
2392
|
+
};
|
2003
2393
|
|
2004
2394
|
/**
|
2005
2395
|
If applied on a link, Follows this link via AJAX and replaces the
|
@@ -2021,16 +2411,20 @@ Read on
|
|
2021
2411
|
@method [up-follow]
|
2022
2412
|
@ujs
|
2023
2413
|
@param {String} [up-follow]
|
2414
|
+
@param up-instant
|
2415
|
+
If set, fetches the element on `mousedown` instead of `click`.
|
2416
|
+
This makes the interaction faster.
|
2024
2417
|
*/
|
2025
2418
|
up.on('click', '[up-follow]', function(event, $element) {
|
2026
|
-
|
2027
|
-
|
2028
|
-
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
|
2033
|
-
|
2419
|
+
if (!childClicked(event, $element)) {
|
2420
|
+
event.preventDefault();
|
2421
|
+
if (!$element.is('[up-instant]')) {
|
2422
|
+
return follow(resolve($element));
|
2423
|
+
}
|
2424
|
+
}
|
2425
|
+
});
|
2426
|
+
up.on('mousedown', '[up-follow][up-instant]', function(event, $element) {
|
2427
|
+
if (!childClicked(event, $element) && event.which === 1) {
|
2034
2428
|
event.preventDefault();
|
2035
2429
|
return follow(resolve($element));
|
2036
2430
|
}
|
@@ -2039,7 +2433,7 @@ Read on
|
|
2039
2433
|
visit: visit,
|
2040
2434
|
follow: follow,
|
2041
2435
|
resolve: resolve,
|
2042
|
-
|
2436
|
+
childClicked: childClicked
|
2043
2437
|
};
|
2044
2438
|
})();
|
2045
2439
|
|
@@ -2064,7 +2458,7 @@ We need to work on this page:
|
|
2064
2458
|
- Explain how to display form errors
|
2065
2459
|
- Explain that the server needs to send 2xx or 5xx status codes so
|
2066
2460
|
Up.js can decide whether the form submission was successful
|
2067
|
-
- Explain that the server needs to send
|
2461
|
+
- Explain that the server needs to send `X-Up-Location` and `X-Up-Method` headers
|
2068
2462
|
if an successful form submission resulted in a redirect
|
2069
2463
|
- Examples
|
2070
2464
|
|
@@ -2191,7 +2585,7 @@ We need to work on this page:
|
|
2191
2585
|
} else if (options.change) {
|
2192
2586
|
callback = options.change;
|
2193
2587
|
} else {
|
2194
|
-
u.error('observe: No change callback given');
|
2588
|
+
u.error('up.observe: No change callback given');
|
2195
2589
|
}
|
2196
2590
|
callbackPromise = u.resolvedPromise();
|
2197
2591
|
nextCallback = null;
|
@@ -2231,7 +2625,7 @@ We need to work on this page:
|
|
2231
2625
|
clearTimer = function() {
|
2232
2626
|
return clearTimeout(callbackTimer);
|
2233
2627
|
};
|
2234
|
-
changeEvents = up.browser.canInputEvent() ? 'input' : 'keypress paste cut
|
2628
|
+
changeEvents = up.browser.canInputEvent() ? 'input change' : 'input change keypress paste cut click propertychange';
|
2235
2629
|
$field.on(changeEvents, check);
|
2236
2630
|
check();
|
2237
2631
|
return clearTimer;
|
@@ -2364,7 +2758,7 @@ We need to work on this page:
|
|
2364
2758
|
bottom: linkBox.top
|
2365
2759
|
};
|
2366
2760
|
default:
|
2367
|
-
return u.error("Unknown origin", origin);
|
2761
|
+
return u.error("Unknown origin %o", origin);
|
2368
2762
|
}
|
2369
2763
|
})();
|
2370
2764
|
$popup.attr('up-origin', origin);
|
@@ -2600,12 +2994,12 @@ We need to work on this page:
|
|
2600
2994
|
|
2601
2995
|
/**
|
2602
2996
|
@method up.modal.defaults
|
2603
|
-
@param {Number} options.width
|
2604
|
-
@param {Number} options.height
|
2605
|
-
@param {String|Function(config)} options.template
|
2606
|
-
@param {String} options.closeLabel
|
2607
|
-
@param {String} options.openAnimation
|
2608
|
-
@param {String} options.closeAnimation
|
2997
|
+
@param {Number} [options.width]
|
2998
|
+
@param {Number} [options.height]
|
2999
|
+
@param {String|Function(config)} [options.template]
|
3000
|
+
@param {String} [options.closeLabel]
|
3001
|
+
@param {String} [options.openAnimation]
|
3002
|
+
@param {String} [options.closeAnimation]
|
2609
3003
|
*/
|
2610
3004
|
defaults = function(options) {
|
2611
3005
|
return u.extend(config, options);
|
@@ -2755,7 +3149,6 @@ We need to work on this page:
|
|
2755
3149
|
});
|
2756
3150
|
up.bus.on('fragment:ready', function($fragment) {
|
2757
3151
|
if (!$fragment.closest('.up-modal').length) {
|
2758
|
-
console.log('fragment inserted', $fragment, $fragment.closest('.up-modal'));
|
2759
3152
|
return autoclose();
|
2760
3153
|
}
|
2761
3154
|
});
|
@@ -2825,7 +3218,7 @@ We need to work on this page:
|
|
2825
3218
|
top: linkBox.top + linkBox.height
|
2826
3219
|
};
|
2827
3220
|
default:
|
2828
|
-
return u.error("Unknown origin", origin);
|
3221
|
+
return u.error("Unknown origin %o", origin);
|
2829
3222
|
}
|
2830
3223
|
})();
|
2831
3224
|
$tooltip.attr('up-origin', origin);
|
@@ -2850,7 +3243,7 @@ We need to work on this page:
|
|
2850
3243
|
options = {};
|
2851
3244
|
}
|
2852
3245
|
$link = $(linkOrSelector);
|
2853
|
-
html = u.option(options.html, $link.attr('up-tooltip'));
|
3246
|
+
html = u.option(options.html, $link.attr('up-tooltip'), $link.attr('title'));
|
2854
3247
|
origin = u.option(options.origin, $link.attr('up-origin'), 'top');
|
2855
3248
|
animation = u.option(options.animation, $link.attr('up-animation'), 'fade-in');
|
2856
3249
|
close();
|
@@ -2883,6 +3276,10 @@ We need to work on this page:
|
|
2883
3276
|
|
2884
3277
|
<a href="/decks" up-tooltip="Show all decks">Decks</a>
|
2885
3278
|
|
3279
|
+
You can also make an existing `title` attribute appear as a tooltip:
|
3280
|
+
|
3281
|
+
<a href="/decks" title="Show all decks" up-tooltip>Decks</a>
|
3282
|
+
|
2886
3283
|
@method [up-tooltip]
|
2887
3284
|
@ujs
|
2888
3285
|
*/
|
@@ -2937,11 +3334,11 @@ From Up's point of view the "current" location is either:
|
|
2937
3334
|
|
2938
3335
|
(function() {
|
2939
3336
|
up.navigation = (function() {
|
2940
|
-
var CLASS_ACTIVE, CLASS_CURRENT, SELECTOR_ACTIVE, SELECTOR_SECTION, enlargeClickArea, locationChanged, normalizeUrl, sectionClicked, u, unmarkActive;
|
3337
|
+
var CLASS_ACTIVE, CLASS_CURRENT, SELECTOR_ACTIVE, SELECTOR_SECTION, enlargeClickArea, locationChanged, normalizeUrl, sectionClicked, sectionUrls, u, unmarkActive;
|
2941
3338
|
u = up.util;
|
2942
3339
|
CLASS_ACTIVE = 'up-active';
|
2943
3340
|
CLASS_CURRENT = 'up-current';
|
2944
|
-
SELECTOR_SECTION = 'a[href], a[up-target], [up-follow], [up-modal], [up-popup]';
|
3341
|
+
SELECTOR_SECTION = 'a[href], a[up-target], [up-follow], [up-modal], [up-popup], [up-source]';
|
2945
3342
|
SELECTOR_ACTIVE = "." + CLASS_ACTIVE;
|
2946
3343
|
normalizeUrl = function(url) {
|
2947
3344
|
if (u.isPresent(url)) {
|
@@ -2951,17 +3348,29 @@ From Up's point of view the "current" location is either:
|
|
2951
3348
|
});
|
2952
3349
|
}
|
2953
3350
|
};
|
3351
|
+
sectionUrls = function($section) {
|
3352
|
+
var $link, attr, url, urls, _i, _len, _ref;
|
3353
|
+
urls = [];
|
3354
|
+
if ($link = up.link.resolve($section)) {
|
3355
|
+
_ref = ['href', 'up-follow', 'up-source'];
|
3356
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
3357
|
+
attr = _ref[_i];
|
3358
|
+
if (url = u.presentAttr($link, attr)) {
|
3359
|
+
url = normalizeUrl(url);
|
3360
|
+
urls.push(url);
|
3361
|
+
}
|
3362
|
+
}
|
3363
|
+
}
|
3364
|
+
return urls;
|
3365
|
+
};
|
2954
3366
|
locationChanged = function() {
|
2955
|
-
var
|
2956
|
-
|
2957
|
-
modalLocation = normalizeUrl(up.modal.source());
|
2958
|
-
popupLocation = normalizeUrl(up.popup.source());
|
3367
|
+
var currentUrls;
|
3368
|
+
currentUrls = u.stringSet([normalizeUrl(up.browser.url()), normalizeUrl(up.modal.source()), normalizeUrl(up.popup.source())]);
|
2959
3369
|
return u.each($(SELECTOR_SECTION), function(section) {
|
2960
|
-
var $section,
|
3370
|
+
var $section, urls;
|
2961
3371
|
$section = $(section);
|
2962
|
-
|
2963
|
-
|
2964
|
-
if (url === windowLocation || url === modalLocation || url === popupLocation) {
|
3372
|
+
urls = sectionUrls($section);
|
3373
|
+
if (currentUrls.includesAny(urls)) {
|
2965
3374
|
return $section.addClass(CLASS_CURRENT);
|
2966
3375
|
} else {
|
2967
3376
|
return $section.removeClass(CLASS_CURRENT);
|
@@ -3040,6 +3449,8 @@ TODO: Write some documentation
|
|
3040
3449
|
|
3041
3450
|
}).call(this);
|
3042
3451
|
(function() {
|
3452
|
+
up.browser.ensureRecentJquery();
|
3453
|
+
|
3043
3454
|
if (up.browser.isSupported()) {
|
3044
3455
|
up.browser.ensureConsoleExists();
|
3045
3456
|
up.bus.emit('framework:ready');
|