diff options
Diffstat (limited to 'testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom.html')
-rw-r--r-- | testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom.html | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom.html b/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom.html new file mode 100644 index 0000000000..87293f1e3d --- /dev/null +++ b/testing/web-platform/tests/html/semantics/popovers/popover-shadow-dom.html @@ -0,0 +1,204 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<link rel="author" href="mailto:masonf@chromium.org"> +<link rel=help href="https://open-ui.org/components/popover.research.explainer"> +<link rel=help href="https://html.spec.whatwg.org/multipage/popover.html"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/declarative-shadow-dom-polyfill.js"></script> +<script src="resources/popover-utils.js"></script> + +<script> + function ensureShadowDom(host) { + host.querySelectorAll('my-element').forEach(host => { + if (host.shadowRoot) + return; // Declarative Shadow DOM is enabled + const template = host.firstElementChild; + assert_true(template instanceof HTMLTemplateElement); + const shadow = host.attachShadow({mode: 'open'}); + shadow.appendChild(template.content); + template.remove(); + }) + } + function findPopovers(root) { + let popovers = []; + if (!root) + return popovers; + if (root instanceof Element && root.matches('[popover]')) + popovers.push(root); + popovers.push(...findPopovers(root.shadowRoot)); + root.childNodes.forEach(child => { + popovers.push(...findPopovers(child)); + }) + return popovers; + } + function getPopoverReferences(testId) { + const testRoot = document.querySelector(`#${testId}`); + assert_true(!!testRoot); + ensureShadowDom(testRoot); + return findPopovers(testRoot); + } + function showTestPopover(testId,popoverNum) { + getPopoverReferences(testId)[popoverNum].showPopover(); + } +</script> + +<div id=test1> + <button onclick='showTestPopover("test1",0)'>Test1 Popover</button> + <my-element> + <template shadowrootmode=open> + <div popover> + <p>This should show, even though it is inside shadow DOM.</p> + </div> + </template> + </my-element> +</div> + +<script> + test(function() { + const popover = getPopoverReferences('test1')[0]; + popover.showPopover(); + assert_true(popover.matches(':popover-open')); + assert_true(isElementVisible(popover)); + popover.hidePopover(); // Cleanup + }, "Popovers located inside shadow DOM can still be shown"); +</script> + + +<div id=test2> + <button id=t2b1 onclick='showTestPopover("test2",0)'>Test 2 Popover 1</button> + <div popover anchor=t2b1 style="top: 200px;"> + <p>Popover 1</p> + <button id=t2b2 onclick='showTestPopover("test2",1)'>Test 2 Popover 2</button> + </div> + <my-element> + <template shadowrootmode=open> + <div popover anchor=t2b2 style="top: 400px;"> + <p>Hiding this popover will hide *all* open popovers,</p> + <p>because t2b2 doesn't exist in this context.</p> + </div> + </template> + </my-element> +</div> + +<script> + test(function() { + const [popover1,popover2] = getPopoverReferences('test2'); + popover1.showPopover(); + assert_true(popover1.matches(':popover-open')); + assert_true(isElementVisible(popover1)); + popover2.showPopover(); + assert_false(popover1.matches(':popover-open'), 'popover1 open'); // P1 was closed by P2 + assert_false(isElementVisible(popover1), 'popover1 visible'); + assert_true(popover2.matches(':popover-open'), 'popover2 open'); // P2 is open + assert_true(isElementVisible(popover2), 'popover2 visible'); + popover2.hidePopover(); // Cleanup + }, "anchor references do not cross shadow boundaries"); +</script> + + +<div id=test3> + <my-element> + <template shadowrootmode=open> + <button id=t3b1 onclick='showTestPopover("test3",0)'>Test 3 Popover 1</button> + <div popover anchor=t3b1> + <p>This popover will stay open when popover2 shows.</p> + <slot></slot> + </div> + </template> + <button id=t3b2 onclick='showTestPopover("test3",1)'>Test 3 Popover 2</button> + </my-element> + <div popover anchor=t3b2>Popover 2</div> +</div> + +<script> + promise_test(async function() { + const [popover1,popover2] = getPopoverReferences('test3'); + popover1.showPopover(); + assert_true(popover1.matches(':popover-open')); + assert_true(isElementVisible(popover1)); + // Showing popover2 should not close popover1, since it is a flat + // tree ancestor of popover2's anchor button. + popover2.showPopover(); + assert_true(popover2.matches(':popover-open')); + assert_true(isElementVisible(popover2)); + assert_true(popover1.matches(':popover-open')); + assert_true(isElementVisible(popover1)); + popover1.hidePopover(); + await waitForRender(); + assert_false(popover1.matches(':popover-open')); + assert_false(isElementVisible(popover1)); + assert_false(popover2.matches(':popover-open')); + assert_false(isElementVisible(popover2)); + }, "anchor references use the flat tree not the DOM tree"); +</script> + + +<div id=test4> + <button id=t4b1 onclick='showTestPopover("test4",0)'>Test 4 Popover 1</button> + <div popover anchor=t4b1> + <p>This should not get hidden when popover2 opens.</p> + <my-element> + <template shadowrootmode=open> + <button id=t4b2 onclick='showTestPopover("test4",1)'>Test 4 Popover 2</button> + <div popover anchor=t4b2> + <p>This should not hide popover1.</p> + </div> + </template> + </my-element> + </div> +</div> + +<script> + promise_test(async function() { + const [popover1,popover2] = getPopoverReferences('test4'); + popover1.showPopover(); + popover2.showPopover(); + // Both 1 and 2 should be open at this point. + assert_true(popover1.matches(':popover-open'), 'popover1 not open'); + assert_true(isElementVisible(popover1)); + assert_true(popover2.matches(':popover-open'), 'popover2 not open'); + assert_true(isElementVisible(popover2)); + // This should hide both of them. + popover1.hidePopover(); + await waitForRender(); + assert_false(popover1.matches(':popover-open')); + assert_false(isElementVisible(popover1)); + assert_false(popover2.matches(':popover-open')); + assert_false(isElementVisible(popover2)); + }, "The popover stack is preserved across shadow-inclusive ancestors"); +</script> + + +<div id=test5> + <template shadowrootmode=open> + <button popovertarget=p1>Test 5 Popover 1</button> + <div popover id=p1>Popover 1 + <p>This should not get hidden when popover2 opens.</p> + <button popovertarget=p2>Click</button> + </div> + <div popover id=p2>Popover 2 + <p>This should not hide popover1.</p> + </div> + </template> +</div> +<script> + promise_test(async function() { + polyfill_declarative_shadow_dom(test5); + const [popover1,popover2] = getPopoverReferences('test5'); + popover1.showPopover(); + popover1.querySelector('button').click(); // Use invoker to keep 2 visible + // Both 1 and 2 should be open at this point. + assert_true(popover1.matches(':popover-open'), 'popover1 not open'); + assert_true(isElementVisible(popover1)); + assert_true(popover2.matches(':popover-open'), 'popover2 not open'); + assert_true(isElementVisible(popover2)); + // This should hide both of them. + popover1.hidePopover(); + await waitForRender(); + assert_false(popover1.matches(':popover-open')); + assert_false(isElementVisible(popover1)); + assert_false(popover2.matches(':popover-open')); + assert_false(isElementVisible(popover2)); + }, "Popover ancestor relationships are within a root, not within the document"); +</script> |