unpoly-rails 0.28.1 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -1
  3. data/dist/unpoly.js +376 -259
  4. data/dist/unpoly.min.js +3 -3
  5. data/lib/assets/javascripts/unpoly/browser.js.coffee +2 -2
  6. data/lib/assets/javascripts/unpoly/bus.js.coffee +40 -13
  7. data/lib/assets/javascripts/unpoly/flow.js.coffee +9 -9
  8. data/lib/assets/javascripts/unpoly/form.js.coffee +18 -18
  9. data/lib/assets/javascripts/unpoly/history.js.coffee +1 -1
  10. data/lib/assets/javascripts/unpoly/layout.js.coffee +9 -9
  11. data/lib/assets/javascripts/unpoly/link.js.coffee +34 -24
  12. data/lib/assets/javascripts/unpoly/modal.js.coffee +38 -37
  13. data/lib/assets/javascripts/unpoly/motion.js.coffee +20 -23
  14. data/lib/assets/javascripts/unpoly/navigation.js.coffee +101 -37
  15. data/lib/assets/javascripts/unpoly/popup.js.coffee +24 -16
  16. data/lib/assets/javascripts/unpoly/proxy.js.coffee +3 -3
  17. data/lib/assets/javascripts/unpoly/syntax.js.coffee +29 -37
  18. data/lib/assets/javascripts/unpoly/tooltip.js.coffee +18 -9
  19. data/lib/assets/javascripts/unpoly/util.js.coffee +15 -7
  20. data/lib/unpoly/rails/version.rb +1 -1
  21. data/spec_app/Gemfile.lock +1 -1
  22. data/spec_app/spec/javascripts/helpers/trigger.js.coffee +6 -0
  23. data/spec_app/spec/javascripts/up/bus_spec.js.coffee +9 -8
  24. data/spec_app/spec/javascripts/up/form_spec.js.coffee +10 -10
  25. data/spec_app/spec/javascripts/up/link_spec.js.coffee +25 -20
  26. data/spec_app/spec/javascripts/up/modal_spec.js.coffee +53 -44
  27. data/spec_app/spec/javascripts/up/navigation_spec.js.coffee +8 -8
  28. data/spec_app/spec/javascripts/up/popup_spec.js.coffee +92 -44
  29. data/spec_app/spec/javascripts/up/tooltip_spec.js.coffee +46 -4
  30. metadata +2 -2
@@ -342,7 +342,7 @@ describe 'up.link', ->
342
342
  $form = affix('form[up-target]')
343
343
  up.hello($form)
344
344
  followSpy = up.link.knife.mock('follow').and.returnValue(u.resolvedPromise())
345
- $form.click()
345
+ Trigger.clickSequence($form)
346
346
  expect(followSpy).not.toHaveBeenCalled()
347
347
 
348
348
  describeCapability 'canPushState', ->
@@ -350,7 +350,7 @@ describe 'up.link', ->
350
350
  it 'adds a history entry', ->
351
351
  affix('.target')
352
352
  $link = affix('a[href="/path"][up-target=".target"]')
353
- $link.click()
353
+ Trigger.clickSequence($link)
354
354
  @respondWith('<div class="target">new text</div>')
355
355
  expect($('.target')).toHaveText('new text')
356
356
  expect(location.pathname).toEqual('/path')
@@ -358,35 +358,41 @@ describe 'up.link', ->
358
358
  it 'respects a X-Up-Location header that the server sends in case of a redirect', ->
359
359
  affix('.target')
360
360
  $link = affix('a[href="/path"][up-target=".target"]')
361
- $link.click()
361
+ Trigger.clickSequence($link)
362
362
  @respondWith
363
363
  responseText: '<div class="target">new text</div>'
364
364
  responseHeaders: { 'X-Up-Location': '/other/path' }
365
365
  expect($('.target')).toHaveText('new text')
366
366
  expect(location.pathname).toEqual('/other/path')
367
367
 
368
- it 'prefers to update a container in the same layer as the clicked link', ->
368
+ it 'prefers to update a container in the same layer as the clicked link', (done) ->
369
369
  up.motion.config.enabled = false
370
370
 
371
371
  $popupOpener = affix('a[href="/popup"]')
