unpoly-rails 0.57.0 → 0.60.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of unpoly-rails might be problematic. Click here for more details.

Files changed (186) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +393 -1
  3. data/Gemfile.lock +5 -2
  4. data/README.md +1 -1
  5. data/README_RAILS.md +1 -1
  6. data/Rakefile +10 -1
  7. data/design/es6.js +32 -0
  8. data/design/ie11.txt +9 -0
  9. data/design/measure_jquery/element_list.js +41 -0
  10. data/design/measure_jquery/up.on_vs_addEventListener.js +56 -0
  11. data/design/todo_jquery.txt +13 -0
  12. data/dist/unpoly-bootstrap3.js +8 -8
  13. data/dist/unpoly-bootstrap3.min.js +1 -1
  14. data/dist/unpoly.css +22 -20
  15. data/dist/unpoly.js +6990 -5336
  16. data/dist/unpoly.min.css +1 -1
  17. data/dist/unpoly.min.js +4 -4
  18. data/lib/assets/javascripts/unpoly-bootstrap3/viewport-ext.coffee +5 -0
  19. data/lib/assets/javascripts/unpoly.coffee +8 -6
  20. data/lib/assets/javascripts/unpoly/browser.coffee.erb +23 -118
  21. data/lib/assets/javascripts/unpoly/classes/body_shifter.coffee +36 -0
  22. data/lib/assets/javascripts/unpoly/classes/cache.coffee +4 -4
  23. data/lib/assets/javascripts/unpoly/classes/compile_pass.coffee +45 -39
  24. data/lib/assets/javascripts/unpoly/classes/config.coffee +9 -0
  25. data/lib/assets/javascripts/unpoly/classes/css_transition.coffee +18 -27
  26. data/lib/assets/javascripts/unpoly/classes/divertible_chain.coffee +39 -0
  27. data/lib/assets/javascripts/unpoly/classes/event_listener.coffee +116 -0
  28. data/lib/assets/javascripts/unpoly/classes/extract_cascade.coffee +8 -8
  29. data/lib/assets/javascripts/unpoly/classes/extract_plan.coffee +19 -19
  30. data/lib/assets/javascripts/unpoly/classes/field_observer.coffee +54 -31
  31. data/lib/assets/javascripts/unpoly/classes/{focus_tracker.coffee → focus_follower.coffee} +2 -2
  32. data/lib/assets/javascripts/unpoly/classes/follow_variant.coffee +25 -25
  33. data/lib/assets/javascripts/unpoly/classes/html_parser.coffee +4 -11
  34. data/lib/assets/javascripts/unpoly/classes/motion_controller.coffee +157 -0
  35. data/lib/assets/javascripts/unpoly/classes/params.coffee.erb +525 -0
  36. data/lib/assets/javascripts/unpoly/classes/record.coffee +8 -2
  37. data/lib/assets/javascripts/unpoly/classes/rect.js +21 -0
  38. data/lib/assets/javascripts/unpoly/classes/request.coffee +41 -35
  39. data/lib/assets/javascripts/unpoly/classes/response.coffee +7 -3
  40. data/lib/assets/javascripts/unpoly/classes/reveal_motion.coffee +102 -0
  41. data/lib/assets/javascripts/unpoly/classes/scroll_motion.coffee +67 -0
  42. data/lib/assets/javascripts/unpoly/classes/selector.coffee +60 -0
  43. data/lib/assets/javascripts/unpoly/classes/tether.coffee +105 -0
  44. data/lib/assets/javascripts/unpoly/classes/url_set.coffee +12 -7
  45. data/lib/assets/javascripts/unpoly/element.coffee.erb +1126 -0
  46. data/lib/assets/javascripts/unpoly/event.coffee.erb +437 -0
  47. data/lib/assets/javascripts/unpoly/feedback.coffee +73 -94
  48. data/lib/assets/javascripts/unpoly/form.coffee.erb +188 -181
  49. data/lib/assets/javascripts/unpoly/{dom.coffee.erb → fragment.coffee.erb} +250 -283
  50. data/lib/assets/javascripts/unpoly/framework.coffee +67 -0
  51. data/lib/assets/javascripts/unpoly/history.coffee +29 -28
  52. data/lib/assets/javascripts/unpoly/legacy.coffee +60 -0
  53. data/lib/assets/javascripts/unpoly/link.coffee.erb +127 -119
  54. data/lib/assets/javascripts/unpoly/log.coffee +99 -19
  55. data/lib/assets/javascripts/unpoly/modal.coffee.erb +95 -118
  56. data/lib/assets/javascripts/unpoly/motion.coffee.erb +158 -138
  57. data/lib/assets/javascripts/unpoly/namespace.coffee.erb +0 -5
  58. data/lib/assets/javascripts/unpoly/popup.coffee.erb +119 -102
  59. data/lib/assets/javascripts/unpoly/protocol.coffee +11 -15
  60. data/lib/assets/javascripts/unpoly/proxy.coffee +62 -65
  61. data/lib/assets/javascripts/unpoly/radio.coffee +3 -5
  62. data/lib/assets/javascripts/unpoly/rails.coffee +8 -9
  63. data/lib/assets/javascripts/unpoly/syntax.coffee.erb +173 -125
  64. data/lib/assets/javascripts/unpoly/toast.coffee +25 -24
  65. data/lib/assets/javascripts/unpoly/tooltip.coffee +89 -79
  66. data/lib/assets/javascripts/unpoly/util.coffee.erb +579 -1074
  67. data/lib/assets/javascripts/unpoly/{layout.coffee.erb → viewport.coffee.erb} +334 -264
  68. data/lib/assets/stylesheets/unpoly/dom.sass +1 -1
  69. data/lib/assets/stylesheets/unpoly/layout.sass +2 -0
  70. data/lib/assets/stylesheets/unpoly/popup.sass +0 -1
  71. data/lib/assets/stylesheets/unpoly/tooltip.sass +17 -12
  72. data/lib/unpoly/rails/version.rb +1 -1
  73. data/package.json +1 -2
  74. data/spec_app/Gemfile +2 -1
  75. data/spec_app/Gemfile.lock +38 -27
  76. data/spec_app/app/assets/javascripts/integration_test.coffee +1 -0
  77. data/spec_app/app/assets/javascripts/jasmine_specs.coffee +1 -2
  78. data/spec_app/app/assets/stylesheets/integration_test.sass +14 -1
  79. data/spec_app/app/controllers/scroll_test_controller.rb +5 -0
  80. data/spec_app/app/views/css_test/modal.erb +6 -6
  81. data/spec_app/app/views/css_test/popup.erb +44 -18
  82. data/spec_app/app/views/css_test/tooltip.erb +23 -4
  83. data/spec_app/app/views/error_test/trigger.erb +1 -1
  84. data/spec_app/app/views/form_test/basics/new.erb +1 -3
  85. data/spec_app/app/views/pages/start.erb +9 -2
  86. data/spec_app/app/views/reveal_test/long1.erb +1 -1
  87. data/spec_app/app/views/reveal_test/long2.erb +1 -1
  88. data/spec_app/app/views/reveal_test/within_document_viewport.erb +24 -0
  89. data/spec_app/app/views/reveal_test/within_overflowing_div_viewport.erb +28 -0
  90. data/spec_app/app/views/scroll_test/long1.erb +30 -0
  91. data/spec_app/config/routes.rb +1 -0
  92. data/spec_app/spec/javascripts/helpers/agent_detector.coffee +3 -0
  93. data/spec_app/spec/javascripts/helpers/async_sequence.js.coffee +1 -0
  94. data/spec_app/spec/javascripts/helpers/browser_switches.js.coffee +17 -5
  95. data/spec_app/spec/javascripts/helpers/enable_logging.js.coffee +1 -1
  96. data/spec_app/spec/javascripts/helpers/fixture.js.coffee +25 -0
  97. data/spec_app/spec/javascripts/helpers/jquery_no_conflict.js +1 -0
  98. data/spec_app/spec/javascripts/helpers/last_request.js.coffee +1 -0
  99. data/spec_app/spec/javascripts/helpers/mock_ajax.js.coffee +1 -1
  100. data/spec_app/spec/javascripts/helpers/parse_form_data.js.coffee +2 -2
  101. data/spec_app/spec/javascripts/helpers/protect_jasmine_runner.coffee +4 -1
  102. data/spec_app/spec/javascripts/helpers/remove_body_margin.js.coffee +3 -0
  103. data/spec_app/spec/javascripts/helpers/reset_history.js.coffee +2 -1
  104. data/spec_app/spec/javascripts/helpers/reset_knife.js.coffee +2 -2
  105. data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +18 -11
  106. data/spec_app/spec/javascripts/helpers/restore_body_scroll.js.coffee +3 -0
  107. data/spec_app/spec/javascripts/helpers/show_lib_versions.coffee +3 -0
  108. data/spec_app/spec/javascripts/helpers/spec_util.coffee +47 -0
  109. data/spec_app/spec/javascripts/helpers/to_be_around.js.coffee +3 -0
  110. data/spec_app/spec/javascripts/helpers/to_be_array.coffee +5 -0
  111. data/spec_app/spec/javascripts/helpers/to_be_attached.coffee +6 -2
  112. data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +3 -0
  113. data/spec_app/spec/javascripts/helpers/to_be_detached.coffee +6 -2
  114. data/spec_app/spec/javascripts/helpers/to_be_element.js.coffee +8 -0
  115. data/spec_app/spec/javascripts/helpers/to_be_error.coffee +3 -0
  116. data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +3 -0
  117. data/spec_app/spec/javascripts/helpers/to_be_hidden.js.coffee +8 -0
  118. data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +3 -0
  119. data/spec_app/spec/javascripts/helpers/to_be_present.js.coffee +3 -0
  120. data/spec_app/spec/javascripts/helpers/to_be_scrolled_to.coffee +3 -0
  121. data/spec_app/spec/javascripts/helpers/to_be_visible.js.coffee +9 -0
  122. data/spec_app/spec/javascripts/helpers/to_contain.js.coffee +3 -0
  123. data/spec_app/spec/javascripts/helpers/to_end_with.js.coffee +3 -0
  124. data/spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee +1 -2
  125. data/spec_app/spec/javascripts/helpers/to_equal_node_list.coffee +7 -0
  126. data/spec_app/spec/javascripts/helpers/to_equal_via_is_equal.js.coffee +7 -0
  127. data/spec_app/spec/javascripts/helpers/to_have_class.js.coffee +10 -0
  128. data/spec_app/spec/javascripts/helpers/to_have_descendant.js.coffee +10 -0
  129. data/spec_app/spec/javascripts/helpers/to_have_length.js.coffee +8 -0
  130. data/spec_app/spec/javascripts/helpers/to_have_opacity.coffee +7 -3
  131. data/spec_app/spec/javascripts/helpers/to_have_own_property.js.coffee +3 -0
  132. data/spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee +1 -0
  133. data/spec_app/spec/javascripts/helpers/to_have_text.js.coffee +9 -0
  134. data/spec_app/spec/javascripts/helpers/to_have_unhandled_rejections.coffee +0 -21
  135. data/spec_app/spec/javascripts/helpers/to_match_list.coffee +14 -0
  136. data/spec_app/spec/javascripts/helpers/to_match_selector.coffee +3 -0
  137. data/spec_app/spec/javascripts/helpers/to_match_text.js.coffee +4 -1
  138. data/spec_app/spec/javascripts/helpers/to_match_url.coffee +1 -0
  139. data/spec_app/spec/javascripts/helpers/trigger.js.coffee +91 -7
  140. data/spec_app/spec/javascripts/helpers/wait_until_dom_ready.js.coffee +3 -0
  141. data/spec_app/spec/javascripts/up/browser_spec.js.coffee +23 -90
  142. data/spec_app/spec/javascripts/up/classes/cache_spec.js.coffee +3 -0
  143. data/spec_app/spec/javascripts/up/classes/config_spec.coffee +24 -0
  144. data/spec_app/spec/javascripts/up/classes/divertible_chain_spec.coffee +45 -0
  145. data/spec_app/spec/javascripts/up/classes/focus_tracker_spec.coffee +5 -2
  146. data/spec_app/spec/javascripts/up/classes/params_spec.coffee +557 -0
  147. data/spec_app/spec/javascripts/up/classes/request_spec.coffee +7 -4
  148. data/spec_app/spec/javascripts/up/classes/scroll_motion_spec.js.coffee +51 -0
  149. data/spec_app/spec/javascripts/up/classes/store/memory_spec.js.coffee +3 -0
  150. data/spec_app/spec/javascripts/up/classes/store/session_spec.js.coffee +3 -2
  151. data/spec_app/spec/javascripts/up/element_spec.coffee +897 -0
  152. data/spec_app/spec/javascripts/up/event_spec.js.coffee +496 -0
  153. data/spec_app/spec/javascripts/up/feedback_spec.js.coffee +69 -48
  154. data/spec_app/spec/javascripts/up/form_spec.js.coffee +252 -194
  155. data/spec_app/spec/javascripts/up/{dom_spec.js.coffee → fragment_spec.js.coffee} +381 -388
  156. data/spec_app/spec/javascripts/up/history_spec.js.coffee +21 -19
  157. data/spec_app/spec/javascripts/up/jquery_spec.js.coffee +4 -0
  158. data/spec_app/spec/javascripts/up/legacy_spec.js.coffee +27 -0
  159. data/spec_app/spec/javascripts/up/link_spec.js.coffee +163 -160
  160. data/spec_app/spec/javascripts/up/log_spec.js.coffee +85 -12
  161. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +141 -123
  162. data/spec_app/spec/javascripts/up/motion_spec.js.coffee +117 -113
  163. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +60 -77
  164. data/spec_app/spec/javascripts/up/protocol_spec.js.coffee +1 -0
  165. data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +85 -78
  166. data/spec_app/spec/javascripts/up/radio_spec.js.coffee +29 -22
  167. data/spec_app/spec/javascripts/up/rails_spec.js.coffee +14 -13
  168. data/spec_app/spec/javascripts/up/spec_spec.js.coffee +9 -0
  169. data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +96 -66
  170. data/spec_app/spec/javascripts/up/toast_spec.js.coffee +37 -0
  171. data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +31 -47
  172. data/spec_app/spec/javascripts/up/util_spec.js.coffee +725 -562
  173. data/spec_app/spec/javascripts/up/{layout_spec.js.coffee → viewport_spec.js.coffee} +175 -149
  174. metadata +57 -19
  175. data/lib/assets/javascripts/unpoly-bootstrap3/layout-ext.coffee +0 -5
  176. data/lib/assets/javascripts/unpoly/bus.coffee.erb +0 -518
  177. data/lib/assets/javascripts/unpoly/classes/extract_step.coffee +0 -4
  178. data/lib/assets/javascripts/unpoly/classes/motion_tracker.coffee +0 -125
  179. data/lib/assets/javascripts/unpoly/params.coffee.erb +0 -522
  180. data/spec_app/spec/javascripts/helpers/append_fixture.js.coffee +0 -8
  181. data/spec_app/spec/javascripts/up/bus_spec.js.coffee +0 -210
  182. data/spec_app/spec/javascripts/up/namespace_spec.js.coffee +0 -9
  183. data/spec_app/spec/javascripts/up/params_spec.coffee +0 -768
  184. data/spec_app/vendor/asset-libs/jasmine-fixture-1.3.4/jasmine-fixture.js +0 -433
  185. data/spec_app/vendor/asset-libs/jasmine-jquery-2.1.1/.bower.json +0 -26
  186. data/spec_app/vendor/asset-libs/jasmine-jquery-2.1.1/jasmine-jquery.js +0 -838
