| <!DOCTYPE html> |
| <meta charset="utf-8"> |
| <link rel="author" href="mailto:[email protected]"> |
| <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/popover-utils.js"></script> |
| |
| <script> |
| 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); |
| return findPopovers(testRoot); |
| } |
| </script> |
| |
| <div id=test1> |
| <button>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=test4> |
| <button>Test 4 Popover 1</button> |
| <div popover> |
| <p>This should not get hidden when popover2 opens.</p> |
| <my-element> |
| <template shadowrootmode=open> |
| <button id=t4b2>Test 4 Popover 2</button> |
| <div popover> |
| <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() { |
| 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> |