372
372
  up.popup.attach($popupOpener, html: "<div class='target'>old popup text</div>", target: '.target')
373
-
374
373
  affix('.document').affix('.target').text('old document text')
375
- $linkInDocument = affix('a[href="/foo"][up-target=".target"]')
376
- $linkInDocument.click()
377
374
 
378
- @respondWith '<div class="target">new text from document link</div>'
375
+ $linkInDocument = affix('a[href="/foo"][up-target=".target"]')
376
+ $linkInPopup = $('.up-popup').affix('a[href="/bar"][up-target=".target"]')
379
377
 
380
- expect($('.document .target')).toHaveText('new text from document link')
378
+ expect($('.document .target')).toHaveText('old document text')
381
379
  expect($('.up-popup .target')).toHaveText('old popup text')
382
380
 
383
- $linkInPopup = $('.up-popup').affix('a[href="/bar"][up-target=".target"]')
384
- $linkInPopup.click()
381
+ u.nextFrame =>
382
+
383
+ Trigger.clickSequence($linkInPopup)
385
384
 
386
- @respondWith '<div class="target">new text from popup link</div>'
385
+ u.nextFrame =>
386
+ @respondWith '<div class="target">new text from popup link</div>'
387
387
 
388
- expect($('.document .target')).toHaveText('new text from document link')
389
- expect($('.up-popup .target')).toHaveText('new text from popup link')
388
+ expect($('.document .target')).toHaveText('old document text')
389
+ expect($('.up-popup .target')).toHaveText('new text from popup link')
390
+ Trigger.clickSequence($linkInDocument)
391
+
392
+ u.nextFrame =>
393
+ @respondWith '<div class="target">new text from document link</div>'
394
+ expect($('.document .target')).toHaveText('new text from document link')
395
+ done()
390
396
 
391
397
 
392
398
  describe 'with [up-transition] modifier', ->
@@ -396,7 +402,7 @@ describe 'up.link', ->
396
402
  it 'morphs between the old and new target element', (done) ->
397
403
  affix('.target.old')
398
404
  $link = affix('a[href="/path"][up-target=".target"][up-transition="cross-fade"][up-duration="500"][up-easing="linear"]')
399
- $link.click()
405
+ Trigger.clickSequence($link)
400
406
  @respondWith '<div class="target new">new text</div>'
401
407
 
402
408
  $oldGhost = $('.target.old.up-ghost')
@@ -414,7 +420,7 @@ describe 'up.link', ->
414
420
  oldPathname = location.pathname
415
421
  affix('.target')
416
422
  $link = affix('a[href="/path"][up-target=".target"][up-history="false"]')
417
- $link.click()
423
+ Trigger.clickSequence($link)
418
424
  @respondWith
419
425
  responseText: '<div class="target">new text</div>'
420
426
  responseHeaders: { 'X-Up-Location': '/other/path' }
@@ -562,15 +568,14 @@ describe 'up.link', ->
562
568
  $area = affix('div[up-expand] a[href="/path"]')
563
569
  up.hello($area)
564
570
  spyOn(up, 'replace')
565
- $area.get(0).click()
571
+ Trigger.clickSequence($area)
566
572
  expect(up.replace).toHaveBeenCalled()
567
573
 
568
574
  it 'does not trigger multiple replaces when the user clicks on the expanded area of an up-instant link (bugfix)', ->
569
- $area = affix('div[up-expand] a[href="/path"][up-instant]')
575
+ $area = affix('div[up-expand] a[href="/path"][up-follow][up-instant]')
570
576
  up.hello($area)
571
577
  spyOn(up, 'replace')
572
- Trigger.mousedown($area)
573
- Trigger.click($area)
578
+ Trigger.clickSequence($area)
574
579
  expect(up.replace.calls.count()).toEqual(1)
575
580
 
576
581
  it 'does not add an up-follow attribute if the expanded link is [up-dash] with a selector (bugfix)', ->
@@ -420,66 +420,54 @@ describe 'up.modal', ->
420
420
 
421
421
  describe '[up-close]', ->
422
422
 