@@ -1,6 +1,7 @@
1
- describe 'up.feedback', ->
1
+ u = up.util
2
+ $ = jQuery
2
3
 
3
- u = up.util
4
+ describe 'up.feedback', ->
4
5
 
5
6
  beforeEach ->
6
7
  up.history.config.enabled = true
@@ -15,7 +16,7 @@ describe 'up.feedback', ->
15
16
 
16
17
  it 'marks a child link as .up-current if it links to the current URL', ->
17
18
  up.history.replace('/foo')
18
- $nav = affix('div[up-nav]')
19
+ $nav = $fixture('div[up-nav]')
19
20
  $currentLink = $nav.affix('a[href="/foo"]')
20
21
  $otherLink = $nav.affix('a[href="/bar"]')
21
22
  up.hello($nav)
@@ -24,8 +25,8 @@ describe 'up.feedback', ->
24
25
 
25
26
  it 'marks the element as .up-current if it is also a link to the current URL', ->
26
27
  up.history.replace('/foo')
27
- $currentLink = affix('a[href="/foo"][up-nav]')
28
- $otherLink = affix('a[href="/bar"][up-nav]')
28
+ $currentLink = $fixture('a[href="/foo"][up-nav]')
29
+ $otherLink = $fixture('a[href="/bar"][up-nav]')
29
30
  up.hello($currentLink)
30
31
  up.hello($otherLink)
31
32
  expect($currentLink).toHaveClass('up-current')
@@ -33,16 +34,16 @@ describe 'up.feedback', ->
33
34
 
34
35
  it 'does not mark a link as .up-current if the link is outside an [up-nav]', ->
35
36
  up.history.replace('/foo')
36
- $nav = affix('div[up-nav]')
37
+ $nav = $fixture('div[up-nav]')
37
38
  $currentLinkInNav = $nav.affix('a[href="/foo"]')
38
- $currentLinkOutsideNav = affix('a[href="/foo"]')
39
+ $currentLinkOutsideNav = $fixture('a[href="/foo"]')
39
40
  up.hello($nav)
40
41
  expect($currentLinkInNav).toHaveClass('up-current')
41
42
  expect($currentLinkOutsideNav).not.toHaveClass('up-current')
42
43
 
43
44
  it 'marks a replaced child link as .up-current if it links to the current URL', asyncSpec (next) ->
44
45
  up.history.replace('/foo')
45
- $nav = affix('div[up-nav]')
46
+ $nav = $fixture('div[up-nav]')
46
47
  $nav.affix('a.link[href="/bar"]').text('old link')
47
48
  up.hello($nav)
48
49
 
@@ -64,7 +65,7 @@ describe 'up.feedback', ->
64
65
 
65
66
  it 'marks any link as .up-current if its up-href attribute matches the current URL', ->
66
67
  up.history.replace('/foo')
67
- $nav = affix('div[up-nav]')
68
+ $nav = $fixture('div[up-nav]')
68
69
  $currentLink = $nav.affix('span[up-href="/foo"]')
69
70
  $otherLink = $nav.affix('span[up-href="/bar"]')
70
71
  up.hello($nav)
@@ -73,21 +74,21 @@ describe 'up.feedback', ->
73
74
 
74
75
  it 'matches the current and destination URLs if they only differ by a trailing slash', ->
75
76
  up.history.replace('/foo')
76
- $nav = affix('div[up-nav]')
77
+ $nav = $fixture('div[up-nav]')
77
78
  $currentLink = $nav.affix('span[up-href="/foo/"]')
78
79
  up.hello($nav)
79
80
  expect($currentLink).toHaveClass('up-current')
80
81
 
81
82
  it 'does not match the current and destination URLs if they differ in the search', ->
82
83
  up.history.replace('/foo?q=1')
83
- $nav = affix('div[up-nav]')
84
+ $nav = $fixture('div[up-nav]')
84
85
  $currentLink = $nav.affix('span[up-href="/foo?q=2"]')
85
86
  up.hello($nav)
86
87
  expect($currentLink).not.toHaveClass('up-current')
87
88
 
88
89
  it 'marks any link as .up-current if any of its space-separated up-alias values matches the current URL', ->
89
90
  up.history.replace('/foo')
90
- $nav = affix('div[up-nav]')
91
+ $nav = $fixture('div[up-nav]')
91
92
  $currentLink = $nav.affix('a[href="/x"][up-alias="/aaa /foo /bbb"]')
92
93
  $otherLink = $nav.affix('a[href="/y"][up-alias="/bar"]')
93
94
  up.hello($nav)
@@ -95,18 +96,18 @@ describe 'up.feedback', ->
95
96
  expect($otherLink).not.toHaveClass('up-current')
96
97
 
97
98
  it 'does not throw if the current location does not match an up-alias wildcard (bugfix)', ->
98
- inserter = -> up.hello(affix('a[up-nav][up-alias="/qqqq*"]'))
99
+ inserter = -> up.hello(fixture('a[up-nav][up-alias="/qqqq*"]'))
99
100
  expect(inserter).not.toThrow()
100
101
 
101
102
  it 'does not highlight a link to "#" (commonly used for JS-only buttons)', ->
102
- $nav = affix('div[up-nav]')
103
+ $nav = $fixture('div[up-nav]')
103
104
  $link = $nav.affix('a[href="#"]')
104
105
  up.hello($nav)
105
106
  expect($link).not.toHaveClass('up-current')
106
107
 
107
108
  it 'does not highlight links with unsafe methods', ->
108
109
  up.history.replace('/foo')
109
- $nav = affix('div[up-nav]')
110
+ $nav = $fixture('div[up-nav]')
110
111
  $defaultLink = $nav.affix('a[href="/foo"]')
111
112
  $getLink = $nav.affix('a[href="/foo"][up-method="get"]')
112
113
  $putLink = $nav.affix('a[href="/foo"][up-method="put"]')
@@ -125,7 +126,7 @@ describe 'up.feedback', ->
125
126
  it 'marks URL prefixes as .up-current if an up-alias value ends in *', ->
126
127
  up.history.replace('/foo/123')
127
128
 
128
- $nav = affix('div[up-nav]')
129
+ $nav = $fixture('div[up-nav]')
129
130
  $currentLink = $nav.affix('a[href="/x"][up-alias="/aaa /foo/* /bbb"]')
130
131
  $otherLink = $nav.affix('a[href="/y"][up-alias="/bar"]')
131
132
  up.hello($nav)
@@ -133,10 +134,30 @@ describe 'up.feedback', ->
133
134
  expect($currentLink).toHaveClass('up-current')
134
135
  expect($otherLink).not.toHaveClass('up-current')
135
136
 
