upjs-rails 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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}