423
+ backgroundClicked = undefined
424
+
425
+ beforeEach ->
426
+ up.motion.config.enabled = false
427
+ backgroundClicked = jasmine.createSpy('background clicked')
428
+ up.on 'click', backgroundClicked
429
+
423
430
  describe 'when clicked inside a modal', ->
424
431
 
425
- it 'closes the open modal and prevents the default action', (done) ->
432
+ it 'closes the open modal and halts the event chain', (done) ->
426
433
  up.modal.extract('.target', '<div class="target"><a up-close>text</a></div>', animation: false)
427
434
  $link = $('.up-modal a[up-close]') # link is within the modal
428
- wasDefaultPrevented = false
429
- wasClosed = false
430
- up.on 'click', 'a[up-close]', (event) ->
431
- wasDefaultPrevented = event.isDefaultPrevented()
432
- true # the line above might return false and cancel propagation / prevent default
433
- up.on 'up:modal:close', ->
434
- wasClosed = true
435
- $link.click()
435
+ Trigger.clickSequence($link)
436
436
  u.nextFrame ->
437
- expect(wasClosed).toBe(true)
438
- expect(wasDefaultPrevented).toBe(true)
437
+ expect(up.modal.isOpen()).toBe(false)
438
+ expect(backgroundClicked).not.toHaveBeenCalled()
439
439
  done()
440
440
 
441
441
  describe 'when no modal is open', ->
442
442
 
443
- it 'does neither close the modal nor prevent the default action', ->
443
+ it 'does nothing and allows the event chain to continue', (done) ->
444
444
  $link = affix('a[up-close]') # link is outside the modal
445
445
  up.hello($link)
446
- wasDefaultPrevented = false
447
- wasClosed = false
448
- up.on 'click', 'a[up-close]', (event) ->
449
- wasDefaultPrevented = event.isDefaultPrevented()
450
- true # the line above might return false and cancel propagation / prevent default
451
- up.on 'up:modal:close', ->
452
- wasClosed = true
453
- $link.click()
454
- expect(wasClosed).toBe(false)
455
- expect(wasDefaultPrevented).toBe(false)
446
+ Trigger.clickSequence($link)
447
+ u.nextFrame ->
448
+ expect(backgroundClicked).toHaveBeenCalled()
449
+ done()
456
450
 
457
451
  describe 'template behavior', ->
458
452
 
459
453
  it 'closes the modal on close icon click', (done) ->
460
- wasClosed = false
461
454
  up.modal.extract('.modal', '<div class="modal">Modal content</div>', animation: false)
462
455
 
463
- closeIcon = $('.up-modal-close')
464
- up.on 'up:modal:close', ->
465
- wasClosed = true
456
+ $closeIcon = $('.up-modal-close')
466
457
 
467
- closeIcon.click()
458
+ Trigger.clickSequence($closeIcon)
468
459
  u.nextFrame ->
469
- expect(wasClosed).toBe(true)
460
+ expect(up.modal.isOpen()).toBe(false)
470
461
  done()
471
462
 
472
463
  it 'closes the modal on backdrop click', (done) ->
473
- wasClosed = false
474
464
  up.modal.extract('.modal', '<div class="modal">Modal content</div>', animation: false)
475
465
 
476
- backdrop = $('.up-modal-backdrop')
477
- up.on 'up:modal:close', ->
478
- wasClosed = true
466
+ $backdrop = $('.up-modal-backdrop')
479
467
 
480
- backdrop.click()
468
+ Trigger.clickSequence($backdrop)
481
469
  u.nextFrame ->
482
- expect(wasClosed).toBe(true)
470
+ expect(up.modal.isOpen()).toBe(false)
483
471
  done()
484
472
 
485
473
  it 'closes the modal when the user presses the escape key', (done) ->
@@ -503,28 +491,22 @@ describe 'up.modal', ->
503
491
  expect(modal).not.toContainElement('.up-modal-close')
504
492
 
505
493
  it 'does not close the modal on backdrop click', (done) ->
506
- wasClosed = false
507
494
  up.modal.extract('.modal', '<div class="modal">Modal content</div>', animation: false, closable: false)
508
495
 
509
- backdrop = $('.up-modal-backdrop')
510
- up.on 'up:modal:close', ->
511
- wasClosed = true
496
+ $backdrop = $('.up-modal-backdrop')
512
497
 