137
+ it 'marks URL prefixes as .up-current if an up-alias has multiple * placeholders', ->
138
+ up.history.replace('/a-foo-b-bar-c')
139
+
140
+ $nav = $fixture('div[up-nav]')
141
+ $currentLink = $nav.affix('a[href="/x"][up-alias="*-foo-*-bar-*"]')
142
+ $otherLink1 = $nav.affix('a[href="/y"][up-alias="/foo-bar"]')
143
+ $otherLink2 = $nav.affix('a[href="/y"][up-alias="/foo-b-bar"]')
144
+ $otherLink3 = $nav.affix('a[href="/y"][up-alias="/a-foo-b-bar"]')
145
+ $otherLink4 = $nav.affix('a[href="/y"][up-alias="/foo-b-bar-c"]')
146
+ $otherLink5 = $nav.affix('a[href="/y"][up-alias="/a-foo-b-bar-c-d"]')
147
+ up.hello($nav)
148
+
149
+ expect($currentLink).toHaveClass('up-current')
150
+ expect($otherLink1).not.toHaveClass('up-current')
151
+ expect($otherLink2).not.toHaveClass('up-current')
152
+ expect($otherLink3).not.toHaveClass('up-current')
153
+ expect($otherLink4).not.toHaveClass('up-current')
154
+ expect($otherLink5).not.toHaveClass('up-current')
155
+
156
+
136
157
  it 'allows to configure a custom "current" class in addition to .up-current', ->
137
158
  up.feedback.config.currentClasses.push('highlight')
138
159
  up.history.replace('/foo')
139
- $nav = affix('div[up-nav]')
160
+ $nav = $fixture('div[up-nav]')
140
161
  $currentLink = $nav.affix('a[href="/foo"]')
141
162
  up.hello($nav)
142
163
 
@@ -147,7 +168,7 @@ describe 'up.feedback', ->
147
168
  up.feedback.config.currentClasses.push('highlight1')
148
169
  up.feedback.config.currentClasses.push('highlight2')
149
170
  up.history.replace('/foo')
150
- $nav = affix('div[up-nav]')
171
+ $nav = $fixture('div[up-nav]')
151
172
  $currentLink = $nav.affix('a[href="/foo"]')
152
173
  up.hello($nav)
153
174
 
@@ -158,7 +179,7 @@ describe 'up.feedback', ->
158
179
  it 'allows to configure additional nav selectors', ->
159
180
  up.history.replace('/foo')
160
181
  up.feedback.config.navs.push('.navi')
161
- $nav = affix('div.navi')
182
+ $nav = $fixture('div.navi')
162
183
  $currentLink = $nav.affix('a[href="/foo"]')
163
184
  $otherLink = $nav.affix('a[href="/bar"]')
164
185
  up.hello($nav)
@@ -170,11 +191,11 @@ describe 'up.feedback', ->
170
191
  describe 'updating .up-current marks wen the URL changes', ->
171
192
 
172
193
  it 'marks a link as .up-current if it links to the current URL, but is missing a trailing slash', asyncSpec (next) ->
173
- $nav = affix('div[up-nav]')
194
+ $nav = $fixture('div[up-nav]')
174
195
  $link = $nav.affix('a[href="/foo"][up-target=".main"]')
175
196
  up.hello($nav)
176
197
 
177
- affix('.main')
198
+ fixture('.main')
178
199
  Trigger.clickSequence($link)
179
200
 
180
201
  next =>
@@ -186,11 +207,11 @@ describe 'up.feedback', ->
186
207
  expect($link).toHaveClass('up-current')
187
208
 
188
209
  it 'marks a link as .up-current if it links to the current URL, but has an extra trailing slash', asyncSpec (next) ->
189
- $nav = affix('div[up-nav]')
210
+ $nav = $fixture('div[up-nav]')
190
211
  $link = $nav.affix('a[href="/foo/"][up-target=".main"]')
191
212
  up.hello($nav)
192
213
 
193
- affix('.main')
214
+ fixture('.main')
194
215
  Trigger.clickSequence($link)
195
216
 
196
217
  next =>
@@ -204,7 +225,7 @@ describe 'up.feedback', ->
204
225
  it 'marks a link as .up-current if it links to an URL currently shown either within or below the modal', asyncSpec (next) ->
205
226
  up.history.replace('/foo')
206
227
 
207
- $nav = affix('div[up-nav]')
228
+ $nav = $fixture('div[up-nav]')
208
229
  $backgroundLink = $nav.affix('a[href="/foo"]')
209
230
  $modalLink = $nav.affix('a[href="/bar"][up-modal=".main"]')
210
231
  $unrelatedLink = $nav.affix('a[href="/baz"]')
@@ -233,7 +254,7 @@ describe 'up.feedback', ->
233
254
  # but we still want to cause their URL to mark links as current.
234
255
  up.popup.config.history = false
235
256
 
236
- $nav = affix('div[up-nav]')
257
+ $nav = $fixture('div[up-nav]')
237
258
  $backgroundLink = $nav.affix('a[href="/foo"]')
238
259
  $popupLink = $nav.affix('a[href="/bar"][up-popup=".main"]')
239
260
  $unrelatedLink = $nav.affix('a[href="/baz"]')
@@ -263,7 +284,7 @@ describe 'up.feedback', ->
263
284
  expect($unrelatedLink).not.toHaveClass('up-current')
264
285
 
265
286
  it "respects links that are added to an existing [up-nav] by a fragment update", asyncSpec (next) ->
266
- $nav = affix('.nav[up-nav]')
287
+ $nav = $fixture('.nav[up-nav]')
267
288
  $link = $nav.affix('a[href="/foo"][up-target=".main"]')
268
289
  $more = $nav.affix('.more')
269
290
  up.hello($nav)
@@ -272,7 +293,7 @@ describe 'up.feedback', ->
272
293
 
273
294
  next =>
274
295
  $moreLink = $('.more').find('a')
275
- expect($moreLink).toExist()
296
+ expect($moreLink).toBeAttached()
276
297
  expect($moreLink).toHaveClass('up-current')
277
298
 
278
299
 
@@ -281,8 +302,8 @@ describe 'up.feedback', ->
281
302
  describeCapability 'canPushState', ->
282
303
 
283
304
  it 'marks clicked links as .up-active until the request finishes', asyncSpec (next) ->
284
- $link = affix('a[href="/foo"][up-target=".main"]')
285
- affix('.main')
305
+ $link = $fixture('a[href="/foo"][up-target=".main"]')
306
+ fixture('.main')
286
307
  Trigger.clickSequence($link)
287
308
 
288
309
  next =>
@@ -293,8 +314,8 @@ describe 'up.feedback', ->
293
314
  expect($link).not.toHaveClass('up-active')
294
315
 
295
316
  it 'does not mark a link as .up-active while it is preloading', asyncSpec (next) ->
296
- $link = affix('a[href="/foo"][up-target=".main"]')
297
- affix('.main')
317
+ $link = $fixture('a[href="/foo"][up-target=".main"]')
318
+ fixture('.main')
298
319
 
299
320
  up.proxy.preload($link)
300
321
 
@@ -303,8 +324,8 @@ describe 'up.feedback', ->
303
324
  expect($link).not.toHaveClass('up-active')
304
325
 
305
326
  it 'marks links with [up-instant] on mousedown as .up-active until the request finishes', asyncSpec (next) ->
306
- $link = affix('a[href="/foo"][up-instant][up-target=".main"]')
307
- affix('.main')
327
+ $link = $fixture('a[href="/foo"][up-instant][up-target=".main"]')
328
+ fixture('.main')
308
329
  Trigger.mousedown($link)
309
330
 
310
331
  next => expect($link).toHaveClass('up-active')
@@ -312,10 +333,10 @@ describe 'up.feedback', ->
312
333
  next => expect($link).not.toHaveClass('up-active')
313
334
 
314
335
  it 'prefers to mark an enclosing [up-expand] click area', asyncSpec (next) ->
315
- $area = affix('div[up-expand] a[href="/foo"][up-target=".main"]')
336
+ $area = $fixture('div[up-expand] a[href="/foo"][up-target=".main"]')
316
337
  up.hello($area)
317
338
  $link = $area.find('a')
318
- affix('.main')
339
+ fixture('.main')
319
340
  Trigger.clickSequence($link)
320
341
 
321
342
  next =>
@@ -327,8 +348,8 @@ describe 'up.feedback', ->
327
348
  expect($area).not.toHaveClass('up-active')
328
349
 
329
350
  it 'marks clicked modal openers as .up-active while the modal is loading', asyncSpec (next) ->
330
- $link = affix('a[href="/foo"][up-modal=".main"]')
331
- affix('.main')
351
+ $link = $fixture('a[href="/foo"][up-modal=".main"]')
352
+ fixture('.main')
332
353
  Trigger.clickSequence($link)
333
354
 
334
355
  next => expect($link).toHaveClass('up-active')
@@ -336,7 +357,7 @@ describe 'up.feedback', ->
336
357
  next => expect($link).not.toHaveClass('up-active')
337
358
 
338
359
  it 'removes .up-active from a clicked modal opener if the target is already preloaded (bugfix)', asyncSpec (next) ->
339
- $link = affix('a[href="/foo"][up-modal=".main"]')
360
+ $link = $fixture('a[href="/foo"][up-modal=".main"]')
340
361
  up.proxy.preload($link)
341
362
 
342
363
  next => @respondWith('<div class="main">new-text</div>')
@@ -346,8 +367,8 @@ describe 'up.feedback', ->
346
367
  expect($link).not.toHaveClass('up-active')
347
368
 
348
369
  it 'removes .up-active from a clicked link if the target is already preloaded (bugfix)', asyncSpec (next) ->
349
- $link = affix('a[href="/foo"][up-target=".main"]')
350
- affix('.main')
370
+ $link = $fixture('a[href="/foo"][up-target=".main"]')
371
+ fixture('.main')
351
372
  up.proxy.preload($link)
352
373
 
353
374
  next => @respondWith('<div class="main">new-text</div>')
@@ -357,15 +378,15 @@ describe 'up.feedback', ->
357
378
  expect($link).not.toHaveClass('up-active')
358
379
 
359
380
  it 'removes .up-active from a clicked link if the request fails (bugfix)', asyncSpec (next) ->
360
- $link = affix('a[href="/foo"][up-target=".main"]')
361
- affix('.main')
381
+ $link = $fixture('a[href="/foo"][up-target=".main"]')
382
+ fixture('.main')
362
383
  Trigger.clickSequence($link)
363
384
 
364
385
  next =>
365
386
  expect($link).toHaveClass('up-active')
366
- @respondWith
367
- responseText: '<div class="main">failed</div>'
368
- status: 400
369
-
370
- next =>
371
- expect($link).not.toHaveClass('up-active')
387
+ # @respondWith
388
+ # responseText: '<div class="main">failed</div>'
389
+ # status: 400
390
+ #
391
+ # next =>
392
+ # expect($link).not.toHaveClass('up-active')
@@ -1,6 +1,8 @@
1
- describe 'up.form', ->
1
+ u = up.util
2
+ e = up.element
3
+ $ = jQuery
2
4
 
3
- u = up.util
5
+ describe 'up.form', ->
4
6
 
5
7
  describe 'JavaScript functions', ->
6
8
 
@@ -20,29 +22,29 @@ describe 'up.form', ->
20
22
  describe "when the input receives a #{eventName} event", ->
21
23
 
22
24
  it "runs the callback if the value changed", asyncSpec (next) ->
