popover-top-layer-interactions.html (3442B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <title>Interactions between top layer element types</title> 4 <link rel="author" href="mailto:masonf@chromium.org"> 5 <link rel=help href="https://open-ui.org/components/popover.research.explainer"> 6 <link rel=help href="https://html.spec.whatwg.org/multipage/popover.html"> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="/resources/testdriver.js"></script> 10 <script src="/resources/testdriver-vendor.js"></script> 11 <script src="/common/top-layer.js"></script> 12 <script src="resources/popover-utils.js"></script> 13 14 <body> 15 <script> 16 const types = Object.freeze({ 17 popover: Symbol("Popover"), 18 modalDialog: Symbol("Modal Dialog"), 19 fullscreen: Symbol("Fullscreen Element"), 20 }); 21 const examples = [ 22 { 23 type: types.popover, 24 closes: [types.popover], 25 createElement: () => Object.assign(document.createElement('div'), {popover: 'auto'}), 26 trigger: function() {this.element.showPopover()}, 27 close: function() {this.element.hidePopover()}, 28 isTopLayer: function() {return this.element.matches(':popover-open')}, 29 }, 30 { 31 type: types.modalDialog, 32 closes: [types.popover], 33 createElement: () => document.createElement('dialog'), 34 trigger: function() {this.element.showModal()}, 35 close: function() {this.element.close()}, 36 isTopLayer: function() {return this.element.matches(':modal')}, 37 }, 38 { 39 type: types.fullscreen, 40 closes: [types.popover], 41 createElement: () => document.createElement('div'), 42 trigger: async function(visibleElement) {assert_false(this.isTopLayer());await blessTopLayer(visibleElement);await this.element.requestFullscreen();}, 43 close: async function() {await document.exitFullscreen();}, 44 isTopLayer: function() {return this.element.matches(':fullscreen')}, 45 }, 46 ]; 47 48 function createElement(ex) { 49 assert_true(!ex.element); 50 const element = ex.element = ex.createElement(); 51 assert_true(!!element); 52 element.appendChild(document.createTextNode(`This is a ${ex.type.description}`)); 53 document.body.appendChild(element); 54 assert_false(ex.isTopLayer(),'Element should start out not in the top layer'); 55 return element; 56 } 57 async function doneWithExample(ex) { 58 assert_true(!!ex.element); 59 if (ex.isTopLayer()) 60 await ex.close(); 61 ex.element.remove(); 62 ex.element = null; 63 } 64 // Test interactions between top layer elements 65 for(let i=0;i<examples.length;++i) { 66 for(let j=0;j<examples.length;++j) { 67 const example1 = Object.assign([],examples[i]); 68 const example2 = Object.assign([],examples[j]); 69 const shouldClose = example2.closes.includes(example1.type); 70 const desc = `A ${example2.type.description} should${shouldClose ? "" : " *not*"} close a ${example1.type.description}.`; 71 promise_test(async t => { 72 const element1 = createElement(example1); 73 const element2 = createElement(example2); 74 t.add_cleanup(() => { 75 return Promise.all([ 76 doneWithExample(example1), 77 doneWithExample(example2), 78 ]); 79 }); 80 await example1.trigger(document.body); // Open the 1st top layer element 81 assert_true(example1.isTopLayer()); // Make sure it is top layer 82 await example2.trigger(element1); // Open the 2nd top layer element 83 assert_true(example2.isTopLayer()); // Make sure it is top layer 84 assert_equals(shouldClose,!example1.isTopLayer(),desc); 85 },desc); 86 } 87 } 88 89 </script>