513
- backdrop.click()
498
+ Trigger.clickSequence($backdrop)
514
499
  u.nextFrame ->
515
- expect(wasClosed).toBe(false)
500
+ expect(up.modal.isOpen()).toBe(true)
516
501
  done()
517
502
 
518
503
  it 'does not close the modal when the user presses the escape key', (done) ->
519
- wasClosed = false
520
504
  up.modal.extract('.modal', '<div class="modal">Modal content</div>', animation: false, closable: false)
521
- up.on 'up:modal:close', ->
522
- wasClosed = true
523
505
 
524
506
  escapeEvent = $.Event('keydown', keyCode: 27)
525
507
  $('body').trigger(escapeEvent)
526
508
  u.nextFrame ->
527
- expect(wasClosed).toBe(false)
509
+ expect(up.modal.isOpen()).toBe(true)
528
510
  done()
529
511
 
530
512
  describe 'when replacing content', ->
@@ -597,3 +579,30 @@ describe 'up.modal', ->
597
579
  @respondWith("<div class='popup-content'></div>")
598
580
  expect($('.up-modal')).toExist()
599
581
  expect($('.up-popup')).toExist()
582
+
583
+ it 'does not close the modal when a clicked [up-target] link within the modal links to cached content (bugfix)', (done) ->
584
+
585
+ up.modal.extract '.content', """
586
+ <div class="content">
587
+ <a href="/foo" up-target=".content">link</a>
588
+ </div>
589
+ """
590
+ $link = $('.up-modal .content a')
591
+ expect($link).toExist()
592
+ whenPreloaded = up.proxy.preload($link)
593
+
594
+ @respondWith """
595
+ <div class="content">
596
+ new text
597
+ </div>
598
+ """
599
+
600
+ whenPreloaded.then ->
601
+
602
+ Trigger.clickSequence($link)
603
+
604
+ u.nextFrame ->
605
+ expect($('.up-modal')).toExist()
606
+ expect($('.up-modal .content')).toHaveText('new text')
607
+
608
+ done()
@@ -67,7 +67,7 @@ describe 'up.navigation', ->
67
67
  it 'marks a link as .up-current if it links to the current URL, but is missing a trailing slash', ->
68
68
  $link = affix('a[href="/foo"][up-target=".main"]')
69
69
  affix('.main')
70
- $link.click()
70
+ Trigger.clickSequence($link)
71
71
  @respondWith
72
72
  responseHeaders: { 'X-Up-Location': '/foo/' }
73
73
  responseText: '<div class="main">new-text</div>'
@@ -76,7 +76,7 @@ describe 'up.navigation', ->
76
76
  it 'marks a link as .up-current if it links to the current URL, but has an extra trailing slash', ->
77
77
  $link = affix('a[href="/foo/"][up-target=".main"]')
78
78
  affix('.main')
79
- $link.click()
79
+ Trigger.clickSequence($link)
80
80
  @respondWith
81
81
  responseHeaders: { 'X-Up-Location': '/foo' }
82
82
  responseText: '<div class="main">new-text</div>'
@@ -106,7 +106,7 @@ describe 'up.navigation', ->
106
106
  $popupLink = affix('a[href="/bar"][up-popup=".main"]')
107
107
  $unrelatedLink = affix('a[href="/baz]')
108
108
 
109
- $popupLink.click()
109
+ Trigger.clickSequence($popupLink)
110
110
  @respondWith('<div class="main">new-text</div>')
111
111
  expect($backgroundLink).toHaveClass('up-current')
112
112
  expect($popupLink).toHaveClass('up-current')
@@ -127,7 +127,7 @@ describe 'up.navigation', ->
127
127
  it 'marks clicked links as .up-active until the request finishes', ->
128
128
  $link = affix('a[href="/foo"][up-target=".main"]')
129
129
  affix('.main')
130
- $link.click()
130
+ Trigger.clickSequence($link)
131
131
  expect($link).toHaveClass('up-active')
132
132
  @respondWith('<div class="main">new-text</div>')
133
133
  expect($link).not.toHaveClass('up-active')
@@ -145,7 +145,7 @@ describe 'up.navigation', ->
145
145
  up.hello($area)