23
- $input = affix('input[value="old-value"]')
25
+ $input = $fixture('input[name="input-name"][value="old-value"]')
24
26
  callback = jasmine.createSpy('change callback')
25
27
  up.observe($input, callback)
26
28
  $input.val('new-value')
27
- u.times 2, -> $input.trigger(eventName)
29
+ u.times 2, -> Trigger[eventName]($input)
28
30
  next =>
29
- expect(callback).toHaveBeenCalledWith('new-value', $input)
31
+ expect(callback).toHaveBeenCalledWith('new-value', 'input-name')
30
32
  expect(callback.calls.count()).toEqual(1)
31
33
 
32
34
  it "does not run the callback if the value didn't change", asyncSpec (next) ->
33
- $input = affix('input[value="old-value"]')
35
+ $input = $fixture('input[name="input-name"][value="old-value"]')
34
36
  callback = jasmine.createSpy('change callback')
35
37
  up.observe($input, callback)
36
- $input.trigger(eventName)
38
+ Trigger[eventName]($input)
37
39
  next =>
38
40
  expect(callback).not.toHaveBeenCalled()
39
41
 
40
42
  it 'debounces the callback when the { delay } option is given', asyncSpec (next) ->
41
- $input = affix('input[value="old-value"]')
43
+ $input = $fixture('input[name="input-name"][value="old-value"]')
42
44
  callback = jasmine.createSpy('change callback')
43
45
  up.observe($input, { delay: 200 }, callback)
44
46
  $input.val('new-value-1')
45
- $input.trigger(eventName)
47
+ Trigger[eventName]($input)
46
48
 
47
49
  next.after 100, ->
48
50
  # 100 ms after change 1: We're still waiting for the 200ms delay to expire
@@ -53,13 +55,13 @@ describe 'up.form', ->
53
55
  expect(callback.calls.count()).toEqual(1)
54
56
  expect(callback.calls.mostRecent().args[0]).toEqual('new-value-1')
55
57
  $input.val('new-value-2')
56
- $input.trigger(eventName)
58
+ Trigger[eventName]($input)
57
59
 
58
60
  next.after 80, ->
59
61
  # 80 ms after change 2: We change again, resetting the delay
60
62
  expect(callback.calls.count()).toEqual(1)
61
63
  $input.val('new-value-3')
62
- $input.trigger(eventName)
64
+ Trigger[eventName]($input)
63
65
 
64
66
  next.after 170, ->
65
67
  # 250 ms after change 2, which was superseded by change 3
@@ -73,20 +75,20 @@ describe 'up.form', ->
73
75
  expect(callback.calls.mostRecent().args[0]).toEqual('new-value-3')
74
76
 
75
77
  it 'delays a callback if a previous async callback is taking long to execute', asyncSpec (next) ->
76
- $input = affix('input[value="old-value"]')
78
+ $input = $fixture('input[name="input-name"][value="old-value"]')
77
79
  callbackCount = 0
78
80
  callback = ->
79
81
  callbackCount += 1
80
- return u.promiseTimer(100)
82
+ return up.specUtil.promiseTimer(100)
81
83
  up.observe($input, { delay: 1 }, callback)
82
84
  $input.val('new-value-1')
83
- $input.trigger(eventName)
85
+ Trigger[eventName]($input)
84
86
 
85
87
  next.after 30, ->
86
88
  # Callback has been called and takes 100 ms to complete
87
89
  expect(callbackCount).toEqual(1)
88
90
  $input.val('new-value-2')
89
- $input.trigger(eventName)
91
+ Trigger[eventName]($input)
90
92
 
91
93
  next.after 30, ->
92
94
  # Second callback is triggerd, but waits for first callback to complete
@@ -97,27 +99,27 @@ describe 'up.form', ->
97
99
  expect(callbackCount).toEqual(2)
98
100
 
99
101
  it 'only runs the last callback when a previous long-running callback has been delaying multiple callbacks', asyncSpec (next) ->
100
- $input = affix('input[value="old-value"]')
102
+ $input = $fixture('input[name="input-name"][value="old-value"]')
101
103
 
102
104
  callbackArgs = []
103
105
  callback = (value, field) ->
104
106
  callbackArgs.push(value)
105
- return u.promiseTimer(100)
107
+ return up.specUtil.promiseTimer(100)
106
108
 
107
109
  up.observe($input, { delay: 1 }, callback)
108
110
  $input.val('new-value-1')
109
- $input.trigger(eventName)
111
+ Trigger[eventName]($input)
110
112
 
111
113
  next.after 10, ->
112
114
  # Callback has been called and takes 100 ms to complete
113
115
  expect(callbackArgs).toEqual ['new-value-1']
114
116
  $input.val('new-value-2')
115
- $input.trigger(eventName)
117
+ Trigger[eventName]($input)
116
118
 
117
119
  next.after 10, ->
118
120
  expect(callbackArgs).toEqual ['new-value-1']
119
121
  $input.val('new-value-3')
120
- $input.trigger(eventName)
122
+ Trigger[eventName]($input)
121
123
 
122
124
  next.after 100, ->
123
125
  expect(callbackArgs).toEqual ['new-value-1', 'new-value-3']
@@ -125,8 +127,8 @@ describe 'up.form', ->
125
127
  describe 'when the first argument is a checkbox', ->
126
128
 
127
129
  it 'runs the callback when the checkbox changes its checked state', asyncSpec (next) ->
128
- $form = affix('form')
129
- $checkbox = $form.affix('input[type="checkbox"][value="checkbox-value"]')
130
+ $form = $fixture('form')
131
+ $checkbox = $form.affix('input[name="input-name"][type="checkbox"][value="checkbox-value"]')
130
132
  callback = jasmine.createSpy('change callback')
131
133
  up.observe($checkbox, callback)
132
134
  expect($checkbox.is(':checked')).toBe(false)
@@ -142,8 +144,8 @@ describe 'up.form', ->
142
144
  expect(callback.calls.count()).toEqual(2)
143
145
 
144
146
  it 'runs the callback when the checkbox is toggled by clicking its label', asyncSpec (next) ->
145
- $form = affix('form')
146
- $checkbox = $form.affix('input#tick[type="checkbox"][value="checkbox-value"]')
147
+ $form = $fixture('form')
148
+ $checkbox = $form.affix('input#tick[name="input-name"][type="checkbox"][value="checkbox-value"]')
147
149
  $label = $form.affix('label[for="tick"]').text('tick label')
148
150
  callback = jasmine.createSpy('change callback')
149
151
  up.observe($checkbox, callback)
@@ -162,26 +164,30 @@ describe 'up.form', ->
162
164
  describe 'when the first argument is a radio button group', ->
163
165
 
164
166
  it 'runs the callback when the group changes its selection', asyncSpec (next) ->
165
- $form = affix('form')
167
+ $form = $fixture('form')
166
168
  $radio1 = $form.affix('input[type="radio"][name="group"][value="1"]')
167
169
  $radio2 = $form.affix('input[type="radio"][name="group"][value="2"]')
168
170
  $group = $radio1.add($radio2)
169
171
  callback = jasmine.createSpy('change callback')
170
172
  up.observe($group, callback)
171
173
  expect($radio1.is(':checked')).toBe(false)
174
+
172
175
  Trigger.clickSequence($radio1)
173
176
 
174
177
  next =>
175
178
  expect($radio1.is(':checked')).toBe(true)
176
179
  expect(callback.calls.count()).toEqual(1)
177
- Trigger.clickSequence($radio2)
180
+ # Trigger.clickSequence($radio2)
181
+ $radio1[0].checked = false
182
+ $radio2[0].checked = true
183
+ Trigger.change($radio2)
178
184
 
179
185
  next =>
180
186
  expect($radio1.is(':checked')).toBe(false)
181
187
  expect(callback.calls.count()).toEqual(2)
182
188
 
183
189
  it "runs the callbacks when a radio button is selected or deselected by clicking a label in the group", asyncSpec (next) ->
184
- $form = affix('form')
190
+ $form = $fixture('form')
185
191
  $radio1 = $form.affix('input#radio1[type="radio"][name="group"][value="1"]')
186
192
  $radio1Label = $form.affix('label[for="radio1"]').text('label 1')
187
193
  $radio2 = $form.affix('input#radio2[type="radio"][name="group"][value="2"]')
@@ -202,7 +208,7 @@ describe 'up.form', ->
202
208
  expect(callback.calls.count()).toEqual(2)
203
209
 
204
210
  it "takes the group's initial selected value into account", asyncSpec (next) ->
205
- $form = affix('form')
211
+ $form = $fixture('form')
206
212
  $radio1 = $form.affix('input[type="radio"][name="group"][value="1"][checked="checked"]')
207
213
  $radio2 = $form.affix('input[type="radio"][name="group"][value="2"]')
208
214
  $group = $radio1.add($radio2)
@@ -232,39 +238,74 @@ describe 'up.form', ->
232
238
  describe "when any of the form's inputs receives a #{eventName} event", ->
233
239
 
234
240
  it "runs the callback if the value changed", asyncSpec (next) ->
235
- $form = affix('form')
236
- $input = $form.affix('input[value="old-value"]')
241
+ $form = $fixture('form')
242
+ $input = $form.affix('input[name="input-name"][value="old-value"]')
237
243
  callback = jasmine.createSpy('change callback')
238
244
  up.observe($form, callback)
239
245
  $input.val('new-value')
240
- u.times 2, -> $input.trigger(eventName)
246
+ u.times 2, -> Trigger[eventName]($input)
241
247
  next =>
242
- expect(callback).toHaveBeenCalledWith('new-value', $input)
248
+ expect(callback).toHaveBeenCalledWith('new-value', 'input-name')
243
249
  expect(callback.calls.count()).toEqual(1)
244
250
 
245
251
  it "does not run the callback if the value didn't change", asyncSpec (next) ->
246
- $form = affix('form')
247
- $input = $form.affix('input[value="old-value"]')
252
+ $form = $fixture('form')
253
+ $input = $form.affix('input[name="input-name"][value="old-value"]')
248
254
  callback = jasmine.createSpy('change callback')
249
255
  up.observe($form, callback)
250
- $input.trigger(eventName)
256
+ Trigger[eventName]($input)
251
257
  next =>
252
258
  expect(callback).not.toHaveBeenCalled()
253
259
 
254
260
  # it 'runs the callback only once when a radio button group changes its selection', ->
255
- # $form = affix('form')
261
+ # $form = $fixture('form')
256
262
  # $radio1 = $form.affix('input[type="radio"][name="group"][value="1"][checked="checked"]')
257
263
  # $radio2 = $form.affix('input[type="radio"][name="group"][value="2"]')
258
264
  # callback = jasmine.createSpy('change callback')
259
265
  # up.observe($form, callback)
260
266
  # $radio2.get(0).click()
261
- # u.nextFrame ->
267
+ # u.task ->
262
268
  # expect(callback.calls.count()).toEqual(1)
263
269
 
