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.
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);