dropEffect-test-helper.js (5580B)
1 const effectAllowedList = ["uninitialized", "undefined", "none", "all", 2 "copy", 3 "move", "link", "copyMove", "copyLink", "linkMove", "dummy" 4 ]; 5 const dropEffectList = ["none", "copy", "move", "link", "dummy"]; 6 7 // Drop callback used for `dropEffect` tests in `dnd/drop/`. This function 8 // compares the text content of the drop target with the `dropEffect` and 9 // `effectAllowed` values of the `dataTransfer` object. The only 10 // `effectAllowed` values that will be compared are "copy", "move", and "link" 11 // since they have to correspond to the `dropEffect` value of the event. 12 function dropEffectOnDropCallBack(event) { 13 assert_equals(event.target.textContent, event.dataTransfer.dropEffect); 14 assert_equals(event.target.textContent, event.dataTransfer.effectAllowed); 15 return true; 16 } 17 18 function buildDragAndDropDivs() { 19 effectAllowedList.forEach(effectAllowed => { 20 document.getElementById('drag-container').innerHTML += 21 `<div id="drag-${effectAllowed}" draggable="true" ondragstart="event.dataTransfer.effectAllowed = '${effectAllowed}'">${effectAllowed}</div>`; 22 }); 23 dropEffectList.forEach(dropEffect => { 24 document.getElementById('drop-container').innerHTML += 25 `<div id="drop-${dropEffect}" ondragover="onDragOver(event, '${dropEffect}')">${dropEffect}</div>`; 26 }); 27 } 28 29 function expectedDropEffectForEffectAllowed(chosenDropEffect, 30 chosenEffectAllowed) { 31 // If the drop effect is not initialized or initialized to an invalid value, 32 // it will be up to the UA's discretion to decide which drop effect to choose 33 // based on the current effectAllowed. 34 if (chosenDropEffect == "dummy") { 35 switch (chosenEffectAllowed) { 36 case "undefined": 37 case "uninitialized": 38 case "all": 39 return ["copy", "move", "link"]; 40 case "copyLink": 41 return ["copy", "link"]; 42 case "linkMove": 43 return ["link", "move"]; 44 case "copyMove": 45 return ["copy", "move"]; 46 default: 47 return [chosenEffectAllowed]; 48 } 49 } 50 return [chosenDropEffect]; 51 } 52 53 function dropEventShouldBeSent(dropEffect, effectAllowed) { 54 let expectedDropEffects = expectedDropEffectForEffectAllowed(dropEffect, 55 effectAllowed); 56 assert_greater_than_equal(expectedDropEffects.length, 1, 57 "Expected drop effect should not be empty"); 58 if (effectAllowed === 'dummy' || effectAllowed === 'undefined') { 59 effectAllowed = 'uninitialized'; 60 } 61 if (effectAllowed === 'none' || expectedDropEffects[0] === 'none') { 62 return false; 63 } 64 if (effectAllowed === 'uninitialized' || effectAllowed === 'all') { 65 return true; 66 } 67 // Matches cases like `copyLink` / `link`. 68 for (let effect of expectedDropEffects) { 69 if (effectAllowed.toLowerCase().includes(effect)) { 70 return true; 71 } 72 } 73 return false; 74 } 75 76 function onDropCallBack(event, chosenDropEffect, chosenEffectAllowed) { 77 const actualDropEffect = event.dataTransfer.dropEffect; 78 const actualEffectAllowed = event.dataTransfer.effectAllowed; 79 let expectedEffectAllowed = chosenEffectAllowed; 80 if (chosenEffectAllowed === 'dummy' || chosenEffectAllowed === 81 'undefined') { 82 expectedEffectAllowed = 'uninitialized'; 83 } 84 assert_equals(actualEffectAllowed, expectedEffectAllowed, 85 `chosenDropEffect: ${chosenDropEffect}, chosenEffectAllowed: ${chosenEffectAllowed}; failed effectAllowed check:` 86 ); 87 let expectedDropEffects = expectedDropEffectForEffectAllowed( 88 chosenDropEffect, actualEffectAllowed); 89 // `dragend` events with invalid dropEffect-effectAllowed combinations have a 90 // `none` dropEffect. 91 if (!dropEventShouldBeSent(chosenDropEffect, chosenEffectAllowed)) { 92 expectedDropEffects = ['none']; 93 } 94 assert_in_array(actualDropEffect, expectedDropEffects, 95 `chosenDropEffect: ${chosenDropEffect}, chosenEffectAllowed: ${chosenEffectAllowed}; failed dropEffect check:` 96 ); 97 return true; 98 } 99 100 function onDragOver(event, dropEffect) { 101 event.dataTransfer.dropEffect = dropEffect; 102 event.preventDefault(); 103 } 104 105 // This function creates the divs with all the `effectAllowed`s defined in 106 // `effectAllowedList` and runs a drag and drop test that verifies that 107 // the correct events are sent (or not) depending on the combination of 108 // `dropEffect` and `effectAllowed`. 109 // `effectAllowed`: string with the `effectAllowed` that will be set on the 110 // drag target. 111 // `dropEffect`: string with the `dropEffect` that will be set on the 112 // drop target. 113 function runDropEffectTestOnDragEnd(effectAllowed, dropEffect) { 114 buildDragAndDropDivs(); 115 const dragDiv = document.getElementById("drag-" + effectAllowed); 116 const dropDiv = document.getElementById("drop-" + dropEffect); 117 dragEndTest(dragDiv, dropDiv, (e) => onDropCallBack(e, 118 dropEffect, effectAllowed), 119 `${effectAllowed} / ${dropEffect}`); 120 } 121 122 // Like `runDropEffectTestOnDragEnd`, but verifies that the drop event has the 123 // correct `dropEffect` and `effectAllowed` values on the drop target, instead 124 // of `dragEnd` on the drag element. 125 function runDropEffectTestOnDrop(effectAllowed, dropEffect) { 126 buildDragAndDropDivs(); 127 const dragDiv = document.getElementById("drag-" + effectAllowed); 128 const dropDiv = document.getElementById("drop-" + dropEffect); 129 const shouldReceiveDropEvent = dropEventShouldBeSent(dropEffect, 130 effectAllowed); 131 if (shouldReceiveDropEvent) { 132 dragDropTest(dragDiv, dropDiv, (e) => onDropCallBack(e, 133 dropEffect, effectAllowed), 134 `${effectAllowed} / ${dropEffect}`); 135 } else { 136 dragDropTestNoDropEvent(dragDiv, dropDiv, 137 `${effectAllowed} / ${dropEffect}`); 138 } 139 }