270
+
271
+ describe 'with { batch: true } options', ->
272
+
273
+ it 'calls the callback once with all collected changes in a diff object', asyncSpec (next) ->
274
+ $form = $fixture('form')
275
+ $input1 = $form.affix('input[name="input1"][value="input1-a"]')
276
+ $input2 = $form.affix('input[name="input2"][value="input2-a"]')
277
+ callback = jasmine.createSpy('change callback')
278
+ up.observe($form, { batch: true }, callback)
279
+
280
+ next ->
281
+ expect(callback.calls.count()).toEqual(0)
282
+
283
+ $input1.val('input1-b')
284
+ Trigger.change($input1)
285
+ $input2.val('input2-b')
286
+ Trigger.change($input2)
287
+
288
+ next ->
289
+ expect(callback.calls.count()).toEqual(1)
290
+ expect(callback.calls.mostRecent().args[0]).toEqual {
291
+ 'input1': 'input1-b'
292
+ 'input2': 'input2-b'
293
+ }
294
+
295
+ $input2.val('input2-c')
296
+ Trigger.change($input2)
297
+
298
+ next ->
299
+ expect(callback.calls.count()).toEqual(2)
300
+ expect(callback.calls.mostRecent().args[0]).toEqual {
301
+ 'input2': 'input2-c'
302
+ }
303
+
304
+
264
305
  describe 'up.submit', ->
265
306
 
266
307
  it 'emits a preventable up:form:submit event', asyncSpec (next) ->
267
- $form = affix('form[action="/form-target"][up-target=".response"]')
308
+ $form = $fixture('form[action="/form-target"][up-target=".response"]')
268
309
 
269
310
  listener = jasmine.createSpy('submit listener').and.callFake (event) ->
270
311
  event.preventDefault()
@@ -275,8 +316,8 @@ describe 'up.form', ->
275
316
 
276
317
  next =>
277
318
  expect(listener).toHaveBeenCalled()
278
- event = listener.calls.mostRecent().args[0]
279
- expect(event.$element).toEqual($form)
319
+ element = listener.calls.mostRecent().args[1]
320
+ expect(element).toEqual(element)
280
321
 
281
322
  # No request should be made because we prevented the event
282
323
  expect(jasmine.Ajax.requests.count()).toEqual(0)
@@ -285,10 +326,10 @@ describe 'up.form', ->
285
326
 
286
327
  beforeEach ->
287
328
  up.history.config.enabled = true
288
- @$form = affix('form[action="/form-target"][method="put"][up-target=".response"]')
329
+ @$form = $fixture('form[action="/form-target"][method="put"][up-target=".response"]')
289
330
  @$form.append('<input name="field1" value="value1">')
290
331
  @$form.append('<input name="field2" value="value2">')
291
- affix('.response').text('old-text')
332
+ $fixture('.response').text('old-text')
292
333
 
293
334
  it 'submits the given form and replaces the target with the response', asyncSpec (next) ->
294
335
  up.submit(@$form)
@@ -398,10 +439,10 @@ describe 'up.form', ->
398
439
  describe 'revealing', ->
399
440
 
400
441
  it 'reaveals the target fragment if the submission succeeds', asyncSpec (next) ->
401
- $form = affix('form[action="/action"][up-target=".target"]')
402
- $target = affix('.target')
442
+ $form = $fixture('form[action="/action"][up-target=".target"]')
443
+ $target = $fixture('.target')
403
444
 
404
- revealStub = up.layout.knife.mock('reveal')
445
+ revealStub = up.viewport.knife.mock('reveal')
405
446
 
406
447
  up.submit($form)
407
448
 
@@ -410,13 +451,13 @@ describe 'up.form', ->
410
451
 
411
452
  next =>
412
453
  expect(revealStub).toHaveBeenCalled()
413
- expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('.target')
454
+ expect(revealStub.calls.mostRecent().args[0]).toMatchSelector('.target')
414
455
 
415
456
  it 'reveals the form if the submission fails', asyncSpec (next) ->
416
- $form = affix('form#foo-form[action="/action"][up-target=".target"]')
417
- $target = affix('.target')
457
+ $form = $fixture('form#foo-form[action="/action"][up-target=".target"]')
458
+ $target = $fixture('.target')
418
459
 
419
- revealStub = up.layout.knife.mock('reveal')
460
+ revealStub = up.viewport.knife.mock('reveal')
420
461
 
421
462
  up.submit($form)
422
463
 
@@ -431,17 +472,17 @@ describe 'up.form', ->
431
472
 
432
473
  next =>
433
474
  expect(revealStub).toHaveBeenCalled()
434
- expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('#foo-form')
475
+ expect(revealStub.calls.mostRecent().args[0]).toMatchSelector('#foo-form')
435
476
 
436
477
 
437
478
  describe 'with { reveal } option', ->
438
479
 
439
480
  it 'allows to reveal a different selector', asyncSpec (next) ->
440
- $form = affix('form[action="/action"][up-target=".target"]')
441
- $target = affix('.target')
442
- $other = affix('.other')
481
+ $form = $fixture('form[action="/action"][up-target=".target"]')
482
+ $target = $fixture('.target')
483
+ $other = $fixture('.other')
443
484
 
444
- revealStub = up.layout.knife.mock('reveal')
485
+ revealStub = up.viewport.knife.mock('reveal')
445
486
 
446
487
  up.submit($form, reveal: '.other')
447
488
 
@@ -457,14 +498,14 @@ describe 'up.form', ->
457
498
 
458
499
  next =>
459
500
  expect(revealStub).toHaveBeenCalled()
460
- expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('.other')
501
+ expect(revealStub.calls.mostRecent().args[0]).toMatchSelector('.other')
461
502
 
462
503
  it 'still reveals the form for a failed submission', asyncSpec (next) ->
463
- $form = affix('form#foo-form[action="/action"][up-target=".target"]')
464
- $target = affix('.target')
465
- $other = affix('.other')
504
+ $form = $fixture('form#foo-form[action="/action"][up-target=".target"]')
505
+ $target = $fixture('.target')
506
+ $other = $fixture('.other')
466
507
 
467
- revealStub = up.layout.knife.mock('reveal')
508
+ revealStub = up.viewport.knife.mock('reveal')
468
509
 
469
510
  up.submit($form, reveal: '.other')
470
511
 
@@ -479,12 +520,12 @@ describe 'up.form', ->
479
520
 
480
521
  next =>
481
522
  expect(revealStub).toHaveBeenCalled()
482
- expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('#foo-form')
523
+ expect(revealStub.calls.mostRecent().args[0]).toMatchSelector('#foo-form')
483
524
 
484
525
  it 'allows to refer to this form as "&" in the selector', asyncSpec (next) ->
485
- $form = affix('form#foo-form[action="/action"][up-target="#foo-form"]')
526
+ $form = $fixture('form#foo-form[action="/action"][up-target="#foo-form"]')
486
527
 
487
- revealStub = up.layout.knife.mock('reveal')
528
+ revealStub = up.viewport.knife.mock('reveal')
488
529
 
489
530
  up.submit($form, reveal: '& .form-child')
490
531
 
@@ -501,16 +542,16 @@ describe 'up.form', ->
501
542
 
502
543
  next =>
503
544
  expect(revealStub).toHaveBeenCalled()
504
- expect(revealStub.calls.mostRecent().args[0]).toEqual($('#foo-form .form-child'))
545
+ expect(revealStub.calls.mostRecent().args[0]).toEqual(e.first('#foo-form .form-child'))
505
546
 
506
547
  describe 'with { failReveal } option', ->
507
548
 
508
549
  it 'reveals the given selector for a failed submission', asyncSpec (next) ->
509
- $form = affix('form#foo-form[action="/action"][up-target=".target"]')
510
- $target = affix('.target')
511
- $other = affix('.other')
550
+ $form = $fixture('form#foo-form[action="/action"][up-target=".target"]')
551
+ $target = $fixture('.target')
552
+ $other = $fixture('.other')
512
553
 
513
- revealStub = up.layout.knife.mock('reveal')
554
+ revealStub = up.viewport.knife.mock('reveal')
514
555
 
515
556
  up.submit($form, reveal: '.other', failReveal: '.error')
516
557
 
@@ -525,13 +566,13 @@ describe 'up.form', ->
525
566
 
526
567
  next =>
527
568
  expect(revealStub).toHaveBeenCalled()
528
- expect(revealStub.calls.mostRecent().args[0]).toBeMatchedBy('.error')
569
+ expect(revealStub.calls.mostRecent().args[0]).toMatchSelector('.error')
529
570
 
530
571
  it 'allows to refer to this form as "&" in the selector', asyncSpec (next) ->
531
- $form = affix('form#foo-form[action="/action"][up-target=".target"][up-fail-reveal="#foo-form .form-child"]')
532
- $target = affix('.target')
572
+ $form = $fixture('form#foo-form[action="/action"][up-target=".target"][up-fail-reveal="#foo-form .form-child"]')
573
+ $target = $fixture('.target')
533
574
 
534
- revealStub = up.layout.knife.mock('reveal')
575
+ revealStub = up.viewport.knife.mock('reveal')
535
576
 
536
577
  up.submit($form, reveal: '& .form-child')
537
578
 
@@ -550,7 +591,7 @@ describe 'up.form', ->
550
591
 
551
592
  next =>
552
593
  expect(revealStub).toHaveBeenCalled()
553
- expect(revealStub.calls.mostRecent().args[0]).toEqual($('#foo-form .form-child'))
594
+ expect(revealStub.calls.mostRecent().args[0]).toEqual(e.first('#foo-form .form-child'))
554
595
 
555
596
  describe 'in a form with file inputs', ->
556
597
 
@@ -567,7 +608,7 @@ describe 'up.form', ->
567
608
  describeFallback 'canPushState', ->
568
609
 
569
610
  it 'falls back to a vanilla form submission', asyncSpec (next) ->
570
- $form = affix('form[action="/path/to"][method="put"][up-target=".response"]')
611
+ $form = $fixture('form[action="/path/to"][method="put"][up-target=".response"]')
571
612
  form = $form.get(0)
572
613
  spyOn(form, 'submit')
573
614
 
@@ -582,9 +623,9 @@ describe 'up.form', ->
582
623
  it 'submits the form with AJAX and replaces the [up-target] selector', asyncSpec (next) ->
583
624
  up.history.config.enabled = true
584
625
 
585
- affix('.response').text('old text')
626
+ $fixture('.response').text('old text')
586
627
 
587
- $form = affix('form[action="/form-target"][method="put"][up-target=".response"]')
628
+ $form = $fixture('form[action="/form-target"][method="put"][up-target=".response"]')
588
629
  $form.append('<input name="field1" value="value1">')
589
630
  $form.append('<input name="field2" value="value2">')
590
631
  $submitButton = $form.affix('input[type="submit"][name="submit-button"][value="submit-button-value"]')
@@ -608,7 +649,7 @@ describe 'up.form', ->
608
649
  expect('.response').toHaveText('new text')
609
650
 
610
651
  it 'allows to refer to this form as "&" in the target selector', asyncSpec (next) ->
611
- $form = affix('form.my-form[action="/form-target"][up-target="&"]').text('old form text')
652
+ $form = $fixture('form.my-form[action="/form-target"][up-target="&"]').text('old form text')
612
653
  $submitButton = $form.affix('input[type="submit"]')
613
654
  up.hello($form)
614
655
 
@@ -629,9 +670,9 @@ describe 'up.form', ->
629
670
  it 'replaces the form instead of the [up-target] selector', asyncSpec (next) ->
630
671
  up.history.config.enabled = true
631
672
 
632
- affix('.response').text('old text')
673
+ $fixture('.response').text('old text')
633
674
 
