popover-stacking.html (4051B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <link rel="author" href="mailto:masonf@chromium.org"> 4 <link rel=help href="https://html.spec.whatwg.org/multipage/popover.html"> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 8 <!-- Enumerate all the ways of creating an ancestor popover relationship --> 9 10 <div class="example"> 11 <p>Direct DOM children</p> 12 <div popover class=ancestor><p>Ancestor popover</p> 13 <div popover class=child><p>Child popover</p></div> 14 </div> 15 </div> 16 17 <div class="example"> 18 <p>Grandchildren</p> 19 <div popover class=ancestor><p>Ancestor popover</p> 20 <div> 21 <div> 22 <div popover class=child><p>Child popover</p></div> 23 </div> 24 </div> 25 </div> 26 </div> 27 28 <div class="example"> 29 <p>popovertarget attribute relationship</p> 30 <div popover class=ancestor><p>Ancestor popover</p> 31 <button popovertarget=trigger1 class=clickme>Button</button> 32 </div> 33 <div id=trigger1 popover class=child><p>Child popover</p></div> 34 </div> 35 36 <div class="example"> 37 <p>nested popovertarget attribute relationship</p> 38 <div popover class=ancestor><p>Ancestor popover</p> 39 <div> 40 <div> 41 <button popovertarget=trigger2 class=clickme>Button</button> 42 </div> 43 </div> 44 </div> 45 <div id=trigger2 popover class=child><p>Child popover</p></div> 46 </div> 47 48 <!-- Other examples --> 49 50 <button id=b1 onclick='p1.showPopover()'>Popover 1</button> 51 <div popover id=p1><p>This is popover #1</p> 52 <button id=b2 onclick='p2.showPopover()'>Popover 2</button> 53 <div popover id=p2><p>This is popover #2</p> 54 <button id=b3 onclick='p3.showPopover()'>Popover 3</button> 55 <div popover id=p3><p>This is popover #3</p></div> 56 </div> 57 </div> 58 59 <dialog id=d1>This is a dialog<button onclick='this.parentElement.close()'>Close</button></dialog> 60 <button id=b5 onclick='d1.showPopover()'>Dialog</button> 61 62 <script> 63 // Test basic ancestor relationships 64 for(let example of document.querySelectorAll('.example')) { 65 const descr = example.querySelector('p').textContent; 66 const ancestor = example.querySelector('[popover].ancestor'); 67 const child = example.querySelector('[popover].child'); 68 const clickToActivate = example.querySelector('.clickme'); 69 test(function() { 70 assert_true(!!descr && !!ancestor && !!child); 71 assert_false(ancestor.matches(':popover-open')); 72 assert_false(child.matches(':popover-open')); 73 ancestor.showPopover(); 74 if (clickToActivate) 75 clickToActivate.click(); 76 else 77 child.showPopover(); 78 assert_true(child.matches(':popover-open')); 79 assert_true(ancestor.matches(':popover-open')); 80 ancestor.hidePopover(); 81 assert_false(ancestor.matches(':popover-open')); 82 assert_false(child.matches(':popover-open')); 83 },descr); 84 } 85 86 const popovers = [p1, p2, p3]; 87 88 function assertState(...states) { 89 assert_equals(popovers.length,states.length); 90 for(let i=0;i<popovers.length;++i) { 91 assert_equals(popovers[i].matches(':popover-open'),states[i],`Popover #${i+1} incorrect state`); 92 } 93 } 94 95 test(function() { 96 function openManyPopovers() { 97 p1.showPopover(); 98 p2.showPopover(); 99 p3.showPopover(); 100 assertState(true,true,true); 101 } 102 openManyPopovers(); 103 d1.show(); // Dialog.show() should hide all popovers. 104 assertState(false,false,false); 105 d1.close(); 106 openManyPopovers(); 107 d1.showModal(); // Dialog.showModal() should also hide all popovers. 108 assertState(false,false,false); 109 d1.close(); 110 }, "popovers should be closed by dialogs") 111 112 test(function() { 113 // Note: d1 is a <dialog> element, not a popover. 114 assert_false(d1.open); 115 d1.show(); 116 assert_true(d1.open); 117 p1.showPopover(); 118 assertState(true,false,false); 119 assert_true(d1.open); 120 p1.hidePopover(); 121 assert_true(d1.open); 122 d1.close(); 123 assert_false(d1.open); 124 }, "dialogs should not be closed by popovers") 125 </script> 126 127 <style> 128 #p1 { top:350px; } 129 #p2 { top:350px; left:200px; } 130 #p3 { top:500px; } 131 </style>