WebCore: dataTransfer.types() should not return Files if file list is empty in the...
[WebKit-https.git] / LayoutTests / http / tests / security / clipboard / resources / clipboard-file-access.js
1 description("Tests access to event.dataTransfer.files and .types");
2
3 var dragTarget = document.createElement("div");
4 dragTarget.innerHTML = "Drag here"
5 dragTarget.style.backgroundColor = "blue";
6 dragTarget.style.width = "100px";
7 dragTarget.style.height = "100px";
8 // Important that we put this at the top of the doc so that logging does not cause it to go out of view (and be undragable)
9 document.body.insertBefore(dragTarget, document.body.firstChild);
10
11 var filesToDrag;
12 dragTarget.addEventListener("dragenter", function() {
13     debug("On dragenter:")
14     event.dataTransfer.dropEffect = "copy";
15     var shouldContainType = (filesToDrag.length > 0);
16     checkForEventTransferType(event, "Files", shouldContainType);
17     fileListShouldBe("event.dataTransfer.files", []);
18     event.preventDefault();
19 }, false);
20
21 dragTarget.addEventListener("dragover", function() {
22     debug("On dragover:")
23     event.dataTransfer.dropEffect = "copy";
24     var shouldContainType = (filesToDrag.length > 0);
25     checkForEventTransferType(event, "Files", shouldContainType);
26     fileListShouldBe("event.dataTransfer.files", []);
27     event.preventDefault();
28 }, false);
29
30 dragTarget.addEventListener("dragleave", function() {
31     debug("On dragleave:")
32     var shouldContainType = (filesToDrag.length > 0);
33     checkForEventTransferType(event, "Files", shouldContainType);
34     fileListShouldBe("event.dataTransfer.files", []);
35 }, false);
36
37 var expectedFilesOnDrop;
38 dragTarget.addEventListener("drop", function() {
39     debug("On drop:")
40     var shouldContainType = (filesToDrag.length > 0);
41     checkForEventTransferType(event, "Files", shouldContainType);
42     fileListShouldBe("event.dataTransfer.files", expectedFilesOnDrop);
43     event.preventDefault();
44 }, false);
45
46 function moveMouseToCenterOfElement(element) {
47     var centerX = element.offsetLeft + element.offsetWidth / 2;
48     var centerY = element.offsetTop + element.offsetHeight / 2;
49     eventSender.mouseMoveTo(centerX, centerY);
50 }
51
52 function moveMouseToOutsideOfElement(element) {
53     var outsideX = element.offsetLeft + element.offsetWidth + 42;
54     var outsideY = element.offsetTop + element.offsetHeight + 42;
55     eventSender.mouseMoveTo(outsideX, outsideY);
56 }
57
58 function dragFilesOntoDragTarget(files, leave) {
59     filesToDrag = files;
60     eventSender.beginDragWithFiles(files);
61     moveMouseToCenterOfElement(dragTarget);
62     if (leave && leave === true)
63         moveMouseToOutsideOfElement(dragTarget);
64     eventSender.mouseUp();
65 }
66
67 function checkForEventTransferType(event, typeString, shouldContainType)
68 {
69     var passedCheck;
70     var message;
71     if (event.dataTransfer.types && event.dataTransfer.types.indexOf(typeString) != -1) {
72         passedCheck = shouldContainType;
73         message = "event.dataTransfer.types contains " + typeString + ".";
74     } else {
75         passedCheck = !shouldContainType;
76         message = "event.dataTransfer.types does not contain " + typeString + ".";
77     }
78     if (passedCheck)
79         testPassed(message);
80     else
81         testFailed(message);
82 }
83
84 function fileListShouldBe(fileListString, filesArray)
85 {
86     shouldBe(fileListString + ".length", "" + filesArray.length);
87     for (var x = 0; x < filesArray.length; x++) {
88         var fileValueString = fileListString + "[" + x + "]";
89         shouldBeEqualToString(fileValueString + ".fileName", filesArray[x]['name']);
90         shouldBe(fileValueString + ".fileSize", "" + filesArray[x]['size']);
91     }
92 }
93
94 function draggingPathsShouldResultInFiles(pathsArray, filesArray, leave)
95 {
96     expectedFilesOnDrop = filesArray;
97     dragFilesOntoDragTarget(pathsArray, leave || false);
98 }
99
100 function testDraggingFiles(filesArray, leave)
101 {
102     // We could make a way to parse the filename from the path, and then only need to pass
103     // the path in the filesArray.
104     var pathsOnly = filesArray.map(function(fileSpec) { return fileSpec['path']; });
105     draggingPathsShouldResultInFiles(pathsOnly, filesArray, leave || false);
106 }
107
108 function runTest()
109 {
110     debug("Dragging no files should return an empty file list (arbitrary implementation detail):");
111     testDraggingFiles([]);
112
113     debug("Drag drop a single (non-existant) file onto an element:");
114     testDraggingFiles([
115         { 'path': 'DRTFakeFile', 'name' : 'DRTFakeFile', 'size' : 0 }
116     ]);
117
118     debug("FIXME: File.fileSize always returns 0 for files dropped by eventSender.beginDragWithFiles from http tests:  https://bugs.webkit.org/show_bug.cgi?id=25909");
119
120     debug("Drag files over an element, leave that element and release the mouse:");   
121     testDraggingFiles([
122         { 'path': 'resources/apple.gif', 'name' : 'apple.gif', 'size' : 1476 }
123     ], true);
124
125     debug("Drag drop a real file onto an element:");
126     testDraggingFiles([
127         { 'path': 'resources/apple.gif', 'name' : 'apple.gif', 'size' : 1476 }
128     ]);
129     
130     debug("Drag drop two files onto an element:");
131     testDraggingFiles([
132         { 'path': 'resources/apple.gif', 'name' : 'apple.gif', 'size' : 1476 },
133         { 'path': 'resources/mozilla.gif', 'name' : 'mozilla.gif', 'size' : 2593 }
134     ]);
135
136     debug("Drag drop two files in reverse alphabetical order onto an element:");
137     testDraggingFiles([
138         { 'path': 'resources/mozilla.gif', 'name' : 'mozilla.gif', 'size' : 2593 },
139         { 'path': 'resources/apple.gif', 'name' : 'apple.gif', 'size' : 1476 }
140     ]);
141
142     // Directory dragging behavior is covered by https://bugs.webkit.org/show_bug.cgi?id=25852 and https://bugs.webkit.org/show_bug.cgi?id=25879
143     debug("FIXME: We should not allow element to accept drops including directories unless https://bugs.webkit.org/show_bug.cgi?id=25879 is fixed to make directory File objects useful from JavaScript.  The page is given File objects corresponding to directories, but form submission and xhr.send() will fail.");
144     debug("Drag drop a directory onto an element:");
145     draggingPathsShouldResultInFiles(['resources/directory-for-dragging'], []);
146
147     // Note: The order of selection in the Finder changes the order of file paths in the pasteboard
148     // thus it's important that we test different orders here as well (at least on the Mac)
149     // Both drops should be refused or succeed based on how https://bugs.webkit.org/show_bug.cgi?id=25879 is resolved.  Currently we expect drops to be refused.
150     debug("Drag drop a file and a directory onto an element:");
151     draggingPathsShouldResultInFiles(['resources/apple.gif', 'resources/directory-for-dragging'], []);
152
153     debug("Drag drop a directory and a file onto an element:")
154     draggingPathsShouldResultInFiles(['resources/directory-for-dragging', 'resources/apple.gif'], []);
155 }
156
157 if (window.eventSender) {
158     runTest();
159     // Clean up after ourselves
160     dragTarget.parentNode.removeChild(dragTarget);
161 } else {
162     testFailed("This test is not interactive, please run using DumpRenderTree");
163 }
164
165 var successfullyParsed = true;