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