blob: 12ee9929edca891700dc5e233675a12be126cc2c [file] [log] [blame] [edit]
<!DOCTYPE html>
<meta charset="utf-8">
<link rel="author" href="mailto:[email protected]">
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<!-- Enumerate all the ways of creating an ancestor popup relationship -->
<div class="example">
<p>Direct DOM children</p>
<div popup=popup class=ancestor><p>Ancestor popup</p>
<div popup=popup class=child><p>Child popup</p></div>
</div>
</div>
<div class="example">
<p>Grandchildren</p>
<div popup=popup class=ancestor><p>Ancestor popup</p>
<div>
<div>
<div popup=popup class=child><p>Child popup</p></div>
</div>
</div>
</div>
</div>
<div class="example">
<p>triggerpopup attribute relationship</p>
<div popup=popup class=ancestor><p>Ancestor popup</p>
<button triggerpopup=trigger1 class=clickme>Button</button>
</div>
<div id=trigger1 popup=popup class=child><p>Child popup</p></div>
</div>
<div class="example">
<p>nested triggerpopup attribute relationship</p>
<div popup=popup class=ancestor><p>Ancestor popup</p>
<div>
<div>
<button triggerpopup=trigger2 class=clickme>Button</button>
</div>
</div>
</div>
<div id=trigger2 popup=popup class=child><p>Child popup</p></div>
</div>
<div class="example">
<p>anchor attribute relationship</p>
<div id=anchor1 popup=popup class=ancestor><p>Ancestor popup</p></div>
<div anchor=anchor1 popup=popup class=child><p>Child popup</p></div>
</div>
<div class="example">
<p>indirect anchor attribute relationship</p>
<div popup=popup class=ancestor>
<p>Ancestor popup</p>
<div>
<div>
<span id=anchor2>Anchor</span>
</div>
</div>
</div>
<div anchor=anchor2 popup=popup class=child><p>Child popup</p></div>
</div>
<!-- Other examples -->
<div popup=popup id=p1 anchor=b1><p>This is popup #1</p>
<button id=b2 onclick='p2.showPopup()'>Popup 2</button>
<button id=b4 onclick='p4.showPopup()'>Popup 4</button>
</div>
<div popup=popup id=p2 anchor=b2><p>This is popup #2</p>
<button id=b3 onclick='p3.showPopup()'>Popup 3</button>
</div>
<div popup=popup id=p3 anchor=b3><p>This is popup #3</p></div>
<div popup=popup id=p4 anchor=b4><p>This is popup #4</p></div>
<button id=b1 onclick='p1.showPopup()'>Popup 1</button>
<dialog id=d1>This is a dialog<button onclick='this.parentElement.close()'>Close</button></dialog>
<button id=b5 onclick='d1.showPopup()'>Dialog</button>
<script>
// Test basic ancestor relationships
for(let example of document.querySelectorAll('.example')) {
const descr = example.querySelector('p').textContent;
const ancestor = example.querySelector('[popup].ancestor');
const child = example.querySelector('[popup].child');
const clickToActivate = example.querySelector('.clickme');
test(function() {
assert_true(!!descr && !!ancestor && !!child);
assert_false(ancestor.matches(':popup-open'));
assert_false(child.matches(':popup-open'));
ancestor.showPopup();
if (clickToActivate)
clickToActivate.click();
else
child.showPopup();
assert_true(child.matches(':popup-open'));
assert_true(ancestor.matches(':popup-open'));
ancestor.hidePopup();
assert_false(ancestor.matches(':popup-open'));
assert_false(child.matches(':popup-open'));
},descr);
}
const popups = [p1, p2, p3, p4];
function assertState(...states) {
assert_equals(popups.length,states.length);
for(let i=0;i<popups.length;++i) {
assert_equals(popups[i].matches(':popup-open'),states[i],`Popup #${i+1} incorrect state`);
}
}
test(function() {
assertState(false,false,false,false);
p1.showPopup();
assertState(true,false,false,false);
p2.showPopup();
assertState(true,true,false,false);
p3.showPopup();
assertState(true,true,true,false);
// P4 is a sibling of P2, so showing it should
// close P2 and P3.
p4.showPopup();
assertState(true,false,false,true);
// P2 should close P4 now.
p2.showPopup();
assertState(true,true,false,false);
// Hiding P1 should hide all.
p1.hidePopup();
assertState(false,false,false,false);
}, "more complex nesting, all using anchor ancestry")
test(function() {
function openManyPopups() {
p1.showPopup();
p2.showPopup();
p3.showPopup();
assertState(true,true,true,false);
}
openManyPopups();
d1.show(); // Dialog.showPopup() should hide all popups.
assertState(false,false,false,false);
d1.close();
openManyPopups();
d1.showModal(); // Dialog.showModal() should also hide all popups.
assertState(false,false,false,false);
d1.close();
}, "popups should be closed by dialogs")
test(function() {
// Note: d1 is a <dialog> element, not a popup.
assert_false(d1.open);
d1.show();
assert_true(d1.open);
p1.showPopup();
assertState(true,false,false,false);
assert_true(d1.open);
p1.hidePopup();
assert_true(d1.open);
d1.close();
assert_false(d1.open);
}, "dialogs should not be closed by popups")
</script>
<style>
#p1 { top:350px; }
#p2 { top:350px; left:200px; }
#p3 { top:500px; }
#p4 { top:500px;left:200px; }
</style>