OLD | NEW |
1 <!doctype html> | 1 <!doctype html> |
2 <!-- | 2 <!-- |
3 @license | 3 @license |
4 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. | 4 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. |
5 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt | 5 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt |
6 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | 6 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt |
7 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt | 7 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt |
8 Code distributed by Google as part of the polymer project is also | 8 Code distributed by Google as part of the polymer project is also |
9 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt | 9 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt |
10 --> | 10 --> |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 <div tabindex="-1">not focusable</div> | 82 <div tabindex="-1">not focusable</div> |
83 <div tabindex="3" class="focusable3">3</div> | 83 <div tabindex="3" class="focusable3">3</div> |
84 <div tabindex="4" class="focusable4">4</div> | 84 <div tabindex="4" class="focusable4">4</div> |
85 <div tabindex="5" class="focusable5">5</div> | 85 <div tabindex="5" class="focusable5">5</div> |
86 <div> | 86 <div> |
87 <div tabindex="1" class="focusable1">1 (nested)</div> | 87 <div tabindex="1" class="focusable1">1 (nested)</div> |
88 <div tabindex="6" class="focusable6">6 (nested)</div> | 88 <div tabindex="6" class="focusable6">6 (nested)</div> |
89 </div> | 89 </div> |
90 <div tabindex="2" class="focusable2">2</div> | 90 <div tabindex="2" class="focusable2">2</div> |
91 </test-overlay> | 91 </test-overlay> |
| 92 <test-overlay2> |
| 93 Overlay with optimized focusableNodes getter |
| 94 <button class="focusable1">1</button> |
| 95 </test-overlay2> |
92 </template> | 96 </template> |
93 </test-fixture> | 97 </test-fixture> |
94 | 98 |
95 <test-fixture id="backdrop"> | 99 <test-fixture id="backdrop"> |
96 <template> | 100 <template> |
97 <test-overlay with-backdrop> | 101 <test-overlay with-backdrop> |
98 Overlay with backdrop | 102 Overlay with backdrop |
99 </test-overlay> | 103 </test-overlay> |
100 </template> | 104 </template> |
101 </test-fixture> | 105 </test-fixture> |
102 | 106 |
103 <test-fixture id="multiple"> | 107 <test-fixture id="multiple"> |
104 <template> | 108 <template> |
105 <test-overlay class="overlay-1"> | 109 <test-overlay class="overlay-1"> |
106 Test overlay 1 | 110 Test overlay 1 |
107 </test-overlay> | 111 </test-overlay> |
108 <test-overlay class="overlay-2"> | 112 <test-overlay class="overlay-2"> |
109 Test overlay 2 | 113 Test overlay 2 |
110 </test-overlay> | 114 </test-overlay> |
111 <test-overlay2 class="overlay-3"> | 115 <test-overlay2 class="overlay-3"> |
112 Other overlay 3 | 116 Other overlay 3 |
113 </test-overlay2> | 117 </test-overlay2> |
114 </template> | 118 </template> |
115 </test-fixture> | 119 </test-fixture> |
116 | 120 |
117 <test-fixture id="composed"> | 121 <test-fixture id="composed"> |
118 <template> | 122 <template> |
119 <test-menu-button> | 123 <test-menu-button></test-menu-button> |
120 Composed overlay | |
121 <button>Button</button> | |
122 </test-menu-button> | |
123 </template> | 124 </template> |
124 </test-fixture> | 125 </test-fixture> |
125 | 126 |
126 <test-buttons id="buttons"></test-buttons> | 127 <test-buttons id="buttons"></test-buttons> |
127 <input id="focusInput" placeholder="focus input"> | 128 <input id="focusInput" placeholder="focus input"> |
128 | 129 |
129 <script> | 130 <script> |
130 | 131 |
131 HTMLImports.whenReady(function() { | |
132 // Enable document-wide tap recognizer. | |
133 Polymer.Gestures.add(document, 'tap', null); | |
134 }); | |
135 | |
136 function runAfterOpen(overlay, callback) { | 132 function runAfterOpen(overlay, callback) { |
137 overlay.addEventListener('iron-overlay-opened', callback); | 133 overlay.addEventListener('iron-overlay-opened', callback); |
138 overlay.open(); | 134 overlay.open(); |
139 } | 135 } |
140 | 136 |
141 function runAfterClose(overlay, callback) { | 137 function runAfterClose(overlay, callback) { |
142 overlay.addEventListener('iron-overlay-closed', callback); | 138 overlay.addEventListener('iron-overlay-closed', callback); |
143 overlay.close(); | 139 overlay.close(); |
144 } | 140 } |
145 | 141 |
146 suite('basic overlay', function() { | 142 suite('basic overlay', function() { |
147 var overlay; | 143 var overlay; |
148 | 144 |
149 setup(function() { | 145 setup(function() { |
150 overlay = fixture('basic'); | 146 overlay = fixture('basic'); |
151 }); | 147 }); |
152 | 148 |
153 test('overlay starts hidden', function() { | 149 test('overlay starts hidden', function() { |
154 assert.isFalse(overlay.opened, 'overlay starts closed'); | 150 assert.isFalse(overlay.opened, 'overlay starts closed'); |
155 assert.equal(getComputedStyle(overlay).display, 'none', 'overlay start
s hidden'); | 151 assert.equal(getComputedStyle(overlay).display, 'none', 'overlay start
s hidden'); |
156 }); | 152 }); |
157 | 153 |
158 test('_renderOpened called only after is attached', function(done) { | 154 test('_renderOpened called only after is attached', function(done) { |
159 var overlay = document.createElement('test-overlay'); | 155 var overlay = document.createElement('test-overlay'); |
160 // The overlay is ready at this point, but not yet attached. | 156 // The overlay is ready at this point, but not yet attached. |
161 var spy = sinon.spy(overlay, '_renderOpened'); | 157 var spy = sinon.spy(overlay, '_renderOpened'); |
162 // This triggers _openedChanged. | 158 // This triggers _openedChanged. |
163 overlay.opened = true; | 159 overlay.opened = true; |
164 // Even if not attached yet, overlay should be the current overlay! | |
165 assert.equal(overlay, overlay._manager.currentOverlay(), 'currentOverl
ay ok'); | |
166 // Wait long enough for requestAnimationFrame callback. | 160 // Wait long enough for requestAnimationFrame callback. |
167 overlay.async(function() { | 161 overlay.async(function() { |
168 assert.isFalse(spy.called, '_renderOpened not called'); | 162 assert.isFalse(spy.called, '_renderOpened not called'); |
| 163 // Because not attached yet, overlay should not be the current overl
ay! |
| 164 assert.isNotOk(overlay._manager.currentOverlay(), 'currentOverlay no
t set'); |
169 done(); | 165 done(); |
170 }, 100); | 166 }, 100); |
171 }); | 167 }); |
172 | 168 |
173 test('overlay open/close events', function(done) { | 169 test('overlay open/close events', function(done) { |
174 var nevents = 0; | 170 var nevents = 0; |
175 | 171 |
176 overlay.addEventListener('iron-overlay-opened', function() { | 172 overlay.addEventListener('iron-overlay-opened', function() { |
177 nevents += 1; | 173 nevents += 1; |
178 overlay.opened = false; | 174 overlay.opened = false; |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 runAfterOpen(overlay, function() { | 498 runAfterOpen(overlay, function() { |
503 // Try to steal the focus | 499 // Try to steal the focus |
504 MockInteractions.focus(button); | 500 MockInteractions.focus(button); |
505 assert.equal(Polymer.dom(overlay).querySelector('[autofocus]'), docu
ment.activeElement, '<button autofocus> is focused'); | 501 assert.equal(Polymer.dom(overlay).querySelector('[autofocus]'), docu
ment.activeElement, '<button autofocus> is focused'); |
506 assert.equal(focusSpy.callCount, 0, 'button in body did not get the
focus'); | 502 assert.equal(focusSpy.callCount, 0, 'button in body did not get the
focus'); |
507 document.body.removeChild(button); | 503 document.body.removeChild(button); |
508 done(); | 504 done(); |
509 }); | 505 }); |
510 }); | 506 }); |
511 | 507 |
| 508 test('overlay with-backdrop and 1 focusable: prevent TAB and trap the fo
cus', function(done) { |
| 509 overlay.withBackdrop = true; |
| 510 runAfterOpen(overlay, function() { |
| 511 // 1ms timeout needed by IE10 to have proper focus switching. |
| 512 Polymer.Base.async(function() { |
| 513 // Spy keydown. |
| 514 var tabSpy = sinon.spy(); |
| 515 document.addEventListener('keydown', tabSpy); |
| 516 // Simulate TAB. |
| 517 MockInteractions.pressAndReleaseKeyOn(document, 9); |
| 518 assert.equal(Polymer.dom(overlay).querySelector('[autofocus]'), do
cument.activeElement, 'focus stays on button'); |
| 519 assert.isTrue(tabSpy.calledOnce, 'keydown spy called'); |
| 520 assert.isTrue(tabSpy.getCall(0).args[0].defaultPrevented, 'keydown
default prevented'); |
| 521 // Cleanup. |
| 522 document.removeEventListener('keydown', tabSpy); |
| 523 done(); |
| 524 }, 1); |
| 525 }); |
| 526 }); |
| 527 |
| 528 test('empty overlay with-backdrop: prevent TAB and trap the focus', func
tion(done) { |
| 529 overlay = fixture('basic'); |
| 530 overlay.withBackdrop = true; |
| 531 runAfterOpen(overlay, function() { |
| 532 // 1ms timeout needed by IE10 to have proper focus switching. |
| 533 Polymer.Base.async(function() { |
| 534 // Spy keydown. |
| 535 var tabSpy = sinon.spy(); |
| 536 document.addEventListener('keydown', tabSpy); |
| 537 // Simulate TAB. |
| 538 MockInteractions.pressAndReleaseKeyOn(document, 9); |
| 539 assert.equal(overlay, document.activeElement, 'focus stays on over
lay'); |
| 540 assert.isTrue(tabSpy.calledOnce, 'keydown spy called'); |
| 541 assert.isTrue(tabSpy.getCall(0).args[0].defaultPrevented, 'keydown
default prevented'); |
| 542 // Cleanup. |
| 543 document.removeEventListener('keydown', tabSpy); |
| 544 done(); |
| 545 }, 1); |
| 546 }); |
| 547 }); |
| 548 |
512 }); | 549 }); |
513 | 550 |
514 suite('focusable nodes', function() { | 551 suite('focusable nodes', function() { |
515 var overlay, overlayWithTabIndex; | 552 var overlay, overlayWithTabIndex, overlayFocusableNodes; |
516 | 553 |
517 setup(function() { | 554 setup(function() { |
518 var f = fixture('focusables'); | 555 var f = fixture('focusables'); |
519 overlay = f[0]; | 556 overlay = f[0]; |
520 overlayWithTabIndex = f[1]; | 557 overlayWithTabIndex = f[1]; |
| 558 overlayFocusableNodes = f[2]; |
521 }); | 559 }); |
522 | 560 |
523 test('_focusableNodes returns nodes that are focusable', function() { | 561 test('_focusableNodes returns nodes that are focusable', function() { |
524 var focusableNodes = overlay._focusableNodes; | 562 var focusableNodes = overlay._focusableNodes; |
525 assert.equal(focusableNodes.length, 3, '3 nodes are focusable'); | 563 assert.equal(focusableNodes.length, 3, '3 nodes are focusable'); |
526 assert.equal(focusableNodes[0], Polymer.dom(overlay).querySelector('.f
ocusable1')); | 564 assert.equal(focusableNodes[0], Polymer.dom(overlay).querySelector('.f
ocusable1')); |
527 assert.equal(focusableNodes[1], Polymer.dom(overlay).querySelector('.f
ocusable2')); | 565 assert.equal(focusableNodes[1], Polymer.dom(overlay).querySelector('.f
ocusable2')); |
528 assert.equal(focusableNodes[2], Polymer.dom(overlay).querySelector('.f
ocusable3')); | 566 assert.equal(focusableNodes[2], Polymer.dom(overlay).querySelector('.f
ocusable3')); |
529 }); | 567 }); |
530 | 568 |
531 test('_focusableNodes includes overlay if it has a valid tabindex', func
tion() { | 569 test('_focusableNodes includes overlay if it has a valid tabindex', func
tion() { |
532 overlay.setAttribute('tabindex', '0'); | 570 overlay.setAttribute('tabindex', '0'); |
533 var focusableNodes = overlay._focusableNodes; | 571 var focusableNodes = overlay._focusableNodes; |
534 assert.equal(focusableNodes.length, 4, '4 focusable nodes'); | 572 assert.equal(focusableNodes.length, 4, '4 focusable nodes'); |
535 assert.notEqual(focusableNodes.indexOf(overlay), -1, 'overlay is inclu
ded'); | 573 assert.notEqual(focusableNodes.indexOf(overlay), -1, 'overlay is inclu
ded'); |
536 }); | 574 }); |
537 | 575 |
538 test('_focusableNodes respects the tabindex order', function() { | 576 test('_focusableNodes respects the tabindex order', function() { |
539 var focusableNodes = overlayWithTabIndex._focusableNodes; | 577 var focusableNodes = overlayWithTabIndex._focusableNodes; |
540 assert.equal(focusableNodes.length, 6, '6 nodes are focusable'); | 578 assert.equal(focusableNodes.length, 6, '6 nodes are focusable'); |
541 assert.equal(focusableNodes[0], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable1')); | 579 assert.equal(focusableNodes[0], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable1')); |
542 assert.equal(focusableNodes[1], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable2')); | 580 assert.equal(focusableNodes[1], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable2')); |
543 assert.equal(focusableNodes[2], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable3')); | 581 assert.equal(focusableNodes[2], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable3')); |
544 assert.equal(focusableNodes[3], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable4')); | 582 assert.equal(focusableNodes[3], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable4')); |
545 assert.equal(focusableNodes[4], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable5')); | 583 assert.equal(focusableNodes[4], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable5')); |
546 assert.equal(focusableNodes[5], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable6')); | 584 assert.equal(focusableNodes[5], Polymer.dom(overlayWithTabIndex).query
Selector('.focusable6')); |
547 }); | 585 }); |
548 | 586 |
| 587 test('_focusableNodes can be overridden', function() { |
| 588 // It has 1 focusable in the light dom, and 2 in the shadow dom. |
| 589 var focusableNodes = overlayFocusableNodes._focusableNodes; |
| 590 assert.equal(focusableNodes.length, 2, 'length ok'); |
| 591 assert.equal(focusableNodes[0], overlayFocusableNodes.$.first, 'first
ok'); |
| 592 assert.equal(focusableNodes[1], overlayFocusableNodes.$.last, 'last ok
'); |
| 593 }); |
| 594 |
549 test('with-backdrop: TAB & Shift+TAB wrap focus', function(done) { | 595 test('with-backdrop: TAB & Shift+TAB wrap focus', function(done) { |
550 overlay.withBackdrop = true; | 596 overlay.withBackdrop = true; |
551 var focusableNodes = overlay._focusableNodes; | 597 var focusableNodes = overlay._focusableNodes; |
552 runAfterOpen(overlay, function() { | 598 runAfterOpen(overlay, function() { |
| 599 // 1ms timeout needed by IE10 to have proper focus switching. |
553 Polymer.Base.async(function() { | 600 Polymer.Base.async(function() { |
554 // Go to last element. | 601 // Go to last element. |
555 MockInteractions.focus(focusableNodes[focusableNodes.length-1]); | 602 focusableNodes[focusableNodes.length-1].focus(); |
556 // Spy keydown. | 603 // Spy keydown. |
557 var tabSpy = sinon.spy(); | 604 var tabSpy = sinon.spy(); |
558 document.addEventListener('keydown', tabSpy); | 605 document.addEventListener('keydown', tabSpy); |
559 // Simulate TAB. | 606 // Simulate TAB. |
560 MockInteractions.pressAndReleaseKeyOn(document, 9); | 607 MockInteractions.pressAndReleaseKeyOn(document, 9); |
561 assert.equal(focusableNodes[0], document.activeElement, 'focus wra
pped to first focusable'); | 608 assert.equal(focusableNodes[0], document.activeElement, 'focus wra
pped to first focusable'); |
562 assert.isTrue(tabSpy.calledOnce, 'keydown spy called'); | 609 assert.isTrue(tabSpy.calledOnce, 'keydown spy called'); |
563 assert.isTrue(tabSpy.getCall(0).args[0].defaultPrevented, 'keydown
default prevented'); | 610 assert.isTrue(tabSpy.getCall(0).args[0].defaultPrevented, 'keydown
default prevented'); |
564 // Simulate Shift+TAB. | 611 // Simulate Shift+TAB. |
565 MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']); | 612 MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']); |
566 assert.equal(focusableNodes[focusableNodes.length-1], document.act
iveElement, 'focus wrapped to last focusable'); | 613 assert.equal(focusableNodes[focusableNodes.length-1], document.act
iveElement, 'focus wrapped to last focusable'); |
567 assert.isTrue(tabSpy.calledTwice, 'keydown spy called again'); | 614 assert.isTrue(tabSpy.calledTwice, 'keydown spy called again'); |
568 assert.isTrue(tabSpy.getCall(1).args[0].defaultPrevented, 'keydown
default prevented again'); | 615 assert.isTrue(tabSpy.getCall(1).args[0].defaultPrevented, 'keydown
default prevented again'); |
569 // Cleanup. | 616 // Cleanup. |
570 document.removeEventListener('keydown', tabSpy); | 617 document.removeEventListener('keydown', tabSpy); |
571 done(); | 618 done(); |
572 }, 1); | 619 }, 1); |
573 }); | 620 }); |
574 }); | 621 }); |
575 | 622 |
576 test('with-backdrop: TAB & Shift+TAB wrap focus respecting tabindex', fu
nction(done) { | 623 test('with-backdrop: TAB & Shift+TAB wrap focus respecting tabindex', fu
nction(done) { |
577 overlayWithTabIndex.withBackdrop = true; | 624 overlayWithTabIndex.withBackdrop = true; |
578 var focusableNodes = overlayWithTabIndex._focusableNodes; | 625 var focusableNodes = overlayWithTabIndex._focusableNodes; |
579 runAfterOpen(overlayWithTabIndex, function() { | 626 runAfterOpen(overlayWithTabIndex, function() { |
| 627 // 1ms timeout needed by IE10 to have proper focus switching. |
580 Polymer.Base.async(function() { | 628 Polymer.Base.async(function() { |
581 // Go to last element. | 629 // Go to last element. |
582 MockInteractions.focus(focusableNodes[focusableNodes.length-1]); | 630 focusableNodes[focusableNodes.length-1].focus(); |
583 // Simulate TAB. | 631 // Simulate TAB. |
584 MockInteractions.pressAndReleaseKeyOn(document, 9); | 632 MockInteractions.pressAndReleaseKeyOn(document, 9); |
585 assert.equal(focusableNodes[0], document.activeElement, 'focus wra
pped to first focusable'); | 633 assert.equal(focusableNodes[0], document.activeElement, 'focus wra
pped to first focusable'); |
586 // Simulate Shift+TAB. | 634 // Simulate Shift+TAB. |
587 MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']); | 635 MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']); |
588 assert.equal(focusableNodes[focusableNodes.length-1], document.act
iveElement, 'focus wrapped to last focusable'); | 636 assert.equal(focusableNodes[focusableNodes.length-1], document.act
iveElement, 'focus wrapped to last focusable'); |
589 done(); | 637 done(); |
590 }, 1); | 638 }, 1); |
591 }); | 639 }); |
592 }); | 640 }); |
593 | 641 |
| 642 test('with-backdrop: Shift+TAB after open wrap focus', function(done) { |
| 643 overlay.withBackdrop = true; |
| 644 var focusableNodes = overlay._focusableNodes; |
| 645 runAfterOpen(overlay, function() { |
| 646 // 1ms timeout needed by IE10 to have proper focus switching. |
| 647 Polymer.Base.async(function() { |
| 648 // Spy keydown. |
| 649 var tabSpy = sinon.spy(); |
| 650 document.addEventListener('keydown', tabSpy); |
| 651 // Simulate Shift+TAB. |
| 652 MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']); |
| 653 assert.equal(focusableNodes[focusableNodes.length-1], document.act
iveElement, 'focus wrapped to last focusable'); |
| 654 assert.isTrue(tabSpy.calledOnce, 'keydown spy called'); |
| 655 assert.isTrue(tabSpy.getCall(0).args[0].defaultPrevented, 'keydown
default prevented'); |
| 656 // Cleanup. |
| 657 document.removeEventListener('keydown', tabSpy); |
| 658 done(); |
| 659 }, 1); |
| 660 }); |
| 661 }); |
| 662 |
| 663 test('with-backdrop: Shift+TAB wrap focus in shadowDOM', function(done)
{ |
| 664 overlayFocusableNodes.withBackdrop = true; |
| 665 runAfterOpen(overlayFocusableNodes, function() { |
| 666 // 1ms timeout needed by IE10 to have proper focus switching. |
| 667 Polymer.Base.async(function() { |
| 668 // Spy keydown. |
| 669 var tabSpy = sinon.spy(); |
| 670 document.addEventListener('keydown', tabSpy); |
| 671 // Simulate Shift+TAB. |
| 672 MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']); |
| 673 assert.equal(overlayFocusableNodes.$.last, Polymer.IronOverlayMana
ger.deepActiveElement, 'focus wrapped to last focusable in the shadowDOM'); |
| 674 assert.isTrue(tabSpy.calledOnce, 'keydown spy called'); |
| 675 assert.isTrue(tabSpy.getCall(0).args[0].defaultPrevented, 'keydown
default prevented'); |
| 676 // Cleanup. |
| 677 document.removeEventListener('keydown', tabSpy); |
| 678 done(); |
| 679 }, 1); |
| 680 }); |
| 681 }); |
| 682 |
594 }); | 683 }); |
595 | 684 |
596 suite('Polymer.IronOverlayManager.deepActiveElement', function() { | 685 suite('Polymer.IronOverlayManager.deepActiveElement', function() { |
597 | 686 |
598 test('handles document.body', function () { | 687 test('handles document.body', function () { |
599 document.body.focus(); | 688 document.body.focus(); |
600 assert.equal(Polymer.IronOverlayManager.deepActiveElement, document.bo
dy); | 689 assert.equal(Polymer.IronOverlayManager.deepActiveElement, document.bo
dy); |
601 }); | 690 }); |
602 | 691 |
603 test('handles light dom', function () { | 692 test('handles light dom', function () { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
738 // Ensure detached is executed. | 827 // Ensure detached is executed. |
739 Polymer.dom.flush(); | 828 Polymer.dom.flush(); |
740 assert.isFalse(overlay.backdropElement.opened, 'backdrop is closed')
; | 829 assert.isFalse(overlay.backdropElement.opened, 'backdrop is closed')
; |
741 assert.isNotOk(overlay.backdropElement.parentNode, 'backdrop is remo
ved from the DOM'); | 830 assert.isNotOk(overlay.backdropElement.parentNode, 'backdrop is remo
ved from the DOM'); |
742 assert.lengthOf(document.querySelectorAll('iron-overlay-backdrop'),
0, 'no backdrop elements on body'); | 831 assert.lengthOf(document.querySelectorAll('iron-overlay-backdrop'),
0, 'no backdrop elements on body'); |
743 assert.isNotOk(overlay._manager.currentOverlay(), 'currentOverlay ok
'); | 832 assert.isNotOk(overlay._manager.currentOverlay(), 'currentOverlay ok
'); |
744 done(); | 833 done(); |
745 }); | 834 }); |
746 }); | 835 }); |
747 | 836 |
748 test('manager.getBackdrops() immediately updated on opened changes', fun
ction() { | 837 test('manager.getBackdrops() updated on opened changes', function(done)
{ |
749 overlay.opened = true; | 838 runAfterOpen(overlay, function() { |
750 assert.equal(Polymer.IronOverlayManager.getBackdrops().length, 1, 'ove
rlay added to manager backdrops'); | 839 assert.equal(Polymer.IronOverlayManager.getBackdrops().length, 1, 'o
verlay added to manager backdrops'); |
751 overlay.opened = false; | 840 overlay.close(); |
752 assert.equal(Polymer.IronOverlayManager.getBackdrops().length, 0, 'ove
rlay removed from manager backdrops'); | 841 assert.equal(Polymer.IronOverlayManager.getBackdrops().length, 0, 'o
verlay removed from manager backdrops'); |
| 842 done(); |
| 843 }); |
753 }); | 844 }); |
754 | 845 |
755 test('updating with-backdrop to false closes backdrop', function(done) { | 846 test('updating with-backdrop to false closes backdrop', function(done) { |
756 runAfterOpen(overlay, function() { | 847 runAfterOpen(overlay, function() { |
757 overlay.withBackdrop = false; | 848 overlay.withBackdrop = false; |
758 assert.isFalse(overlay.backdropElement.opened, 'backdrop is closed')
; | 849 assert.isFalse(overlay.backdropElement.opened, 'backdrop is closed')
; |
759 assert.isNotObject(overlay.backdropElement.parentNode, 'backdrop is
removed from document'); | 850 assert.isNotObject(overlay.backdropElement.parentNode, 'backdrop is
removed from document'); |
760 done(); | 851 done(); |
761 }); | 852 }); |
762 }); | 853 }); |
763 | 854 |
764 test('backdrop is removed when toggling overlay opened', function(done)
{ | 855 test('backdrop is removed when toggling overlay opened', function(done)
{ |
765 overlay.open(); | 856 overlay.open(); |
766 assert.isOk(overlay.backdropElement.parentNode, 'backdrop is immediate
ly inserted in the document'); | |
767 runAfterClose(overlay, function() { | 857 runAfterClose(overlay, function() { |
768 assert.isFalse(overlay.backdropElement.opened, 'backdrop is closed')
; | 858 assert.isFalse(overlay.backdropElement.opened, 'backdrop is closed')
; |
769 assert.isNotOk(overlay.backdropElement.parentNode, 'backdrop is remo
ved from document'); | 859 assert.isNotOk(overlay.backdropElement.parentNode, 'backdrop is remo
ved from document'); |
770 done(); | 860 done(); |
771 }); | 861 }); |
772 }); | 862 }); |
773 | 863 |
774 test('withBackdrop = true prevents click outside event', function(done)
{ | |
775 runAfterOpen(overlay, function() { | |
776 overlay.addEventListener('iron-overlay-canceled', function(event) { | |
777 assert.isTrue(event.detail.defaultPrevented, 'click event prevente
d'); | |
778 done(); | |
779 }); | |
780 MockInteractions.tap(document.body); | |
781 }); | |
782 }); | |
783 | |
784 test('withBackdrop = false does not prevent click outside event', functi
on(done) { | 864 test('withBackdrop = false does not prevent click outside event', functi
on(done) { |
785 overlay.withBackdrop = false; | 865 overlay.withBackdrop = false; |
786 runAfterOpen(overlay, function() { | 866 runAfterOpen(overlay, function() { |
787 overlay.addEventListener('iron-overlay-canceled', function(event) { | 867 overlay.addEventListener('iron-overlay-canceled', function(event) { |
788 assert.isFalse(event.detail.defaultPrevented, 'click event not pre
vented'); | 868 assert.isFalse(event.detail.defaultPrevented, 'click event not pre
vented'); |
789 done(); | 869 done(); |
790 }); | 870 }); |
791 MockInteractions.tap(document.body); | 871 MockInteractions.tap(document.body); |
792 }); | 872 }); |
793 }); | 873 }); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 | 927 |
848 setup(function() { | 928 setup(function() { |
849 var f = fixture('multiple'); | 929 var f = fixture('multiple'); |
850 overlay1 = f[0]; | 930 overlay1 = f[0]; |
851 overlay2 = f[1]; | 931 overlay2 = f[1]; |
852 overlays = Polymer.IronOverlayManager._overlays; | 932 overlays = Polymer.IronOverlayManager._overlays; |
853 }); | 933 }); |
854 | 934 |
855 test('no duplicates after attached', function(done) { | 935 test('no duplicates after attached', function(done) { |
856 overlay1 = document.createElement('test-overlay'); | 936 overlay1 = document.createElement('test-overlay'); |
857 overlay1.addEventListener('iron-overlay-opened',function() { | 937 runAfterOpen(overlay1, function() { |
858 assert.equal(overlays.length, 1, 'correct count after open and attac
hed'); | 938 assert.equal(overlays.length, 1, 'correct count after open and attac
hed'); |
859 document.body.removeChild(overlay1); | 939 document.body.removeChild(overlay1); |
860 done(); | 940 done(); |
861 }); | 941 }); |
862 overlay1.opened = true; | |
863 assert.equal(overlays.length, 1, 'immediately updated'); | |
864 document.body.appendChild(overlay1); | 942 document.body.appendChild(overlay1); |
865 }); | 943 }); |
866 | 944 |
867 test('open twice handled', function() { | 945 test('call open multiple times handled', function(done) { |
868 overlay1.open(); | 946 overlay1.open(); |
869 assert.equal(overlays.length, 1, '1 overlay after open'); | |
870 overlay1.open(); | 947 overlay1.open(); |
871 assert.equal(overlays.length, 1, '1 overlay after second open'); | 948 runAfterOpen(overlay1, function() { |
| 949 assert.equal(overlays.length, 1, '1 overlay after open'); |
| 950 done(); |
| 951 }) |
872 }); | 952 }); |
873 | 953 |
874 test('close handled', function() { | 954 test('close handled', function(done) { |
875 overlay1.open(); | 955 runAfterOpen(overlay1, function() { |
876 overlay1.close(); | 956 overlay1.close(); |
877 assert.equal(overlays.length, 0, '0 overlays after close'); | 957 assert.equal(overlays.length, 0, '0 overlays after close'); |
| 958 done(); |
| 959 }); |
878 }); | 960 }); |
879 | 961 |
880 test('open/close brings overlay on top', function() { | 962 test('open/close brings overlay on top', function(done) { |
881 overlay1.open(); | 963 overlay1.open(); |
882 overlay2.open(); | 964 runAfterOpen(overlay2, function() { |
883 assert.equal(overlays.indexOf(overlay1), 0, 'overlay1 at index 0'); | 965 assert.equal(overlays.indexOf(overlay1), 0, 'overlay1 at index 0'); |
884 assert.equal(overlays.indexOf(overlay2), 1, 'overlay2 at index 1'); | 966 assert.equal(overlays.indexOf(overlay2), 1, 'overlay2 at index 1'); |
885 overlay1.close(); | 967 overlay1.close(); |
886 overlay1.open(); | 968 runAfterOpen(overlay1, function() { |
887 assert.equal(overlays.indexOf(overlay1), 1, 'overlay1 moved at index 1
'); | 969 assert.equal(overlays.indexOf(overlay1), 1, 'overlay1 moved at ind
ex 1'); |
888 assert.isAbove(parseInt(overlay1.style.zIndex), parseInt(overlay2.styl
e.zIndex), 'overlay1 on top of overlay2'); | 970 assert.isAbove(parseInt(overlay1.style.zIndex), parseInt(overlay2.
style.zIndex), 'overlay1 on top of overlay2'); |
| 971 done(); |
| 972 }); |
| 973 }); |
889 }); | 974 }); |
890 }); | 975 }); |
891 | 976 |
892 suite('z-ordering', function() { | 977 suite('z-ordering', function() { |
893 | 978 |
894 var originalMinimumZ; | 979 var originalMinimumZ; |
895 var overlay1, overlay2; | 980 var overlay1, overlay2; |
896 | 981 |
897 setup(function() { | 982 setup(function() { |
898 var f = fixture('multiple'); | 983 var f = fixture('multiple'); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 overlay2 = f[1]; | 1031 overlay2 = f[1]; |
947 overlay3 = f[2]; | 1032 overlay3 = f[2]; |
948 overlay1.withBackdrop = overlay2.withBackdrop = overlay3.withBackdrop
= true; | 1033 overlay1.withBackdrop = overlay2.withBackdrop = overlay3.withBackdrop
= true; |
949 }); | 1034 }); |
950 | 1035 |
951 test('multiple overlays share the same backdrop', function() { | 1036 test('multiple overlays share the same backdrop', function() { |
952 assert.isTrue(overlay1.backdropElement === overlay2.backdropElement, '
overlay1 and overlay2 have the same backdrop element'); | 1037 assert.isTrue(overlay1.backdropElement === overlay2.backdropElement, '
overlay1 and overlay2 have the same backdrop element'); |
953 assert.isTrue(overlay1.backdropElement === overlay3.backdropElement, '
overlay1 and overlay3 have the same backdrop element'); | 1038 assert.isTrue(overlay1.backdropElement === overlay3.backdropElement, '
overlay1 and overlay3 have the same backdrop element'); |
954 }); | 1039 }); |
955 | 1040 |
956 test('only one iron-overlay-backdrop in the DOM', function() { | 1041 test('only one iron-overlay-backdrop in the DOM', function(done) { |
957 // Open them all. | 1042 // Open them all. |
958 overlay1.opened = overlay2.opened = overlay3.opened = true; | 1043 overlay1.opened = true; |
959 assert.lengthOf(document.querySelectorAll('iron-overlay-backdrop'), 1,
'only one backdrop element in the DOM'); | 1044 overlay2.opened = true; |
| 1045 runAfterOpen(overlay3, function() { |
| 1046 assert.lengthOf(document.querySelectorAll('iron-overlay-backdrop'),
1, 'only one backdrop element in the DOM'); |
| 1047 done(); |
| 1048 }); |
960 }); | 1049 }); |
961 | 1050 |
962 test('iron-overlay-backdrop is removed from the DOM when all overlays wi
th backdrop are closed', function(done) { | 1051 test('iron-overlay-backdrop is removed from the DOM when all overlays wi
th backdrop are closed', function(done) { |
963 // Open & close them all. | 1052 // Open & close them all. |
964 overlay1.opened = overlay2.opened = overlay3.opened = true; | 1053 overlay1.opened = true; |
965 overlay1.opened = overlay2.opened = overlay3.opened = false; | 1054 overlay2.opened = true; |
966 Polymer.Base.async(function() { | 1055 runAfterOpen(overlay3, function() { |
| 1056 overlay1.opened = overlay2.opened = overlay3.opened = false; |
| 1057 Polymer.dom.flush(); |
967 assert.lengthOf(document.querySelectorAll('iron-overlay-backdrop'),
0, 'backdrop element removed from the DOM'); | 1058 assert.lengthOf(document.querySelectorAll('iron-overlay-backdrop'),
0, 'backdrop element removed from the DOM'); |
968 done(); | 1059 done(); |
969 }, 100); | 1060 }); |
970 }); | 1061 }); |
971 | 1062 |
972 test('newest overlay appear on top', function(done) { | 1063 test('newest overlay appear on top', function(done) { |
973 runAfterOpen(overlay1, function() { | 1064 runAfterOpen(overlay1, function() { |
974 runAfterOpen(overlay2, function() { | 1065 runAfterOpen(overlay2, function() { |
975 var styleZ = parseInt(window.getComputedStyle(overlay1).zIndex, 10
); | 1066 var styleZ = parseInt(window.getComputedStyle(overlay1).zIndex, 10
); |
976 var style1Z = parseInt(window.getComputedStyle(overlay2).zIndex, 1
0); | 1067 var style1Z = parseInt(window.getComputedStyle(overlay2).zIndex, 1
0); |
977 var bgStyleZ = parseInt(window.getComputedStyle(overlay1.backdropE
lement).zIndex, 10); | 1068 var bgStyleZ = parseInt(window.getComputedStyle(overlay1.backdropE
lement).zIndex, 10); |
978 assert.isTrue(style1Z > styleZ, 'overlay2 has higher z-index than
overlay1'); | 1069 assert.isTrue(style1Z > styleZ, 'overlay2 has higher z-index than
overlay1'); |
979 assert.isTrue(styleZ > bgStyleZ, 'overlay1 has higher z-index than
backdrop'); | 1070 assert.isTrue(styleZ > bgStyleZ, 'overlay1 has higher z-index than
backdrop'); |
(...skipping 26 matching lines...) Expand all Loading... |
1006 assert.isTrue(style1Z > bgStyleZ, 'overlay2 has higher z-index tha
n backdrop'); | 1097 assert.isTrue(style1Z > bgStyleZ, 'overlay2 has higher z-index tha
n backdrop'); |
1007 assert.isTrue(styleZ < bgStyleZ, 'overlay1 has lower z-index than
backdrop'); | 1098 assert.isTrue(styleZ < bgStyleZ, 'overlay1 has lower z-index than
backdrop'); |
1008 done(); | 1099 done(); |
1009 }); | 1100 }); |
1010 }); | 1101 }); |
1011 }); | 1102 }); |
1012 | 1103 |
1013 }); | 1104 }); |
1014 | 1105 |
1015 suite('overlay in composed tree', function() { | 1106 suite('overlay in composed tree', function() { |
| 1107 var composed, overlay, trigger; |
| 1108 setup(function(done) { |
| 1109 composed = fixture('composed'); |
| 1110 overlay = composed.$.overlay; |
| 1111 trigger = composed.$.trigger; |
| 1112 overlay.withBackdrop = true; |
| 1113 overlay.addEventListener('iron-overlay-opened', function() { |
| 1114 done(); |
| 1115 }); |
| 1116 // Opens the overlay. |
| 1117 MockInteractions.tap(trigger); |
| 1118 }); |
| 1119 |
1016 test('click on overlay content does not close it', function(done) { | 1120 test('click on overlay content does not close it', function(done) { |
1017 var composed = fixture('composed'); | 1121 // Tap on button inside overlay. |
1018 // Opens overlay. | 1122 MockInteractions.tap(Polymer.dom(overlay).querySelector('button')); |
1019 MockInteractions.tap(composed.$.trigger); | 1123 Polymer.Base.async(function(){ |
1020 composed.$.dropdown.addEventListener('iron-overlay-opened', function()
{ | 1124 assert.isTrue(overlay.opened, 'overlay still opened'); |
1021 // Tap on button inside overlay. | 1125 done(); |
1022 MockInteractions.tap(Polymer.dom(composed).querySelector('button')); | 1126 }, 1); |
1023 Polymer.Base.async(function(){ | 1127 }); |
1024 assert.isTrue(composed.$.dropdown.opened, 'overlay still opened'); | 1128 |
1025 done(); | 1129 test('with-backdrop wraps the focus within the overlay', function(done)
{ |
1026 }, 1); | 1130 // 1ms timeout needed by IE10 to have proper focus switching. |
1027 }); | 1131 Polymer.Base.async(function(){ |
| 1132 var buttons = Polymer.dom(overlay).querySelectorAll('button'); |
| 1133 // Go to last element. |
| 1134 buttons[buttons.length-1].focus(); |
| 1135 // Spy keydown. |
| 1136 var tabSpy = sinon.spy(); |
| 1137 document.addEventListener('keydown', tabSpy); |
| 1138 // Simulate TAB. |
| 1139 MockInteractions.pressAndReleaseKeyOn(document, 9); |
| 1140 assert.equal(buttons[0], Polymer.IronOverlayManager.deepActiveElemen
t, 'focus wrapped to first focusable'); |
| 1141 assert.isTrue(tabSpy.calledOnce, 'keydown spy called'); |
| 1142 assert.isTrue(tabSpy.getCall(0).args[0].defaultPrevented, 'keydown d
efault prevented'); |
| 1143 // Simulate Shift+TAB. |
| 1144 MockInteractions.pressAndReleaseKeyOn(document, 9, ['shift']); |
| 1145 assert.equal(buttons[buttons.length-1], Polymer.IronOverlayManager.d
eepActiveElement, 'focus wrapped to last focusable'); |
| 1146 assert.isTrue(tabSpy.calledTwice, 'keydown spy called again'); |
| 1147 assert.isTrue(tabSpy.getCall(1).args[0].defaultPrevented, 'keydown d
efault prevented again'); |
| 1148 // Cleanup. |
| 1149 document.removeEventListener('keydown', tabSpy); |
| 1150 done(); |
| 1151 }, 1); |
1028 }); | 1152 }); |
1029 | 1153 |
1030 }); | 1154 }); |
1031 | 1155 |
1032 suite('always-on-top', function() { | 1156 suite('always-on-top', function() { |
1033 var overlay1, overlay2; | 1157 var overlay1, overlay2; |
1034 | 1158 |
1035 setup(function() { | 1159 setup(function() { |
1036 var f = fixture('multiple'); | 1160 var f = fixture('multiple'); |
1037 overlay1 = f[0]; | 1161 overlay1 = f[0]; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1106 overlay.close(); | 1230 overlay.close(); |
1107 assert.equal(overlay.getAttribute('aria-hidden'), 'true', 'overlay has
aria-hidden="true"'); | 1231 assert.equal(overlay.getAttribute('aria-hidden'), 'true', 'overlay has
aria-hidden="true"'); |
1108 }); | 1232 }); |
1109 | 1233 |
1110 }); | 1234 }); |
1111 </script> | 1235 </script> |
1112 | 1236 |
1113 </body> | 1237 </body> |
1114 | 1238 |
1115 </html> | 1239 </html> |
OLD | NEW |