634
- $form = affix('form.test-form[action="/form-target"][method="put"][up-target=".response"]')
675
+ $form = $fixture('form.test-form[action="/form-target"][method="put"][up-target=".response"]')
635
676
  $form.append('<input name="field1" value="value1">')
636
677
  $form.append('<input name="field2" value="value2">')
637
678
  $submitButton = $form.affix('input[type="submit"][name="submit-button"][value="submit-button-value"]')
@@ -662,9 +703,9 @@ describe 'up.form', ->
662
703
  expect(window).not.toHaveUnhandledRejections() if REJECTION_EVENTS_SUPPORTED
663
704
 
664
705
  it 'updates a given selector when an [up-fail-target] is given', asyncSpec (next) ->
665
- $form = affix('form.my-form[action="/path"][up-target=".target"][up-fail-target=".errors"]').text('old form text')
666
- $errors = affix('.target').text('old target text')
667
- $errors = affix('.errors').text('old errors text')
706
+ $form = $fixture('form.my-form[action="/path"][up-target=".target"][up-fail-target=".errors"]').text('old form text')
707
+ $errors = $fixture('.target').text('old target text')
708
+ $errors = $fixture('.errors').text('old errors text')
668
709
 
669
710
  $submitButton = $form.affix('input[type="submit"]')
670
711
  up.hello($form)
@@ -690,8 +731,8 @@ describe 'up.form', ->
690
731
  expect('.errors').toHaveText('new errors text')
691
732
 
692
733
  it 'allows to refer to this form as "&" in the [up-fail-target] selector', asyncSpec (next) ->
693
- $form = affix('form.my-form[action="/form-target"][up-target=".target"][up-fail-target="&"]').text('old form text')
694
- $target = affix('.target').text('old target text')
734
+ $form = $fixture('form.my-form[action="/form-target"][up-target=".target"][up-fail-target="&"]').text('old form text')
735
+ $target = $fixture('.target').text('old target text')
695
736
 
696
737
  $submitButton = $form.affix('input[type="submit"]')
697
738
  up.hello($form)
@@ -714,7 +755,7 @@ describe 'up.form', ->
714
755
  describe 'submit buttons', ->
715
756
 
716
757
  it 'includes the clicked submit button in the params', asyncSpec (next) ->
717
- $form = affix('form[action="/action"][up-target=".target"]')
758
+ $form = $fixture('form[action="/action"][up-target=".target"]')
718
759
  $textField = $form.affix('input[type="text"][name="text-field"][value="text-field-value"]')
719
760
  $submitButton = $form.affix('input[type="submit"][name="submit-button"][value="submit-button-value"]')
720
761
  up.hello($form)
@@ -726,7 +767,7 @@ describe 'up.form', ->
726
767
  expect(params['submit-button']).toEqual(['submit-button-value'])
727
768
 
728
769
  it 'excludes an unused submit button in the params', asyncSpec (next) ->
729
- $form = affix('form[action="/action"][up-target=".target"]')
770
+ $form = $fixture('form[action="/action"][up-target=".target"]')
730
771
  $textField = $form.affix('input[type="text"][name="text-field"][value="text-field-value"]')
731
772
  $submitButton1 = $form.affix('input[type="submit"][name="submit-button-1"][value="submit-button-1-value"]')
732
773
  $submitButton2 = $form.affix('input[type="submit"][name="submit-button-2"][value="submit-button-2-value"]')
@@ -740,12 +781,13 @@ describe 'up.form', ->
740
781
  expect(params['submit-button-2']).toEqual(['submit-button-2-value'])
741
782
 
742
783
  it 'includes the first submit button if the form was submitted with enter', asyncSpec (next) ->
743
- $form = affix('form[action="/action"][up-target=".target"]')
784
+ $form = $fixture('form[action="/action"][up-target=".target"]')
744
785
  $textField = $form.affix('input[type="text"][name="text-field"][value="text-field-value"]')
745
786
  $submitButton1 = $form.affix('input[type="submit"][name="submit-button-1"][value="submit-button-1-value"]')
746
787
  $submitButton2 = $form.affix('input[type="submit"][name="submit-button-2"][value="submit-button-2-value"]')
747
788
  up.hello($form)
748
- $form.submit() # sorry
789
+
790
+ Trigger.submit($form) # sorry
749
791
 
750
792
  next =>
751
793
  params = @lastRequest().data()
@@ -754,10 +796,11 @@ describe 'up.form', ->
754
796
  expect(params['submit-button-2']).toBeUndefined()
755
797
 
756
798
  it 'does not explode if the form has no submit buttons', asyncSpec (next) ->
757
- $form = affix('form[action="/action"][up-target=".target"]')
799
+ $form = $fixture('form[action="/action"][up-target=".target"]')
758
800
  $textField = $form.affix('input[type="text"][name="text-field"][value="text-field-value"]')
759
801
  up.hello($form)
760
- $form.submit() # sorry
802
+
803
+ Trigger.submit($form) # sorry
761
804
 
762
805
  next =>
763
806
  params = @lastRequest().data()
@@ -767,52 +810,36 @@ describe 'up.form', ->
767
810
  describe 'input[up-autosubmit]', ->
768
811
 
769
812
  it 'submits the form when a change is observed in the given form field', asyncSpec (next) ->
770
- $form = affix('form')
771
- $field = $form.affix('input[up-autosubmit][val="old-value"]')
813
+ $form = $fixture('form')
814
+ $field = $form.affix('input[up-autosubmit][name="input-name"][value="old-value"]')
772
815
  up.hello($field)
773
816
  submitSpy = up.form.knife.mock('submit').and.returnValue(u.unresolvablePromise())
774
817
  $field.val('new-value')
775
- $field.trigger('change')
818
+ Trigger.change($field)
776
819
  next => expect(submitSpy).toHaveBeenCalled()
777
820
 
778
- it 'marks the field with an .up-active class while the form is submitting', asyncSpec (next) ->
779
- $form = affix('form')
780
- $field = $form.affix('input[up-autosubmit][val="old-value"]')
781
- up.hello($field)
782
- submission = u.newDeferred()
783
- submitSpy = up.form.knife.mock('submit').and.returnValue(submission)
784
- $field.val('new-value')
785
- $field.trigger('change')
786
- next =>
787
- expect(submitSpy).toHaveBeenCalled()
788
- expect($field).toHaveClass('up-active')
789
- submission.resolve()
790
-
791
- next =>
792
- expect($field).not.toHaveClass('up-active')
793
-
794
821
  describe 'form[up-autosubmit]', ->
795
822
 
796
823
  it 'submits the form when a change is observed in any of its fields', asyncSpec (next) ->
797
- $form = affix('form[up-autosubmit]')
798
- $field = $form.affix('input[val="old-value"]')
824
+ $form = $fixture('form[up-autosubmit]')
825
+ $field = $form.affix('input[name="input-name"][value="old-value"]')
799
826
  up.hello($form)
800
827
  submitSpy = up.form.knife.mock('submit').and.returnValue(u.unresolvablePromise())
801
828
  $field.val('new-value')
802
- $field.trigger('change')
829
+ Trigger.change($field)
803
830
  next => expect(submitSpy).toHaveBeenCalled()
804
831
 
805
832
  describe 'with [up-delay] modifier', ->
806
833
 
807
834
  it 'debounces the form submission', asyncSpec (next) ->
808
- $form = affix('form[up-autosubmit][up-delay="50"]')
809
- $field = $form.affix('input[val="old-value"]')
835
+ $form = $fixture('form[up-autosubmit][up-delay="50"]')
836
+ $field = $form.affix('input[name="input-name"][value="old-value"]')
810
837
  up.hello($form)
811
838
  submitSpy = up.form.knife.mock('submit').and.returnValue(u.unresolvablePromise())
812
839
  $field.val('new-value-1')
813
- $field.trigger('change')
840
+ Trigger.change($field)
814
841
  $field.val('new-value-2')
815
- $field.trigger('change')
842
+ Trigger.change($field)
816
843
 
817
844
  next =>
818
845
  expect(submitSpy.calls.count()).toBe(0)
@@ -826,25 +853,25 @@ describe 'up.form', ->
826
853
  window.observeCallbackSpy = undefined
827
854
 
828
855
  it 'runs the JavaScript code in the attribute value when a change is observed in the field', asyncSpec (next) ->
829
- $form = affix('form')
856
+ $form = $fixture('form')
830
857
  window.observeCallbackSpy = jasmine.createSpy('observe callback')
831
- $field = $form.affix('input[val="old-value"][up-observe="window.observeCallbackSpy(value, $field.get(0))"]')
858
+ $field = $form.affix('input[name="input-name"][value="old-value"][up-observe="window.observeCallbackSpy(value, name)"]')
832
859
  up.hello($form)
833
860
  $field.val('new-value')
834
- $field.trigger('change')
861
+ Trigger.change($field)
835
862
 
836
863
  next =>
837
- expect(window.observeCallbackSpy).toHaveBeenCalledWith('new-value', $field.get(0))
864
+ expect(window.observeCallbackSpy).toHaveBeenCalledWith('new-value', 'input-name')
838
865
 
839
866
  describe 'with [up-delay] modifier', ->
840
867
 
841
868
  it 'debounces the callback', asyncSpec (next) ->
842
- $form = affix('form')
869
+ $form = $fixture('form')
843
870
  window.observeCallbackSpy = jasmine.createSpy('observe callback')
844
- $field = $form.affix('input[val="old-value"][up-observe="window.observeCallbackSpy()"][up-delay="50"]')
871
+ $field = $form.affix('input[name="input-name"][value="old-value"][up-observe="window.observeCallbackSpy()"][up-delay="50"]')
845
872
  up.hello($form)
846
873
  $field.val('new-value')
847
- $field.trigger('change')
874
+ Trigger.change($field)
848
875
 
849
876
  next => expect(window.observeCallbackSpy).not.toHaveBeenCalled()
850
877
  next.after 80, => expect(window.observeCallbackSpy).toHaveBeenCalled()
@@ -856,21 +883,26 @@ describe 'up.form', ->
856
883
 
857
884
  it 'runs the JavaScript code in the attribute value when a change is observed in any contained field', asyncSpec (next) ->
858
885
  window.observeCallbackSpy = jasmine.createSpy('observe callback')
859
- $form = affix('form[up-observe="window.observeCallbackSpy(value, $field.get(0))"]')
860
- $field1 = $form.affix('input[val="field1-old-value"]')
861
- $field2 = $form.affix('input[val="field2-old-value"]')
886
+ $form = $fixture('form[up-observe="window.observeCallbackSpy(value, name)"]')
887
+ $field1 = $form.affix('input[name="field1"][value="field1-old-value"]')
888
+ $field2 = $form.affix('input[name="field2"][value="field2-old-value"]')
862
889
  up.hello($form)
863
890
  $field1.val('field1-new-value')
864
- $field1.trigger('change')
891
+ Trigger.change($field1)
865
892
 
866
893
  next =>
867
- expect(window.observeCallbackSpy.calls.allArgs()).toEqual [['field1-new-value', $field1.get(0)]]
894
+ expect(window.observeCallbackSpy.calls.allArgs()).toEqual [
895
+ ['field1-new-value', 'field1']
896
+ ]
868
897
 
869
898
  $field2.val('field2-new-value')
