|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 #define MOZILLA_INTERNAL_API |
|
6 |
|
7 #include <ole2.h> |
|
8 #include <shlobj.h> |
|
9 |
|
10 #include "TestHarness.h" |
|
11 #include "nsIArray.h" |
|
12 #include "nsIFile.h" |
|
13 #include "nsNetUtil.h" |
|
14 #include "nsISupportsPrimitives.h" |
|
15 #include "nsIFileURL.h" |
|
16 #include "nsITransferable.h" |
|
17 #include "nsClipboard.h" |
|
18 #include "nsDataObjCollection.h" |
|
19 |
|
20 nsIFile* xferFile; |
|
21 |
|
22 nsresult CheckValidHDROP(STGMEDIUM* pSTG) |
|
23 { |
|
24 if (pSTG->tymed != TYMED_HGLOBAL) { |
|
25 fail("Received data is not in an HGLOBAL"); |
|
26 return NS_ERROR_UNEXPECTED; |
|
27 } |
|
28 |
|
29 HGLOBAL hGlobal = pSTG->hGlobal; |
|
30 DROPFILES* pDropFiles; |
|
31 pDropFiles = (DROPFILES*)GlobalLock(hGlobal); |
|
32 if (!pDropFiles) { |
|
33 fail("There is no data at the given HGLOBAL"); |
|
34 return NS_ERROR_UNEXPECTED; |
|
35 } |
|
36 |
|
37 if (pDropFiles->pFiles != sizeof(DROPFILES)) |
|
38 fail("DROPFILES struct has wrong size"); |
|
39 |
|
40 if (pDropFiles->fWide != true) { |
|
41 fail("Received data is not Unicode"); |
|
42 return NS_ERROR_UNEXPECTED; |
|
43 } |
|
44 nsString s; |
|
45 unsigned long offset = 0; |
|
46 while (1) { |
|
47 s = (char16_t*)((char*)pDropFiles + pDropFiles->pFiles + offset); |
|
48 if (s.IsEmpty()) |
|
49 break; |
|
50 nsresult rv; |
|
51 nsCOMPtr<nsIFile> localFile( |
|
52 do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv)); |
|
53 rv = localFile->InitWithPath(s); |
|
54 if (NS_FAILED(rv)) { |
|
55 fail("File could not be opened"); |
|
56 return NS_ERROR_UNEXPECTED; |
|
57 } |
|
58 offset += sizeof(char16_t) * (s.Length() + 1); |
|
59 } |
|
60 return NS_OK; |
|
61 } |
|
62 |
|
63 nsresult CheckValidTEXT(STGMEDIUM* pSTG) |
|
64 { |
|
65 if (pSTG->tymed != TYMED_HGLOBAL) { |
|
66 fail("Received data is not in an HGLOBAL"); |
|
67 return NS_ERROR_UNEXPECTED; |
|
68 } |
|
69 |
|
70 HGLOBAL hGlobal = pSTG->hGlobal; |
|
71 char* pText; |
|
72 pText = (char*)GlobalLock(hGlobal); |
|
73 if (!pText) { |
|
74 fail("There is no data at the given HGLOBAL"); |
|
75 return NS_ERROR_UNEXPECTED; |
|
76 } |
|
77 |
|
78 nsCString string; |
|
79 string = pText; |
|
80 |
|
81 if (!string.Equals(NS_LITERAL_CSTRING("Mozilla can drag and drop"))) { |
|
82 fail("Text passed through drop object wrong"); |
|
83 return NS_ERROR_UNEXPECTED; |
|
84 } |
|
85 return NS_OK; |
|
86 } |
|
87 |
|
88 nsresult CheckValidTEXTTwo(STGMEDIUM* pSTG) |
|
89 { |
|
90 if (pSTG->tymed != TYMED_HGLOBAL) { |
|
91 fail("Received data is not in an HGLOBAL"); |
|
92 return NS_ERROR_UNEXPECTED; |
|
93 } |
|
94 |
|
95 HGLOBAL hGlobal = pSTG->hGlobal; |
|
96 char* pText; |
|
97 pText = (char*)GlobalLock(hGlobal); |
|
98 if (!pText) { |
|
99 fail("There is no data at the given HGLOBAL"); |
|
100 return NS_ERROR_UNEXPECTED; |
|
101 } |
|
102 |
|
103 nsCString string; |
|
104 string = pText; |
|
105 |
|
106 if (!string.Equals(NS_LITERAL_CSTRING("Mozilla can drag and drop twice over"))) { |
|
107 fail("Text passed through drop object wrong"); |
|
108 return NS_ERROR_UNEXPECTED; |
|
109 } |
|
110 return NS_OK; |
|
111 } |
|
112 |
|
113 nsresult CheckValidUNICODE(STGMEDIUM* pSTG) |
|
114 { |
|
115 if (pSTG->tymed != TYMED_HGLOBAL) { |
|
116 fail("Received data is not in an HGLOBAL"); |
|
117 return NS_ERROR_UNEXPECTED; |
|
118 } |
|
119 |
|
120 HGLOBAL hGlobal = pSTG->hGlobal; |
|
121 char16_t* pText; |
|
122 pText = (char16_t*)GlobalLock(hGlobal); |
|
123 if (!pText) { |
|
124 fail("There is no data at the given HGLOBAL"); |
|
125 return NS_ERROR_UNEXPECTED; |
|
126 } |
|
127 |
|
128 nsString string; |
|
129 string = pText; |
|
130 |
|
131 if (!string.Equals(NS_LITERAL_STRING("Mozilla can drag and drop"))) { |
|
132 fail("Text passed through drop object wrong"); |
|
133 return NS_ERROR_UNEXPECTED; |
|
134 } |
|
135 return NS_OK; |
|
136 } |
|
137 |
|
138 nsresult CheckValidUNICODETwo(STGMEDIUM* pSTG) |
|
139 { |
|
140 if (pSTG->tymed != TYMED_HGLOBAL) { |
|
141 fail("Received data is not in an HGLOBAL"); |
|
142 return NS_ERROR_UNEXPECTED; |
|
143 } |
|
144 |
|
145 HGLOBAL hGlobal = pSTG->hGlobal; |
|
146 char16_t* pText; |
|
147 pText = (char16_t*)GlobalLock(hGlobal); |
|
148 if (!pText) { |
|
149 fail("There is no data at the given HGLOBAL"); |
|
150 return NS_ERROR_UNEXPECTED; |
|
151 } |
|
152 |
|
153 nsString string; |
|
154 string = pText; |
|
155 |
|
156 if (!string.Equals(NS_LITERAL_STRING("Mozilla can drag and drop twice over"))) { |
|
157 fail("Text passed through drop object wrong"); |
|
158 return NS_ERROR_UNEXPECTED; |
|
159 } |
|
160 return NS_OK; |
|
161 } |
|
162 |
|
163 nsresult GetTransferableFile(nsCOMPtr<nsITransferable>& pTransferable) |
|
164 { |
|
165 nsresult rv; |
|
166 |
|
167 nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferFile); |
|
168 |
|
169 pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); |
|
170 pTransferable->Init(nullptr); |
|
171 rv = pTransferable->SetTransferData("application/x-moz-file", genericWrapper, |
|
172 0); |
|
173 return rv; |
|
174 } |
|
175 |
|
176 nsresult GetTransferableText(nsCOMPtr<nsITransferable>& pTransferable) |
|
177 { |
|
178 nsresult rv; |
|
179 NS_NAMED_LITERAL_STRING(mozString, "Mozilla can drag and drop"); |
|
180 nsCOMPtr<nsISupportsString> xferString = |
|
181 do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); |
|
182 rv = xferString->SetData(mozString); |
|
183 NS_ENSURE_SUCCESS(rv, rv); |
|
184 |
|
185 nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferString); |
|
186 |
|
187 pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); |
|
188 pTransferable->Init(nullptr); |
|
189 rv = pTransferable->SetTransferData("text/unicode", genericWrapper, |
|
190 mozString.Length() * sizeof(char16_t)); |
|
191 return rv; |
|
192 } |
|
193 |
|
194 nsresult GetTransferableTextTwo(nsCOMPtr<nsITransferable>& pTransferable) |
|
195 { |
|
196 nsresult rv; |
|
197 NS_NAMED_LITERAL_STRING(mozString, " twice over"); |
|
198 nsCOMPtr<nsISupportsString> xferString = |
|
199 do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); |
|
200 rv = xferString->SetData(mozString); |
|
201 NS_ENSURE_SUCCESS(rv, rv); |
|
202 |
|
203 nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferString); |
|
204 |
|
205 pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); |
|
206 pTransferable->Init(nullptr); |
|
207 rv = pTransferable->SetTransferData("text/unicode", genericWrapper, |
|
208 mozString.Length() * sizeof(char16_t)); |
|
209 return rv; |
|
210 } |
|
211 |
|
212 nsresult GetTransferableURI(nsCOMPtr<nsITransferable>& pTransferable) |
|
213 { |
|
214 nsresult rv; |
|
215 |
|
216 nsCOMPtr<nsIURI> xferURI; |
|
217 |
|
218 rv = NS_NewURI(getter_AddRefs(xferURI), "http://www.mozilla.org"); |
|
219 NS_ENSURE_SUCCESS(rv, rv); |
|
220 |
|
221 nsCOMPtr<nsISupports> genericWrapper = do_QueryInterface(xferURI); |
|
222 |
|
223 pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); |
|
224 pTransferable->Init(nullptr); |
|
225 rv = pTransferable->SetTransferData("text/x-moz-url", genericWrapper, 0); |
|
226 return rv; |
|
227 } |
|
228 |
|
229 nsresult MakeDataObject(nsISupportsArray* transferableArray, |
|
230 nsRefPtr<IDataObject>& itemToDrag) |
|
231 { |
|
232 nsresult rv; |
|
233 uint32_t itemCount = 0; |
|
234 |
|
235 nsCOMPtr<nsIURI> uri; |
|
236 rv = NS_NewURI(getter_AddRefs(uri), "http://www.mozilla.org"); |
|
237 NS_ENSURE_SUCCESS(rv, rv); |
|
238 |
|
239 rv = transferableArray->Count(&itemCount); |
|
240 NS_ENSURE_SUCCESS(rv, rv); |
|
241 |
|
242 // Copied more or less exactly from nsDragService::InvokeDragSession |
|
243 // This is what lets us play fake Drag Service for the test |
|
244 if (itemCount > 1) { |
|
245 nsDataObjCollection * dataObjCollection = new nsDataObjCollection(); |
|
246 if (!dataObjCollection) |
|
247 return NS_ERROR_OUT_OF_MEMORY; |
|
248 itemToDrag = dataObjCollection; |
|
249 for (uint32_t i=0; i<itemCount; ++i) { |
|
250 nsCOMPtr<nsISupports> supports; |
|
251 transferableArray->GetElementAt(i, getter_AddRefs(supports)); |
|
252 nsCOMPtr<nsITransferable> trans(do_QueryInterface(supports)); |
|
253 if (trans) { |
|
254 nsRefPtr<IDataObject> dataObj; |
|
255 rv = nsClipboard::CreateNativeDataObject(trans, |
|
256 getter_AddRefs(dataObj), uri); |
|
257 NS_ENSURE_SUCCESS(rv, rv); |
|
258 // Add the flavors to the collection object too |
|
259 rv = nsClipboard::SetupNativeDataObject(trans, dataObjCollection); |
|
260 NS_ENSURE_SUCCESS(rv, rv); |
|
261 |
|
262 dataObjCollection->AddDataObject(dataObj); |
|
263 } |
|
264 } |
|
265 } // if dragging multiple items |
|
266 else { |
|
267 nsCOMPtr<nsISupports> supports; |
|
268 transferableArray->GetElementAt(0, getter_AddRefs(supports)); |
|
269 nsCOMPtr<nsITransferable> trans(do_QueryInterface(supports)); |
|
270 if (trans) { |
|
271 rv = nsClipboard::CreateNativeDataObject(trans, |
|
272 getter_AddRefs(itemToDrag), |
|
273 uri); |
|
274 NS_ENSURE_SUCCESS(rv, rv); |
|
275 } |
|
276 } // else dragging a single object |
|
277 return rv; |
|
278 } |
|
279 |
|
280 nsresult Do_CheckOneFile() |
|
281 { |
|
282 nsresult rv; |
|
283 nsCOMPtr<nsITransferable> transferable; |
|
284 nsCOMPtr<nsISupportsArray> transferableArray; |
|
285 nsCOMPtr<nsISupports> genericWrapper; |
|
286 nsRefPtr<IDataObject> dataObj; |
|
287 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); |
|
288 if (NS_FAILED(rv)) { |
|
289 fail("Could not create the necessary nsISupportsArray"); |
|
290 return rv; |
|
291 } |
|
292 |
|
293 rv = GetTransferableFile(transferable); |
|
294 if (NS_FAILED(rv)) { |
|
295 fail("Could not create the proper nsITransferable!"); |
|
296 return rv; |
|
297 } |
|
298 genericWrapper = do_QueryInterface(transferable); |
|
299 rv = transferableArray->AppendElement(genericWrapper); |
|
300 if (NS_FAILED(rv)) { |
|
301 fail("Could not append element to transferable array"); |
|
302 return rv; |
|
303 } |
|
304 |
|
305 rv = MakeDataObject(transferableArray, dataObj); |
|
306 if (NS_FAILED(rv)) { |
|
307 fail("Could not create data object"); |
|
308 return rv; |
|
309 } |
|
310 |
|
311 FORMATETC fe; |
|
312 SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); |
|
313 if (dataObj->QueryGetData(&fe) != S_OK) { |
|
314 fail("File data object does not support the file data type!"); |
|
315 return NS_ERROR_UNEXPECTED; |
|
316 } |
|
317 |
|
318 STGMEDIUM* stg; |
|
319 stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); |
|
320 if (dataObj->GetData(&fe, stg) != S_OK) { |
|
321 fail("File data object did not provide data on request"); |
|
322 return NS_ERROR_UNEXPECTED; |
|
323 } |
|
324 |
|
325 rv = CheckValidHDROP(stg); |
|
326 if (NS_FAILED(rv)) { |
|
327 fail("HDROP was invalid"); |
|
328 return rv; |
|
329 } |
|
330 |
|
331 ReleaseStgMedium(stg); |
|
332 |
|
333 return NS_OK; |
|
334 } |
|
335 |
|
336 nsresult Do_CheckTwoFiles() |
|
337 { |
|
338 nsresult rv; |
|
339 nsCOMPtr<nsITransferable> transferable; |
|
340 nsCOMPtr<nsISupportsArray> transferableArray; |
|
341 nsCOMPtr<nsISupports> genericWrapper; |
|
342 nsRefPtr<IDataObject> dataObj; |
|
343 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); |
|
344 if (NS_FAILED(rv)) { |
|
345 fail("Could not create the necessary nsISupportsArray"); |
|
346 return rv; |
|
347 } |
|
348 |
|
349 rv = GetTransferableFile(transferable); |
|
350 if (NS_FAILED(rv)) { |
|
351 fail("Could not create the proper nsITransferable!"); |
|
352 return rv; |
|
353 } |
|
354 genericWrapper = do_QueryInterface(transferable); |
|
355 rv = transferableArray->AppendElement(genericWrapper); |
|
356 if (NS_FAILED(rv)) { |
|
357 fail("Could not append element to transferable array"); |
|
358 return rv; |
|
359 } |
|
360 |
|
361 rv = GetTransferableFile(transferable); |
|
362 if (NS_FAILED(rv)) { |
|
363 fail("Could not create the proper nsITransferable!"); |
|
364 return rv; |
|
365 } |
|
366 genericWrapper = do_QueryInterface(transferable); |
|
367 rv = transferableArray->AppendElement(genericWrapper); |
|
368 if (NS_FAILED(rv)) { |
|
369 fail("Could not append element to transferable array"); |
|
370 return rv; |
|
371 } |
|
372 |
|
373 rv = MakeDataObject(transferableArray, dataObj); |
|
374 if (NS_FAILED(rv)) { |
|
375 fail("Could not create data object"); |
|
376 return rv; |
|
377 } |
|
378 |
|
379 FORMATETC fe; |
|
380 SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); |
|
381 if (dataObj->QueryGetData(&fe) != S_OK) { |
|
382 fail("File data object does not support the file data type!"); |
|
383 return NS_ERROR_UNEXPECTED; |
|
384 } |
|
385 |
|
386 STGMEDIUM* stg; |
|
387 stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); |
|
388 if (dataObj->GetData(&fe, stg) != S_OK) { |
|
389 fail("File data object did not provide data on request"); |
|
390 return NS_ERROR_UNEXPECTED; |
|
391 } |
|
392 |
|
393 rv = CheckValidHDROP(stg); |
|
394 if (NS_FAILED(rv)) { |
|
395 fail("HDROP was invalid"); |
|
396 return rv; |
|
397 } |
|
398 |
|
399 ReleaseStgMedium(stg); |
|
400 |
|
401 return NS_OK; |
|
402 } |
|
403 |
|
404 nsresult Do_CheckOneString() |
|
405 { |
|
406 nsresult rv; |
|
407 nsCOMPtr<nsITransferable> transferable; |
|
408 nsCOMPtr<nsISupportsArray> transferableArray; |
|
409 nsCOMPtr<nsISupports> genericWrapper; |
|
410 nsRefPtr<IDataObject> dataObj; |
|
411 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); |
|
412 if (NS_FAILED(rv)) { |
|
413 fail("Could not create the necessary nsISupportsArray"); |
|
414 return rv; |
|
415 } |
|
416 |
|
417 rv = GetTransferableText(transferable); |
|
418 if (NS_FAILED(rv)) { |
|
419 fail("Could not create the proper nsITransferable!"); |
|
420 return rv; |
|
421 } |
|
422 genericWrapper = do_QueryInterface(transferable); |
|
423 rv = transferableArray->AppendElement(genericWrapper); |
|
424 if (NS_FAILED(rv)) { |
|
425 fail("Could not append element to transferable array"); |
|
426 return rv; |
|
427 } |
|
428 |
|
429 rv = MakeDataObject(transferableArray, dataObj); |
|
430 if (NS_FAILED(rv)) { |
|
431 fail("Could not create data object"); |
|
432 return rv; |
|
433 } |
|
434 |
|
435 FORMATETC fe; |
|
436 SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); |
|
437 if (dataObj->QueryGetData(&fe) != S_OK) { |
|
438 fail("String data object does not support the ASCII text data type!"); |
|
439 return NS_ERROR_UNEXPECTED; |
|
440 } |
|
441 |
|
442 STGMEDIUM* stg; |
|
443 stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); |
|
444 if (dataObj->GetData(&fe, stg) != S_OK) { |
|
445 fail("String data object did not provide ASCII data on request"); |
|
446 return NS_ERROR_UNEXPECTED; |
|
447 } |
|
448 |
|
449 rv = CheckValidTEXT(stg); |
|
450 if (NS_FAILED(rv)) { |
|
451 fail("TEXT was invalid"); |
|
452 return rv; |
|
453 } |
|
454 |
|
455 ReleaseStgMedium(stg); |
|
456 |
|
457 SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); |
|
458 if (dataObj->QueryGetData(&fe) != S_OK) { |
|
459 fail("String data object does not support the wide text data type!"); |
|
460 return NS_ERROR_UNEXPECTED; |
|
461 } |
|
462 |
|
463 if (dataObj->GetData(&fe, stg) != S_OK) { |
|
464 fail("String data object did not provide wide data on request"); |
|
465 return NS_ERROR_UNEXPECTED; |
|
466 } |
|
467 |
|
468 rv = CheckValidUNICODE(stg); |
|
469 if (NS_FAILED(rv)) { |
|
470 fail("UNICODE was invalid"); |
|
471 return rv; |
|
472 } |
|
473 |
|
474 return NS_OK; |
|
475 } |
|
476 |
|
477 nsresult Do_CheckTwoStrings() |
|
478 { |
|
479 nsresult rv; |
|
480 nsCOMPtr<nsITransferable> transferable; |
|
481 nsCOMPtr<nsISupportsArray> transferableArray; |
|
482 nsCOMPtr<nsISupports> genericWrapper; |
|
483 nsRefPtr<IDataObject> dataObj; |
|
484 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); |
|
485 if (NS_FAILED(rv)) { |
|
486 fail("Could not create the necessary nsISupportsArray"); |
|
487 return rv; |
|
488 } |
|
489 |
|
490 rv = GetTransferableText(transferable); |
|
491 if (NS_FAILED(rv)) { |
|
492 fail("Could not create the proper nsITransferable!"); |
|
493 return rv; |
|
494 } |
|
495 genericWrapper = do_QueryInterface(transferable); |
|
496 rv = transferableArray->AppendElement(genericWrapper); |
|
497 if (NS_FAILED(rv)) { |
|
498 fail("Could not append element to transferable array"); |
|
499 return rv; |
|
500 } |
|
501 |
|
502 rv = GetTransferableTextTwo(transferable); |
|
503 if (NS_FAILED(rv)) { |
|
504 fail("Could not create the proper nsITransferable!"); |
|
505 return rv; |
|
506 } |
|
507 genericWrapper = do_QueryInterface(transferable); |
|
508 rv = transferableArray->AppendElement(genericWrapper); |
|
509 if (NS_FAILED(rv)) { |
|
510 fail("Could not append element to transferable array"); |
|
511 return rv; |
|
512 } |
|
513 |
|
514 rv = MakeDataObject(transferableArray, dataObj); |
|
515 if (NS_FAILED(rv)) { |
|
516 fail("Could not create data object"); |
|
517 return rv; |
|
518 } |
|
519 |
|
520 FORMATETC fe; |
|
521 SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); |
|
522 if (dataObj->QueryGetData(&fe) != S_OK) { |
|
523 fail("String data object does not support the ASCII text data type!"); |
|
524 return NS_ERROR_UNEXPECTED; |
|
525 } |
|
526 |
|
527 STGMEDIUM* stg; |
|
528 stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); |
|
529 if (dataObj->GetData(&fe, stg) != S_OK) { |
|
530 fail("String data object did not provide ASCII data on request"); |
|
531 return NS_ERROR_UNEXPECTED; |
|
532 } |
|
533 |
|
534 rv = CheckValidTEXTTwo(stg); |
|
535 if (NS_FAILED(rv)) { |
|
536 fail("TEXT was invalid"); |
|
537 return rv; |
|
538 } |
|
539 |
|
540 ReleaseStgMedium(stg); |
|
541 |
|
542 SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); |
|
543 if (dataObj->QueryGetData(&fe) != S_OK) { |
|
544 fail("String data object does not support the wide text data type!"); |
|
545 return NS_ERROR_UNEXPECTED; |
|
546 } |
|
547 |
|
548 if (dataObj->GetData(&fe, stg) != S_OK) { |
|
549 fail("String data object did not provide wide data on request"); |
|
550 return NS_ERROR_UNEXPECTED; |
|
551 } |
|
552 |
|
553 rv = CheckValidUNICODETwo(stg); |
|
554 if (NS_FAILED(rv)) { |
|
555 fail("UNICODE was invalid"); |
|
556 return rv; |
|
557 } |
|
558 |
|
559 return NS_OK; |
|
560 } |
|
561 |
|
562 nsresult Do_CheckSetArbitraryData(bool aMultiple) |
|
563 { |
|
564 nsresult rv; |
|
565 nsCOMPtr<nsITransferable> transferable; |
|
566 nsCOMPtr<nsISupportsArray> transferableArray; |
|
567 nsCOMPtr<nsISupports> genericWrapper; |
|
568 nsRefPtr<IDataObject> dataObj; |
|
569 rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); |
|
570 if (NS_FAILED(rv)) { |
|
571 fail("Could not create the necessary nsISupportsArray"); |
|
572 return rv; |
|
573 } |
|
574 |
|
575 rv = GetTransferableText(transferable); |
|
576 if (NS_FAILED(rv)) { |
|
577 fail("Could not create the proper nsITransferable!"); |
|
578 return rv; |
|
579 } |
|
580 genericWrapper = do_QueryInterface(transferable); |
|
581 rv = transferableArray->AppendElement(genericWrapper); |
|
582 if (NS_FAILED(rv)) { |
|
583 fail("Could not append element to transferable array"); |
|
584 return rv; |
|
585 } |
|
586 |
|
587 if (aMultiple) { |
|
588 rv = GetTransferableText(transferable); |
|
589 if (NS_FAILED(rv)) { |
|
590 fail("Could not create the proper nsITransferable!"); |
|
591 return rv; |
|
592 } |
|
593 genericWrapper = do_QueryInterface(transferable); |
|
594 rv = transferableArray->AppendElement(genericWrapper); |
|
595 if (NS_FAILED(rv)) { |
|
596 fail("Could not append element to transferable array"); |
|
597 return rv; |
|
598 } |
|
599 } |
|
600 |
|
601 rv = MakeDataObject(transferableArray, dataObj); |
|
602 if (NS_FAILED(rv)) { |
|
603 fail("Could not create data object"); |
|
604 return rv; |
|
605 } |
|
606 |
|
607 static CLIPFORMAT mozArbitraryFormat = |
|
608 ::RegisterClipboardFormatW(L"MozillaTestFormat"); |
|
609 FORMATETC fe; |
|
610 STGMEDIUM stg; |
|
611 SET_FORMATETC(fe, mozArbitraryFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); |
|
612 |
|
613 HGLOBAL hg = GlobalAlloc(GPTR, 1024); |
|
614 stg.tymed = TYMED_HGLOBAL; |
|
615 stg.hGlobal = hg; |
|
616 stg.pUnkForRelease = nullptr; |
|
617 |
|
618 if (dataObj->SetData(&fe, &stg, true) != S_OK) { |
|
619 if (aMultiple) { |
|
620 fail("Unable to set arbitrary data type on data object collection!"); |
|
621 } else { |
|
622 fail("Unable to set arbitrary data type on data object!"); |
|
623 } |
|
624 return NS_ERROR_UNEXPECTED; |
|
625 } |
|
626 |
|
627 if (dataObj->QueryGetData(&fe) != S_OK) { |
|
628 fail("Arbitrary data set on data object is not advertised!"); |
|
629 return NS_ERROR_UNEXPECTED; |
|
630 } |
|
631 |
|
632 STGMEDIUM* stg2; |
|
633 stg2 = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); |
|
634 if (dataObj->GetData(&fe, stg2) != S_OK) { |
|
635 fail("Data object did not provide arbitrary data upon request!"); |
|
636 return NS_ERROR_UNEXPECTED; |
|
637 } |
|
638 |
|
639 if (stg2->hGlobal != hg) { |
|
640 fail("Arbitrary data was not returned properly!"); |
|
641 return rv; |
|
642 } |
|
643 ReleaseStgMedium(stg2); |
|
644 |
|
645 return NS_OK; |
|
646 } |
|
647 |
|
648 // This function performs basic drop tests, testing a data object consisting |
|
649 // of one transferable |
|
650 nsresult Do_Test1() |
|
651 { |
|
652 nsresult rv = NS_OK; |
|
653 nsresult workingrv; |
|
654 |
|
655 workingrv = Do_CheckOneFile(); |
|
656 if (NS_FAILED(workingrv)) { |
|
657 fail("Drag object tests failed on a single file"); |
|
658 rv = NS_ERROR_UNEXPECTED; |
|
659 } else { |
|
660 passed("Successfully created a working file drag object!"); |
|
661 } |
|
662 |
|
663 workingrv = Do_CheckOneString(); |
|
664 if (NS_FAILED(workingrv)) { |
|
665 fail("Drag object tests failed on a single string"); |
|
666 rv = NS_ERROR_UNEXPECTED; |
|
667 } else { |
|
668 passed("Successfully created a working string drag object!"); |
|
669 } |
|
670 |
|
671 workingrv = Do_CheckSetArbitraryData(false); |
|
672 if (NS_FAILED(workingrv)) { |
|
673 fail("Drag object tests failed on setting arbitrary data"); |
|
674 rv = NS_ERROR_UNEXPECTED; |
|
675 } else { |
|
676 passed("Successfully set arbitrary data on a drag object"); |
|
677 } |
|
678 |
|
679 return rv; |
|
680 } |
|
681 |
|
682 // This function performs basic drop tests, testing a data object consisting of |
|
683 // two transferables. |
|
684 nsresult Do_Test2() |
|
685 { |
|
686 nsresult rv = NS_OK; |
|
687 nsresult workingrv; |
|
688 |
|
689 workingrv = Do_CheckTwoFiles(); |
|
690 if (NS_FAILED(workingrv)) { |
|
691 fail("Drag object tests failed on multiple files"); |
|
692 rv = NS_ERROR_UNEXPECTED; |
|
693 } else { |
|
694 passed("Successfully created a working multiple file drag object!"); |
|
695 } |
|
696 |
|
697 workingrv = Do_CheckTwoStrings(); |
|
698 if (NS_FAILED(workingrv)) { |
|
699 fail("Drag object tests failed on multiple strings"); |
|
700 rv = NS_ERROR_UNEXPECTED; |
|
701 } else { |
|
702 passed("Successfully created a working multiple string drag object!"); |
|
703 } |
|
704 |
|
705 workingrv = Do_CheckSetArbitraryData(true); |
|
706 if (NS_FAILED(workingrv)) { |
|
707 fail("Drag object tests failed on setting arbitrary data"); |
|
708 rv = NS_ERROR_UNEXPECTED; |
|
709 } else { |
|
710 passed("Successfully set arbitrary data on a drag object"); |
|
711 } |
|
712 |
|
713 return rv; |
|
714 } |
|
715 |
|
716 // This function performs advanced drag and drop tests, testing a data object |
|
717 // consisting of multiple transferables that have different data types |
|
718 nsresult Do_Test3() |
|
719 { |
|
720 nsresult rv = NS_OK; |
|
721 nsresult workingrv; |
|
722 |
|
723 // XXX TODO Write more advanced tests in Bug 535860 |
|
724 return rv; |
|
725 } |
|
726 |
|
727 int main(int argc, char** argv) |
|
728 { |
|
729 ScopedXPCOM xpcom("Test Windows Drag and Drop"); |
|
730 |
|
731 nsCOMPtr<nsIFile> file; |
|
732 file = xpcom.GetProfileDirectory(); |
|
733 xferFile = file; |
|
734 |
|
735 if (NS_SUCCEEDED(Do_Test1())) |
|
736 passed("Basic Drag and Drop data type tests (single transferable) succeeded!"); |
|
737 |
|
738 if (NS_SUCCEEDED(Do_Test2())) |
|
739 passed("Basic Drag and Drop data type tests (multiple transferables) succeeded!"); |
|
740 |
|
741 //if (NS_SUCCEEDED(Do_Test3())) |
|
742 // passed("Advanced Drag and Drop data type tests succeeded!"); |
|
743 |
|
744 return gFailCount; |
|
745 } |