unpoly-rails 0.26.2 → 0.27.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -1
- data/dist/unpoly.js +704 -446
- data/dist/unpoly.min.js +3 -3
- data/lib/assets/javascripts/unpoly/browser.js.coffee +18 -9
- data/lib/assets/javascripts/unpoly/bus.js.coffee +28 -1
- data/lib/assets/javascripts/unpoly/flow.js.coffee +1 -1
- data/lib/assets/javascripts/unpoly/history.js.coffee +54 -22
- data/lib/assets/javascripts/unpoly/link.js.coffee +1 -1
- data/lib/assets/javascripts/unpoly/log.js.coffee +19 -12
- data/lib/assets/javascripts/unpoly/modal.js.coffee +119 -124
- data/lib/assets/javascripts/unpoly/motion.js.coffee +1 -0
- data/lib/assets/javascripts/unpoly/navigation.js.coffee +2 -6
- data/lib/assets/javascripts/unpoly/popup.js.coffee +136 -126
- data/lib/assets/javascripts/unpoly/proxy.js.coffee +0 -2
- data/lib/assets/javascripts/unpoly/syntax.js.coffee +1 -1
- data/lib/assets/javascripts/unpoly/tooltip.js.coffee +101 -46
- data/lib/assets/javascripts/unpoly/util.js.coffee +76 -7
- data/lib/unpoly/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +1 -1
- data/spec_app/app/assets/stylesheets/integration_test.sass +4 -0
- data/spec_app/app/assets/stylesheets/jasmine_specs.sass +5 -0
- data/spec_app/app/views/css_test/modal.erb +3 -0
- data/spec_app/app/views/css_test/modal_contents.erb +5 -0
- data/spec_app/app/views/css_test/popup.erb +11 -11
- data/spec_app/app/views/css_test/tooltip.erb +12 -5
- data/spec_app/app/views/pages/start.erb +4 -0
- data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +2 -3
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +97 -88
- data/spec_app/spec/javascripts/up/history_spec.js.coffee +100 -1
- data/spec_app/spec/javascripts/up/link_spec.js.coffee +18 -16
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +102 -97
- data/spec_app/spec/javascripts/up/motion_spec.js.coffee +89 -75
- data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +17 -5
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +89 -70
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +23 -0
- metadata +4 -2
@@ -37,7 +37,7 @@ describe 'up.history', ->
|
|
37
37
|
$element = up.hello(affix('a[href="/three"][up-back]').text('text'))
|
38
38
|
expect($element.attr('up-href')).toBeUndefined()
|
39
39
|
|
40
|
-
describe 'scroll
|
40
|
+
describe 'scroll restoration', ->
|
41
41
|
|
42
42
|
describeCapability 'canPushState', ->
|
43
43
|
|
@@ -96,3 +96,102 @@ describe 'up.history', ->
|
|
96
96
|
respond() # we need to respond since we've never requested /three with the popTarget
|
97
97
|
expect($('.viewport').scrollTop()).toBe(250)
|
98
98
|
done()
|
99
|
+
|
100
|
+
describe 'events', ->
|
101
|
+
|
102
|
+
describeCapability 'canPushState', ->
|
103
|
+
|
104
|
+
it 'emits up:history:* events as the user goes forwards and backwards through history', (done) ->
|
105
|
+
up.proxy.config.cacheSize = 0
|
106
|
+
up.history.config.popTargets = ['.viewport']
|
107
|
+
|
108
|
+
affix('.viewport .content')
|
109
|
+
respond = =>
|
110
|
+
@respondWith """
|
111
|
+
<div class="viewport">
|
112
|
+
<div class="content">content</div>
|
113
|
+
</div>
|
114
|
+
"""
|
115
|
+
|
116
|
+
events = []
|
117
|
+
u.each ['up:history:pushed', 'up:history:restored'], (eventName) ->
|
118
|
+
up.on eventName, (event) ->
|
119
|
+
events.push [eventName, event.url]
|
120
|
+
|
121
|
+
normalize = up.history.normalizeUrl
|
122
|
+
|
123
|
+
up.replace('.content', '/one')
|
124
|
+
respond()
|
125
|
+
|
126
|
+
expect(events).toEqual [
|
127
|
+
['up:history:pushed', normalize('/one')]
|
128
|
+
]
|
129
|
+
|
130
|
+
up.replace('.content', '/two')
|
131
|
+
respond()
|
132
|
+
|
133
|
+
expect(events).toEqual [
|
134
|
+
['up:history:pushed', normalize('/one')]
|
135
|
+
['up:history:pushed', normalize('/two')]
|
136
|
+
]
|
137
|
+
|
138
|
+
up.replace('.content', '/three')
|
139
|
+
respond()
|
140
|
+
|
141
|
+
expect(events).toEqual [
|
142
|
+
['up:history:pushed', normalize('/one')]
|
143
|
+
['up:history:pushed', normalize('/two')]
|
144
|
+
['up:history:pushed', normalize('/three')]
|
145
|
+
]
|
146
|
+
|
147
|
+
history.back()
|
148
|
+
u.setTimer 50, ->
|
149
|
+
respond()
|
150
|
+
|
151
|
+
expect(events).toEqual [
|
152
|
+
['up:history:pushed', normalize('/one')]
|
153
|
+
['up:history:pushed', normalize('/two')]
|
154
|
+
['up:history:pushed', normalize('/three')]
|
155
|
+
['up:history:restored', normalize('/two')]
|
156
|
+
]
|
157
|
+
|
158
|
+
history.back()
|
159
|
+
u.setTimer 50, ->
|
160
|
+
respond()
|
161
|
+
|
162
|
+
expect(events).toEqual [
|
163
|
+
['up:history:pushed', normalize('/one')]
|
164
|
+
['up:history:pushed', normalize('/two')]
|
165
|
+
['up:history:pushed', normalize('/three')]
|
166
|
+
['up:history:restored', normalize('/two')]
|
167
|
+
['up:history:restored', normalize('/one')]
|
168
|
+
]
|
169
|
+
|
170
|
+
history.forward()
|
171
|
+
u.setTimer 50, ->
|
172
|
+
respond()
|
173
|
+
|
174
|
+
expect(events).toEqual [
|
175
|
+
['up:history:pushed', normalize('/one')]
|
176
|
+
['up:history:pushed', normalize('/two')]
|
177
|
+
['up:history:pushed', normalize('/three')]
|
178
|
+
['up:history:restored', normalize('/two')]
|
179
|
+
['up:history:restored', normalize('/one')]
|
180
|
+
['up:history:restored', normalize('/two')]
|
181
|
+
]
|
182
|
+
|
183
|
+
history.forward()
|
184
|
+
u.setTimer 50, ->
|
185
|
+
respond() # we need to respond since we've never requested /three with the popTarget
|
186
|
+
|
187
|
+
expect(events).toEqual [
|
188
|
+
['up:history:pushed', normalize('/one')]
|
189
|
+
['up:history:pushed', normalize('/two')]
|
190
|
+
['up:history:pushed', normalize('/three')]
|
191
|
+
['up:history:restored', normalize('/two')]
|
192
|
+
['up:history:restored', normalize('/one')]
|
193
|
+
['up:history:restored', normalize('/two')]
|
194
|
+
['up:history:restored', normalize('/three')]
|
195
|
+
]
|
196
|
+
|
197
|
+
done()
|
@@ -367,22 +367,24 @@ describe 'up.link', ->
|
|
367
367
|
|
368
368
|
describe 'with [up-transition] modifier', ->
|
369
369
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
expect(u.opacity($
|
384
|
-
|
385
|
-
|
370
|
+
describeCapability 'canCssTransition', ->
|
371
|
+
|
372
|
+
it 'morphs between the old and new target element', (done) ->
|
373
|
+
affix('.target.old')
|
374
|
+
$link = affix('a[href="/path"][up-target=".target"][up-transition="cross-fade"][up-duration="300"][up-easing="linear"]')
|
375
|
+
$link.click()
|
376
|
+
@respondWith '<div class="target new">new text</div>'
|
377
|
+
|
378
|
+
$oldGhost = $('.target.old.up-ghost')
|
379
|
+
$newGhost = $('.target.new.up-ghost')
|
380
|
+
expect($oldGhost).toExist()
|
381
|
+
expect($newGhost).toExist()
|
382
|
+
expect(u.opacity($oldGhost)).toBeAround(1, 0.15)
|
383
|
+
expect(u.opacity($newGhost)).toBeAround(0, 0.15)
|
384
|
+
u.setTimer 150, ->
|
385
|
+
expect(u.opacity($oldGhost)).toBeAround(0.5, 0.15)
|
386
|
+
expect(u.opacity($newGhost)).toBeAround(0.5, 0.15)
|
387
|
+
done()
|
386
388
|
|
387
389
|
it 'does not add a history entry when an up-history attribute is set to "false"', ->
|
388
390
|
oldPathname = location.pathname
|
@@ -68,20 +68,21 @@ describe 'up.modal', ->
|
|
68
68
|
expect(parseInt($body.css('padding-right'))).toBe(0)
|
69
69
|
done()
|
70
70
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
openPromise.then ->
|
78
|
-
expect($modal.css('overflow-y')).toEqual('auto')
|
79
|
-
expect($viewport.css('overflow-y')).toEqual('scroll')
|
80
|
-
closePromise = up.modal.close(animation: 'fade-out', duration: 100)
|
71
|
+
describeCapability 'canCssTransition', ->
|
72
|
+
|
73
|
+
it "gives the scrollbar to .up-modal instead of .up-modal-viewport while animating, so we don't see scaled scrollbars in a zoom-in animation", (done) ->
|
74
|
+
openPromise = up.modal.extract('.container', '<div class="container">text</div>', animation: 'fade-in', duration: 100)
|
75
|
+
$modal = $('.up-modal')
|
76
|
+
$viewport = $modal.find('.up-modal-viewport')
|
81
77
|
expect($modal.css('overflow-y')).toEqual('scroll')
|
82
78
|
expect($viewport.css('overflow-y')).toEqual('hidden')
|
83
|
-
|
84
|
-
|
79
|
+
openPromise.then ->
|
80
|
+
expect($modal.css('overflow-y')).not.toEqual('scroll')
|
81
|
+
expect($viewport.css('overflow-y')).toEqual('scroll')
|
82
|
+
closePromise = up.modal.close(animation: 'fade-out', duration: 100)
|
83
|
+
expect($modal.css('overflow-y')).toEqual('scroll')
|
84
|
+
expect($viewport.css('overflow-y')).toEqual('hidden')
|
85
|
+
done()
|
85
86
|
|
86
87
|
it 'does not add right padding to the body if the body has overflow-y: hidden', (done) ->
|
87
88
|
restoreBody = u.temporaryCss($('body'), 'overflow-y': 'hidden')
|
@@ -133,99 +134,95 @@ describe 'up.modal', ->
|
|
133
134
|
|
134
135
|
it 'does not open multiple modals or pad the body twice if the user starts loading a second modal before the first was done loading', (done) ->
|
135
136
|
up.modal.config.closeDuration = 10
|
136
|
-
promise1 = up.modal.visit('/path1', target: '.container', animation: 'fade-in', duration:
|
137
|
-
promise2 = up.modal.visit('/path2', target: '.container', animation: 'fade-in', duration:
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
bodyPadding = parseInt($('body').css('padding-right'))
|
151
|
-
expect(bodyPadding).toBeAround(assumedScrollbarWidth, 10)
|
152
|
-
expect(bodyPadding).not.toBeAround(2 * assumedScrollbarWidth, 2 * 5)
|
153
|
-
done()
|
154
|
-
|
155
|
-
it 'closes the current modal and wait for its close animation to finish before starting the open animation of a second modal', (done) ->
|
156
|
-
up.modal.config.openAnimation = 'fade-in'
|
157
|
-
up.modal.config.openDuration = 5
|
158
|
-
up.modal.config.closeAnimation = 'fade-out'
|
159
|
-
up.modal.config.closeDuration = 50
|
137
|
+
promise1 = up.modal.visit('/path1', target: '.container', animation: 'fade-in', duration: 50)
|
138
|
+
promise2 = up.modal.visit('/path2', target: '.container', animation: 'fade-in', duration: 50)
|
139
|
+
@respondWith('<div class="container">response1</div>')
|
140
|
+
|
141
|
+
u.setTimer 80, =>
|
142
|
+
@respondWith('<div class="container">response2</div>')
|
143
|
+
$.when(promise1, promise2).then ->
|
144
|
+
expect($('.up-modal').length).toBe(1)
|
145
|
+
expect($('.up-modal-dialog').length).toBe(1)
|
146
|
+
expect($('.container')).toHaveText('response2')
|
147
|
+
bodyPadding = parseInt($('body').css('padding-right'))
|
148
|
+
expect(bodyPadding).toBeAround(assumedScrollbarWidth, 10)
|
149
|
+
expect(bodyPadding).not.toBeAround(2 * assumedScrollbarWidth, 2 * 5)
|
150
|
+
done()
|
160
151
|
|
161
|
-
|
162
|
-
u.each ['up:modal:open', 'up:modal:opened', 'up:modal:close', 'up:modal:closed'], (event) ->
|
163
|
-
up.on event, ->
|
164
|
-
events.push(event)
|
152
|
+
describeCapability 'canCssTransition', ->
|
165
153
|
|
166
|
-
|
154
|
+
it 'closes the current modal and wait for its close animation to finish before starting the open animation of a second modal', (done) ->
|
155
|
+
up.modal.config.openAnimation = 'fade-in'
|
156
|
+
up.modal.config.openDuration = 5
|
157
|
+
up.modal.config.closeAnimation = 'fade-out'
|
158
|
+
up.modal.config.closeDuration = 50
|
167
159
|
|
168
|
-
|
169
|
-
|
170
|
-
|
160
|
+
events = []
|
161
|
+
u.each ['up:modal:open', 'up:modal:opened', 'up:modal:close', 'up:modal:closed'], (event) ->
|
162
|
+
up.on event, ->
|
163
|
+
events.push(event)
|
171
164
|
|
172
|
-
|
173
|
-
# First modal has completed opening animation
|
174
|
-
expect(events).toEqual ['up:modal:open', 'up:modal:opened']
|
175
|
-
expect($('.target')).toHaveText('response1')
|
165
|
+
up.modal.extract('.target', '<div class="target">response1</div>')
|
176
166
|
|
177
|
-
|
178
|
-
|
179
|
-
# First modal is starting close animation. Second modal waits for that.
|
180
|
-
expect(events).toEqual ['up:modal:open', 'up:modal:opened', 'up:modal:open', 'up:modal:close']
|
167
|
+
# First modal is starting opening animation
|
168
|
+
expect(events).toEqual ['up:modal:open']
|
181
169
|
expect($('.target')).toHaveText('response1')
|
182
170
|
|
183
171
|
u.setTimer 40, ->
|
184
|
-
|
185
|
-
|
186
|
-
expect(events).toEqual ['up:modal:open', 'up:modal:opened', 'up:modal:open', 'up:modal:close']
|
172
|
+
# First modal has completed opening animation
|
173
|
+
expect(events).toEqual ['up:modal:open', 'up:modal:opened']
|
187
174
|
expect($('.target')).toHaveText('response1')
|
188
175
|
|
189
|
-
|
176
|
+
up.modal.extract('.target', '<div class="target">response2</div>')
|
190
177
|
|
191
|
-
|
192
|
-
expect(events).toEqual ['up:modal:open', 'up:modal:opened', 'up:modal:open', 'up:modal:close', 'up:modal:closed', 'up:modal:opened']
|
193
|
-
expect($('.target')).toHaveText('response2')
|
178
|
+
expect($('.target')).toHaveText('response1')
|
194
179
|
|
195
|
-
|
180
|
+
u.setTimer 40, ->
|
196
181
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
up.modal.config.closeAnimation = 'fade-out'
|
201
|
-
up.modal.config.closeDuration = 50
|
182
|
+
# Second modal is still waiting for first modal's closing animaton to finish.
|
183
|
+
expect(events).toEqual ['up:modal:open', 'up:modal:opened', 'up:modal:close']
|
184
|
+
expect($('.target')).toHaveText('response1')
|
202
185
|
|
203
|
-
|
186
|
+
u.setTimer 100, ->
|
204
187
|
|
205
|
-
|
206
|
-
|
207
|
-
|
188
|
+
# First modal has finished closing, second modal has finished opening.
|
189
|
+
expect(events).toEqual ['up:modal:open', 'up:modal:opened', 'up:modal:close', 'up:modal:closed', 'up:modal:open', 'up:modal:opened']
|
190
|
+
expect($('.target')).toHaveText('response2')
|
208
191
|
|
209
|
-
|
192
|
+
done()
|
210
193
|
|
211
|
-
|
212
|
-
|
194
|
+
it 'closes an opening modal if a second modal starts opening before the first modal has finished its open animation', (done) ->
|
195
|
+
up.modal.config.openAnimation = 'fade-in'
|
196
|
+
up.modal.config.openDuration = 50
|
197
|
+
up.modal.config.closeAnimation = 'fade-out'
|
198
|
+
up.modal.config.closeDuration = 50
|
199
|
+
|
200
|
+
up.modal.extract('.target', '<div class="target">response1</div>')
|
213
201
|
|
214
202
|
u.setTimer 10, ->
|
215
|
-
#
|
203
|
+
# First modal is still in its opening animation
|
216
204
|
expect($('.target')).toHaveText('response1')
|
217
205
|
|
218
|
-
|
219
|
-
|
220
|
-
|
206
|
+
up.modal.extract('.target', '<div class="target">response2</div>')
|
207
|
+
|
208
|
+
# First modal is starting close animation. Second modal waits for that.
|
209
|
+
expect($('.target')).toHaveText('response1')
|
221
210
|
|
222
|
-
|
211
|
+
u.setTimer 10, ->
|
212
|
+
# Second modal is still waiting for first modal's closing animaton to finish.
|
213
|
+
expect($('.target')).toHaveText('response1')
|
214
|
+
|
215
|
+
u.setTimer 90, ->
|
216
|
+
# First modal has finished closing, second modal has finished opening.
|
217
|
+
expect($('.target')).toHaveText('response2')
|
218
|
+
|
219
|
+
done()
|
223
220
|
|
224
221
|
it 'uses the correct flavor config for the first and second modal', (done) ->
|
225
222
|
up.modal.config.openAnimation = 'fade-in'
|
226
|
-
up.modal.config.openDuration =
|
223
|
+
up.modal.config.openDuration = 20
|
227
224
|
up.modal.config.closeAnimation = 'fade-out'
|
228
|
-
up.modal.config.closeDuration =
|
225
|
+
up.modal.config.closeDuration = 20
|
229
226
|
up.modal.flavor 'drawer',
|
230
227
|
openAnimation: 'move-from-right'
|
231
228
|
closeAnimation: 'move-to-right'
|
@@ -245,24 +242,31 @@ describe 'up.modal', ->
|
|
245
242
|
{ animation: 'fade-in', text: 'response1' }
|
246
243
|
]
|
247
244
|
|
248
|
-
|
245
|
+
u.setTimer 30, ->
|
249
246
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
247
|
+
# first modal is now done animating
|
248
|
+
expect(animations).toEqual [
|
249
|
+
{ animation: 'fade-in', text: 'response1' }
|
250
|
+
]
|
254
251
|
|
255
|
-
u.setTimer 20, ->
|
256
252
|
|
253
|
+
up.modal.extract('.target', '<div class="target">response2</div>', flavor: 'drawer')
|
257
254
|
expect(animations).toEqual [
|
258
255
|
{ animation: 'fade-in', text: 'response1' },
|
259
256
|
{ animation: 'fade-out', text: 'response1' },
|
260
|
-
{ animation: 'move-from-right', text: 'response2' }
|
261
257
|
]
|
262
258
|
|
263
|
-
|
259
|
+
u.setTimer 30, ->
|
264
260
|
|
265
|
-
|
261
|
+
expect(animations).toEqual [
|
262
|
+
{ animation: 'fade-in', text: 'response1' },
|
263
|
+
{ animation: 'fade-out', text: 'response1' },
|
264
|
+
{ animation: 'move-from-right', text: 'response2' }
|
265
|
+
]
|
266
|
+
|
267
|
+
expect($('.up-modal').attr('up-flavor')).toEqual('drawer')
|
268
|
+
|
269
|
+
done()
|
266
270
|
|
267
271
|
|
268
272
|
it 'does not explode if up.modal.close() was called before the response was received', ->
|
@@ -278,13 +282,13 @@ describe 'up.modal', ->
|
|
278
282
|
|
279
283
|
it 'returns the URL behind the modal overlay', (done) ->
|
280
284
|
up.history.replace('/foo')
|
281
|
-
expect(up.modal.coveredUrl()).
|
285
|
+
expect(up.modal.coveredUrl()).toBeMissing()
|
282
286
|
visitPromise = up.modal.visit('/bar', target: '.container')
|
283
287
|
@respondWith('<div class="container">text</div>')
|
284
288
|
visitPromise.then ->
|
285
289
|
expect(up.modal.coveredUrl()).toEndWith('/foo')
|
286
290
|
up.modal.close().then ->
|
287
|
-
expect(up.modal.coveredUrl()).
|
291
|
+
expect(up.modal.coveredUrl()).toBeMissing()
|
288
292
|
done()
|
289
293
|
|
290
294
|
describe 'up.modal.flavor', ->
|
@@ -327,7 +331,7 @@ describe 'up.modal', ->
|
|
327
331
|
beforeEach ->
|
328
332
|
@stubFollow = =>
|
329
333
|
@$link = affix('a[href="/path"][up-modal=".target"]')
|
330
|
-
@followSpy = up.modal.knife.mock('
|
334
|
+
@followSpy = up.modal.knife.mock('followAsap').and.returnValue(u.resolvedPromise())
|
331
335
|
@defaultSpy = up.link.knife.mock('allowDefault').and.callFake((event) -> event.preventDefault())
|
332
336
|
|
333
337
|
it 'opens the clicked link in a modal', ->
|
@@ -405,10 +409,9 @@ describe 'up.modal', ->
|
|
405
409
|
|
406
410
|
describe 'when clicked inside a modal', ->
|
407
411
|
|
408
|
-
it 'closes the open modal and prevents the default action', ->
|
409
|
-
|
410
|
-
$link = $
|
411
|
-
up.hello($link)
|
412
|
+
it 'closes the open modal and prevents the default action', (done) ->
|
413
|
+
up.modal.extract('.target', '<div class="target"><a up-close>text</a></div>', animation: false)
|
414
|
+
$link = $('.up-modal a[up-close]') # link is within the modal
|
412
415
|
wasDefaultPrevented = false
|
413
416
|
wasClosed = false
|
414
417
|
up.on 'click', 'a[up-close]', (event) ->
|
@@ -417,8 +420,10 @@ describe 'up.modal', ->
|
|
417
420
|
up.on 'up:modal:close', ->
|
418
421
|
wasClosed = true
|
419
422
|
$link.click()
|
420
|
-
|
421
|
-
|
423
|
+
u.nextFrame ->
|
424
|
+
expect(wasClosed).toBe(true)
|
425
|
+
expect(wasDefaultPrevented).toBe(true)
|
426
|
+
done()
|
422
427
|
|
423
428
|
describe 'when no modal is open', ->
|
424
429
|
|
@@ -60,101 +60,115 @@ describe 'up.motion', ->
|
|
60
60
|
|
61
61
|
describe 'when called with an element or selector', ->
|
62
62
|
|
63
|
-
|
64
|
-
$element = affix('.element').text('content')
|
65
|
-
up.animate($element, { 'font-size': '40px', 'opacity': '0.33' }, duration: 10000)
|
66
|
-
up.motion.finish($element)
|
67
|
-
expect($element.css('font-size')).toEqual('40px')
|
68
|
-
expect($element.css('opacity')).toEqual('0.33')
|
69
|
-
|
70
|
-
it 'cancels animations on children of the given element', ->
|
71
|
-
$parent = affix('.element')
|
72
|
-
$child = $parent.affix('.child')
|
73
|
-
up.animate($child, { 'font-size': '40px' }, duration: 10000)
|
74
|
-
up.motion.finish($parent)
|
75
|
-
expect($child.css('font-size')).toEqual('40px')
|
76
|
-
|
77
|
-
it 'does not cancel animations on other elements', ->
|
78
|
-
$element1 = affix('.element1').text('content1')
|
79
|
-
$element2 = affix('.element2').text('content2')
|
80
|
-
up.animate($element1, 'fade-in', duration: 10000)
|
81
|
-
up.animate($element2, 'fade-in', duration: 10000)
|
82
|
-
up.motion.finish($element1)
|
83
|
-
expect(Number($element1.css('opacity'))).toEqual(1)
|
84
|
-
expect(Number($element2.css('opacity'))).toEqual(0, 0.1)
|
85
|
-
|
86
|
-
it 'restores existing transitions on the element', ->
|
87
|
-
$element = affix('.element').text('content')
|
88
|
-
$element.css('transition': 'font-size 3s ease')
|
89
|
-
oldTransitionProperty = $element.css('transition-property')
|
90
|
-
expect(oldTransitionProperty).toContain('font-size') # be paranoid
|
91
|
-
up.animate($element, 'fade-in', duration: 10000)
|
92
|
-
up.motion.finish($element)
|
93
|
-
expect(u.opacity($element)).toEqual(1)
|
94
|
-
currentTransitionProperty = $element.css('transition-property')
|
95
|
-
expect(currentTransitionProperty).toEqual(oldTransitionProperty)
|
96
|
-
expect(currentTransitionProperty).toContain('font-size')
|
97
|
-
expect(currentTransitionProperty).not.toContain('opacity')
|
63
|
+
describeCapability 'canCssTransition', ->
|
98
64
|
|
99
|
-
|
100
|
-
|
101
|
-
|
65
|
+
it 'cancels an existing animation on the given element by instantly jumping to the last frame', ->
|
66
|
+
$element = affix('.element').text('content')
|
67
|
+
up.animate($element, { 'font-size': '40px', 'opacity': '0.33' }, duration: 10000)
|
68
|
+
up.motion.finish($element)
|
69
|
+
expect($element.css('font-size')).toEqual('40px')
|
70
|
+
expect($element.css('opacity')).toEqual('0.33')
|
71
|
+
|
72
|
+
it 'cancels animations on children of the given element', ->
|
73
|
+
$parent = affix('.element')
|
74
|
+
$child = $parent.affix('.child')
|
75
|
+
up.animate($child, { 'font-size': '40px' }, duration: 10000)
|
76
|
+
up.motion.finish($parent)
|
77
|
+
expect($child.css('font-size')).toEqual('40px')
|
78
|
+
|
79
|
+
it 'does not cancel animations on other elements', ->
|
80
|
+
$element1 = affix('.element1').text('content1')
|
81
|
+
$element2 = affix('.element2').text('content2')
|
82
|
+
up.animate($element1, 'fade-in', duration: 10000)
|
83
|
+
up.animate($element2, 'fade-in', duration: 10000)
|
84
|
+
up.motion.finish($element1)
|
85
|
+
expect(Number($element1.css('opacity'))).toEqual(1)
|
86
|
+
expect(Number($element2.css('opacity'))).toEqual(0, 0.1)
|
87
|
+
|
88
|
+
it 'restores existing transitions on the element', ->
|
89
|
+
$element = affix('.element').text('content')
|
90
|
+
$element.css('transition': 'font-size 3s ease')
|
91
|
+
oldTransitionProperty = $element.css('transition-property')
|
92
|
+
expect(oldTransitionProperty).toBeDefined()
|
93
|
+
expect(oldTransitionProperty).toContain('font-size') # be paranoid
|
94
|
+
up.animate($element, 'fade-in', duration: 10000)
|
95
|
+
up.motion.finish($element)
|
96
|
+
expect(u.opacity($element)).toEqual(1)
|
97
|
+
currentTransitionProperty = $element.css('transition-property')
|
98
|
+
expect(currentTransitionProperty).toEqual(oldTransitionProperty)
|
99
|
+
expect(currentTransitionProperty).toContain('font-size')
|
100
|
+
expect(currentTransitionProperty).not.toContain('opacity')
|
101
|
+
|
102
|
+
it 'cancels an existing transition on the element by instantly jumping to the last frame', ->
|
103
|
+
$old = affix('.old').text('old content')
|
104
|
+
$new = affix('.new').text('new content')
|
102
105
|
|
103
|
-
|
104
|
-
|
106
|
+
up.morph($old, $new, 'cross-fade', duration: 2000)
|
107
|
+
expect($('.up-ghost').length).toBe(2)
|
105
108
|
|
106
|
-
|
109
|
+
up.motion.finish($old)
|
107
110
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
+
expect($('.up-ghost').length).toBe(0)
|
112
|
+
expect($old.css('display')).toEqual('none')
|
113
|
+
expect($new.css('display')).toEqual('block')
|
111
114
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
+
it 'can be called on either element involved in a transition', ->
|
116
|
+
$old = affix('.old').text('old content')
|
117
|
+
$new = affix('.new').text('new content')
|
115
118
|
|
116
|
-
|
117
|
-
|
119
|
+
up.morph($old, $new, 'cross-fade', duration: 2000)
|
120
|
+
expect($('.up-ghost').length).toBe(2)
|
118
121
|
|
119
|
-
|
122
|
+
up.motion.finish($new)
|
120
123
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
+
expect($('.up-ghost').length).toBe(0)
|
125
|
+
expect($old.css('display')).toEqual('none')
|
126
|
+
expect($new.css('display')).toEqual('block')
|
124
127
|
|
125
128
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
129
|
+
it 'cancels transitions on children of the given element', ->
|
130
|
+
$parent = affix('.parent')
|
131
|
+
$old = $parent.affix('.old').text('old content')
|
132
|
+
$new = $parent.affix('.new').text('new content')
|
130
133
|
|
131
|
-
|
132
|
-
|
134
|
+
up.morph($old, $new, 'cross-fade', duration: 2000)
|
135
|
+
expect($('.up-ghost').length).toBe(2)
|
133
136
|
|
134
|
-
|
137
|
+
up.motion.finish($parent)
|
135
138
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
+
expect($('.up-ghost').length).toBe(0)
|
140
|
+
expect($old.css('display')).toEqual('none')
|
141
|
+
expect($new.css('display')).toEqual('block')
|
142
|
+
|
143
|
+
describeFallback 'canCssTransition', ->
|
144
|
+
|
145
|
+
it 'does nothing'
|
139
146
|
|
140
147
|
describe 'when called without arguments', ->
|
141
148
|
|
142
|
-
|
143
|
-
|
144
|
-
|
149
|
+
describeCapability 'canCssTransition', ->
|
150
|
+
|
151
|
+
it 'cancels all animations on the screen', ->
|
152
|
+
$element1 = affix('.element1').text('content1')
|
153
|
+
$element2 = affix('.element2').text('content2')
|
154
|
+
|
155
|
+
up.animate($element1, 'fade-in', duration: 3000)
|
156
|
+
up.animate($element2, 'fade-in', duration: 3000)
|
157
|
+
|
158
|
+
expect(u.opacity($element1)).toBeAround(0.0, 0.1)
|
159
|
+
expect(u.opacity($element2)).toBeAround(0.0, 0.1)
|
160
|
+
|
161
|
+
up.motion.finish()
|
145
162
|
|
146
|
-
|
147
|
-
|
163
|
+
$element1 = $('.element1')
|
164
|
+
$element2 = $('.element2')
|
165
|
+
expect(u.opacity($element1)).toBe(1.0)
|
166
|
+
expect(u.opacity($element2)).toBe(1.0)
|
148
167
|
|
149
|
-
|
150
|
-
expect(u.opacity($element2)).toBeAround(0.0, 0.1)
|
168
|
+
describeFallback 'canCssTransition', ->
|
151
169
|
|
152
|
-
|
170
|
+
it 'does nothing'
|
153
171
|
|
154
|
-
$element1 = $('.element1')
|
155
|
-
$element2 = $('.element2')
|
156
|
-
expect(u.opacity($element1)).toBe(1.0)
|
157
|
-
expect(u.opacity($element2)).toBe(1.0)
|
158
172
|
|
159
173
|
describe 'up.morph', ->
|
160
174
|
|