870
- $field2.trigger('change')
899
+ Trigger.change($field2)
871
900
 
872
901
  next =>
873
- expect(window.observeCallbackSpy.calls.allArgs()).toEqual [['field1-new-value', $field1.get(0)], ['field2-new-value', $field2.get(0)]]
902
+ expect(window.observeCallbackSpy.calls.allArgs()).toEqual [
903
+ ['field1-new-value', 'field1'],
904
+ ['field2-new-value', 'field2']
905
+ ]
874
906
 
875
907
  describe 'input[up-validate]', ->
876
908
 
@@ -878,13 +910,14 @@ describe 'up.form', ->
878
910
 
879
911
  it "submits the input's form with an 'X-Up-Validate' header and replaces the selector with the response", asyncSpec (next) ->
880
912
 
881
- $form = affix('form[action="/path/to"]')
913
+ $form = $fixture('form[action="/path/to"]')
882
914
  $group = $("""
883
915
  <div class="field-group">
884
916
  <input name="user" value="judy" up-validate=".field-group:has(&)">
885
917
  </div>
886
918
  """).appendTo($form)
887
- $group.find('input').trigger('change')
919
+
920
+ Trigger.change($group.find('input'))
888
921
 
889
922
  next =>
890
923
  request = @lastRequest()
@@ -911,15 +944,15 @@ describe 'up.form', ->
911
944
  expect(window).not.toHaveUnhandledRejections() if REJECTION_EVENTS_SUPPORTED
912
945
 
913
946
  it 'does not reveal the updated fragment (bugfix)', asyncSpec (next) ->
914
- revealSpy = up.layout.knife.mock('reveal').and.returnValue(Promise.resolve())
947
+ revealSpy = up.viewport.knife.mock('reveal').and.returnValue(Promise.resolve())
915
948
 
916
- $form = affix('form[action="/path/to"]')
949
+ $form = $fixture('form[action="/path/to"]')
917
950
  $group = $("""
918
951
  <div class="field-group">
919
952
  <input name="user" value="judy" up-validate=".field-group:has(&)">
920
953
  </div>
921
954
  """).appendTo($form)
922
- $group.find('input').trigger('change')
955
+ Trigger.change($group.find('input'))
923
956
 
924
957
  next =>
925
958
  @respondWith """
@@ -936,8 +969,8 @@ describe 'up.form', ->
936
969
  describe 'when no selector is given', ->
937
970
 
938
971
  it 'automatically finds a form group around the input field and only updates that', asyncSpec (next) ->
939
-
940
- @appendFixture """
972
+ container = fixture('.container')
973
+ container.innerHTML = """
941
974
  <form action="/users" id="registration">
942
975
 
943
976
  <label>
@@ -951,7 +984,7 @@ describe 'up.form', ->
951
984
  </form>
952
985
  """
953
986
 
954
- $('#registration input[name=password]').trigger('change')
987
+ Trigger.change $('#registration input[name=password]')
955
988
 
956
989
  next =>
