test_drag_drop_shadow_crossing_selection.html (4351B)
1 <!doctype html> 2 <title>Test dnd for shadow-crossing selection</title> 3 <script src="/tests/SimpleTest/SimpleTest.js"></script> 4 <script src="/tests/SimpleTest/EventUtils.js"></script> 5 <link rel="stylesheet" href="/tests/SimpleTest/test.css"/> 6 <style> 7 </style> 8 <div> 9 <span id="outer1">Outer1</span> 10 <div id="host"> 11 <template shadowrootmode="open"> 12 <span>Inner1</span> 13 <span>Inner2</span> 14 <span id="inner3">Inner3</span> 15 </template> 16 </div> 17 <span id="outer2">Outer2</span> 18 <div id="host2"> 19 <template shadowrootmode="open"> 20 <span id="inner4">Inner4</span> 21 </template> 22 </div> 23 </div> 24 25 <input id="dropZone" /> 26 <script> 27 const selection = window.getSelection(); 28 29 async function waitForEvent(event) { 30 return new Promise(r => { 31 addEventListener(event, function(e) { 32 r(e.target); 33 }, { once : true}); 34 }); 35 } 36 37 async function waitForDropEvent() { 38 return new Promise(r => { 39 addEventListener("drop", function(e) { 40 r(event.dataTransfer.getData('text/html')); 41 }, { once : true}); 42 }); 43 } 44 45 async function run(startNode, startOffset, endNode, endOffset, expectedValue, expectedTarget, expectedHTML, assertionMessage) { 46 selection.setBaseAndExtent(startNode, startOffset, endNode, endOffset); 47 const waitForDragStart = waitForEvent("dragstart"); 48 const waitForDragEnd = waitForEvent("dragend"); 49 const waitForDrop = waitForDropEvent(); 50 await synthesizePlainDragAndDrop({ 51 srcSelection: selection, 52 destElement: dropZone 53 }); 54 55 const dragStartTarget = await waitForDragStart; 56 const dragEndTarget = await waitForDragEnd; 57 const htmlData = await waitForDrop; 58 59 is(dropZone.value, expectedValue, assertionMessage); 60 is(dragStartTarget, dragEndTarget, "dragstart and dragend should have the same target"); 61 is(dragStartTarget, expectedTarget, "dragstart target should be the same as expectedTarget"); 62 is(htmlData.replace(/\r\n?/g, "\n"), expectedHTML, "dragged html should match") 63 64 selection.empty(); 65 dropZone.value = ''; 66 } 67 68 add_task(async function runTests() { 69 await SpecialPowers.pushPrefEnv({ 70 set: [ 71 ["dom.shadowdom.selection_across_boundary.enabled", true], 72 ["ui.dragThresholdX", 4], // bug 1873142 73 ["ui.dragThresholdY", 4], // bug 1873142 74 ], 75 }); 76 77 // synthesizePlainDragAndDrop would use the focused node to initiate DnD, so 78 // the expectedTarget is provided based this. 79 80 // light to shadow 81 let sel = [outer1.firstChild, 2, host.shadowRoot.getElementById("inner3").firstChild, 5]; 82 await run( 83 ...sel, 84 "ter1 Inner1 Inner2 Inner", 85 host, // expectedTarget - focused node is inside the shadow dom, hence the host is the target to preserve encapsulation. 86 "<span id=\"outer1\">ter1</span>\n <div id=\"host\">\n <span>Inner1</span>\n <span>Inner2</span>\n <span id=\"inner3\">Inner</span></div>", 87 "start is in light DOM and end is in shadow DOM"); 88 89 // light to light 90 sel = [outer1.firstChild, 2, outer2.firstChild, 6]; 91 await run( 92 ...sel, 93 "ter1 Inner1 Inner2 Inner3 Outer2", 94 outer2.firstChild, // expectedTarget - focused node is outer2.firstChild 95 "<span id=\"outer1\">ter1</span>\n <div id=\"host\">\n <span>Inner1</span>\n <span>Inner2</span>\n <span id=\"inner3\">Inner3</span>\n </div>\n <span id=\"outer2\">Outer2</span>", 96 "start is in light DOM and end is in light DOM" 97 ); 98 99 // shadow to light 100 sel = [host.shadowRoot.getElementById("inner3").firstChild, 2, outer2.firstChild, 6]; 101 await run( 102 ...sel, 103 "ner3 Outer2", 104 outer2.firstChild, // expectedTarget - focused node is outer2.firstChild 105 "<div id=\"host\"><span id=\"inner3\">ner3</span>\n </div>\n <span id=\"outer2\">Outer2</span>", 106 "start is in shadow DOM and end is in light DOM" 107 ); 108 109 // shadow to shadow 110 sel = [host.shadowRoot.getElementById("inner3").firstChild, 2, host2.shadowRoot.getElementById("inner4").firstChild, 6]; 111 await run( 112 ...sel, 113 "ner3 Outer2 Inner4 ", 114 host2, // expectedTarget - focused node is inside the shadow dom, hence the host is the target to preserve encapsulation. 115 "<div id=\"host\"><span id=\"inner3\">ner3</span>\n </div>\n <span id=\"outer2\">Outer2</span>\n <div id=\"host2\">\n <span id=\"inner4\">Inner4</span>\n </div>", 116 "start is in shadow DOM and end is in shadow DOM" 117 ); 118 }); 119 </script>