upjs-rails 0.2.1 → 0.2.2

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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -45
  3. data/Rakefile +3 -0
  4. data/bower.json +6 -1
  5. data/dist/up.css +27 -4
  6. data/dist/up.js +197 -60
  7. data/dist/up.min.css +1 -1
  8. data/dist/up.min.js +1 -1
  9. data/lib/assets/javascripts/up/bus.js.coffee +16 -6
  10. data/lib/assets/javascripts/up/flow.js.coffee +30 -13
  11. data/lib/assets/javascripts/up/form.js.coffee +40 -10
  12. data/lib/assets/javascripts/up/history.js.coffee +8 -1
  13. data/lib/assets/javascripts/up/magic.js.coffee +17 -5
  14. data/lib/assets/javascripts/up/modal.js.coffee +16 -2
  15. data/lib/assets/javascripts/up/motion.js.coffee +14 -1
  16. data/lib/assets/javascripts/up/navigation.js.coffee +15 -6
  17. data/lib/assets/javascripts/up/popup.js.coffee +21 -3
  18. data/lib/assets/javascripts/up/tooltip.js.coffee +15 -1
  19. data/lib/assets/javascripts/up/util.js.coffee +24 -8
  20. data/lib/assets/stylesheets/up/tooltip.css.sass +30 -5
  21. data/lib/upjs/rails/current_location.rb +19 -0
  22. data/lib/upjs/rails/version.rb +1 -1
  23. data/lib/upjs-rails.rb +1 -4
  24. data/spec_app/Gemfile.lock +11 -11
  25. data/spec_app/app/assets/stylesheets/application.css +2 -0
  26. data/spec_app/app/assets/stylesheets/jasmine_specs.css +5 -0
  27. data/spec_app/app/views/pages/home.html.haml +8 -1
  28. data/spec_app/spec/javascripts/support/jasmine.yml +1 -0
  29. data/spec_app/spec/javascripts/up/bus_spec.js.coffee +12 -0
  30. data/spec_app/spec/javascripts/up/flow_spec.js.coffee +92 -68
  31. data/spec_app/spec/javascripts/up/form_spec.js.coffee +100 -0
  32. data/spec_app/spec/javascripts/up/history_spec.js.coffee +12 -0
  33. data/spec_app/spec/javascripts/up/link_spec.js.coffee +47 -0
  34. data/spec_app/spec/javascripts/up/magic_spec.js.coffee +49 -0
  35. data/spec_app/spec/javascripts/up/marker_spec.js.coffee +14 -12
  36. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +30 -0
  37. data/spec_app/spec/javascripts/up/motion_spec.js.coffee +25 -0
  38. data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +60 -24
  39. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +30 -0
  40. data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +46 -0
  41. data/spec_app/spec/javascripts/up/util_spec.js.coffee +27 -25
  42. metadata +13 -3
  43. data/lib/upjs/rails/redirection.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 326b8437947e8413899ee4faf621b7ae64310e98
4
- data.tar.gz: 7889244e2873ebd3105cfde16b4bf0f47109549f
3
+ metadata.gz: bfd395defeb823375907c8c74a3e2d739928ca82
4
+ data.tar.gz: 149d22961c624278e228d63f87f5a21ac447c4ee
5
5
  SHA512:
