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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -1
- data/dist/up.js +126 -70
- data/dist/up.min.js +2 -2
- data/lib/assets/javascripts/up.js.coffee +1 -0
- data/lib/assets/javascripts/up/form.js.coffee +17 -15
- data/lib/assets/javascripts/up/link.js.coffee +74 -49
- data/lib/assets/javascripts/up/modal.js.coffee +1 -2
- data/lib/assets/javascripts/up/navigation.js.coffee +5 -5
- data/lib/assets/javascripts/up/popup.js.coffee +2 -2
- data/lib/assets/javascripts/up/rails.js.coffee +18 -0
- data/lib/upjs/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +2 -2
- data/spec_app/spec/javascripts/helpers/knife.js.coffee +2 -3
- data/spec_app/spec/javascripts/helpers/reset_knife.js.coffee +2 -0
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +18 -0
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +85 -42
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +57 -5
- data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +1 -1
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +78 -22
- data/spec_app/spec/javascripts/up/rails_spec.js.coffee +53 -0
- metadata +5 -2
@@ -430,13 +430,12 @@ up.modal = (($) ->
|
|
430
430
|
@param [up-history]
|
431
431
|
@stable
|
432
432
|
###
|
433
|
-
up.
|
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
|
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
|
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.
|
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)
|
data/lib/upjs/rails/version.rb
CHANGED
data/spec_app/Gemfile.lock
CHANGED
@@ -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
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
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
|
-
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
77
|
+
it 'opens the clicked link in a popup', ->
|
78
|
+
Trigger.click(@$link)
|
79
|
+
expect(@attachSpy).toHaveBeenCalledWith(@$link)
|
58
80
|
|
59
|
-
|
60
|
-
|
61
|
-
expect(
|
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
|
-
|
65
|
-
|
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
|
-
|
68
|
-
|
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
|
|