146
146
  $link = $area.find('a')
147
147
  affix('.main')
148
- $link.click()
148
+ Trigger.clickSequence($link)
149
149
  expect($link).not.toHaveClass('up-active')
150
150
  expect($area).toHaveClass('up-active')
151
151
  @respondWith('<div class="main">new-text</div>')
@@ -154,7 +154,7 @@ describe 'up.navigation', ->
154
154
  it 'marks clicked modal openers as .up-active while the modal is loading', ->
155
155
  $link = affix('a[href="/foo"][up-modal=".main"]')
156
156
  affix('.main')
157
- $link.click()
157
+ Trigger.clickSequence($link)
158
158
  expect($link).toHaveClass('up-active')
159
159
  @respondWith('<div class="main">new-text</div>')
160
160
  expect($link).not.toHaveClass('up-active')
@@ -163,7 +163,7 @@ describe 'up.navigation', ->
163
163
  $link = affix('a[href="/foo"][up-modal=".main"]')
164
164
  up.proxy.preload($link)
165
165
  @respondWith('<div class="main">new-text</div>')
166
- $link.click()
166
+ Trigger.clickSequence($link)
167
167
  expect('.up-modal .main').toHaveText('new-text')
168
168
  expect($link).not.toHaveClass('up-active')
169
169
 
@@ -172,7 +172,7 @@ describe 'up.navigation', ->
172
172
  affix('.main')
173
173
  up.proxy.preload($link)
174
174
  @respondWith('<div class="main">new-text</div>')
175
- $link.click()
175
+ Trigger.clickSequence($link)
176
176
  expect('.main').toHaveText('new-text')
177
177
  expect($link).not.toHaveClass('up-active')
178
178
 
@@ -134,7 +134,7 @@ describe 'up.popup', ->
134
134
  expect(up.popup.coveredUrl()).toBeMissing()
135
135
 
136
136
  $popupLink = affix('a[href="/bar"][up-popup=".container"][up-history="true"]')
137
- $popupLink.click()
137
+ Trigger.clickSequence($popupLink)
138
138
  @respondWith('<div class="container">text</div>')
139
139
  expect(up.popup.coveredUrl()).toEndWith('/foo')
140
140
  up.popup.close().then ->
@@ -255,42 +255,37 @@ describe 'up.popup', ->
255
255
 
256
256
  describe '[up-close]', ->
257
257
 
258
+ backgroundClicked = undefined
259
+
260
+ beforeEach ->
261
+ up.motion.config.enabled = false
262
+ backgroundClicked = jasmine.createSpy('background clicked')
263
+ up.on 'click', backgroundClicked
264
+
258
265
  describe 'when clicked inside a popup', ->
259
266
 
260
- it 'closes the open popup and prevents the default action', (done) ->
261
- $link = affix('a')
262
- up.popup.attach($link, html: '<div class="target">text</div>', target: '.target').then ->
263
- $popup = affix('.up-popup')
264
- $link = $popup.affix('a[up-close]') # link is within the popup
265
- up.hello($link)
266
- wasDefaultPrevented = false
267
- wasClosed = false
268
- up.on 'click', 'a[up-close]', (event) ->
269
- wasDefaultPrevented = event.isDefaultPrevented()
270
- true # the line above might return false and cancel propagation / prevent default
271
- up.on 'up:popup:close', ->
272
- wasClosed = true
273
- $link.click()
274
- u.nextFrame ->
275
- expect(wasClosed).toBe(true)
276
- expect(wasDefaultPrevented).toBe(true)
277
- done()
267
+ it 'closes the open popup and halts the event chain', (done) ->
268
+ $opener = affix('a')
269
+ up.popup.attach($opener, html: '<div class="target">text</div>', target: '.target')
270
+ $popup = affix('.up-popup')
271
+ $closer = $popup.affix('a[up-close]') # link is within the popup
272
+ up.hello($closer)
273
+ Trigger.clickSequence($closer)
274
+ u.nextFrame ->
275
+ expect(up.popup.isOpen()).toBe(false)
276
+ expect(backgroundClicked).not.toHaveBeenCalled()
277
+ done()
278
278
 
279
279
  describe 'when no popup is open', ->