6
- metadata.gz: 4c7014666f7b1a87805281f304f66ddf1e75fb58f2a4f64a02e2de30b80dfe73183bee6e48e132a9bcf37e75fe4582ef8ec6e9db665b8078aad5f11298f23055
7
- data.tar.gz: a6cf6cb6a573ee566439f8fb94e700888a07c6484ca0afc1539400c8acae01f1ce9c233b4fca4f8f97b02fbb3e0a51903c09c6daab7c371cb6908deb71e50ea3
6
+ metadata.gz: 8e9dc65fba23982223a3f8281e6e9799757aea4f0e0c14e1a50670f58dd414a529b4d2fbc48c21a77430d098c1cd06121102187db3783e608e0d5bc94bf3631b
7
+ data.tar.gz: ff942b938f7a97d600733fdcacad7c71c5f53617c3db06c01d92e1275de1ce36bd6844d648c9bac6c8cd5a918a81bf6a737b2e5b54613e5b61b01ab1ef664117
data/README.md CHANGED
@@ -1,47 +1,5 @@
1
- # Up + Rails bindings (WIP)
2
-
3
- Up.js is a solution for Rails apps that need fast-responding UI
4
- but don't want to pay the Javascript MVC complexity tax.
5
-
6
- ## Design manifesto
7
-
8
- ### Client-side code is a complexity driver
9
-
10
- ### Server-side code should stay the same
11
- - We like the simplicity of classic Rails development
12
- - It should not require extra controller actions to update a page part via AJAX
13
-
14
- ### Batteries included
15
- - We will ship a basic implementation for the most established UI patterns like navigation bars, infinite scrolling, drop-down menus, modals
16
- - We will split this out into a plugin architecture eventually, but not now
17
-
18
- ### Ruby on Rails first
19
- - We will leverage the assumptions that Rails is underneath
20
- - Other frameworks once we’re happy with Rails
21
-
22
- ### Not for ambitious UIs
23
- - We don’t want to compromise ease of use for simple patterns by providing a million hooks and options
24
- - Limits in configurability
25
- - You can always roll your own code
26
- - Probably the wrong choice if you want to create something very ambitious
27
-
28
- ### (Sort of) Plays nice with existing JS code
29
- - If you're ready to go into our event binding
30
-
31
- ### URLs are important
32
- - Every page has an URL
33
- - Works nice with Google
34
- Works with browsers that don’t speak Up.js (e. g. IE9 doesn’t speak pushState)
35
-
36
- ### Be small
37
-
38
- ### Few dependencies
39
- - jQuery
40
-
41
- ### Convention over configuration
42
-
43
- ### Interface: Both UJS and programmatic
44
-
45
-
1
+ # Up.js: Snappy UI for server-side web applications
46
2
 
3
+ Up.js gives your traditional web application fast-responding views with minimal changes to your code and development style. If you require modern UX but don't want to pay the Javascript MVC complexity tax, Up.js can be a solution for you.
47
4
 
5
+ See [upjs.io](http://upjs.io) for more information and API documentation.
data/Rakefile CHANGED
@@ -1,4 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'sass/util'
3
+ require 'sass/script'
2
4
  require 'sprockets/standalone'
3
5
 
4
6
  module Upjs
@@ -30,6 +32,7 @@ Sprockets::Standalone::RakeTask.new(:minified_assets) do |task, sprockets|
30
32
  end
31
33
 
32
34
  namespace :assets do
35
+ desc 'Compile assets for Bower and manual download'
33
36
  task :compile do
34
37
  Rake::Task['minified_assets:compile'].invoke
35
38
  File.rename('dist/up.js', 'dist/up.min.js')
data/bower.json CHANGED
@@ -13,7 +13,12 @@
13
13
  "doc",
14
14
  "lib",
15
15
  "pkg",
16
- "spec_app"
16
+ "spec_app",
17
+ "Gemfile",
18
+ "Gemfile.lock",
19
+ "Rakefile",
20
+ ".ruby-version",
21
+ "upjs-rails.gemspec"
17
22
  ],
18
23
  "dependencies": {
19
24
  "jquery": ">= 1.9.1"
data/dist/up.css CHANGED
@@ -56,14 +56,37 @@
56
56
  .up-tooltip {
57
57
  z-index: 30000;
58
58
  position: fixed;
59
- background-color: rgba(30, 30, 30, 0.8);
59
+ background-color: #666;
60
60
  color: white;
61
- padding: 6px 8px;
62
- box-shadow: 0 0 4px rgba(0, 0, 0, 0.2); }
61
+ padding: 6px 9px; }
63
62
  .up-tooltip[up-origin=top] {
64
63
  margin-top: -6px; }
64
+ .up-tooltip[up-origin=top]:after {
65
+ content: "";
66
+ position: absolute;
67
+ border-style: solid;
68
+ border-width: 8px 8px 0;
69
+ border-color: #666 transparent;
70
+ display: block;
71
+ width: 0;
72
+ z-index: 1;
73
+ bottom: -8px;
74
+ left: 50%;
75
+ margin-left: -8px; }
65
76
  .up-tooltip[up-origin=bottom] {
66
- margin-bottom: -6px; }
77
+ margin-top: 6px; }
78
+ .up-tooltip[up-origin=bottom]:after {
79
+ content: "";
80
+ position: absolute;
81
+ border-style: solid;
82
+ border-width: 0 8px 8px;
83
+ border-color: #666 transparent;
84
+ display: block;
85
+ width: 0;
86
+ z-index: 1;
87
+ top: -8px;
88
+ left: 50%;
89
+ margin-left: -8px; }
67
90
  /*
68
91
 
69
92
  */
data/dist/up.js CHANGED
@@ -25,7 +25,7 @@ If you use them in your own code, you will get hurt.
25
25
  var __slice = [].slice;
26
26
 
