upjs-rails 0.3.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/dist/up.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');
|