upjs-rails 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -430,13 +430,12 @@ up.modal = (($) ->
430
430
  @param [up-history]
431
431
  @stable
432
432
  ###
433
- up.on('click', 'a[up-modal]', (event, $link) ->
433
+ up.link.registerFollowVariant '[up-modal]', ($link) ->
434
434
  event.preventDefault()
435
435
  if $link.is('.up-current')
436
436
  close()
437
437
  else
438
438
  follow($link)
439
- )
440
439
 
441
440
  # Close the modal when someone clicks outside the dialog
442
441
  # (but not on a modal opener).
@@ -119,14 +119,14 @@ up.navigation = (($) ->
119
119
  The user clicks on the link. While the request is loading,
120
120
  the link has the `up-active` class:
121
121
 
122
- <a href="/foo" up-follow up-active>Foo</a>
122
+ <a href="/foo" up-follow class="up-active">Foo</a>
123
123
 
124
124
  Once the link destination has loaded and rendered, the `up-active` class
125
125
  is removed and the [`up-current`](/up-current) class is added:
126
126
 
127
- <a href="/foo" up-follow up-current>Foo</a>
127
+ <a href="/foo" up-follow class="up-current">Foo</a>
128
128
 
129
- @selector [up-active]
129
+ @selector .up-active
130
130
  @stable
131
131
  ###
132
132
  sectionClicked = ($section) ->
@@ -162,7 +162,7 @@ up.navigation = (($) ->
162
162
  If the browser location changes to `/foo`, the markup changes to this:
163
163
 
164
164
  <nav>
165
- <a href="/foo" up-current>Foo</a>
165
+ <a href="/foo" class="up-current">Foo</a>
166
166
  <a href="/bar">Bar</a>
167
167
  </nav>
168
168
 
@@ -189,7 +189,7 @@ up.navigation = (($) ->
189
189
 
190
190
  <a href="/reports" up-alias="/reports/*">Reports</a>
191
191
 
192
- @selector [up-current]
192
+ @selector .up-current
193
193
  @stable
194
194
  ###
195
195
  up.on 'up:fragment:inserted', ->
@@ -330,8 +330,7 @@ up.popup = (($) ->
330
330
  open even if the page changes in the background.
331
331
  @stable
332
332
  ###
333
- up.on('click', 'a[up-popup]', (event, $link) ->
334
- event.preventDefault()
333
+ up.link.registerFollowVariant('[up-popup]', ($link) ->
335
334
  if $link.is('.up-current')
336
335
  close()
337
336
  else
@@ -383,6 +382,7 @@ up.popup = (($) ->
383
382
  # The framework is reset between tests
384
383
  up.on 'up:framework:reset', reset
385
384
 
385
+ knife: eval(Knife?.point)
386
386
  attach: attach
387
387
  close: close
388
388
  url: -> currentUrl
@@ -0,0 +1,18 @@
1
+ ###*
2
+ Play nice with Rails UJS
3
+ ========================
4
+ ###
5
+
6
+ up.rails = (($) ->
7
+
8
+ u = up.util
9
+
10
+ willHandle = ($element) ->
11
+ $element.is('[up-follow], [up-target], [up-modal], [up-popup]')
12
+
13
+ up.compiler '[data-method]', ($element) ->
14
+ if $.rails && willHandle($element)
15
+ u.setMissingAttrs($element, 'up-method': $element.attr('data-method'))
16
+ $element.removeAttr('data-method')
17
+
18
+ )(jQuery)
@@ -4,6 +4,6 @@ module Upjs
4
4
  # The current version of the upjs-rails gem.
5
5
  # This version number is also used for releases of the Up.js
6
6
  # frontend code.
7
- VERSION = '0.16.0'
7
+ VERSION = '0.17.0'
8
8
  end
9
9
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- upjs-rails (0.15.1)
4
+ upjs-rails (0.16.0)
5
5
  rails (>= 3)
6
6
 
7
7
  GEM
@@ -212,4 +212,4 @@ DEPENDENCIES
212
212
  web-console (~> 2.0)
213
213
 
214
214
  BUNDLED WITH
215
- 1.10.6
215
+ 1.11.2
@@ -51,9 +51,8 @@
51
51
  mock: mock
52
52
 
53
53
  reset = ->
54
- for cleaner in Knife.cleaners
55
- cleaner()
56
- Knife.cleaners = []
54
+ console.log("Reset with cleaners %o", Knife.cleaners)
55
+ cleaner() while cleaner = Knife.cleaners.pop()
57
56
 
58
57
  me = {}
59
58
  me.reset = reset
@@ -0,0 +1,2 @@
1
+ #afterEach ->
2
+ # Knife.reset()
@@ -40,6 +40,24 @@ describe 'up.form', ->
40
40
  expect(callback).not.toHaveBeenCalled()
41
41
  done()
42
42
 
43
+ it "runs a callback in the same frame if the delay is 0 and it receives a '#{eventName}' event", ->
44
+ $input = affix('input[value="old-value"]')
45
+ callback = jasmine.createSpy('change callback')
46
+ up.observe($input, { delay: 0 }, callback)
47
+ $input.val('new-value')
48
+ $input.trigger(eventName)
49
+ expect(callback.calls.count()).toEqual(1)
50
+
51
+ it "runs multiple callbacks in the same frame if the delay is 0 and it receives a '#{eventName}' event", ->
52
+ $input = affix('input[value="old-value"]')
53
+ callback = jasmine.createSpy('change callback')
54
+ up.observe($input, { delay: 0 }, callback)
55
+ $input.val('new-value')
56
+ $input.trigger(eventName)
57
+ $input.val('yet-another-value')
58
+ $input.trigger(eventName)
59
+ expect(callback.calls.count()).toEqual(2)
60
+
43
61
  describe 'when the first argument is a form', ->
44
62
 
45
63
  it "runs the callback when any of the form's inputs receives a '#{eventName}' event and the value changed", (done) ->
@@ -172,14 +172,94 @@ describe 'up.link', ->
172
172
  $form.click()
173
173
  expect(followSpy).not.toHaveBeenCalled()
174
174
 
175
+ it 'adds a history entry', ->
176
+ affix('.target')
177
+ $link = affix('a[href="/path"][up-target=".target"]')
178
+ $link.click()
179
+ @respondWith('<div class="target">new text</div>')
180
+ expect($('.target')).toHaveText('new text')
181
+ expect(location.pathname).toEqual('/path')
182
+
183
+ it 'respects a X-Up-Location header that the server sends in case of a redirect', ->
184
+ affix('.target')
185
+ $link = affix('a[href="/path"][up-target=".target"]')
186
+ $link.click()
187
+ @respondWith
188
+ responseText: '<div class="target">new text</div>'
189
+ responseHeaders: { 'X-Up-Location': '/other/path' }
190
+ expect($('.target')).toHaveText('new text')
191
+ expect(location.pathname).toEqual('/other/path')
192
+
193
+ it 'does not add a history entry when an up-history attribute is set to "false"', ->
194
+ oldPathname = location.pathname
195
+ affix('.target')
196
+ $link = affix('a[href="/path"][up-target=".target"][up-history="false"]')
197
+ $link.click()
198
+ @respondWith
199
+ responseText: '<div class="target">new text</div>'
200
+ responseHeaders: { 'X-Up-Location': '/other/path' }
201
+ expect($('.target')).toHaveText('new text')
202
+ expect(location.pathname).toEqual(oldPathname)
203
+
175
204
  describe 'a[up-follow]', ->
176
205
 
206
+ beforeEach ->
207
+ @$link = affix('a[href="/path"][up-follow]')
208
+ @followSpy = up.link.knife.mock('follow')
209
+ @defaultSpy = up.link.knife.mock('allowDefault').and.callFake((event) -> event.preventDefault())
210
+
177
211
  it "calls up.follow with the clicked link", ->
178
- followSpy = up.link.knife.mock('follow')
179
- $link = affix('a[href="/path"][up-follow]')
180
- up.hello($link)
181
- $link.click()
182
- expect(followSpy).toHaveBeenCalledWith($link)
212
+ Trigger.click(@$link)
213
+ expect(@followSpy).toHaveBeenCalledWith(@$link)
214
+
215
+ it 'does nothing if the right mouse button is used', ->
216
+ Trigger.click(@$link, button: 2)
217
+ expect(@followSpy).not.toHaveBeenCalled()
218
+
219
+ it 'does nothing if shift is pressed during the click', ->
220
+ Trigger.click(@$link, shiftKey: true)
221
+ expect(@followSpy).not.toHaveBeenCalled()
222
+
223
+ it 'does nothing if ctrl is pressed during the click', ->
224
+ Trigger.click(@$link, ctrlKey: true)
225
+ expect(@followSpy).not.toHaveBeenCalled()
226
+
227
+ # it 'does nothing if meta is pressed during the click', ->
228
+ # Trigger.click(@$link, metaKey: true)
229
+ # expect(@followSpy).not.toHaveBeenCalled()
230
+
231
+ describe 'with [up-instant] modifier', ->
232
+
233
+ beforeEach ->
234
+ @$link.attr('up-instant', '')
235
+
236
+ it 'follows a link on mousedown (instead of on click)', ->
237
+ Trigger.mousedown(@$link)
238
+ expect(@followSpy.calls.mostRecent().args[0]).toEqual(@$link)
239
+
240
+ it 'does nothing on mouseup', ->
241
+ Trigger.mouseup(@$link)
242
+ expect(@followSpy).not.toHaveBeenCalled()
243
+
244
+ it 'does nothing on click', ->
245
+ Trigger.click(@$link)
246
+ expect(@followSpy).not.toHaveBeenCalled()
247
+
248
+ it 'does nothing if the right mouse button is pressed down', ->
249
+ Trigger.mousedown(@$link, button: 2)
250
+ expect(@followSpy).not.toHaveBeenCalled()
251
+
252
+ it 'does nothing if shift is pressed during mousedown', ->
253
+ Trigger.mousedown(@$link, shiftKey: true)
254
+ expect(@followSpy).not.toHaveBeenCalled()
255
+
256
+ it 'does nothing if ctrl is pressed during mousedown', ->
257
+ Trigger.mousedown(@$link, ctrlKey: true)
258
+ expect(@followSpy).not.toHaveBeenCalled()
259
+
260
+ it 'does nothing if meta is pressed during mousedown', ->
261
+ Trigger.mousedown(@$link, metaKey: true)
262
+ expect(@followSpy).not.toHaveBeenCalled()
183
263
 
184
264
  describe '[up-expand]', ->
185
265
 
@@ -205,40 +285,3 @@ describe 'up.link', ->
205
285
  up.hello($area)
206
286
  expect($area.attr('up-follow')).toEqual('')
207
287
 
208
- describe '[up-instant]', ->
209
-
210
- beforeEach ->
211
- @$link = affix('a[href="/path"][up-follow][up-instant]')
212
- @followSpy = up.link.knife.mock('follow')
213
-
214
- afterEach ->
215
- Knife.reset()
216
-
217
- it 'follows a link on mousedown (instead of on click)', ->
218
- Trigger.mousedown(@$link)
219
- expect(@followSpy.calls.mostRecent().args[0]).toEqual(@$link)
220
-
221
- it 'does nothing on mouseup', ->
222
- Trigger.mouseup(@$link)
223
- expect(@followSpy).not.toHaveBeenCalled()
224
-
225
- it 'does nothing on click', ->
226
- Trigger.click(@$link)
227
- expect(@followSpy).not.toHaveBeenCalled()
228
-
229
- it 'does nothing if the right mouse button is pressed down', ->
230
- Trigger.mousedown(@$link, button: 2)
231
- expect(@followSpy).not.toHaveBeenCalled()
232
-
233
- it 'does nothing if shift is pressed during mousedown', ->
234
- Trigger.mousedown(@$link, shiftKey: true)
235
- expect(@followSpy).not.toHaveBeenCalled()
236
-
237
- it 'does nothing if ctrl is pressed during mousedown', ->
238
- Trigger.mousedown(@$link, ctrlKey: true)
239
- expect(@followSpy).not.toHaveBeenCalled()
240
-
241
- it 'does nothing if meta is pressed during mousedown', ->
242
- Trigger.mousedown(@$link, metaKey: true)
243
- expect(@followSpy).not.toHaveBeenCalled()
244
-
@@ -100,12 +100,64 @@ describe 'up.modal', ->
100
100
 
101
101
  describe 'a[up-modal]', ->
102
102
 
103
+ beforeEach ->
104
+ @$link = affix('a[href="/path"][up-modal=".target"]')
105
+ @followSpy = up.modal.knife.mock('follow')
106
+ @defaultSpy = up.link.knife.mock('allowDefault').and.callFake((event) -> event.preventDefault())
107
+
103
108
  it 'opens the clicked link in a modal', ->
104
- followSpy = up.modal.knife.mock('follow')
105
- $link = affix('a[href="/path"][up-modal=".foo"]')
106
- up.hello($link)
107
- $link.click()
108
- expect(followSpy).toHaveBeenCalledWith($link)
109
+ Trigger.click(@$link)
110
+ expect(@followSpy).toHaveBeenCalledWith(@$link)
111
+
112
+ it 'does nothing if the right mouse button is used', ->
113
+ Trigger.click(@$link, button: 2)
114
+ expect(@followSpy).not.toHaveBeenCalled()
115
+
116
+ it 'does nothing if shift is pressed during the click', ->
117
+ Trigger.click(@$link, shiftKey: true)
118
+ expect(@followSpy).not.toHaveBeenCalled()
119
+
120
+ it 'does nothing if ctrl is pressed during the click', ->
121
+ Trigger.click(@$link, ctrlKey: true)
122
+ expect(@followSpy).not.toHaveBeenCalled()
123
+
124
+ # it 'does nothing if meta is pressed during the click', ->
125
+ # Trigger.click(@$link, metaKey: true)
126
+ # expect(@followSpy).not.toHaveBeenCalled()
127
+
128
+ describe 'with [up-instant] modifier', ->
129
+
130
+ beforeEach ->
131
+ @$link.attr('up-instant', '')
132
+
133
+ it 'opens the modal on mousedown (instead of on click)', ->
134
+ Trigger.mousedown(@$link)
135
+ expect(@followSpy.calls.mostRecent().args[0]).toEqual(@$link)
136
+
137
+ it 'does nothing on mouseup', ->
138
+ Trigger.mouseup(@$link)
139
+ expect(@followSpy).not.toHaveBeenCalled()
140
+
141
+ it 'does nothing on click', ->
142
+ Trigger.click(@$link)
143
+ expect(@followSpy).not.toHaveBeenCalled()
144
+
145
+ it 'does nothing if the right mouse button is pressed down', ->
146
+ Trigger.mousedown(@$link, button: 2)
147
+ expect(@followSpy).not.toHaveBeenCalled()
148
+
149
+ it 'does nothing if shift is pressed during mousedown', ->
150
+ Trigger.mousedown(@$link, shiftKey: true)
151
+ expect(@followSpy).not.toHaveBeenCalled()
152
+
153
+ it 'does nothing if ctrl is pressed during mousedown', ->
154
+ Trigger.mousedown(@$link, ctrlKey: true)
155
+ expect(@followSpy).not.toHaveBeenCalled()
156
+
157
+ it 'does nothing if meta is pressed during mousedown', ->
158
+ Trigger.mousedown(@$link, metaKey: true)
159
+ expect(@followSpy).not.toHaveBeenCalled()
160
+
109
161
 
110
162
  describe '[up-close]', ->
111
163
 
@@ -70,7 +70,7 @@ describe 'up.navigation', ->
70
70
  $modalLink = affix('a[href="/bar"][up-modal=".main"]')
71
71
  $unrelatedLink = affix('a[href="/baz]')
72
72
 
73
- $modalLink.click()
73
+ Trigger.click($modalLink)
74
74
  @respondWith('<div class="main">new-text</div>')
75
75
  expect($backgroundLink).toHaveClass('up-current')
76
76
  expect($modalLink).toHaveClass('up-current')
@@ -6,6 +6,35 @@ describe 'up.popup', ->
6
6
 
7
7
  describe 'up.popup.attach', ->
8
8
 
9
+ it "loads this link's destination in a popup when clicked", ->
10
+ $link = affix('a[href="/path/to"][up-popup=".middle"]').text('link')
11
+ $link.css
12
+ position: 'fixed'
13
+ left: '100px'
14
+ top: '50px'
15
+
16
+ up.popup.attach($link)
17
+
18
+ expect(@lastRequest().url).toMatch /\/path\/to$/
19
+ @respondWith """
20
+ <div class="before">new-before</div>
21
+ <div class="middle">new-middle</div>
22
+ <div class="after">new-after</div>
23
+ """
24
+
25
+ $popup = $('.up-popup')
26
+
27
+ expect($popup).toExist()
28
+ expect($popup.find('.middle')).toHaveText('new-middle')
29
+ expect($popup.find('.before')).not.toExist()
30
+ expect($popup.find('.after')).not.toExist()
31
+
32
+ popupDims = u.measure($popup, full: true)
33
+ linkDims = u.measure($link, full: true)
34
+
35
+ expect(popupDims.right).toBeAround(linkDims.right, 1)
36
+ expect(popupDims.top).toBeAround(linkDims.top + linkDims.height, 1)
37
+
9
38
  it 'does not explode if the popup was closed before the response was received', ->
10
39
  $span = affix('span')
11
40
  up.popup.attach($span, url: '/foo', target: '.container')
@@ -40,32 +69,59 @@ describe 'up.popup', ->
40
69
 
41
70
  describe 'a[up-popup]', ->
42
71
 
43
- it "loads this link's destination in a popup when clicked", ->
44
- $link = affix('a[href="/path/to"][up-popup=".middle"]').text('link')
45
- $link.css
46
- position: 'fixed'
47
- left: '100px'
48
- top: '50px'
49
- $link.click()
50
- expect(@lastRequest().url).toMatch /\/path\/to$/
51
- @respondWith """
52
- <div class="before">new-before</div>
53
- <div class="middle">new-middle</div>
54
- <div class="after">new-after</div>
55
- """
72
+ beforeEach ->
73
+ @$link = affix('a[href="/path"][up-popup=".target"]')
74
+ @attachSpy = up.popup.knife.mock('attach')
75
+ @defaultSpy = up.link.knife.mock('allowDefault').and.callFake((event) -> event.preventDefault())
56
76
 
57
- $popup = $('.up-popup')
77
+ it 'opens the clicked link in a popup', ->
78
+ Trigger.click(@$link)
79
+ expect(@attachSpy).toHaveBeenCalledWith(@$link)
58
80
 
59
- expect($popup).toExist()
60
- expect($popup.find('.middle')).toHaveText('new-middle')
61
- expect($popup.find('.before')).not.toExist()
62
- expect($popup.find('.after')).not.toExist()
81
+ it 'does nothing if the right mouse button is used', ->
82
+ Trigger.click(@$link, button: 2)
83
+ expect(@attachSpy).not.toHaveBeenCalled()
63
84
 
64
- popupDims = u.measure($popup, full: true)
65
- linkDims = u.measure($link, full: true)
85
+ it 'does nothing if shift is pressed during the click', ->
86
+ Trigger.click(@$link, shiftKey: true)
87
+ expect(@attachSpy).not.toHaveBeenCalled()
66
88
 
67
- expect(popupDims.right).toBeAround(linkDims.right, 1)
68
- expect(popupDims.top).toBeAround(linkDims.top + linkDims.height, 1)
89
+ it 'does nothing if ctrl is pressed during the click', ->
90
+ Trigger.click(@$link, ctrlKey: true)
91
+ expect(@attachSpy).not.toHaveBeenCalled()
92
+
93
+ describe 'with [up-instant] modifier', ->
94
+
95
+ beforeEach ->
96
+ @$link.attr('up-instant', '')
97
+
98
+ it 'opens the modal on mousedown (instead of on click)', ->
99
+ Trigger.mousedown(@$link)
100
+ expect(@attachSpy.calls.mostRecent().args[0]).toEqual(@$link)
101
+
102
+ it 'does nothing on mouseup', ->
103
+ Trigger.mouseup(@$link)
104
+ expect(@attachSpy).not.toHaveBeenCalled()
105
+
106
+ it 'does nothing on click', ->
107
+ Trigger.click(@$link)
108
+ expect(@attachSpy).not.toHaveBeenCalled()
109
+
110
+ it 'does nothing if the right mouse button is pressed down', ->
111
+ Trigger.mousedown(@$link, button: 2)
112
+ expect(@attachSpy).not.toHaveBeenCalled()
113
+
114
+ it 'does nothing if shift is pressed during mousedown', ->
115
+ Trigger.mousedown(@$link, shiftKey: true)
116
+ expect(@attachSpy).not.toHaveBeenCalled()
117
+
118
+ it 'does nothing if ctrl is pressed during mousedown', ->
119
+ Trigger.mousedown(@$link, ctrlKey: true)
120
+ expect(@attachSpy).not.toHaveBeenCalled()
121
+
122
+ it 'does nothing if meta is pressed during mousedown', ->
123
+ Trigger.mousedown(@$link, metaKey: true)
124
+ expect(@attachSpy).not.toHaveBeenCalled()
69
125
 
70
126
  describe '[up-close]', ->
71
127