upjs-rails 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
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 slice = [].slice;
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 = isString(urlOrAnchor) ? $('<a>').attr({
65
- href: urlOrAnchor
66
- }).get(0) : unwrap(urlOrAnchor);
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, j, k, len, len1, path, tag;
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 = j = 0, len = path.length; j < len; iteration = ++j) {
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 (k = 0, len1 = conjunction.length; k < len1; k++) {
107
- expression = conjunction[k];
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, ref, value;
148
- args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
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 = ((ref = message.match(CONSOLE_PLACEHOLDERS)) != null ? ref.length : void 0) || 0;
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(slice.call(args)));
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 ? slice.call(arguments, 0) : [];
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, j, klass, len, selector;
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 (j = 0, len = classes.length; j < len; j++) {
212
- klass = classes[j];
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 j, key, len, result;
260
+ var key, result, _i, _len;
250
261
  result = [];
251
- for (j = 0, len = object.length; j < len; j++) {
252
- key = object[j];
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, j, len, results;
261
- results = [];
262
- for (index = j = 0, len = collection.length; j < len; index = ++j) {
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
- results.push(block(item, index));
275
+ _results.push(block(item, index));
265
276
  }
266
- return results;
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, j, len, match, value;
378
- args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
391
+ var arg, args, match, value, _i, _len;
392
+ args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
379
393
  match = null;
380
- for (j = 0, len = args.length; j < len; j++) {
381
- arg = args[j];
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, j, len, match;
408
+ var element, match, _i, _len;
395
409
  match = null;
396
- for (j = 0, len = array.length; j < len; j++) {
397
- element = array[j];
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 ? slice.call(arguments, 1) : [];
431
+ $element = arguments[0], attrNames = 2 <= arguments.length ? __slice.call(arguments, 1) : [];
418
432
  values = (function() {
419
- var j, len, results;
420
- results = [];
421
- for (j = 0, len = attrNames.length; j < len; j++) {
422
- attrName = attrNames[j];
423
- results.push($element.attr(attrName));
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 results;
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, j, len, ref, results;
582
- ref = $source.get(0).attributes;
583
- results = [];
584
- for (j = 0, len = ref.length; j < len; j++) {
585
- attr = ref[j];
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
- results.push($target.attr(attr.name, attr.value));
601
+ _results.push($target.attr(attr.name, attr.value));
588
602
  } else {
589
- results.push(void 0);
603
+ _results.push(void 0);
590
604
  }
591
605
  }
592
- return results;
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, j, key, keys, len, object;
634
- object = arguments[0], keys = 2 <= arguments.length ? slice.call(arguments, 1) : [];
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 (j = 0, len = keys.length; j < len; j++) {
637
- key = keys[j];
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 ? slice.call(arguments, 0) : [];
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, results, value;
672
- results = [];
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
- results.push($element.attr(key, value));
701
+ _results.push($element.attr(key, value));
677
702
  } else {
678
- results.push(void 0);
703
+ _results.push(void 0);
679
704
  }
680
705
  }
681
- return results;
706
+ return _results;
682
707
  };
683
708
  stringSet = function(array) {
684
- var includes, includesAny, j, key, len, put, set, string;
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 (j = 0, len = array.length; j < len; j++) {
699
- string = array[j];
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 slice = [].slice;
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 base, base1, base2, base3, base4, base5, base6, noop;
852
+ var noop, _base, _base1, _base2, _base3, _base4, _base5, _base6;
823
853
  window.console || (window.console = {});
824
854
  noop = function() {};
825
- (base = window.console).log || (base.log = noop);
826
- (base1 = window.console).info || (base1.info = noop);
827
- (base2 = window.console).error || (base2.error = noop);
828
- (base3 = window.console).debug || (base3.debug = noop);
829
- (base4 = window.console).group || (base4.group = noop);
830
- (base5 = window.console).groupCollapsed || (base5.groupCollapsed = noop);
831
- return (base6 = window.console).groupEnd || (base6.groupEnd = noop);
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 ? slice.call(arguments, 0) : [];
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
- \#\#\# Available events
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
- - `app:ready`
895
- - `fragment:ready` with arguments `($fragment)`
896
- - `fragment:destroy` with arguments `($fragment)`
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
- - Document events
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 slice = [].slice;
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, results;
978
+ var callbacks, event, _results;
930
979
  defaultCallbacksByEvent = {};
931
- results = [];
980
+ _results = [];
932
981
  for (event in callbacksByEvent) {
933
982
  callbacks = callbacksByEvent[event];
934
- results.push(defaultCallbacksByEvent[event] = u.copy(callbacks));
983
+ _results.push(defaultCallbacksByEvent[event] = u.copy(callbacks));
935
984
  }
936
- return results;
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 ? slice.call(arguments, 1) : [];
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
- @returns {Deferred}
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
- @returns {Deferred}
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, j, len, ref, response, results, step;
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
- ref = parseImplantSteps(selector, options);
1255
- results = [];
1256
- for (j = 0, len = ref.length; j < len; j++) {
1257
- step = ref[j];
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
- results.push(prepareForReplacement($old, options).then(function() {
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 results;
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 ref;
1275
- return (ref = htmlElement.querySelector("title")) != null ? ref.textContent : void 0;
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, j, len, results, selectorAtom, selectorParts, transition, transitionString, transitions;
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
- results = [];
1346
- for (i = j = 0, len = disjunction.length; j < len; i = ++j) {
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
- results.push({
1415
+ _results.push({
1351
1416
  selector: selectorParts[1],
1352
1417
  pseudoClass: selectorParts[2],
1353
1418
  transition: transition
1354
1419
  });
1355
1420
  }
1356
- return results;
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
- - Explain when to use `up.on` and when to use `up.awaken`
1459
- - Example for integrating an external JS lib that is not aware of Up.js
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 slice = [].slice;
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
- which will be executed whenever the given event
1479
- is triggered on the given selector.
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, ref;
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 (ref = $(document)).on.apply(ref, description);
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 ? slice.call(arguments, 1) : [];
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, i, len, results;
1762
+ var $matches, awakener, _i, _len, _results;
1558
1763
  u.debug("Compiling fragment %o", $fragment);
1559
- results = [];
1560
- for (i = 0, len = awakeners.length; i < len; i++) {
1561
- awakener = awakeners[i];
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
- results.push(applyAwakener(awakener, $matches, $matches.get()));
1770
+ _results.push(applyAwakener(awakener, $matches, $matches.get()));
1566
1771
  } else {
1567
- results.push($matches.each(function() {
1772
+ _results.push($matches.each(function() {
1568
1773
  return applyAwakener(awakener, $(this), this);
1569
1774
  }));
1570
1775
  }
1571
1776
  } else {
1572
- results.push(void 0);
1777
+ _results.push(void 0);
1573
1778
  }
1574
1779
  }
1575
- return results;
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, i, len, ref;
1647
- for (i = 0, len = liveDescriptions.length; i < len; i++) {
1648
- description = liveDescriptions[i];
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
- (ref = $(document)).off.apply(ref, description);
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.history, $link.attr('up-scroll'), 'body');
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
- @param {Number} [options.height]
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
- @param {String} [options.closeLabel]
3314
- @param {String} [options.openAnimation]
3315
- @param {String} [options.closeAnimation]
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(linkOrSelector, options) {
3384
- var $link, $modal, animation, height, history, selector, sticky, url, width;
3385
- $link = $(linkOrSelector);
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
- Opens the target of this link in a modal dialog:
3696
+ Clicking this link will load the destination via AJAX and open
3697
+ the given selector in a modal dialog.
3450
3698
 
3451
- <a href="/decks" up-modal=".deck_list">Switch deck</a>
3699
+ Example:
3452
3700
 
3453
- If the `up-sticky` attribute is set, the dialog does not auto-close
3454
- if a page fragment below the dialog updates:
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 i, len, results;
3672
- results = [];
3673
- for (i = 0, len = SELECTORS_SECTION.length; i < len; i++) {
3674
- selector = SELECTORS_SECTION[i];
3675
- results.push(selector + "[up-instant]");
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 results;
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, i, len, ref, url, urls;
3986
+ var $link, attr, url, urls, _i, _len, _ref;
3690
3987
  urls = [];
3691
3988
  if ($link = up.link.resolve($section)) {
3692
- ref = ['href', 'up-follow', 'up-href'];
3693
- for (i = 0, len = ref.length; i < len; i++) {
3694
- attr = ref[i];
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);