object-retention.html (6964B)
1 <!DOCTYPE html> 2 <title>drag & drop - variable retention within event handlers</title> 3 <style> 4 body > div { 5 height: 200px; 6 width: 200px; 7 background-color: orange; 8 } 9 body > div + div { 10 margin-top: 10px; 11 height: 200px; 12 width: 200px; 13 background-color: blue; 14 } 15 </style> 16 17 <script> 18 window.onload = function() { 19 var orange = document.getElementsByTagName('div')[0], blue = document.getElementsByTagName('div')[1], fails = [], evs = {}; 20 orange.ondragstart = function(e) { 21 e.dataTransfer.effectAllowed = 'copy'; 22 var foo = {}; 23 e.dataTransfer.setData('text', foo); 24 if( e.dataTransfer.getData('text') === foo ) { 25 fails[fails.length] = 'object was not cast to string'; 26 } 27 evs[e.type] = {}; 28 evs[e.type].dataTransfer = e.dataTransfer; 29 evs[e.type].items = e.dataTransfer.items; 30 evs[e.type].types = e.dataTransfer.types; 31 evs[e.type].files = e.dataTransfer.files; 32 //"The same object must be returned each time." 33 if( evs[e.type].dataTransfer !== e.dataTransfer ) { 34 fails[fails.length] = '.dataTransfer is not returning the same object during '+e.type; 35 } 36 if( !e.dataTransfer.items ) { 37 fails[fails.length] = '.items is not returning anything during '+e.type; 38 } else if( evs[e.type].items !== e.dataTransfer.items ) { 39 fails[fails.length] = '.items is not returning the same object during '+e.type; 40 } 41 if( !e.dataTransfer.types ) { 42 fails[fails.length] = '.types is not returning anything during '+e.type; 43 } else if( evs[e.type].types !== e.dataTransfer.types ) { 44 fails[fails.length] = '.types is not returning the same object during '+e.type; 45 } 46 if( !e.dataTransfer.files ) { 47 fails[fails.length] = '.files is not returning anything during '+e.type; 48 } else if( evs[e.type].files !== e.dataTransfer.files ) { 49 fails[fails.length] = '.files is not returning the same object during '+e.type; 50 } 51 }; 52 blue.ondragover = blue.ondragenter = function(e) { 53 e.preventDefault(); 54 e.dataTransfer.dropEffect = 'copy'; 55 if( !evs[e.type] ) { evs[e.type] = {}; } 56 evs[e.type].dataTransfer = e.dataTransfer; 57 evs[e.type].items = e.dataTransfer.items; 58 evs[e.type].types = e.dataTransfer.types; 59 evs[e.type].files = e.dataTransfer.files; 60 if( evs[e.type].dataTransfer != e.dataTransfer ) { 61 fails[fails.length] = '.dataTransfer is not returning the same object during '+e.type; 62 } 63 if( !e.dataTransfer.items ) { 64 fails[fails.length] = '.items is not returning anything during '+e.type; 65 } else if( evs[e.type].items !== e.dataTransfer.items ) { 66 fails[fails.length] = '.items is not returning the same object during '+e.type; 67 } 68 if( !e.dataTransfer.types ) { 69 fails[fails.length] = '.types is not returning anything during '+e.type; 70 } else if( evs[e.type].types !== e.dataTransfer.types ) { 71 fails[fails.length] = '.types is not returning the same object during '+e.type; 72 } 73 if( !e.dataTransfer.files ) { 74 fails[fails.length] = '.files is not returning anything during '+e.type; 75 } else if( evs[e.type].files !== e.dataTransfer.files ) { 76 fails[fails.length] = '.files is not returning the same object during '+e.type; 77 } 78 //http://dev.w3.org/html5/spec/dnd.html#datatransfer 79 //"The * attribute must return a * object associated with the DataTransfer object." 80 //Note that it is associated with the DataTransfer object, *not* the data store 81 //http://dev.w3.org/html5/spec/dnd.html#dragevent 82 //"when a user agent is required to fire a DND event named e at an element, using a particular drag data store... 83 //Let dataTransfer be a newly created DataTransfer object associated with the given drag data store." 84 //A new DataTransfer object therefore means a new set of properties, not the same ones as last event 85 if( evs.dragstart.dataTransfer === e.dataTransfer ) { 86 fails[fails.length] = '.dataTransfer is returning the same object during '+e.type+' as it did during dragstart'; 87 } 88 if( e.dataTransfer.items && evs.dragstart.items === e.dataTransfer.items ) { 89 fails[fails.length] = '.items is returning the same object during '+e.type+' as it did during dragstart'; 90 } 91 if( e.dataTransfer.types && evs.dragstart.types === e.dataTransfer.types ) { 92 fails[fails.length] = '.types is returning the same object during '+e.type+' as it did during dragstart'; 93 } 94 if( e.dataTransfer.files && evs.dragstart.files === e.dataTransfer.files ) { 95 fails[fails.length] = '.files is returning the same object during '+e.type+' as it did during dragstart'; 96 } 97 }; 98 blue.ondrop = function(e) { 99 e.preventDefault(); 100 evs[e.type] = {}; 101 evs[e.type].dataTransfer = e.dataTransfer; 102 evs[e.type].items = e.dataTransfer.items; 103 evs[e.type].types = e.dataTransfer.types; 104 evs[e.type].files = e.dataTransfer.files; 105 if( evs[e.type].dataTransfer !== e.dataTransfer ) { 106 fails[fails.length] = '.dataTransfer is not returning the same object during '+e.type; 107 } 108 if( !e.dataTransfer.items ) { 109 fails[fails.length] = '.items is not returning anything during '+e.type; 110 } else if( evs[e.type].items !== e.dataTransfer.items ) { 111 fails[fails.length] = '.items is not returning the same object during '+e.type; 112 } 113 if( !e.dataTransfer.types ) { 114 fails[fails.length] = '.types is not returning anything during '+e.type; 115 } else if( evs[e.type].types !== e.dataTransfer.types ) { 116 fails[fails.length] = '.types is not returning the same object during '+e.type; 117 } 118 if( !e.dataTransfer.files ) { 119 fails[fails.length] = '.files is not returning anything during '+e.type; 120 } else if( evs[e.type].files !== e.dataTransfer.files ) { 121 fails[fails.length] = '.files is not returning the same object during '+e.type; 122 } 123 if( evs.dragstart.dataTransfer === e.dataTransfer ) { 124 fails[fails.length] = '.dataTransfer is returning the same object during '+e.type+' as it did during dragstart'; 125 } 126 if( e.dataTransfer.items && evs.dragstart.items === e.dataTransfer.items ) { 127 fails[fails.length] = '.items is returning the same object during '+e.type+' as it did during dragstart'; 128 } 129 if( e.dataTransfer.types && evs.dragstart.types === e.dataTransfer.types ) { 130 fails[fails.length] = '.types is returning the same object during '+e.type+' as it did during dragstart'; 131 } 132 if( e.dataTransfer.files && evs.dragstart.files === e.dataTransfer.files ) { 133 fails[fails.length] = '.files is returning the same object during '+e.type+' as it did during dragstart'; 134 } 135 document.getElementsByTagName('p')[0].innerHTML = fails.length ? ( 'FAIL:<br>' + fails.join('<br>') ) : 'PASS'; 136 }; 137 }; 138 </script> 139 140 <p>Drag the orange square onto the blue square. Fail if this text does not change.</p> 141 <div draggable="true"></div> 142 <div></div> 143 144 <noscript><p>Enable JavaScript and reload</p></noscript>