280
280
 
281
- it 'does neither close the popup nor prevent the default action', ->
281
+ it 'does nothing and allows the event chain to continue', (done) ->
282
282
  $link = affix('a[up-close]') # link is outside the popup
283
283
  up.hello($link)
284
- wasDefaultPrevented = false
285
- wasClosed = false
286
- up.on 'click', 'a[up-close]', (event) ->
287
- wasDefaultPrevented = event.isDefaultPrevented()
288
- true # the line above might return false and cancel propagation / prevent default
289
- up.on 'up:popup:close', ->
290
- wasClosed = true
291
- $link.click()
292
- expect(wasClosed).toBe(false)
293
- expect(wasDefaultPrevented).toBe(false)
284
+ Trigger.clickSequence($link)
285
+ u.nextFrame ->
286
+ expect(up.popup.isOpen()).toBe(false)
287
+ expect(backgroundClicked).toHaveBeenCalled()
288
+ done()
294
289
 
295
290
  describe 'when replacing content', ->
296
291
 
@@ -300,8 +295,7 @@ describe 'up.popup', ->
300
295
  it 'prefers to replace a selector within the popup', ->
301
296
  $outside = affix('.foo').text('old outside')
302
297
  $link = affix('.link')
303
- up.popup.attach($link, target: '.foo')
304
- @respondWith("<div class='foo'>old inside</div>")
298
+ up.popup.attach($link, target: '.foo', html: "<div class='foo'>old inside</div>")
305
299
  up.extract('.foo', "<div class='foo'>new text</div>")
306
300
  expect($outside).toBeInDOM()
307
301
  expect($outside).toHaveText('old outside')
@@ -310,8 +304,7 @@ describe 'up.popup', ->
310
304
  it 'auto-closes the popup when a replacement from inside the popup affects a selector behind the popup', ->
311
305
  affix('.outside').text('old outside')
312
306
  $link = affix('.link')
313
- up.popup.attach($link, target: '.inside')
314
- @respondWith("<div class='inside'>old inside</div>")
307
+ up.popup.attach($link, target: '.inside', html: "<div class='inside'>old inside</div>")
315
308
  up.extract('.outside', "<div class='outside'>new outside</div>", origin: $('.inside'))
316
309
  expect($('.outside')).toHaveText('new outside')
317
310
  expect($('.up-popup')).not.toExist()
@@ -325,7 +318,7 @@ describe 'up.popup', ->
325
318
  affix('.outside').text('old outside')
326
319
  $link = affix('.link')
327
320
  whenPopupOpen = up.popup.attach($link, url: '/path', target: '.inside')
328
- @respondWith("<div class='inside'>old inside</div>") # Populate popup
321
+ @respondWith("<div class='inside'>old inside</div>")
329
322
 
330
323
  whenPopupOpen.then ->