27
27
  up.util = (function() {
28
- var $createElementFromSelector, ajax, castsToFalse, castsToTrue, clientSize, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, detect, each, error, escapePressed, extend, findWithSelf, get, ifGiven, isArray, isBlank, isDefined, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, last, measure, merge, nextFrame, normalizeUrl, option, options, prependGhost, presence, presentAttr, select, temporaryCss, unwrap;
28
+ var $createElementFromSelector, ajax, castsToFalse, castsToTrue, clientSize, contains, copy, copyAttributes, createElement, createElementFromHtml, createSelectorFromElement, cssAnimate, detect, each, error, escapePressed, extend, findWithSelf, get, ifGiven, isArray, isBlank, isDefined, isFunction, isGiven, isHash, isJQuery, isMissing, isNull, isObject, isPresent, isPromise, isStandardPort, isString, isUndefined, last, locationFromXhr, measure, merge, nextFrame, normalizeUrl, option, options, prependGhost, presence, presentAttr, select, temporaryCss, unwrap;
29
29
  get = function(url, options) {
30
30
  options = options || {};
31
31
  options.url = url;
@@ -60,7 +60,7 @@ If you use them in your own code, you will get hurt.
60
60
  @protected
61
61
  */
62
62
  normalizeUrl = function(urlOrAnchor, options) {
63
- var anchor, normalized;
63
+ var anchor, normalized, pathname;
64
64
  anchor = isString(urlOrAnchor) ? $('<a>').attr({
65
65
  href: urlOrAnchor
66
66
  }).get(0) : unwrap(urlOrAnchor);
@@ -68,7 +68,11 @@ If you use them in your own code, you will get hurt.
68
68
  if (!isStandardPort(anchor.protocol, anchor.port)) {
69
69
  normalized += ":" + anchor.port;
70
70
  }
71
- normalized += anchor.pathname;
71
+ pathname = anchor.pathname;
72
+ if ((options != null ? options.stripTrailingSlash : void 0) === true) {
73
+ pathname = pathname.replace(/\/$/, '');
74
+ }
75
+ normalized += pathname;
72
76
  if ((options != null ? options.hash : void 0) === true) {
73
77
  normalized += anchor.hash;
74
78
  }
@@ -270,16 +274,23 @@ If you use them in your own code, you will get hurt.
270
274
  @param {Array} args...
271
275
  */
272
276
  option = function() {
273
- var args;
277
+ var args, match;
274
278
  args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
275
- return detect(args, function(arg) {
279
+ match = null;
280
+ args.every(function(arg) {
276
281
  var value;
277
282
  value = arg;
278
283
  if (isFunction(value)) {
279
284
  value = value();
280
285
  }
281
- return isPresent(value);
286
+ if (isPresent(value)) {
287
+ match = value;
288
+ return false;
289
+ } else {
290
+ return true;
291
+ }
282
292
  });
293
+ return match;
283
294
  };
284
295
  detect = function(array, tester) {
285
296
  var match;
@@ -390,11 +401,11 @@ If you use them in your own code, you will get hurt.
390
401
  return deferred.promise();
391
402
  };
392
403
  measure = function($element, options) {
393
- var box, offset, viewport;
394
- offset = $element.offset();
404
+ var box, coordinates, viewport;
405
+ coordinates = (options != null ? options.relative : void 0) ? $element.position() : $element.offset();
395
406
  box = {
396
- left: offset.left,
397
- top: offset.top,
407
+ left: coordinates.left,
408
+ top: coordinates.top,
398
409
  width: $element.outerWidth(),
399
410
  height: $element.outerHeight()
400
411
  };
@@ -449,6 +460,9 @@ If you use them in your own code, you will get hurt.
449
460
  castsToFalse = function(object) {
450
461
  return String(object) === "false";
451
462
  };
463
+ locationFromXhr = function(xhr) {
464
+ return xhr.getResponseHeader('X-Up-Current-Location');
465
+ };
452
466
  return {
453
467
  presentAttr: presentAttr,
454
468
  createElement: createElement,
@@ -495,7 +509,8 @@ If you use them in your own code, you will get hurt.
495
509
  contains: contains,
496
510
  isArray: isArray,
497
511
  castsToTrue: castsToTrue,
498
- castsToFalse: castsToFalse
512
+ castsToFalse: castsToFalse,
513
+ locationFromXhr: locationFromXhr
499
514
  };
500
515
  })();
501
516
 
@@ -525,15 +540,25 @@ Browser interface
525
540
  Framework events
526
541
  ================
527
542
 
528
- TODO: Write some documentation
529
-
530
- This class is kind-of internal and in flux.
531
- This might eventually be rolled into regular document events.
543
+ This class is kind-of internal and in constant flux.
544
+
545
+ The framework event bus might eventually be rolled
546
+ into regular document events.
532
547
 
548
+ \#\#\# Available events
549
+
533
550
  - `app:ready`
534
551
  - `fragment:ready` with arguments `($fragment)`
535
552
  - `fragment:destroy` with arguments `($fragment)`
536
553
 
554
+ \#\#\# Incomplete documentation!
555
+
556
+ We need to work on this page:
557
+
558
+ - Decide whether to refactor this into document events
559
+ - Document events
560
+
561
+
537
562
  @class up.bus
538
563
  */
539
564
 
@@ -581,7 +606,7 @@ This might eventually be rolled into regular document events.
581
606
  Registers an event handler to be called when the given
582
607
  event is triggered.
583
608
 
584
- @method up.bus.listen
609
+ @method up.bus.on
585
610
  @param {String} eventName
586
611
  The event name to match.
587
612
  @param {Function} handler
@@ -597,7 +622,7 @@ This might eventually be rolled into regular document events.
597
622
  @method up.bus.emit
598
623
  @param {String} eventName
599
624
  The name of the event.
600
- @param {Anything...} args
625
+ @param args...
601
626
  The arguments that describe the event.
602
627
  */
603
628
  emit = function() {
@@ -622,10 +647,18 @@ This might eventually be rolled into regular document events.
622
647
  /**
623
648
  Changing page fragments programmatically
624
649
  ========================================
650
+
651
+ This module contains Up's core functions to insert, change
652
+ or destroy page fragments.
625
653
 
626
- TODO: Write some documentation
627
-
628
-
654
+ \#\#\# Incomplete documentation!
655
+
656
+ We need to work on this page:
657
+
658
+ - Explain the UJS approach vs. pragmatic approach
659
+ - Examples
660
+
661
+
629
662
  @class up.flow
630
663
  */
631
664
 
@@ -672,21 +705,26 @@ TODO: Write some documentation
672
705
  var selector;
673
706
  options = u.options(options);
674
707
  selector = u.presence(selectorOrElement) ? selectorOrElement : u.createSelectorFromElement($(selectorOrElement));
675
- if (u.isMissing(options.history) || u.castsToTrue(options.history)) {
676
- options.history = url;
677
- }
678
- if (u.isMissing(options.source) || u.castsToTrue(options.source)) {
679
- options.source = url;
680
- }
681
- return u.get(url, {
708
+ return u.ajax({
709
+ url: url,
682
710
  selector: selector
683
- }).done(function(html) {
711
+ }).done(function(html, textStatus, xhr) {
712
+ var currentLocation;
713
+ if (currentLocation = u.locationFromXhr(xhr)) {
714
+ url = currentLocation;
715
+ }
716
+ if (u.isMissing(options.history) || u.castsToTrue(options.history)) {
717
+ options.history = url;
718
+ }
719
+ if (u.isMissing(options.source) || u.castsToTrue(options.source)) {
720
+ options.source = url;
721
+ }
684
722
  return implant(selector, html, options);
685
723
  }).fail(u.error);
686
724
  };
687
725
 
688
726
  /**
689
- Replaces the given selector with the same selector from the given HTML string.
727
+ Replaces the given selector with the same CSS selector from the given HTML string.
690
728
 
691
729
  @method up.flow.implant
692
730
  @protected
@@ -873,7 +911,19 @@ TODO: Write some documentation
873
911
  Registering behavior and custom elements
874
912
  ========================================
875
913
 
876
- TODO: Write some documentation
914
+ Up.js keeps a persistent Javascript environment during page transitions.
915
+ To prevent memory leaks it is important to cleanly set up and tear down
916
+ event handlers and custom elements.
917
+
918
+ \#\#\# Incomplete documentation!
919
+
920
+ We need to work on this page:
921
+
922
+ - Explain when to use `up.on` and when to use `up.awaken`
923
+ - Example for integrating an external JS lib that is not aware of Up.js
924
+ - Example for defining a custom element
925
+ - Tell more about memory leaks and why they don't matter
926
+ so much when you have full page loads.
877
927
 
878
928
  @class up.magic
879
929
  */
@@ -895,7 +945,7 @@ TODO: Write some documentation
895
945
  A space-separated list of event names to bind.
896
946
  @param {String} selector
897
947
  The selector an on which the event must be triggered.
898
- @param {Function} behavior
948
+ @param {Function(event, $element)} behavior
899
949
  The handler that should be called.
900
950
  */
901
951
  liveDescriptions = [];
@@ -936,16 +986,13 @@ TODO: Write some documentation
936
986
  };
937
987
  compile = function($fragment) {
938
988
  var awakener, _i, _len, _results;
939
- console.log("Compiling fragment", $fragment, "with", awakeners);
940
989
  _results = [];
941
990
  for (_i = 0, _len = awakeners.length; _i < _len; _i++) {
942
991
  awakener = awakeners[_i];
943
- console.log("running", awakener.selector, "on", $fragment);
944
992
  _results.push(util.findWithSelf($fragment, awakener.selector).each(function() {
945
993
  var $element, destroyer;
946
994
  $element = $(this);
947
995
  destroyer = awakener.callback.apply(this, [$element]);
948
- console.log("got destroyer", destroyer);
949
996
  if (util.isFunction(destroyer)) {
950
997
  $element.addClass(DESTROYABLE_CLASS);
951
998
  return $element.data(DESTROYER_KEY, destroyer);
@@ -1046,8 +1093,15 @@ TODO: Write some documentation
1046
1093
  Manipulating the browser history
1047
1094
  =======
1048
1095
 
1049
- TODO: Write some documentation
1096
+ \#\#\# Incomplete documentation!
1097
+
1098
+ We need to work on this page:
1099
+
1100
+ - Explain how the other modules manipulate history
1101
+ - Decide whether we want to expose these methods as public API
1102
+ - Document methods and parameters
1050
1103
 
1104
+
1051
1105
  @class up.history
1052
1106
  */
1053
1107
 
@@ -1119,7 +1173,20 @@ TODO: Write some documentation
1119
1173
  Animation and transitions
1120
1174
  =========================
1121
1175
 
1122
- TODO: Write some documentation.
1176
+ Any fragment change in Up.js can be animated.
1177
+ Up.js ships with a number of predefined animations and transitions,
1178
+ and you can easily define your own using Javascript or CSS.
1179
+
1180
+
1181
+ \#\#\# Incomplete documentation!
1182
+
1183
+ We need to work on this page:
1184
+
1185
+ - Explain the difference between transitions and animations
1186
+ - Demo the built-in animations and transitions
1187
+ - Examples for defining your own animations and transitions
1188
+ - Explain ghosting
1189
+
1123
1190
 
1124
1191
  @class up.motion
1125
1192
  */
@@ -1648,7 +1715,22 @@ Read on
1648
1715
  Forms and controls
1649
1716
  ==================
1650
1717
 
1651
- TODO: Write some documentation
1718
+ Up.js comes with functionality to submit forms without
1719
+ leaving the current page. This means you can replace page fragments,
1720
+ open dialogs with sub-forms, etc. all without losing form state.
1721
+
1722
+ \#\#\# Incomplete documentation!
1723
+
1724
+ We need to work on this page:
1725
+
1726
+ - Explain how to display form errors
1727
+ - Explain that the server needs to send 2xx or 5xx status codes so
1728
+ Up.js can decide whether the form submission was successful
1729
+ - Explain that the server needs to send an `X-Up-Current-Location` header
1730
+ if an successful form submission resulted in a redirect
1731
+ - Examples
1732
+
1733
+
1652
1734
 
1653
1735
  @class up.form
1654
1736
  */
@@ -1663,11 +1745,17 @@ TODO: Write some documentation
1663
1745
 
1664
1746
  up.submit('form.new_user')
1665
1747
 
1748
+ Instead of loading a new page, the form is submitted via AJAX.
1749
+ The response is parsed for a CSS selector and the matching elements will
1750
+ replace corresponding elements on the current page.
1751
+
1666
1752
  @method up.submit
1667
1753
  @param {Element|jQuery|String} formOrSelector
1668
1754
  A reference or selector for the form to submit.
1669
1755
  If the argument points to an element that is not a form,
1670
1756
  Up.js will search its ancestors for the closest form.
1757
+ @param {String} [options.url]
1758
+ @param {String} [options.method]
1671
1759
  @param {String} [options.target]
1672
1760
  @param {String} [options.failTarget]
1673
1761
  @param {Boolean|String} [options.history=true]
@@ -1682,7 +1770,7 @@ TODO: Write some documentation
1682
1770
  A promise for the AJAX response
1683
1771
  */
1684
1772
  submit = function(formOrSelector, options) {
1685
- var $form, failureSelector, failureTransition, historyOption, request, successSelector, successTransition, successUrl, _ref;
1773
+ var $form, failureSelector, failureTransition, historyOption, httpMethod, request, successSelector, successTransition, successUrl, url;
1686
1774
  $form = $(formOrSelector).closest('form');
1687
1775
  options = u.options(options);
1688
1776
  successSelector = u.option(options.target, $form.attr('up-target'), 'body');
@@ -1692,16 +1780,18 @@ TODO: Write some documentation
1692
1780
  historyOption = u.option(options.history, $form.attr('up-history'), true);
1693
1781
  successTransition = u.option(options.transition, $form.attr('up-transition'));
1694
1782
  failureTransition = u.option(options.failTransition, $form.attr('up-fail-transition'));
1783
+ httpMethod = u.option(options.method, $form.attr('up-method'), $form.attr('data-method'), $form.attr('method'), 'post').toUpperCase();
1784
+ url = u.option(options.url, $form.attr('action'), up.browser.url());
1695
1785
  $form.addClass('up-active');
1696
1786
  request = {
1697
- url: $form.attr('action') || up.browser.url(),
1698
- type: ((_ref = $form.attr('method')) != null ? _ref.toUpperCase() : void 0) || 'POST',
1787
+ url: url,
1788
+ type: httpMethod,
1699
1789
  data: $form.serialize(),
1700
1790
  selector: successSelector
1701
1791
  };
1702
1792
  successUrl = function(xhr) {
1703
- var redirectLocation, url;
1704
- url = historyOption ? u.isString(historyOption) ? historyOption : (redirectLocation = xhr.getResponseHeader('X-Up-Previous-Redirect-Location')) ? redirectLocation : request.type === 'GET' ? request.url + '?' + request.data : void 0 : void 0;
1793
+ var currentLocation;
1794
+ url = historyOption ? historyOption === 'false' ? false : u.isString(historyOption) ? historyOption : (currentLocation = u.locationFromXhr(xhr)) ? currentLocation : request.type === 'GET' ? request.url + '?' + request.data : void 0 : void 0;
1705
1795
  return u.option(url, false);
1706
1796
  };
1707
1797
  return u.ajax(request).always(function() {
@@ -1793,7 +1883,7 @@ TODO: Write some documentation
1793
1883
  Submits the form through AJAX, searches the response for the selector
1794
1884
  given in `up-target` and replaces the selector content in the current page:
1795
1885
 
1796
- <form method="POST" action="/users" up-target=".main">
1886
+ <form method="post" action="/users" up-target=".main">
1797
1887
  ...
1798
1888
  </form>
1799
1889
 
@@ -1801,9 +1891,14 @@ TODO: Write some documentation
1801
1891
  @ujs
1802
1892
  @param {String} up-target
1803
1893
  @param {String} [up-fail-target]
1804
- @param {String} [up-history]
1805
1894
  @param {String} [up-transition]
1806
1895
  @param {String} [up-fail-transition]
1896
+ @param {String} [up-history]
1897
+ @param {String} [up-method]
1898
+ The HTTP method to be used to submit the form
1899
+ (`get`, `post`, `put`, `delete`, `patch`).
1900
+ Alternately you can use an attribute `data-method` (Rails UJS)
1901
+ or `method` (vanilla HTML) for the same purpose.
1807
1902
  */
1808
1903
  up.on('submit', 'form[up-target]', function(event, $form) {
1809
1904
  event.preventDefault();
@@ -1844,8 +1939,23 @@ TODO: Write some documentation
1844
1939
  /**
1845
1940
  Pop-up overlays
1846
1941
  ===============
1942
+
1943
+ Instead of linking to another page fragment, you can also choose
1944
+ to "roll up" any target CSS selector in a popup overlay.
1945
+ Popup overlays close themselves if the user clicks somewhere outside the
1946
+ popup area.
1947
+
1948
+ For modal dialogs see [up.modal](/up.modal) instead.
1949
+
1950
+ \#\#\# Incomplete documentation!
1951
+
1952
+ We need to work on this page:
1953
+
1954
+ - Show the HTML structure of the popup elements, and how to style them via CSS
1955
+ - Explain how to position popup using `up-origin`
1956
+ - Explain how dialogs auto-close themselves when a fragment changes behind the popup layer
1957
+ - Document method parameters
1847
1958
 
1848
- For modal dialogs see [up.modal](/up.modal).
1849
1959
 
1850
1960
  @class up.popup
1851
1961
  */
@@ -2045,7 +2155,6 @@ For modal dialogs see [up.modal](/up.modal).
2045
2155
 
2046
2156
  @method a[up-popup]
2047
2157
  @ujs
2048
- @param up-target
2049
2158
  @param [up-sticky]
2050
2159
  @param [up-origin]
2051
2160
  */
@@ -2085,6 +2194,7 @@ For modal dialogs see [up.modal](/up.modal).
2085
2194
  return close();
2086
2195
  }
2087
2196
  });
2197
+ up.bus.on('framework:reset', close);
2088
2198
  return {
2089
2199
  open: open,
2090
2200
  close: close,
@@ -2099,7 +2209,18 @@ For modal dialogs see [up.modal](/up.modal).
2099
2209
  Modal dialogs
2100
2210
  =============
2101
2211
 
2102
- TODO: Write some documentation
2212
+ Instead of linking to another page fragment, you can also choose
2213
+ to open any target CSS selector in a modal dialog.
2214
+
2215
+ For popup overlays see [up.popup](/up.popup) instead.
2216
+
2217
+ \#\#\# Incomplete documentation!
2218
+
2219
+ We need to work on this page:
2220
+
2221
+ - Show the HTML structure of the dialog elements, and how to style them via CSS
2222
+ - Explain how dialogs auto-close themselves when a fragment changes behind the modal layer
2223
+ - Document method parameters
2103
2224
 
2104
2225
  @class up.modal
2105
2226
  */
@@ -2257,7 +2378,6 @@ TODO: Write some documentation
2257
2378
 
2258
2379
  @method a[up-modal]
2259
2380
  @ujs
2260
- @param up-target
2261
2381
  @param [up-sticky]
2262
2382
  */
2263
2383
  up.on('click', 'a[up-modal]', function(event, $link) {
@@ -2295,6 +2415,7 @@ TODO: Write some documentation
2295
2415
  return close();
2296
2416
  }
2297
2417
  });
2418
+ up.bus.on('framework:reset', close);
2298
2419
  return {
2299
2420
  open: open,
2300
2421
  close: close,
@@ -2309,7 +2430,17 @@ TODO: Write some documentation
2309
2430
  Tooltips
2310
2431
  ========
2311
2432
 
2312
- TODO: Write some documentation.
2433
+ Elements that have an `up-tooltip` attribute will show the attribute
2434
+ value in a tooltip when a user hovers over the element.
2435
+
2436
+ \#\#\# Incomplete documentation!
2437
+
2438
+ We need to work on this page:
2439
+
2440
+ - Show the tooltip's HTML structure and how to style the elements
2441
+ - Explain how to position tooltips using `up-origin`
2442
+ - We should have a position about tooltips that contain HTML.
2443
+
2313
2444
 
2314
2445
  @class up.tooltip
2315
2446
  */
@@ -2407,6 +2538,7 @@ TODO: Write some documentation.
2407
2538
  up.on('click', 'body', function(event, $body) {
2408
2539
  return close();
2409
2540
  });
2541
+ up.bus.on('framework:reset', close);
2410
2542
  up.magic.onEscape(function() {
2411
2543
  return close();
2412
2544
  });
@@ -2446,25 +2578,30 @@ From Up's point of view the "current" location is either:
2446
2578
 
2447
2579
  (function() {
2448
2580
  up.navigation = (function() {
2449
- var CLASS_ACTIVE, CLASS_CURRENT, SELECTOR_ACTIVE, SELECTOR_SECTION, enlargeClickArea, locationChanged, sectionClicked, unmarkActive;
2581
+ var CLASS_ACTIVE, CLASS_CURRENT, SELECTOR_ACTIVE, SELECTOR_SECTION, enlargeClickArea, locationChanged, normalizeUrl, sectionClicked, u, unmarkActive;
2582
+ u = up.util;
2450
2583
  CLASS_ACTIVE = 'up-active';
2451
2584
  CLASS_CURRENT = 'up-current';
2452
2585
  SELECTOR_SECTION = 'a[href], a[up-target], [up-follow], [up-modal], [up-popup]';
2453
2586
  SELECTOR_ACTIVE = "." + CLASS_ACTIVE;
2587
+ normalizeUrl = function(url) {
2588
+ if (u.isPresent(url)) {
2589
+ return u.normalizeUrl(url, {
2590
+ search: false,
2591
+ stripTrailingSlash: true
2592
+ });
2593
+ }
2594
+ };
2454
2595
  locationChanged = function() {
2455
2596
  var modalLocation, popupLocation, windowLocation;
2456
- windowLocation = up.util.normalizeUrl(up.browser.url(), {
2457
- search: false
2458
- });
2459
- modalLocation = up.modal.source();
2460
- popupLocation = up.popup.source();
2461
- return up.util.each($(SELECTOR_SECTION), function(section) {
2597
+ windowLocation = normalizeUrl(up.browser.url());
2598
+ modalLocation = normalizeUrl(up.modal.source());
2599
+ popupLocation = normalizeUrl(up.popup.source());
2600
+ return u.each($(SELECTOR_SECTION), function(section) {
2462
2601
  var $section, url;
2463
2602
  $section = $(section);
2464
2603
  url = up.link.resolveUrl($section);
2465
- url = up.util.normalizeUrl(url, {
2466
- search: false
2467
- });
2604
+ url = normalizeUrl(url);
2468
2605
  if (url === windowLocation || url === modalLocation || url === popupLocation) {
2469
2606
  return $section.addClass(CLASS_CURRENT);
2470
2607
  } else {
@@ -2478,7 +2615,7 @@ From Up's point of view the "current" location is either:
2478
2615
  return $section.addClass(CLASS_ACTIVE);
2479
2616
  };
2480
2617
  enlargeClickArea = function($section) {
2481
- return up.util.presence($section.parents(SELECTOR_SECTION)) || $section;
2618
+ return u.presence($section.parents(SELECTOR_SECTION)) || $section;
2482
2619
  };
2483
2620
  unmarkActive = function() {
2484
2621
  return $(SELECTOR_ACTIVE).removeClass(CLASS_ACTIVE);
data/dist/up.min.css CHANGED
@@ -1 +1 @@
1
- [up-close]{cursor:pointer}[up-follow]{cursor:pointer}.up-modal{position:fixed;top:0;left:0;bottom:0;right:0;z-index:10000;background-color:rgba(90,90,90,0.4)}.up-modal-dialog{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);max-width:100%;max-height:100%;background-color:#fff;box-shadow:0 0 10px 1px rgba(0,0,0,0.3);box-sizing:border-box}.up-modal-close{position:absolute;right:0;top:0;width:36px;text-align:center;line-height:24px;height:24px;background-color:#999;color:#fff;font-weight:bold;text-transform:uppercase;cursor:pointer;transform:translateY(-100%)}.up-modal-content{overflow-x:hidden;overflow-y:auto;width:100%;height:100%;padding:20px;box-sizing:border-box}.up-popup{z-index:10000;position:fixed;background-color:#fff;padding:15px;box-shadow:0 0 4px rgba(0,0,0,0.3)}.up-modal .up-popup{z-index:15000}.up-tooltip{z-index:30000;position:fixed;background-color:rgba(30,30,30,0.8);color:white;padding:6px 8px;box-shadow:0 0 4px rgba(0,0,0,0.2)}.up-tooltip[up-origin=top]{margin-top:-6px}.up-tooltip[up-origin=bottom]{margin-bottom:-6px}
1
+ [up-close]{cursor:pointer}[up-follow]{cursor:pointer}.up-modal{position:fixed;top:0;left:0;bottom:0;right:0;z-index:10000;background-color:rgba(90,90,90,0.4)}.up-modal-dialog{position:absolute;top:50%;left:50%;transform:translate(-50%, -50%);max-width:100%;max-height:100%;background-color:#fff;box-shadow:0 0 10px 1px rgba(0,0,0,0.3);box-sizing:border-box}.up-modal-close{position:absolute;right:0;top:0;width:36px;text-align:center;line-height:24px;height:24px;background-color:#999;color:#fff;font-weight:bold;text-transform:uppercase;cursor:pointer;transform:translateY(-100%)}.up-modal-content{overflow-x:hidden;overflow-y:auto;width:100%;height:100%;padding:20px;box-sizing:border-box}.up-popup{z-index:10000;position:fixed;background-color:#fff;padding:15px;box-shadow:0 0 4px rgba(0,0,0,0.3)}.up-modal .up-popup{z-index:15000}.up-tooltip{z-index:30000;position:fixed;background-color:#666;color:white;padding:6px 9px}.up-tooltip[up-origin=top]{margin-top:-6px}.up-tooltip[up-origin=top]:after{content:"";position:absolute;border-style:solid;border-width:8px 8px 0;border-color:#666 transparent;display:block;width:0;z-index:1;bottom:-8px;left:50%;margin-left:-8px}.up-tooltip[up-origin=bottom]{margin-top:6px}.up-tooltip[up-origin=bottom]:after{content:"";position:absolute;border-style:solid;border-width:0 8px 8px;border-color:#666 transparent;display:block;width:0;z-index:1;top:-8px;left:50%;margin-left:-8px}