957
990
  @respondWith """
@@ -980,63 +1013,68 @@ describe 'up.form', ->
980
1013
  describe 'on a select', ->
981
1014
 
982
1015
  beforeEach ->
983
- @$select = affix('select[up-switch=".target"]')
1016
+ @$select = $fixture('select[name="select-name"][up-switch=".target"]')
984
1017
  @$blankOption = @$select.affix('option').text('<Please select something>').val('')
985
1018
  @$fooOption = @$select.affix('option[value="foo"]').text('Foo')
986
1019
  @$barOption = @$select.affix('option[value="bar"]').text('Bar')
987
1020
  @$bazOption = @$select.affix('option[value="baz"]').text('Baz')
988
1021
 
989
1022
  it "shows the target element iff its up-show-for attribute contains the select value", asyncSpec (next) ->
990
- $target = affix('.target[up-show-for="something bar other"]')
1023
+ $target = $fixture('.target[up-show-for="something bar other"]')
991
1024
  up.hello(@$select)
992
1025
 
993
1026
  next =>
994
1027
  expect($target).toBeHidden()
995
- @$select.val('bar').change()
1028
+ @$select.val('bar')
1029
+ Trigger.change(@$select)
996
1030
 
997
1031
  next =>
998
1032
  expect($target).toBeVisible()
999
1033
 
1000
1034
  it "shows the target element iff its up-hide-for attribute doesn't contain the select value", asyncSpec (next) ->
1001
- $target = affix('.target[up-hide-for="something bar other"]')
1035
+ $target = $fixture('.target[up-hide-for="something bar other"]')
1002
1036
  up.hello(@$select)
1003
1037
 
1004
1038
  next =>
1005
1039
  expect($target).toBeVisible()
1006
- @$select.val('bar').change()
1040
+ @$select.val('bar')
1041
+ Trigger.change(@$select)
1007
1042
 
1008
1043
  next =>
1009
1044
  expect($target).toBeHidden()
1010
1045
 
1011
1046
  it "shows the target element iff it has neither up-show-for nor up-hide-for and the select value is present", asyncSpec (next) ->
1012
- $target = affix('.target')
1047
+ $target = $fixture('.target')
1013
1048
  up.hello(@$select)
1014
1049
 
1015
1050
  next =>
1016
1051
  expect($target).toBeHidden()
1017
- @$select.val('bar').change()
1052
+ @$select.val('bar')
1053
+ Trigger.change(@$select)
1018
1054
 
1019
1055
  next =>
1020
1056
  expect($target).toBeVisible()
1021
1057
 
1022
1058
  it "shows the target element iff its up-show-for attribute contains a value ':present' and the select value is present", asyncSpec (next) ->
1023
- $target = affix('.target[up-show-for=":present"]')
1059
+ $target = $fixture('.target[up-show-for=":present"]')
1024
1060
  up.hello(@$select)
1025
1061
 
1026
1062
  next =>
1027
1063
  expect($target).toBeHidden()
1028
- @$select.val('bar').change()
1064
+ @$select.val('bar')
1065
+ Trigger.change(@$select)
1029
1066
 
1030
1067
  next =>
1031
1068
  expect($target).toBeVisible()
1032
1069
 
1033
1070
  it "shows the target element iff its up-show-for attribute contains a value ':blank' and the select value is blank", asyncSpec (next) ->
1034
- $target = affix('.target[up-show-for=":blank"]')
1071
+ $target = $fixture('.target[up-show-for=":blank"]')
1035
1072
  up.hello(@$select)
1036
1073
 
1037
1074
  next =>
1038
1075
  expect($target).toBeVisible()
1039
- @$select.val('bar').change()
1076
+ @$select.val('bar')
1077
+ Trigger.change(@$select)
1040
1078
 
1041
1079
  next =>
1042
1080
  expect($target).toBeHidden()
@@ -1044,59 +1082,64 @@ describe 'up.form', ->
1044
1082
  describe 'on a checkbox', ->
1045
1083
 
1046
1084
  beforeEach ->
1047
- @$checkbox = affix('input[type="checkbox"][value="1"][up-switch=".target"]')
1085
+ @$checkbox = $fixture('input[name="input-name"][type="checkbox"][value="1"][up-switch=".target"]')
1048
1086
 
1049
1087
  it "shows the target element iff its up-show-for attribute is :checked and the checkbox is checked", asyncSpec (next) ->
1050
- $target = affix('.target[up-show-for=":checked"]')
1088
+ $target = $fixture('.target[up-show-for=":checked"]')
1051
1089
  up.hello(@$checkbox)
1052
1090
 
1053
1091
  next =>
1054
1092
  expect($target).toBeHidden()
1055
- @$checkbox.prop('checked', true).change()
1093
+ @$checkbox.prop('checked', true)
1094
+ Trigger.change(@$checkbox)
1056
1095
 
1057
1096
  next =>
1058
1097
  expect($target).toBeVisible()
1059
1098
 
1060
1099
  it "shows the target element iff its up-show-for attribute is :unchecked and the checkbox is unchecked", asyncSpec (next) ->
1061
- $target = affix('.target[up-show-for=":unchecked"]')
1100
+ $target = $fixture('.target[up-show-for=":unchecked"]')
1062
1101
  up.hello(@$checkbox)
1063
1102
 
1064
1103
  next =>
1065
1104
  expect($target).toBeVisible()
1066
- @$checkbox.prop('checked', true).change()
1105
+ @$checkbox.prop('checked', true)
1106
+ Trigger.change(@$checkbox)
1067
1107
 
1068
1108
  next =>
1069
1109
  expect($target).toBeHidden()
1070
1110
 
1071
1111
  it "shows the target element iff its up-hide-for attribute is :checked and the checkbox is unchecked", asyncSpec (next) ->
1072
- $target = affix('.target[up-hide-for=":checked"]')
1112
+ $target = $fixture('.target[up-hide-for=":checked"]')
1073
1113
  up.hello(@$checkbox)
1074
1114
 
1075
1115
  next =>
1076
1116
  expect($target).toBeVisible()
1077
- @$checkbox.prop('checked', true).change()
1117
+ @$checkbox.prop('checked', true)
1118
+ Trigger.change(@$checkbox)
1078
1119
 
1079
1120
  next =>
1080
1121
  expect($target).toBeHidden()
1081
1122
 
1082
1123
  it "shows the target element iff its up-hide-for attribute is :unchecked and the checkbox is checked", asyncSpec (next) ->
1083
- $target = affix('.target[up-hide-for=":unchecked"]')
1124
+ $target = $fixture('.target[up-hide-for=":unchecked"]')
1084
1125
  up.hello(@$checkbox)
1085
1126
 
1086
1127
  next =>
1087
1128
  expect($target).toBeHidden()
1088
- @$checkbox.prop('checked', true).change()
1129
+ @$checkbox.prop('checked', true)
1130
+ Trigger.change(@$checkbox)
1089
1131
 
1090
1132
  next =>
1091
1133
  expect($target).toBeVisible()
1092
1134
 
1093
1135
  it "shows the target element iff it has neither up-show-for nor up-hide-for and the checkbox is checked", asyncSpec (next) ->
1094
- $target = affix('.target')
1136
+ $target = $fixture('.target')
1095
1137
  up.hello(@$checkbox)
1096
1138
 
1097
1139
  next =>
1098
1140
  expect($target).toBeHidden()
1099
- @$checkbox.prop('checked', true).change()
1141
+ @$checkbox.prop('checked', true)
1142
+ Trigger.change(@$checkbox)
1100
1143
 
1101
1144
  next =>
1102
1145
  expect($target).toBeVisible()
@@ -1104,93 +1147,102 @@ describe 'up.form', ->
1104
1147
  describe 'on a group of radio buttons', ->
1105
1148
 
1106
1149
  beforeEach ->
1107
- @$buttons = affix('.radio-buttons')
1150
+ @$buttons = $fixture('.radio-buttons')
1108
1151
  @$blankButton = @$buttons.affix('input[type="radio"][name="group"][up-switch=".target"]').val('')
1109
1152
  @$fooButton = @$buttons.affix('input[type="radio"][name="group"][up-switch=".target"]').val('foo')
1110
1153
  @$barButton = @$buttons.affix('input[type="radio"][name="group"][up-switch=".target"]').val('bar')
1111
1154
  @$bazkButton = @$buttons.affix('input[type="radio"][name="group"][up-switch=".target"]').val('baz')
1112
1155
 
1113
1156
  it "shows the target element iff its up-show-for attribute contains the selected button value", asyncSpec (next) ->
1114
- $target = affix('.target[up-show-for="something bar other"]')
1157
+ $target = $fixture('.target[up-show-for="something bar other"]')
1115
1158
  up.hello(@$buttons)
1116
1159
 
1117
1160
  next =>
1118
1161
  expect($target).toBeHidden()
1119
- @$barButton.prop('checked', true).change()
1162
+ @$barButton.prop('checked', true)
1163
+ Trigger.change(@$barButton)
1120
1164
 
1121
1165
  next =>
1122
1166
  expect($target).toBeVisible()
1123
1167
 
1124
1168
  it "shows the target element iff its up-hide-for attribute doesn't contain the selected button value", asyncSpec (next) ->
1125
- $target = affix('.target[up-hide-for="something bar other"]')
1169
+ $target = $fixture('.target[up-hide-for="something bar other"]')
1126
1170
  up.hello(@$buttons)
1127
1171
 
1128
1172
  next =>
1129
1173
  expect($target).toBeVisible()
1130
- @$barButton.prop('checked', true).change()
1174
+ @$barButton.prop('checked', true)
1175
+ Trigger.change(@$barButton)
1131
1176
 
1132
1177
  next =>
1133
1178
  expect($target).toBeHidden()
1134
1179
 
1135
1180
  it "shows the target element iff it has neither up-show-for nor up-hide-for and the selected button value is present", asyncSpec (next) ->
1136
- $target = affix('.target')
1181
+ $target = $fixture('.target')
1137
1182
  up.hello(@$buttons)
1138
1183
 
1139
1184
  next =>
1140
1185
  expect($target).toBeHidden()
1141
- @$barButton.prop('checked', true).change()
1186
+ @$barButton.prop('checked', true)
1187
+ Trigger.change(@$barButton)
1142
1188
 
1143
1189
  next =>
1144
1190
  expect($target).toBeVisible()
1145
1191
 
1146
1192
  it "shows the target element iff its up-show-for attribute contains a value ':present' and the selected button value is present", asyncSpec (next) ->
1147
- $target = affix('.target[up-show-for=":present"]')
1193
+ $target = $fixture('.target[up-show-for=":present"]')
1148
1194
  up.hello(@$buttons)
1149
1195
 
1150
1196
  next =>
1151
1197
  expect($target).toBeHidden()
1152
- @$blankButton.prop('checked', true).change()
1198
+ @$blankButton.prop('checked', true)
1199
+ Trigger.change(@$blankButton)
1153
1200
 
1154
1201
  next =>
1155
1202
  expect($target).toBeHidden()
1156
- @$barButton.prop('checked', true).change()
1203
+ @$barButton.prop('checked', true)
1204
+ Trigger.change(@$barButton)
1157
1205
 
1158
1206
  next =>
1159
1207
  expect($target).toBeVisible()
1160
1208
 
1161
1209
  it "shows the target element iff its up-show-for attribute contains a value ':blank' and the selected button value is blank", asyncSpec (next) ->
1162
- $target = affix('.target[up-show-for=":blank"]')
1210
+ $target = $fixture('.target[up-show-for=":blank"]')
1163
1211
  up.hello(@$buttons)
1164
1212
 
1165
1213
  next =>
1166
1214
  expect($target).toBeVisible()
1167
- @$blankButton.prop('checked', true).change()
1215
+ @$blankButton.prop('checked', true)
1216
+ Trigger.change(@$blankButton)
1168
1217
 
1169
1218
  next =>
1170
1219
  expect($target).toBeVisible()
1171
- @$barButton.prop('checked', true).change()
1220
+ @$barButton.prop('checked', true)
1221
+ Trigger.change(@$barButton)
1172
1222
 
1173
1223
  next =>
1174
1224
  expect($target).toBeHidden()
1175
1225
 
1176
1226
  it "shows the target element iff its up-show-for attribute contains a value ':checked' and any button is checked", asyncSpec (next) ->
1177
- $target = affix('.target[up-show-for=":checked"]')
1227
+ $target = $fixture('.target[up-show-for=":checked"]')
1178
1228
  up.hello(@$buttons)
1179
1229
 
1180
1230
  next =>
1181
1231
  expect($target).toBeHidden()
1182
- @$blankButton.prop('checked', true).change()
1232
+ @$blankButton.prop('checked', true)
1233
+ Trigger.change(@$blankButton)
1183
1234
 
1184
1235
  next =>
1185
1236
  expect($target).toBeVisible()
1186
1237
 
1187
1238
  it "shows the target element iff its up-show-for attribute contains a value ':unchecked' and no button is checked", asyncSpec (next) ->
1188
- $target = affix('.target[up-show-for=":unchecked"]')
1239
+ $target = $fixture('.target[up-show-for=":unchecked"]')
1189
1240
  up.hello(@$buttons)
1190
1241
 
1191
1242
  next =>
1192
1243
  expect($target).toBeVisible()
1193
- @$blankButton.prop('checked', true).change()
1244
+ @$blankButton.prop('checked', true)
1245
+ Trigger.change(@$blankButton)
1194
1246
 
1195
1247
  next =>
1196
1248
  expect($target).toBeHidden()
@@ -1198,59 +1250,64 @@ describe 'up.form', ->
1198
1250
  describe 'on a text input', ->
1199
1251
 
1200
1252
  beforeEach ->
1201
- @$textInput = affix('input[type="text"][up-switch=".target"]')
1253
+ @$textInput = $fixture('input[name="input-name"][type="text"][up-switch=".target"]')
1202
1254
 
1203
1255
  it "shows the target element iff its up-show-for attribute contains the input value", asyncSpec (next) ->
1204
- $target = affix('.target[up-show-for="something bar other"]')
1256
+ $target = $fixture('.target[up-show-for="something bar other"]')
1205
1257
  up.hello(@$textInput)
1206
1258
 
1207
1259
  next =>
1208
1260
  expect($target).toBeHidden()
1209
- @$textInput.val('bar').change()
1261
+ @$textInput.val('bar')
1262
+ Trigger.change(@$textInput)
1210
1263
 
1211
1264
  next =>
1212
1265
  expect($target).toBeVisible()
1213
1266
 
1214
1267
  it "shows the target element iff its up-hide-for attribute doesn't contain the input value", asyncSpec (next) ->
1215
- $target = affix('.target[up-hide-for="something bar other"]')
1268
+ $target = $fixture('.target[up-hide-for="something bar other"]')
1216
1269
  up.hello(@$textInput)
1217
1270
 
1218
1271
  next =>
1219
1272
  expect($target).toBeVisible()
1220
- @$textInput.val('bar').change()
1273
+ @$textInput.val('bar')
1274
+ Trigger.change(@$textInput)
1221
1275
 
1222
1276
  next =>
1223
1277
  expect($target).toBeHidden()
1224
1278
 
1225
1279
  it "shows the target element iff it has neither up-show-for nor up-hide-for and the input value is present", asyncSpec (next) ->
1226
- $target = affix('.target')
1280
+ $target = $fixture('.target')
1227
1281
  up.hello(@$textInput)
1228
1282
 
1229
1283
  next =>
1230
1284
  expect($target).toBeHidden()
1231
- @$textInput.val('bar').change()
1285
+ @$textInput.val('bar')
1286
+ Trigger.change(@$textInput)
1232
1287
 
1233
1288
  next =>
1234
1289
  expect($target).toBeVisible()
1235
1290
 
1236
1291
  it "shows the target element iff its up-show-for attribute contains a value ':present' and the input value is present", asyncSpec (next) ->
1237
- $target = affix('.target[up-show-for=":present"]')
1292
+ $target = $fixture('.target[up-show-for=":present"]')
1238
1293
  up.hello(@$textInput)
1239
1294
 
1240
1295
  next =>
1241
1296
  expect($target).toBeHidden()
1242
- @$textInput.val('bar').change()
1297
+ @$textInput.val('bar')
1298
+ Trigger.change(@$textInput)
1243
1299
 
1244
1300
  next =>
1245
1301
  expect($target).toBeVisible()
1246
1302
 
1247
1303
  it "shows the target element iff its up-show-for attribute contains a value ':blank' and the input value is blank", asyncSpec (next) ->
1248
- $target = affix('.target[up-show-for=":blank"]')
1304
+ $target = $fixture('.target[up-show-for=":blank"]')
1249
1305
  up.hello(@$textInput)
1250
1306
 
1251
1307
  next =>
1252
1308
  expect($target).toBeVisible()
1253
- @$textInput.val('bar').change()
1309
+ @$textInput.val('bar')
1310
+ Trigger.change(@$textInput)
1254
1311
 
1255
1312
  next =>
1256
1313
  expect($target).toBeHidden()
@@ -1258,7 +1315,7 @@ describe 'up.form', ->
1258
1315
  describe 'when an [up-show-for] element is dynamically inserted later', ->
1259
1316
 
1260
1317
  it "shows the element iff it matches the [up-switch] control's value", asyncSpec (next) ->
1261
- $select = affix('select[up-switch=".target"]')
1318
+ $select = $fixture('select[name="select-name"][up-switch=".target"]')
1262
1319
  $select.affix('option[value="foo"]').text('Foo')
1263
1320
  $select.affix('option[value="bar"]').text('Bar')
1264
1321
  $select.val('foo')
@@ -1266,7 +1323,7 @@ describe 'up.form', ->
1266
1323
 
1267
1324
  next =>
1268
1325
  # New target enters the DOM after [up-switch] has been compiled
1269
- @$target = affix('.target[up-show-for="bar"]')
1326
+ @$target = $fixture('.target[up-show-for="bar"]')
1270
1327
  up.hello(@$target)
1271
1328
 
1272
1329
  next =>
@@ -1274,13 +1331,14 @@ describe 'up.form', ->
1274
1331
 
1275
1332
  next =>
1276
1333
  # Check that the new element will notify subsequent changes
1277
- $select.val('bar').change()
1334
+ $select.val('bar')
1335
+ Trigger.change($select)
1278
1336
  expect(@$target).toBeVisible()
1279
1337
 
1280
1338
  it "doesn't re-switch targets that were part of the original compile run", asyncSpec (next) ->
1281
- $container = affix('.container')
1339
+ $container = $fixture('.container')
1282
1340
 
1283
- $select = $container.affix('select[up-switch=".target"]')
1341
+ $select = $container.affix('select[name="select-name"][up-switch=".target"]')
1284
1342
  $select.affix('option[value="foo"]').text('Foo')
1285
1343
  $select.affix('option[value="bar"]').text('Bar')
1286
1344
  $select.val('foo')
@@ -1297,5 +1355,5 @@ describe 'up.form', ->
1297
1355
 
1298
1356
  next =>
1299
1357
  expect(switchTargetSpy.calls.count()).toBe(2)
1300
- expect(switchTargetSpy.calls.argsFor(0)[0]).toEqual($existingTarget)
1301
- expect(switchTargetSpy.calls.argsFor(1)[0]).toEqual(@$lateTarget)
1358
+ expect(switchTargetSpy.calls.argsFor(0)[0]).toEqual($existingTarget[0])
1359
+ expect(switchTargetSpy.calls.argsFor(1)[0]).toEqual(@$lateTarget[0])