331
324
  up.extract('.outside', "<div class='outside'>new outside</div>",
@@ -347,8 +340,7 @@ describe 'up.popup', ->
347
340
  it 'does not auto-close the popup when a replacement from outside the popup affects a selector outside the popup', ->
348
341
  affix('.outside').text('old outside')
349
342
  $link = affix('.link')
350
- up.popup.attach($link, target: '.inside')
351
- @respondWith("<div class='inside'>old inside</div>")
343
+ up.popup.attach($link, target: '.inside', html: "<div class='inside'>old inside</div>")
352
344
  up.extract('.outside', "<div class='outside'>new outside</div>", origin: $('.outside'))
353
345
  expect($('.outside')).toHaveText('new outside')
354
346
  expect($('.up-popup')).toExist()
@@ -356,8 +348,7 @@ describe 'up.popup', ->
356
348
  it 'does not auto-close the popup when a replacement from outside the popup affects a selector inside the popup', ->
357
349
  affix('.outside').text('old outside')
358
350
  $link = affix('.link')
359
- up.popup.attach($link, target: '.inside')
360
- @respondWith("<div class='inside'>old inside</div>")
351
+ up.popup.attach($link, target: '.inside', html: "<div class='inside'>old inside</div>")
361
352
  up.extract('.inside', "<div class='inside'>new inside</div>", origin: $('.outside'))
362
353
  expect($('.inside')).toHaveText('new inside')
363
354
  expect($('.up-popup')).toExist()
@@ -367,10 +358,67 @@ describe 'up.popup', ->
367
358
  beforeEach ->
368
359
  up.motion.config.enabled = false
369
360
 
370
- it 'closes a popup on mousedown (in case an [up-instant] link removes its parent and thus a click event never fires)', ->
361
+ it 'closes the popup', (done) ->
371
362
  affix('.outside').text('old outside')
372
363
  $link = affix('.link')
373
- up.popup.attach($link, target: '.inside')
374
- @respondWith("<div class='inside'>inside</div>")
375
- Trigger.mousedown($('body'))
376
- expect($('.up-popup')).not.toExist()
364
+ up.popup.attach($link, target: '.inside', html: "<div class='inside'>inside</div>")
365
+ expect(up.popup.isOpen()).toBe(true)
366
+ Trigger.clickSequence($('body'))
367
+ u.nextFrame ->
368
+ expect(up.popup.isOpen()).toBe(false)
369
+ done()
370
+
371
+ it 'closes the popup when a an [up-instant] link removes its parent (and thus a click event never bubbles up to the document)', (done) ->
372
+ $parent = affix('.parent')
373
+ $parentReplacingLink = $parent.affix('a[href="/foo"][up-target=".parent"][up-instant]')
374
+ $popupOpener = affix('.link')
375
+ up.popup.attach($popupOpener, target: '.inside', html: "<div class='inside'>inside</div>")
376
+ expect(up.popup.isOpen()).toBe(true)
377
+ Trigger.clickSequence($parentReplacingLink)
378
+ u.nextFrame ->
379
+ expect(up.popup.isOpen()).toBe(false)
380
+ done()
381
+
382
+ it 'closes the popup when the user clicks on an [up-target] link outside the popup', (done) ->
383
+ $target = affix('.target')
384
+ $outsideLink = affix('a[href="/foo"][up-target=".target"]')
385
+ $popupOpener = affix('.link')
386
+ up.popup.attach($popupOpener, target: '.inside', html: "<div class='inside'>inside</div>")
387
+ expect(up.popup.isOpen()).toBe(true)
388
+ Trigger.clickSequence($outsideLink)
389
+ u.nextFrame ->
390
+ expect(up.popup.isOpen()).toBe(false)
391
+ done()
392
+
393
+ it 'closes the popup when the user clicks on an [up-instant] link outside the popup', (done) ->
394
+ $target = affix('.target')
395
+ $outsideLink = affix('a[href="/foo"][up-target=".target"][up-instant]')
396
+ $popupOpener = affix('.link')
397
+ up.popup.attach($popupOpener, target: '.inside', html: "<div class='inside'>inside</div>")
398
+ expect(up.popup.isOpen()).toBe(true)
399
+ Trigger.clickSequence($outsideLink)
400
+ u.nextFrame ->
401
+ expect(up.popup.isOpen()).toBe(false)
402
+ done()
403
+
404
+ it 'does not close the popup if a link outside the popup is followed with the up.follow function (bugfix)', (done) ->
405
+ $target = affix('.target')
406
+ $outsideLink = affix('a[href="/foo"][up-target=".target"]')
407
+ $popupOpener = affix('.link')
408
+ up.popup.attach($popupOpener, target: '.inside', html: "<div class='inside'>inside</div>")
409
+ expect(up.popup.isOpen()).toBe(true)
410
+ up.follow($outsideLink)
411
+ u.nextFrame ->
412
+ expect(up.popup.isOpen()).toBe(true)
413
+ done()
414
+
415
+ it 'does not close the popup if a form outside the popup is followed with the up.submit function (bugfix)', (done) ->
416
+ $target = affix('.target')
417
+ $outsideForm = affix('form[action="/foo"][up-target=".target"]')
418
+ $popupOpener = affix('.link')
419
+ up.popup.attach($popupOpener, target: '.inside', html: "<div class='inside'>inside</div>")
420
+ expect(up.popup.isOpen()).toBe(true)
421
+ up.submit($outsideForm)
422
+ u.nextFrame ->
423
+ expect(up.popup.isOpen()).toBe(true)
424
+ done()