upjs-rails 0.4.3 → 0.4.4
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.js +469 -172
- data/dist/up.min.js +2 -2
- data/lib/assets/javascripts/up/flow.js.coffee +2 -0
- data/lib/assets/javascripts/up/link.js.coffee +2 -2
- data/lib/assets/javascripts/up/modal.js.coffee +99 -23
- data/lib/assets/javascripts/up/popup.js.coffee +2 -1
- data/lib/assets/javascripts/up/util.js.coffee +10 -0
- data/lib/upjs/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +23 -1
- metadata +2 -2
data/dist/up.js
CHANGED
@@ -22,10 +22,10 @@ If you use them in your own code, you will get hurt.
|
|
22
22
|
*/
|
23
23
|
|
24
24
|
(function() {
|
25
|
-
var
|
25
|
+
var __slice = [].slice;
|
26
26
|
|
27
27
|
up.util = (function() {
|
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, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, keys, last, locationFromXhr, measure, merge, methodFromXhr, nextFrame, normalizeMethod, normalizeUrl, only, option, options, prependGhost, presence, presentAttr, resolvableWhen, resolvedDeferred, resolvedPromise, select, setMissingAttrs, stringSet, stringifyConsoleArgs, temporaryCss, toArray, 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, isElement, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, isUnmodifiedKeyEvent, isUnmodifiedMouseEvent, keys, last, locationFromXhr, measure, merge, methodFromXhr, nextFrame, normalizeMethod, normalizeUrl, nullJquery, only, option, options, prependGhost, presence, presentAttr, resolvableWhen, resolvedDeferred, resolvedPromise, select, setMissingAttrs, stringSet, stringifyConsoleArgs, temporaryCss, toArray, trim, unwrap;
|
29
29
|
get = function(url, options) {
|
30
30
|
options = options || {};
|
31
31
|
options.url = url;
|
@@ -61,14 +61,25 @@ If you use them in your own code, you will get hurt.
|
|
61
61
|
*/
|
62
62
|
normalizeUrl = function(urlOrAnchor, options) {
|
63
63
|
var anchor, normalized, pathname;
|
64
|
-
anchor =
|
65
|
-
|
66
|
-
|
64
|
+
anchor = null;
|
65
|
+
if (isString(urlOrAnchor)) {
|
66
|
+
anchor = $('<a>').attr({
|
67
|
+
href: urlOrAnchor
|
68
|
+
}).get(0);
|
69
|
+
if (isBlank(anchor.hostname)) {
|
70
|
+
anchor.href = anchor.href;
|
71
|
+
}
|
72
|
+
} else {
|
73
|
+
anchor = unwrap(urlOrAnchor);
|
74
|
+
}
|
67
75
|
normalized = anchor.protocol + "//" + anchor.hostname;
|
68
76
|
if (!isStandardPort(anchor.protocol, anchor.port)) {
|
69
77
|
normalized += ":" + anchor.port;
|
70
78
|
}
|
71
79
|
pathname = anchor.pathname;
|
80
|
+
if (pathname[0] !== '/') {
|
81
|
+
pathname = "/" + pathname;
|
82
|
+
}
|
72
83
|
if ((options != null ? options.stripTrailingSlash : void 0) === true) {
|
73
84
|
pathname = pathname.replace(/\/$/, '');
|
74
85
|
}
|
@@ -94,17 +105,17 @@ If you use them in your own code, you will get hurt.
|
|
94
105
|
}
|
95
106
|
};
|
96
107
|
$createElementFromSelector = function(selector) {
|
97
|
-
var $element, $parent, $root, classes, conjunction, depthSelector, expression, html, id, iteration,
|
108
|
+
var $element, $parent, $root, classes, conjunction, depthSelector, expression, html, id, iteration, path, tag, _i, _j, _len, _len1;
|
98
109
|
path = selector.split(/[ >]/);
|
99
110
|
$root = null;
|
100
|
-
for (iteration =
|
111
|
+
for (iteration = _i = 0, _len = path.length; _i < _len; iteration = ++_i) {
|
101
112
|
depthSelector = path[iteration];
|
102
113
|
conjunction = depthSelector.match(/(^|\.|\#)[A-Za-z0-9\-_]+/g);
|
103
114
|
tag = "div";
|
104
115
|
classes = [];
|
105
116
|
id = null;
|
106
|
-
for (
|
107
|
-
expression = conjunction[
|
117
|
+
for (_j = 0, _len1 = conjunction.length; _j < _len1; _j++) {
|
118
|
+
expression = conjunction[_j];
|
108
119
|
switch (expression[0]) {
|
109
120
|
case ".":
|
110
121
|
classes.push(expression.substr(1));
|
@@ -144,16 +155,16 @@ If you use them in your own code, you will get hurt.
|
|
144
155
|
return element;
|
145
156
|
};
|
146
157
|
debug = function() {
|
147
|
-
var args, group, message, placeHolderCount,
|
148
|
-
args = 1 <= arguments.length ?
|
158
|
+
var args, group, message, placeHolderCount, value, _ref;
|
159
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
149
160
|
args = toArray(args);
|
150
161
|
message = args.shift();
|
151
162
|
message = "[UP] " + message;
|
152
|
-
placeHolderCount = ((
|
163
|
+
placeHolderCount = ((_ref = message.match(CONSOLE_PLACEHOLDERS)) != null ? _ref.length : void 0) || 0;
|
153
164
|
if (isFunction(last(args)) && placeHolderCount < args.length) {
|
154
165
|
group = args.pop();
|
155
166
|
}
|
156
|
-
value = console.debug.apply(console, [message].concat(
|
167
|
+
value = console.debug.apply(console, [message].concat(__slice.call(args)));
|
157
168
|
if (group) {
|
158
169
|
console.groupCollapsed();
|
159
170
|
try {
|
@@ -166,7 +177,7 @@ If you use them in your own code, you will get hurt.
|
|
166
177
|
};
|
167
178
|
error = function() {
|
168
179
|
var $error, args, asString;
|
169
|
-
args = 1 <= arguments.length ?
|
180
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
170
181
|
args[0] = "[UP] " + args[0];
|
171
182
|
console.error.apply(console, args);
|
172
183
|
asString = stringifyConsoleArgs(args);
|
@@ -200,7 +211,7 @@ If you use them in your own code, you will get hurt.
|
|
200
211
|
});
|
201
212
|
};
|
202
213
|
createSelectorFromElement = function($element) {
|
203
|
-
var classString, classes, id,
|
214
|
+
var classString, classes, id, klass, selector, _i, _len;
|
204
215
|
debug("Creating selector from element %o", $element);
|
205
216
|
classes = (classString = $element.attr("class")) ? classString.split(" ") : [];
|
206
217
|
id = $element.attr("id");
|
@@ -208,8 +219,8 @@ If you use them in your own code, you will get hurt.
|
|
208
219
|
if (id) {
|
209
220
|
selector += "#" + id;
|
210
221
|
}
|
211
|
-
for (
|
212
|
-
klass = classes[
|
222
|
+
for (_i = 0, _len = classes.length; _i < _len; _i++) {
|
223
|
+
klass = classes[_i];
|
213
224
|
selector += "." + klass;
|
214
225
|
}
|
215
226
|
return selector;
|
@@ -246,10 +257,10 @@ If you use them in your own code, you will get hurt.
|
|
246
257
|
extend = $.extend;
|
247
258
|
trim = $.trim;
|
248
259
|
keys = Object.keys || function(object) {
|
249
|
-
var
|
260
|
+
var key, result, _i, _len;
|
250
261
|
result = [];
|
251
|
-
for (
|
252
|
-
key = object[
|
262
|
+
for (_i = 0, _len = object.length; _i < _len; _i++) {
|
263
|
+
key = object[_i];
|
253
264
|
if (object.hasOwnProperty(key)) {
|
254
265
|
result.push(key);
|
255
266
|
}
|
@@ -257,13 +268,13 @@ If you use them in your own code, you will get hurt.
|
|
257
268
|
return result;
|
258
269
|
};
|
259
270
|
each = function(collection, block) {
|
260
|
-
var index, item,
|
261
|
-
|
262
|
-
for (index =
|
271
|
+
var index, item, _i, _len, _results;
|
272
|
+
_results = [];
|
273
|
+
for (index = _i = 0, _len = collection.length; _i < _len; index = ++_i) {
|
263
274
|
item = collection[index];
|
264
|
-
|
275
|
+
_results.push(block(item, index));
|
265
276
|
}
|
266
|
-
return
|
277
|
+
return _results;
|
267
278
|
};
|
268
279
|
isNull = function(object) {
|
269
280
|
return object === null;
|
@@ -308,6 +319,9 @@ If you use them in your own code, you will get hurt.
|
|
308
319
|
isObject = function(object) {
|
309
320
|
return isHash(object) || (typeof object === 'function');
|
310
321
|
};
|
322
|
+
isElement = function(object) {
|
323
|
+
return !!(object && object.nodeType === 1);
|
324
|
+
};
|
311
325
|
isJQuery = function(object) {
|
312
326
|
return object instanceof jQuery;
|
313
327
|
};
|
@@ -374,11 +388,11 @@ If you use them in your own code, you will get hurt.
|
|
374
388
|
@param {Array} args...
|
375
389
|
*/
|
376
390
|
option = function() {
|
377
|
-
var arg, args,
|
378
|
-
args = 1 <= arguments.length ?
|
391
|
+
var arg, args, match, value, _i, _len;
|
392
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
379
393
|
match = null;
|
380
|
-
for (
|
381
|
-
arg = args[
|
394
|
+
for (_i = 0, _len = args.length; _i < _len; _i++) {
|
395
|
+
arg = args[_i];
|
382
396
|
value = arg;
|
383
397
|
if (isFunction(value)) {
|
384
398
|
value = value();
|
@@ -391,10 +405,10 @@ If you use them in your own code, you will get hurt.
|
|
391
405
|
return match;
|
392
406
|
};
|
393
407
|
detect = function(array, tester) {
|
394
|
-
var element,
|
408
|
+
var element, match, _i, _len;
|
395
409
|
match = null;
|
396
|
-
for (
|
397
|
-
element = array[
|
410
|
+
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
411
|
+
element = array[_i];
|
398
412
|
if (tester(element)) {
|
399
413
|
match = element;
|
400
414
|
break;
|
@@ -414,15 +428,15 @@ If you use them in your own code, you will get hurt.
|
|
414
428
|
};
|
415
429
|
presentAttr = function() {
|
416
430
|
var $element, attrName, attrNames, values;
|
417
|
-
$element = arguments[0], attrNames = 2 <= arguments.length ?
|
431
|
+
$element = arguments[0], attrNames = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
418
432
|
values = (function() {
|
419
|
-
var
|
420
|
-
|
421
|
-
for (
|
422
|
-
attrName = attrNames[
|
423
|
-
|
433
|
+
var _i, _len, _results;
|
434
|
+
_results = [];
|
435
|
+
for (_i = 0, _len = attrNames.length; _i < _len; _i++) {
|
436
|
+
attrName = attrNames[_i];
|
437
|
+
_results.push($element.attr(attrName));
|
424
438
|
}
|
425
|
-
return
|
439
|
+
return _results;
|
426
440
|
})();
|
427
441
|
return detect(values, isPresent);
|
428
442
|
};
|
@@ -578,18 +592,18 @@ If you use them in your own code, you will get hurt.
|
|
578
592
|
return box;
|
579
593
|
};
|
580
594
|
copyAttributes = function($source, $target) {
|
581
|
-
var attr,
|
582
|
-
|
583
|
-
|
584
|
-
for (
|
585
|
-
attr =
|
595
|
+
var attr, _i, _len, _ref, _results;
|
596
|
+
_ref = $source.get(0).attributes;
|
597
|
+
_results = [];
|
598
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
599
|
+
attr = _ref[_i];
|
586
600
|
if (attr.specified) {
|
587
|
-
|
601
|
+
_results.push($target.attr(attr.name, attr.value));
|
588
602
|
} else {
|
589
|
-
|
603
|
+
_results.push(void 0);
|
590
604
|
}
|
591
605
|
}
|
592
|
-
return
|
606
|
+
return _results;
|
593
607
|
};
|
594
608
|
prependGhost = function($element) {
|
595
609
|
var $ghost, dimensions;
|
@@ -630,11 +644,11 @@ If you use them in your own code, you will get hurt.
|
|
630
644
|
return xhr.getResponseHeader('X-Up-Method');
|
631
645
|
};
|
632
646
|
only = function() {
|
633
|
-
var filtered,
|
634
|
-
object = arguments[0], keys = 2 <= arguments.length ?
|
647
|
+
var filtered, key, keys, object, _i, _len;
|
648
|
+
object = arguments[0], keys = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
635
649
|
filtered = {};
|
636
|
-
for (
|
637
|
-
key = keys[
|
650
|
+
for (_i = 0, _len = keys.length; _i < _len; _i++) {
|
651
|
+
key = keys[_i];
|
638
652
|
if (object.hasOwnProperty(key)) {
|
639
653
|
filtered[key] = object[key];
|
640
654
|
}
|
@@ -656,9 +670,20 @@ If you use them in your own code, you will get hurt.
|
|
656
670
|
resolvedPromise = function() {
|
657
671
|
return resolvedDeferred().promise();
|
658
672
|
};
|
673
|
+
nullJquery = function() {
|
674
|
+
return {
|
675
|
+
is: function() {
|
676
|
+
return false;
|
677
|
+
},
|
678
|
+
attr: function() {},
|
679
|
+
find: function() {
|
680
|
+
return [];
|
681
|
+
}
|
682
|
+
};
|
683
|
+
};
|
659
684
|
resolvableWhen = function() {
|
660
685
|
var deferreds, joined;
|
661
|
-
deferreds = 1 <= arguments.length ?
|
686
|
+
deferreds = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
662
687
|
joined = $.when.apply($, deferreds);
|
663
688
|
joined.resolve = function() {
|
664
689
|
return each(deferreds, function(deferred) {
|
@@ -668,20 +693,20 @@ If you use them in your own code, you will get hurt.
|
|
668
693
|
return joined;
|
669
694
|
};
|
670
695
|
setMissingAttrs = function($element, attrs) {
|
671
|
-
var key,
|
672
|
-
|
696
|
+
var key, value, _results;
|
697
|
+
_results = [];
|
673
698
|
for (key in attrs) {
|
674
699
|
value = attrs[key];
|
675
700
|
if (isMissing($element.attr(key))) {
|
676
|
-
|
701
|
+
_results.push($element.attr(key, value));
|
677
702
|
} else {
|
678
|
-
|
703
|
+
_results.push(void 0);
|
679
704
|
}
|
680
705
|
}
|
681
|
-
return
|
706
|
+
return _results;
|
682
707
|
};
|
683
708
|
stringSet = function(array) {
|
684
|
-
var includes, includesAny,
|
709
|
+
var includes, includesAny, key, put, set, string, _i, _len;
|
685
710
|
set = {};
|
686
711
|
includes = function(string) {
|
687
712
|
return set[key(string)];
|
@@ -695,8 +720,8 @@ If you use them in your own code, you will get hurt.
|
|
695
720
|
key = function(string) {
|
696
721
|
return "_" + string;
|
697
722
|
};
|
698
|
-
for (
|
699
|
-
string = array[
|
723
|
+
for (_i = 0, _len = array.length; _i < _len; _i++) {
|
724
|
+
string = array[_i];
|
700
725
|
put(string);
|
701
726
|
}
|
702
727
|
return {
|
@@ -737,6 +762,7 @@ If you use them in your own code, you will get hurt.
|
|
737
762
|
isObject: isObject,
|
738
763
|
isFunction: isFunction,
|
739
764
|
isString: isString,
|
765
|
+
isElement: isElement,
|
740
766
|
isJQuery: isJQuery,
|
741
767
|
isPromise: isPromise,
|
742
768
|
isDeferred: isDeferred,
|
@@ -744,6 +770,7 @@ If you use them in your own code, you will get hurt.
|
|
744
770
|
ifGiven: ifGiven,
|
745
771
|
isUnmodifiedKeyEvent: isUnmodifiedKeyEvent,
|
746
772
|
isUnmodifiedMouseEvent: isUnmodifiedMouseEvent,
|
773
|
+
nullJquery: nullJquery,
|
747
774
|
unwrap: unwrap,
|
748
775
|
nextFrame: nextFrame,
|
749
776
|
measure: measure,
|
@@ -779,12 +806,15 @@ If you use them in your own code, you will get hurt.
|
|
779
806
|
/**
|
780
807
|
Browser interface
|
781
808
|
=================
|
782
|
-
|
809
|
+
|
810
|
+
Some browser-interfacing methods and switches that we can't currently get rid off.
|
811
|
+
|
812
|
+
@protected
|
783
813
|
@class up.browser
|
784
814
|
*/
|
785
815
|
|
786
816
|
(function() {
|
787
|
-
var
|
817
|
+
var __slice = [].slice;
|
788
818
|
|
789
819
|
up.browser = (function() {
|
790
820
|
var canCssAnimation, canInputEvent, canPushState, ensureConsoleExists, ensureRecentJquery, isSupported, loadPage, memoize, u, url;
|
@@ -819,16 +849,16 @@ Browser interface
|
|
819
849
|
return location.href;
|
820
850
|
};
|
821
851
|
ensureConsoleExists = function() {
|
822
|
-
var
|
852
|
+
var noop, _base, _base1, _base2, _base3, _base4, _base5, _base6;
|
823
853
|
window.console || (window.console = {});
|
824
854
|
noop = function() {};
|
825
|
-
(
|
826
|
-
(
|
827
|
-
(
|
828
|
-
(
|
829
|
-
(
|
830
|
-
(
|
831
|
-
return (
|
855
|
+
(_base = window.console).log || (_base.log = noop);
|
856
|
+
(_base1 = window.console).info || (_base1.info = noop);
|
857
|
+
(_base2 = window.console).error || (_base2.error = noop);
|
858
|
+
(_base3 = window.console).debug || (_base3.debug = noop);
|
859
|
+
(_base4 = window.console).group || (_base4.group = noop);
|
860
|
+
(_base5 = window.console).groupCollapsed || (_base5.groupCollapsed = noop);
|
861
|
+
return (_base6 = window.console).groupEnd || (_base6.groupEnd = noop);
|
832
862
|
};
|
833
863
|
memoize = function(func) {
|
834
864
|
var cache, cached;
|
@@ -836,7 +866,7 @@ Browser interface
|
|
836
866
|
cached = false;
|
837
867
|
return function() {
|
838
868
|
var args;
|
839
|
-
args = 1 <= arguments.length ?
|
869
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
840
870
|
if (cached) {
|
841
871
|
return cache;
|
842
872
|
} else {
|
@@ -883,31 +913,50 @@ Browser interface
|
|
883
913
|
/**
|
884
914
|
Framework events
|
885
915
|
================
|
886
|
-
|
887
|
-
This class is kind-of internal and in constant flux.
|
888
|
-
|
889
|
-
The framework event bus might eventually be rolled
|
890
|
-
into regular document events.
|
891
916
|
|
892
|
-
|
917
|
+
Up.js uses an internal event bus that you can use to hook into lifecycle events like "an HTML fragment into the DOM".
|
893
918
|
|
894
|
-
|
895
|
-
|
896
|
-
|
919
|
+
This internal event bus might eventually be rolled into regular events that we trigger on `document`.
|
920
|
+
|
921
|
+
\#\#\# `fragment:ready` event
|
922
|
+
|
923
|
+
This event is triggered after Up.js has inserted an HTML fragment into the DOM through mechanisms like [`[up-target]`](/up.flow#up-target) or [`up.replace`](/up.flow#up.replace):
|
924
|
+
|
925
|
+
up.bus.on('fragment:ready', function($fragment) {
|
926
|
+
console.log("Looks like we have a new %o!", $fragment);
|
927
|
+
});
|
928
|
+
|
929
|
+
The event is triggered *before* Up has compiled the fragment with your [custom behavior](/up.magic).
|
930
|
+
Upon receiving the event, Up.js will start compilation.
|
931
|
+
|
932
|
+
|
933
|
+
\#\#\# `fragment:destroy` event
|
934
|
+
|
935
|
+
This event is triggered when Up.js is destroying an HTML fragment, e.g. because it's being replaced
|
936
|
+
with a new version or because someone explicitly called [`up.destroy`](/up.flow#up.destroy):
|
937
|
+
|
938
|
+
up.bus.on('fragment:destroy', function($fragment) {
|
939
|
+
console.log("Looks like we lost %o!", $fragment);
|
940
|
+
});
|
941
|
+
|
942
|
+
After triggering this event, Up.js will remove the fragment from the DOM.
|
943
|
+
In case the fragment destruction is animated, Up.js will complete the
|
944
|
+
animation before removing the fragment from the DOM.
|
945
|
+
|
897
946
|
|
898
947
|
\#\#\# Incomplete documentation!
|
899
948
|
|
900
949
|
We need to work on this page:
|
901
950
|
|
902
951
|
- Decide whether to refactor this into document events
|
903
|
-
-
|
904
|
-
|
952
|
+
- Decide whether `fragment:enter` and `fragment:leave` would be better names
|
953
|
+
|
905
954
|
|
906
955
|
@class up.bus
|
907
956
|
*/
|
908
957
|
|
909
958
|
(function() {
|
910
|
-
var
|
959
|
+
var __slice = [].slice;
|
911
960
|
|
912
961
|
up.bus = (function() {
|
913
962
|
var callbacksByEvent, callbacksFor, defaultCallbacksByEvent, emit, listen, reset, snapshot, u;
|
@@ -926,14 +975,14 @@ We need to work on this page:
|
|
926
975
|
@method up.bus.snapshot
|
927
976
|
*/
|
928
977
|
snapshot = function() {
|
929
|
-
var callbacks, event,
|
978
|
+
var callbacks, event, _results;
|
930
979
|
defaultCallbacksByEvent = {};
|
931
|
-
|
980
|
+
_results = [];
|
932
981
|
for (event in callbacksByEvent) {
|
933
982
|
callbacks = callbacksByEvent[event];
|
934
|
-
|
983
|
+
_results.push(defaultCallbacksByEvent[event] = u.copy(callbacks));
|
935
984
|
}
|
936
|
-
return
|
985
|
+
return _results;
|
937
986
|
};
|
938
987
|
|
939
988
|
/**
|
@@ -962,7 +1011,21 @@ We need to work on this page:
|
|
962
1011
|
};
|
963
1012
|
|
964
1013
|
/**
|
965
|
-
Triggers an event.
|
1014
|
+
Triggers an event over the framework bus.
|
1015
|
+
|
1016
|
+
All arguments will be passed as arguments to event listeners:
|
1017
|
+
|
1018
|
+
up.bus.on('foo:bar', function(x, y) {
|
1019
|
+
console.log("Value of x is " + x);
|
1020
|
+
console.log("Value of y is " + y);
|
1021
|
+
});
|
1022
|
+
|
1023
|
+
up.bus.emit('foo:bar', 'arg1', 'arg2')
|
1024
|
+
|
1025
|
+
// This prints to the console:
|
1026
|
+
//
|
1027
|
+
// Value of x is arg1
|
1028
|
+
// Value of y is arg2
|
966
1029
|
|
967
1030
|
@method up.bus.emit
|
968
1031
|
@param {String} eventName
|
@@ -972,7 +1035,7 @@ We need to work on this page:
|
|
972
1035
|
*/
|
973
1036
|
emit = function() {
|
974
1037
|
var args, callbacks, eventName;
|
975
|
-
eventName = arguments[0], args = 2 <= arguments.length ?
|
1038
|
+
eventName = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
976
1039
|
u.debug("Emitting event %o with args %o", eventName, args);
|
977
1040
|
callbacks = callbacksFor(eventName);
|
978
1041
|
return u.each(callbacks, function(callback) {
|
@@ -1028,7 +1091,7 @@ By default Up.js will always scroll to an element before updating it.
|
|
1028
1091
|
@param {Number} scrollPos
|
1029
1092
|
@param {String}[options.duration]
|
1030
1093
|
@param {String}[options.easing]
|
1031
|
-
@
|
1094
|
+
@return {Deferred}
|
1032
1095
|
@protected
|
1033
1096
|
*/
|
1034
1097
|
scroll = function(viewOrSelector, scrollPos, options) {
|
@@ -1082,7 +1145,7 @@ By default Up.js will always scroll to an element before updating it.
|
|
1082
1145
|
@param {Number} [options.duration]
|
1083
1146
|
@param {String} [options.easing]
|
1084
1147
|
@param {Number} [options.padding]
|
1085
|
-
@
|
1148
|
+
@return {Deferred}
|
1086
1149
|
@protected
|
1087
1150
|
*/
|
1088
1151
|
reveal = function(elementOrSelector, options) {
|
@@ -1180,6 +1243,8 @@ We need to work on this page:
|
|
1180
1243
|
@param {String} [options.transition]
|
1181
1244
|
@param {String} [options.scroll='body']
|
1182
1245
|
@param {String} [options.historyMethod='push']
|
1246
|
+
@return {Promise}
|
1247
|
+
A promise that will be resolved when the page has been updated.
|
1183
1248
|
*/
|
1184
1249
|
replace = function(selectorOrElement, url, options) {
|
1185
1250
|
var promise, request, selector;
|
@@ -1238,7 +1303,7 @@ We need to work on this page:
|
|
1238
1303
|
@param {String} [options.historyMethod='push']
|
1239
1304
|
*/
|
1240
1305
|
implant = function(selector, html, options) {
|
1241
|
-
var $new, $old,
|
1306
|
+
var $new, $old, response, step, _i, _len, _ref, _results;
|
1242
1307
|
options = u.options(options, {
|
1243
1308
|
historyMethod: 'push'
|
1244
1309
|
});
|
@@ -1251,17 +1316,17 @@ We need to work on this page:
|
|
1251
1316
|
options.source = u.option(options.source, options.history);
|
1252
1317
|
response = parseResponse(html);
|
1253
1318
|
options.title || (options.title = response.title());
|
1254
|
-
|
1255
|
-
|
1256
|
-
for (
|
1257
|
-
step =
|
1319
|
+
_ref = parseImplantSteps(selector, options);
|
1320
|
+
_results = [];
|
1321
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
1322
|
+
step = _ref[_i];
|
1258
1323
|
$old = findOldFragment(step.selector);
|
1259
1324
|
$new = response.find(step.selector);
|
1260
|
-
|
1325
|
+
_results.push(prepareForReplacement($old, options).then(function() {
|
1261
1326
|
return swapElements($old, $new, step.pseudoClass, step.transition, options);
|
1262
1327
|
}));
|
1263
1328
|
}
|
1264
|
-
return
|
1329
|
+
return _results;
|
1265
1330
|
};
|
1266
1331
|
findOldFragment = function(selector) {
|
1267
1332
|
return u.presence($(".up-popup " + selector)) || u.presence($(".up-modal " + selector)) || u.presence($(selector)) || u.error('Could not find selector %o in current body HTML', selector);
|
@@ -1271,8 +1336,8 @@ We need to work on this page:
|
|
1271
1336
|
htmlElement = u.createElementFromHtml(html);
|
1272
1337
|
return {
|
1273
1338
|
title: function() {
|
1274
|
-
var
|
1275
|
-
return (
|
1339
|
+
var _ref;
|
1340
|
+
return (_ref = htmlElement.querySelector("title")) != null ? _ref.textContent : void 0;
|
1276
1341
|
},
|
1277
1342
|
find: function(selector) {
|
1278
1343
|
var child;
|
@@ -1335,25 +1400,25 @@ We need to work on this page:
|
|
1335
1400
|
}
|
1336
1401
|
};
|
1337
1402
|
parseImplantSteps = function(selector, options) {
|
1338
|
-
var comma, disjunction, i,
|
1403
|
+
var comma, disjunction, i, selectorAtom, selectorParts, transition, transitionString, transitions, _i, _len, _results;
|
1339
1404
|
transitionString = options.transition || options.animation || 'none';
|
1340
1405
|
comma = /\ *,\ */;
|
1341
1406
|
disjunction = selector.split(comma);
|
1342
1407
|
if (u.isPresent(transitionString)) {
|
1343
1408
|
transitions = transitionString.split(comma);
|
1344
1409
|
}
|
1345
|
-
|
1346
|
-
for (i =
|
1410
|
+
_results = [];
|
1411
|
+
for (i = _i = 0, _len = disjunction.length; _i < _len; i = ++_i) {
|
1347
1412
|
selectorAtom = disjunction[i];
|
1348
1413
|
selectorParts = selectorAtom.match(/^(.+?)(?:\:(before|after))?$/);
|
1349
1414
|
transition = transitions[i] || u.last(transitions);
|
1350
|
-
|
1415
|
+
_results.push({
|
1351
1416
|
selector: selectorParts[1],
|
1352
1417
|
pseudoClass: selectorParts[2],
|
1353
1418
|
transition: transition
|
1354
1419
|
});
|
1355
1420
|
}
|
1356
|
-
return
|
1421
|
+
return _results;
|
1357
1422
|
};
|
1358
1423
|
autofocus = function($element) {
|
1359
1424
|
var $control, selector;
|
@@ -1450,22 +1515,18 @@ Registering behavior and custom elements
|
|
1450
1515
|
Up.js keeps a persistent Javascript environment during page transitions.
|
1451
1516
|
To prevent memory leaks it is important to cleanly set up and tear down
|
1452
1517
|
event handlers and custom elements.
|
1453
|
-
|
1518
|
+
|
1454
1519
|
\#\#\# Incomplete documentation!
|
1455
|
-
|
1520
|
+
|
1456
1521
|
We need to work on this page:
|
1457
|
-
|
1458
|
-
-
|
1459
|
-
|
1460
|
-
- Example for defining a custom element
|
1461
|
-
- Tell more about memory leaks and why they don't matter
|
1462
|
-
so much when you have full page loads.
|
1463
|
-
|
1522
|
+
|
1523
|
+
- Better class-level introduction for this module
|
1524
|
+
|
1464
1525
|
@class up.magic
|
1465
1526
|
*/
|
1466
1527
|
|
1467
1528
|
(function() {
|
1468
|
-
var
|
1529
|
+
var __slice = [].slice;
|
1469
1530
|
|
1470
1531
|
up.magic = (function() {
|
1471
1532
|
var DESTROYABLE_CLASS, DESTROYER_KEY, applyAwakener, awaken, awakeners, compile, data, defaultAwakeners, defaultLiveDescriptions, destroy, live, liveDescriptions, onEscape, ready, reset, snapshot, u;
|
@@ -1474,9 +1535,49 @@ We need to work on this page:
|
|
1474
1535
|
DESTROYER_KEY = 'up-destroyer';
|
1475
1536
|
|
1476
1537
|
/**
|
1477
|
-
Binds an event handler to the document,
|
1478
|
-
|
1479
|
-
|
1538
|
+
Binds an event handler to the document, which will be executed whenever the
|
1539
|
+
given event is triggered on the given selector:
|
1540
|
+
|
1541
|
+
up.on('click', '.button', function(event, $element) {
|
1542
|
+
console.log("Someone clicked the button %o", $element);
|
1543
|
+
});
|
1544
|
+
|
1545
|
+
This is roughly equivalent to binding a jQuery element to `document`.
|
1546
|
+
|
1547
|
+
|
1548
|
+
\#\#\#\# Attaching structured data
|
1549
|
+
|
1550
|
+
In case you want to attach structured data to the event you're observing,
|
1551
|
+
you can serialize the data to JSON and put it into an `[up-data]` attribute:
|
1552
|
+
|
1553
|
+
<span class="person" up-data="{ age: 18, name: 'Bob' }">Bob</span>
|
1554
|
+
<span class="person" up-data="{ age: 22, name: 'Jim' }">Jim</span>
|
1555
|
+
|
1556
|
+
The JSON will parsed and handed to your event handler as a third argument:
|
1557
|
+
|
1558
|
+
up.on('click', '.person', function(event, $element, data) {
|
1559
|
+
console.log("This is %o who is %o years old", data.name, data.age);
|
1560
|
+
});
|
1561
|
+
|
1562
|
+
|
1563
|
+
\#\#\#\# Migrating jQuery event handlers to `up.on`
|
1564
|
+
|
1565
|
+
Within the event handler, Up.js will bind `this` to the
|
1566
|
+
native DOM element to help you migrate your existing jQuery code to
|
1567
|
+
this new syntax.
|
1568
|
+
|
1569
|
+
So if you had this before:
|
1570
|
+
|
1571
|
+
$(document).on('click', '.button', function() {
|
1572
|
+
$(this).something();
|
1573
|
+
});
|
1574
|
+
|
1575
|
+
... you can simply copy the event handler to `up.on`:
|
1576
|
+
|
1577
|
+
up.on('click', '.button', function() {
|
1578
|
+
$(this).something();
|
1579
|
+
});
|
1580
|
+
|
1480
1581
|
|
1481
1582
|
@method up.on
|
1482
1583
|
@param {String} events
|
@@ -1492,7 +1593,7 @@ We need to work on this page:
|
|
1492
1593
|
liveDescriptions = [];
|
1493
1594
|
defaultLiveDescriptions = null;
|
1494
1595
|
live = function(events, selector, behavior) {
|
1495
|
-
var description,
|
1596
|
+
var description, _ref;
|
1496
1597
|
if (!up.browser.isSupported()) {
|
1497
1598
|
return;
|
1498
1599
|
}
|
@@ -1502,13 +1603,117 @@ We need to work on this page:
|
|
1502
1603
|
}
|
1503
1604
|
];
|
1504
1605
|
liveDescriptions.push(description);
|
1505
|
-
return (
|
1606
|
+
return (_ref = $(document)).on.apply(_ref, description);
|
1506
1607
|
};
|
1507
1608
|
|
1508
1609
|
/**
|
1509
1610
|
Registers a function to be called whenever an element with
|
1510
1611
|
the given selector is inserted into the DOM through Up.js.
|
1511
1612
|
|
1613
|
+
This is a great way to integrate jQuery plugins.
|
1614
|
+
Let's say your Javascript plugin wants you to call `lightboxify()`
|
1615
|
+
on links that should open a lightbox. You decide to
|
1616
|
+
do this for all links with an `[rel=lightbox]` attribute:
|
1617
|
+
|
1618
|
+
<a href="river.png" rel="lightbox">River</a>
|
1619
|
+
<a href="ocean.png" rel="lightbox">Ocean</a>
|
1620
|
+
|
1621
|
+
This Javascript will do exactly that:
|
1622
|
+
|
1623
|
+
up.awaken('a[rel=lightbox]', function($element) {
|
1624
|
+
$element.lightboxify();
|
1625
|
+
});
|
1626
|
+
|
1627
|
+
Note that within the awakener, Up.js will bind `this` to the
|
1628
|
+
native DOM element to help you migrate your existing jQuery code to
|
1629
|
+
this new syntax.
|
1630
|
+
|
1631
|
+
|
1632
|
+
\#\#\#\# Custom elements
|
1633
|
+
|
1634
|
+
You can also use `up.awaken` to implement custom elements like this:
|
1635
|
+
|
1636
|
+
<current-time></current-time>
|
1637
|
+
|
1638
|
+
Here is the Javascript that inserts the current time into to these elements:
|
1639
|
+
|
1640
|
+
up.awaken('current-time', function($element) {
|
1641
|
+
var now = new Date();
|
1642
|
+
$element.text(now.toString()));
|
1643
|
+
});
|
1644
|
+
|
1645
|
+
|
1646
|
+
\#\#\#\# Cleaning up after yourself
|
1647
|
+
|
1648
|
+
If your awakener returns a function, Up.js will use this as a *destructor* to
|
1649
|
+
clean up if the element leaves the DOM. Note that in Up.js the same DOM ad Javascript environment
|
1650
|
+
will persist through many page loads, so it's important to not create
|
1651
|
+
[memory leaks](https://makandracards.com/makandra/31325-how-to-create-memory-leaks-in-jquery).
|
1652
|
+
|
1653
|
+
You should clean up after yourself whenever your awakeners have global
|
1654
|
+
side effects, like a [`setInterval`](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval)
|
1655
|
+
or event handlers bound to the document root.
|
1656
|
+
|
1657
|
+
Here is a version of `<current-time>` that updates
|
1658
|
+
the time every second, and cleans up once it's done:
|
1659
|
+
|
1660
|
+
up.awaken('current-time', function($element) {
|
1661
|
+
|
1662
|
+
function update() {
|
1663
|
+
var now = new Date();
|
1664
|
+
$element.text(now.toString()));
|
1665
|
+
}
|
1666
|
+
|
1667
|
+
setInterval(update, 1000);
|
1668
|
+
|
1669
|
+
return function() {
|
1670
|
+
clearInterval(update);
|
1671
|
+
};
|
1672
|
+
|
1673
|
+
});
|
1674
|
+
|
1675
|
+
If we didn't clean up after ourselves, we would have many ticking intervals
|
1676
|
+
operating on detached DOM elements after we have created and removed a couple
|
1677
|
+
of `<current-time>` elements.
|
1678
|
+
|
1679
|
+
|
1680
|
+
\#\#\#\# Attaching structured data
|
1681
|
+
|
1682
|
+
In case you want to attach structured data to the event you're observing,
|
1683
|
+
you can serialize the data to JSON and put it into an `[up-data]` attribute.
|
1684
|
+
For instance, a container for a [Google Map](https://developers.google.com/maps/documentation/javascript/tutorial)
|
1685
|
+
might attach the location and names of its marker pins:
|
1686
|
+
|
1687
|
+
<div class="google-map" up-data="[
|
1688
|
+
{ lat: 48.36, lng: 10.99, title: 'Friedberg' },
|
1689
|
+
{ lat: 48.75, lng: 11.45, title: 'Ingolstadt' }
|
1690
|
+
]"></div>
|
1691
|
+
|
1692
|
+
The JSON will parsed and handed to your event handler as a second argument:
|
1693
|
+
|
1694
|
+
up.awaken('.google-map', function($element, pins) {
|
1695
|
+
|
1696
|
+
var map = new google.maps.Map($element);
|
1697
|
+
|
1698
|
+
pins.forEach(function(pin) {
|
1699
|
+
var position = new google.maps.LatLng(pin.lat, pin.lng);
|
1700
|
+
new google.maps.Marker({
|
1701
|
+
position: position,
|
1702
|
+
map: map,
|
1703
|
+
title: pin.title
|
1704
|
+
});
|
1705
|
+
});
|
1706
|
+
|
1707
|
+
});
|
1708
|
+
|
1709
|
+
|
1710
|
+
\#\#\#\# Migrating jQuery event handlers to `up.on`
|
1711
|
+
|
1712
|
+
Within the awakener, Up.js will bind `this` to the
|
1713
|
+
native DOM element to help you migrate your existing jQuery code to
|
1714
|
+
this new syntax.
|
1715
|
+
|
1716
|
+
|
1512
1717
|
@method up.awaken
|
1513
1718
|
@param {String} selector
|
1514
1719
|
The selector to match.
|
@@ -1530,7 +1735,7 @@ We need to work on this page:
|
|
1530
1735
|
defaultAwakeners = null;
|
1531
1736
|
awaken = function() {
|
1532
1737
|
var args, awakener, options, selector;
|
1533
|
-
selector = arguments[0], args = 2 <= arguments.length ?
|
1738
|
+
selector = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
|
1534
1739
|
if (!up.browser.isSupported()) {
|
1535
1740
|
return;
|
1536
1741
|
}
|
@@ -1554,25 +1759,25 @@ We need to work on this page:
|
|
1554
1759
|
}
|
1555
1760
|
};
|
1556
1761
|
compile = function($fragment) {
|
1557
|
-
var $matches, awakener,
|
1762
|
+
var $matches, awakener, _i, _len, _results;
|
1558
1763
|
u.debug("Compiling fragment %o", $fragment);
|
1559
|
-
|
1560
|
-
for (
|
1561
|
-
awakener = awakeners[
|
1764
|
+
_results = [];
|
1765
|
+
for (_i = 0, _len = awakeners.length; _i < _len; _i++) {
|
1766
|
+
awakener = awakeners[_i];
|
1562
1767
|
$matches = u.findWithSelf($fragment, awakener.selector);
|
1563
1768
|
if ($matches.length) {
|
1564
1769
|
if (awakener.batch) {
|
1565
|
-
|
1770
|
+
_results.push(applyAwakener(awakener, $matches, $matches.get()));
|
1566
1771
|
} else {
|
1567
|
-
|
1772
|
+
_results.push($matches.each(function() {
|
1568
1773
|
return applyAwakener(awakener, $(this), this);
|
1569
1774
|
}));
|
1570
1775
|
}
|
1571
1776
|
} else {
|
1572
|
-
|
1777
|
+
_results.push(void 0);
|
1573
1778
|
}
|
1574
1779
|
}
|
1575
|
-
return
|
1780
|
+
return _results;
|
1576
1781
|
};
|
1577
1782
|
destroy = function($fragment) {
|
1578
1783
|
return u.findWithSelf($fragment, "." + DESTROYABLE_CLASS).each(function() {
|
@@ -1643,11 +1848,11 @@ We need to work on this page:
|
|
1643
1848
|
@method up.magic.reset
|
1644
1849
|
*/
|
1645
1850
|
reset = function() {
|
1646
|
-
var description,
|
1647
|
-
for (
|
1648
|
-
description = liveDescriptions[
|
1851
|
+
var description, _i, _len, _ref;
|
1852
|
+
for (_i = 0, _len = liveDescriptions.length; _i < _len; _i++) {
|
1853
|
+
description = liveDescriptions[_i];
|
1649
1854
|
if (!u.contains(defaultLiveDescriptions, description)) {
|
1650
|
-
(
|
1855
|
+
(_ref = $(document)).off.apply(_ref, description);
|
1651
1856
|
}
|
1652
1857
|
}
|
1653
1858
|
liveDescriptions = u.copy(defaultLiveDescriptions);
|
@@ -2536,13 +2741,15 @@ Read on
|
|
2536
2741
|
This is done by fetching `url` through an AJAX request
|
2537
2742
|
and replacing the current `<body>` element with the response's `<body>` element.
|
2538
2743
|
|
2744
|
+
For example, this would fetch the `/users` URL:
|
2745
|
+
|
2746
|
+
up.visit('/users')
|
2747
|
+
|
2539
2748
|
@method up.visit
|
2540
2749
|
@param {String} url
|
2541
2750
|
The URL to visit.
|
2542
2751
|
@param {Object} options
|
2543
2752
|
See options for [`up.replace`](/up.flow#up.replace)
|
2544
|
-
@example
|
2545
|
-
up.visit('/users')
|
2546
2753
|
*/
|
2547
2754
|
visit = function(url, options) {
|
2548
2755
|
u.debug("Visiting " + url);
|
@@ -2553,6 +2760,15 @@ Read on
|
|
2553
2760
|
Follows the given link via AJAX and replaces a CSS selector in the current page
|
2554
2761
|
with corresponding elements from a new page fetched from the server.
|
2555
2762
|
|
2763
|
+
Any Up.js UJS attributes on the given link will be honored. E. g. you have this link:
|
2764
|
+
|
2765
|
+
<a href="/users" up-target=".main">Users</a>
|
2766
|
+
|
2767
|
+
You can update the page's `.main` selector with the `.main` from `/users` like this:
|
2768
|
+
|
2769
|
+
var $link = $('a:first'); // select link with jQuery
|
2770
|
+
up.follow($link);
|
2771
|
+
|
2556
2772
|
@method up.follow
|
2557
2773
|
@param {Element|jQuery|String} link
|
2558
2774
|
An element or selector which resolves to an `<a>` tag
|
@@ -2563,7 +2779,7 @@ Read on
|
|
2563
2779
|
or to `body` if such an attribute does not exist.
|
2564
2780
|
@param {Function|String} [options.transition]
|
2565
2781
|
A transition function or name.
|
2566
|
-
@param {Element|jQuery|String} scroll
|
2782
|
+
@param {Element|jQuery|String} [options.scroll]
|
2567
2783
|
An element or selector that will be scrolled to the top in
|
2568
2784
|
case the replaced element is not visible in the viewport.
|
2569
2785
|
*/
|
@@ -2575,7 +2791,7 @@ Read on
|
|
2575
2791
|
selector = u.option(options.target, $link.attr('up-target'), 'body');
|
2576
2792
|
options.transition = u.option(options.transition, $link.attr('up-transition'), $link.attr('up-animation'));
|
2577
2793
|
options.history = u.option(options.history, $link.attr('up-history'));
|
2578
|
-
options.scroll = u.option(options.
|
2794
|
+
options.scroll = u.option(options.scroll, $link.attr('up-scroll'), 'body');
|
2579
2795
|
return up.replace(selector, url, options);
|
2580
2796
|
};
|
2581
2797
|
resolve = function(element) {
|
@@ -3136,6 +3352,7 @@ We need to work on this page:
|
|
3136
3352
|
|
3137
3353
|
@method up.popup.open
|
3138
3354
|
@param {Element|jQuery|String} elementOrSelector
|
3355
|
+
@param {String} [options.url]
|
3139
3356
|
@param {String} [options.origin='bottom-right']
|
3140
3357
|
@param {String} [options.animation]
|
3141
3358
|
@param {Boolean} [options.sticky=false]
|
@@ -3147,7 +3364,7 @@ We need to work on this page:
|
|
3147
3364
|
var $link, $popup, animation, history, origin, selector, sticky, url;
|
3148
3365
|
$link = $(linkOrSelector);
|
3149
3366
|
options = u.options(options);
|
3150
|
-
url = u.option($link.attr('href'));
|
3367
|
+
url = u.option(options.url, $link.attr('href'));
|
3151
3368
|
selector = u.option(options.target, $link.attr('up-popup'), 'body');
|
3152
3369
|
origin = u.option(options.origin, $link.attr('up-origin'), config.origin);
|
3153
3370
|
animation = u.option(options.animation, $link.attr('up-animation'), config.openAnimation);
|
@@ -3277,20 +3494,14 @@ Modal dialogs
|
|
3277
3494
|
Instead of linking to another page fragment, you can also choose
|
3278
3495
|
to open any target CSS selector in a modal dialog.
|
3279
3496
|
|
3280
|
-
For popup overlays see [up.popup](/up.popup) instead.
|
3281
|
-
|
3282
|
-
\#\#\# Incomplete documentation!
|
3283
|
-
|
3284
|
-
We need to work on this page:
|
3285
|
-
|
3286
|
-
- Show the HTML structure of the dialog elements, and how to style them via CSS
|
3287
|
-
- Explain how dialogs auto-close themselves when a fragment changes behind the modal layer
|
3288
|
-
- Document method parameters
|
3497
|
+
For small popup overlays ("dropdowns") see [up.popup](/up.popup) instead.
|
3289
3498
|
|
3290
3499
|
@class up.modal
|
3291
3500
|
*/
|
3292
3501
|
|
3293
3502
|
(function() {
|
3503
|
+
var __slice = [].slice;
|
3504
|
+
|
3294
3505
|
up.modal = (function() {
|
3295
3506
|
var autoclose, close, config, createHiddenModal, defaults, discardHistory, open, rememberHistory, source, templateHtml, u, updated;
|
3296
3507
|
u = up.util;
|
@@ -3306,13 +3517,31 @@ We need to work on this page:
|
|
3306
3517
|
};
|
3307
3518
|
|
3308
3519
|
/**
|
3520
|
+
Sets default options for future modals.
|
3521
|
+
|
3309
3522
|
@method up.modal.defaults
|
3310
|
-
@param {Number} [options.width]
|
3311
|
-
|
3523
|
+
@param {Number} [options.width='auto']
|
3524
|
+
The width of the dialog.
|
3525
|
+
Defaults to `'auto'`, meaning that the dialog will grow to fit its contents.
|
3526
|
+
@param {Number} [options.height='auto']
|
3527
|
+
The height of the dialog.
|
3528
|
+
Defaults to `'auto'`, meaning that the dialog will grow to fit its contents.
|
3312
3529
|
@param {String|Function(config)} [options.template]
|
3313
|
-
|
3314
|
-
|
3315
|
-
|
3530
|
+
A string containing the HTML structure of the modal.
|
3531
|
+
You can supply an alternative template string, but make sure that it
|
3532
|
+
contains tags with the classes `up-modal`, `up-modal-dialog` and `up-modal-content`.
|
3533
|
+
|
3534
|
+
You can also supply a function that returns a HTML string.
|
3535
|
+
The function will be called with the modal options (merged from these defaults
|
3536
|
+
and any per-open overrides) whenever a modal opens.
|
3537
|
+
@param {String} [options.closeLabel='X']
|
3538
|
+
The label of the button that closes the dialog.
|
3539
|
+
@param {String} [options.openAnimation='fade-in']
|
3540
|
+
The animation used to open the modal. The animation will be applied
|
3541
|
+
to both the dialog box and the overlay dimming the page.
|
3542
|
+
@param {String} [options.closeAnimation='fade-out']
|
3543
|
+
The animation used to close the modal. The animation will be applied
|
3544
|
+
to both the dialog box and the overlay dimming the page.
|
3316
3545
|
*/
|
3317
3546
|
defaults = function(options) {
|
3318
3547
|
return u.extend(config, options);
|
@@ -3367,24 +3596,42 @@ We need to work on this page:
|
|
3367
3596
|
};
|
3368
3597
|
|
3369
3598
|
/**
|
3370
|
-
Opens a modal overlay
|
3599
|
+
Opens the given link's destination in a modal overlay:
|
3600
|
+
|
3601
|
+
var $link = $('...');
|
3602
|
+
up.modal.open($link);
|
3603
|
+
|
3604
|
+
Any option attributes for [`a[up-modal]`](#a.up-modal) will be honored.
|
3605
|
+
|
3606
|
+
You can also open a URL directly like this:
|
3607
|
+
|
3608
|
+
up.modal.open({ url: '/foo' })
|
3371
3609
|
|
3372
3610
|
@method up.modal.open
|
3373
3611
|
@param {Element|jQuery|String} elementOrSelector
|
3612
|
+
@param {String} [options.url]
|
3374
3613
|
@param {Number} [options.width]
|
3375
3614
|
@param {Number} [options.height]
|
3376
|
-
@param {String} [options.origin='bottom-right']
|
3377
3615
|
@param {String} [options.animation]
|
3378
3616
|
@param {Boolean} [options.sticky=false]
|
3379
3617
|
If set to `true`, the modal remains
|
3380
3618
|
open even if the page changes in the background.
|
3381
3619
|
@param {Object} [options.history=true]
|
3620
|
+
@return {Promise}
|
3621
|
+
A promise that will be resolved when the modal has finished loading.
|
3382
3622
|
*/
|
3383
|
-
open = function(
|
3384
|
-
var $link, $modal, animation, height, history, selector, sticky, url, width;
|
3385
|
-
|
3623
|
+
open = function() {
|
3624
|
+
var $link, $modal, animation, args, height, history, options, selector, sticky, url, width;
|
3625
|
+
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
3626
|
+
if (u.isObject(args[0]) && !u.isElement(args[0]) && !u.isJQuery(args[0])) {
|
3627
|
+
$link = u.nullJquery();
|
3628
|
+
options = args[0];
|
3629
|
+
} else {
|
3630
|
+
$link = $(args[0]);
|
3631
|
+
options = args[1];
|
3632
|
+
}
|
3386
3633
|
options = u.options(options);
|
3387
|
-
url = u.option($link.attr('href'));
|
3634
|
+
url = u.option(options.url, $link.attr('href'), $link.attr('up-href'));
|
3388
3635
|
selector = u.option(options.target, $link.attr('up-modal'), 'body');
|
3389
3636
|
width = u.option(options.width, $link.attr('up-width'), config.width);
|
3390
3637
|
height = u.option(options.height, $link.attr('up-height'), config.height);
|
@@ -3446,18 +3693,68 @@ We need to work on this page:
|
|
3446
3693
|
};
|
3447
3694
|
|
3448
3695
|
/**
|
3449
|
-
|
3696
|
+
Clicking this link will load the destination via AJAX and open
|
3697
|
+
the given selector in a modal dialog.
|
3450
3698
|
|
3451
|
-
|
3699
|
+
Example:
|
3452
3700
|
|
3453
|
-
|
3454
|
-
|
3701
|
+
<a href="/blogs" up-modal=".blog-list">Switch blog</a>
|
3702
|
+
|
3703
|
+
Clicking would request the path `/blog` and select `.blog-list` from
|
3704
|
+
the HTML response. Up.js will dim the page with an overlay
|
3705
|
+
and place the matching `.blog_list` tag will be placed in
|
3706
|
+
a modal dialog.
|
3707
|
+
|
3708
|
+
|
3709
|
+
\#\#\#\# Customizing the dialog design
|
3710
|
+
|
3711
|
+
Loading the Up.js stylesheet will give you a minimal dialog design:
|
3712
|
+
|
3713
|
+
- Dialog contents are displayed in a white box that is centered vertically and horizontally.
|
3714
|
+
- There is a a subtle box shadow around the dialog
|
3715
|
+
- The box will grow to fit the dialog contents, but never grow larger than the screen
|
3716
|
+
- The box is placed over a semi-transparent background to dim the rest of the page
|
3717
|
+
- There is a button to close the dialog in the top-right corner
|
3718
|
+
|
3719
|
+
The easiest way to change how the dialog looks is by overriding the [default CSS styles](https://github.com/makandra/upjs/blob/master/lib/assets/stylesheets/up/modal.css.sass).
|
3720
|
+
|
3721
|
+
By default the dialog uses the following DOM structure (continuing the blog-switcher example from above):
|
3722
|
+
|
3723
|
+
<div class="up-modal">
|
3724
|
+
<div class="up-modal-dialog">
|
3725
|
+
<div class="up-modal-close" up-close>X</div>
|
3726
|
+
<div class="up-modal-content">
|
3727
|
+
<ul class="blog-list">
|
3728
|
+
...
|
3729
|
+
</ul>
|
3730
|
+
</div>
|
3731
|
+
</div>
|
3732
|
+
</div>
|
3733
|
+
|
3734
|
+
If you want to change the design beyond CSS, you can
|
3735
|
+
configure Up.js to [use a different HTML structure](#up.modal.defaults).
|
3736
|
+
|
3737
|
+
|
3738
|
+
\#\#\#\# Closing behavior
|
3739
|
+
|
3740
|
+
By default the dialog automatically closes
|
3741
|
+
*whenever a page fragment below the dialog is updated*.
|
3742
|
+
This is useful to have the dialog interact with the page that
|
3743
|
+
opened it, e.g. by updating parts of a larger form or by signing in a user
|
3744
|
+
and revealing additional information.
|
3745
|
+
|
3746
|
+
To disable this behavior, give the opening link an `up-sticky` attribute:
|
3455
3747
|
|
3456
3748
|
<a href="/settings" up-modal=".options" up-sticky>Settings</a>
|
3457
3749
|
|
3750
|
+
|
3458
3751
|
@method a[up-modal]
|
3459
3752
|
@ujs
|
3460
3753
|
@param [up-sticky]
|
3754
|
+
@param [up-animation]
|
3755
|
+
@param [up-height]
|
3756
|
+
@param [up-width]
|
3757
|
+
@param [up-history]
|
3461
3758
|
*/
|
3462
3759
|
up.on('click', 'a[up-modal]', function(event, $link) {
|
3463
3760
|
event.preventDefault();
|
@@ -3668,13 +3965,13 @@ From Up's point of view the "current" location is either:
|
|
3668
3965
|
SELECTORS_SECTION = ['a[href]', 'a[up-target]', '[up-follow]', '[up-modal]', '[up-popup]', '[up-href]'];
|
3669
3966
|
SELECTOR_SECTION = SELECTORS_SECTION.join(', ');
|
3670
3967
|
SELECTOR_SECTION_INSTANT = ((function() {
|
3671
|
-
var
|
3672
|
-
|
3673
|
-
for (
|
3674
|
-
selector = SELECTORS_SECTION[
|
3675
|
-
|
3968
|
+
var _i, _len, _results;
|
3969
|
+
_results = [];
|
3970
|
+
for (_i = 0, _len = SELECTORS_SECTION.length; _i < _len; _i++) {
|
3971
|
+
selector = SELECTORS_SECTION[_i];
|
3972
|
+
_results.push(selector + "[up-instant]");
|
3676
3973
|
}
|
3677
|
-
return
|
3974
|
+
return _results;
|
3678
3975
|
})()).join(', ');
|
3679
3976
|
SELECTOR_ACTIVE = "." + CLASS_ACTIVE;
|
3680
3977
|
normalizeUrl = function(url) {
|
@@ -3686,12 +3983,12 @@ From Up's point of view the "current" location is either:
|
|
3686
3983
|
}
|
3687
3984
|
};
|
3688
3985
|
sectionUrls = function($section) {
|
3689
|
-
var $link, attr,
|
3986
|
+
var $link, attr, url, urls, _i, _len, _ref;
|
3690
3987
|
urls = [];
|
3691
3988
|
if ($link = up.link.resolve($section)) {
|
3692
|
-
|
3693
|
-
for (
|
3694
|
-
attr =
|
3989
|
+
_ref = ['href', 'up-follow', 'up-href'];
|
3990
|
+
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
3991
|
+
attr = _ref[_i];
|
3695
3992
|
if (url = u.presentAttr($link, attr)) {
|
3696
3993
|
url = normalizeUrl(url);
|
3697
3994
|
urls.push(url);
|