|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <head> |
|
4 <title>Test for Clipboard Events</title> |
|
5 <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> |
|
6 <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
7 <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> |
|
8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> |
|
9 </head> |
|
10 <body> |
|
11 <p id="display"></p> |
|
12 <div id="content" style="border: 3px solid black; padding: 3em;">CONTENT TEXT<input id="content-input" value="INPUT TEXT"></div> |
|
13 <button id="button">Button</button> |
|
14 |
|
15 <div id="syntheticSpot" oncut="compareSynthetic(event, 'cut')" |
|
16 oncopy="compareSynthetic(event, 'copy')" |
|
17 onpaste="compareSynthetic(event, 'paste')">Spot</div> |
|
18 |
|
19 <pre id="test"> |
|
20 <script class="testbody" type="text/javascript;version=1.7"> |
|
21 |
|
22 var content = document.getElementById("content"); |
|
23 var contentInput = document.getElementById("content-input"); |
|
24 var clipboardInitialValue = "empty"; |
|
25 |
|
26 // Test that clearing and reading the clipboard works. A random number |
|
27 // is used to make sure that leftover clipboard values from a previous |
|
28 // test run don't cause a false-positive test. |
|
29 var cb_text = "empty_" + Math.random(); |
|
30 setClipboardText(cb_text); |
|
31 |
|
32 is(getClipboardText(), cb_text, "set/get clipboard text failed"); |
|
33 |
|
34 // Some test functions need to be run with delays. |
|
35 var delayedTests = []; |
|
36 |
|
37 var cachedCutData, cachedCopyData, cachedPasteData; |
|
38 |
|
39 // Ensure window focus before running tests, otherwise key events can |
|
40 // misfire. We set the onfocus event handler here to actually begin |
|
41 // running tests, and call window.focus() afterwards. |
|
42 window.onfocus = function() |
|
43 { |
|
44 window.onfocus = null; |
|
45 |
|
46 // A list of test functions to run. Before each test function is run, the |
|
47 // clipboard is initialized to clipboardInitialValue, and the contents of |
|
48 // div#content are set as the window's selection. |
|
49 var testFunctions = [ |
|
50 test_dom_oncopy, |
|
51 test_dom_oncut, |
|
52 test_dom_onpaste, |
|
53 test_dom_oncopy_abort, |
|
54 test_input_oncopy, |
|
55 test_input_oncut, |
|
56 test_input_onpaste, |
|
57 test_input_oncopy_abort, |
|
58 test_input_oncut_abort, |
|
59 test_input_onpaste_abort, |
|
60 test_input_cut_dataTransfer, |
|
61 test_input_cut_abort_dataTransfer, |
|
62 test_input_copy_dataTransfer, |
|
63 test_input_paste_dataTransfer, |
|
64 test_input_paste_abort_dataTransfer, |
|
65 test_input_copypaste_dataTransfer_multiple, |
|
66 test_input_copy_button_dataTransfer, |
|
67 test_eventspref_disabled |
|
68 ]; |
|
69 |
|
70 // Run the main tests. This will also populate the delayedTests array |
|
71 for (let i = 0; i < testFunctions.length; i++) { |
|
72 // Init clipboard |
|
73 setClipboardText(clipboardInitialValue); |
|
74 |
|
75 // Reset value of contentInput. |
|
76 contentInput.value = "INPUT TEXT"; |
|
77 |
|
78 var func = testFunctions[i]; |
|
79 func(); |
|
80 } |
|
81 |
|
82 // Check if the cached clipboard data can be accessed or modified |
|
83 // and whether it modifies the real clipboard |
|
84 checkCachedDataTransfer(cachedCutData, "cut"); |
|
85 checkCachedDataTransfer(cachedCopyData, "copy"); |
|
86 checkCachedDataTransfer(cachedPasteData, "paste"); |
|
87 |
|
88 checkSyntheticEvents(); |
|
89 |
|
90 SimpleTest.finish(); |
|
91 } |
|
92 |
|
93 // Calling .focus begins the test run. |
|
94 SimpleTest.waitForExplicitFinish(); |
|
95 window.focus(); |
|
96 |
|
97 function getLoadContext() { |
|
98 return SpecialPowers.wrap(window).QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor) |
|
99 .getInterface(SpecialPowers.Ci.nsIWebNavigation) |
|
100 .QueryInterface(SpecialPowers.Ci.nsILoadContext); |
|
101 } |
|
102 |
|
103 function getClipboardText() { |
|
104 return SpecialPowers.getClipboardData("text/unicode"); |
|
105 } |
|
106 |
|
107 |
|
108 function setClipboardText(text) { |
|
109 var helper = SpecialPowers.Cc["@mozilla.org/widget/clipboardhelper;1"] |
|
110 .getService(SpecialPowers.Ci.nsIClipboardHelper); |
|
111 helper.copyString(text); |
|
112 } |
|
113 |
|
114 function selectContentDiv() { |
|
115 // Set selection |
|
116 var selection = window.getSelection(); |
|
117 selection.removeAllRanges(); |
|
118 selection.selectAllChildren(content); |
|
119 } |
|
120 |
|
121 function selectContentInput() { |
|
122 contentInput.select(); |
|
123 contentInput.focus(); |
|
124 } |
|
125 |
|
126 function test_dom_oncopy() { |
|
127 // Setup an oncopy event handler, fire copy. Ensure that the event |
|
128 // handler was called, and the clipboard contents have set to CONTENT TEXT. |
|
129 // Test firing oncopy event on ctrl-c: |
|
130 selectContentDiv(); |
|
131 |
|
132 var oncopy_fired = false; |
|
133 content.oncopy = function() { oncopy_fired = true; }; |
|
134 try { |
|
135 synthesizeKey("c", {accelKey: 1}); |
|
136 ok(oncopy_fired, "copy event firing on DOM element"); |
|
137 is(getClipboardText(), "CONTENT TEXT", |
|
138 "copy on DOM element set clipboard correctly"); |
|
139 } finally { |
|
140 content.oncopy = null; |
|
141 } |
|
142 } |
|
143 |
|
144 function test_dom_oncut() { |
|
145 // Setup an oncut event handler, fire cut. Ensure that the event handler |
|
146 // was called. The <div> doesn't handle a cut, so ensure that the |
|
147 // clipboard text is clipboardInitialValue, NOT "CONTENT TEXT". |
|
148 selectContentDiv(); |
|
149 var oncut_fired = false; |
|
150 content.oncut = function() { oncut_fired = true; }; |
|
151 try { |
|
152 synthesizeKey("x", {accelKey: 1}); |
|
153 ok(!oncut_fired, "cut event firing on DOM element") |
|
154 is(getClipboardText(), clipboardInitialValue, |
|
155 "cut on DOM element did not modify clipboard"); |
|
156 } finally { |
|
157 content.oncut = null; |
|
158 } |
|
159 } |
|
160 |
|
161 |
|
162 function test_dom_onpaste() { |
|
163 // Setup an onpaste event handler, fire paste. Ensure that the event |
|
164 // handler was called. |
|
165 selectContentDiv(); |
|
166 var onpaste_fired = false; |
|
167 content.onpaste = function() { onpaste_fired = true; }; |
|
168 try { |
|
169 synthesizeKey("v", {accelKey: 1}); |
|
170 ok(!onpaste_fired, "paste event firing on DOM element"); |
|
171 } finally { |
|
172 content.onpaste = null; |
|
173 } |
|
174 } |
|
175 |
|
176 |
|
177 function test_dom_oncopy_abort() { |
|
178 // Setup an oncopy event handler that aborts the copy, and fire the copy |
|
179 // event. Ensure that the event handler was fired, and the clipboard |
|
180 // contents have not been modified. |
|
181 selectContentDiv(); |
|
182 var oncopy_fired = false; |
|
183 content.oncopy = function() { oncopy_fired = true; return false; }; |
|
184 try { |
|
185 synthesizeKey("c", {accelKey: 1}); |
|
186 ok(oncopy_fired, "copy event (to-be-cancelled) firing on DOM element"); |
|
187 is(getClipboardText(), clipboardInitialValue, |
|
188 "aborted copy on DOM element did not modify clipboard"); |
|
189 } finally { |
|
190 content.oncopy = null; |
|
191 } |
|
192 } |
|
193 |
|
194 |
|
195 function test_input_oncopy() { |
|
196 // Setup an oncopy event handler, fire copy. Ensure that the event |
|
197 // handler was called, and the clipboard contents have been set to 'PUT TE', |
|
198 // which is the part that is selected below. |
|
199 selectContentInput(); |
|
200 contentInput.focus(); |
|
201 contentInput.setSelectionRange(2, 8); |
|
202 |
|
203 var oncopy_fired = false; |
|
204 contentInput.oncopy = function() { oncopy_fired = true; }; |
|
205 try { |
|
206 synthesizeKey("c", {accelKey: 1}); |
|
207 ok(oncopy_fired, "copy event firing on plaintext editor"); |
|
208 is(getClipboardText(), "PUT TE", |
|
209 "copy on plaintext editor set clipboard correctly"); |
|
210 } finally { |
|
211 contentInput.oncopy = null; |
|
212 } |
|
213 } |
|
214 |
|
215 |
|
216 function test_input_oncut() { |
|
217 // Setup an oncut event handler, and fire cut. Ensure that the event |
|
218 // handler was fired, the clipboard contains the INPUT TEXT, and |
|
219 // that the input itself is empty. |
|
220 selectContentInput(); |
|
221 var oncut_fired = false; |
|
222 contentInput.oncut = function() { oncut_fired = true; }; |
|
223 try { |
|
224 synthesizeKey("x", {accelKey: 1}); |
|
225 ok(oncut_fired, "cut event firing on plaintext editor"); |
|
226 is(getClipboardText(), "INPUT TEXT", |
|
227 "cut on plaintext editor set clipboard correctly"); |
|
228 is(contentInput.value, "", |
|
229 "cut on plaintext editor emptied editor"); |
|
230 } finally { |
|
231 contentInput.oncut = null; |
|
232 } |
|
233 } |
|
234 |
|
235 |
|
236 function test_input_onpaste() { |
|
237 // Setup an onpaste event handler, and fire paste. Ensure that the event |
|
238 // handler was fired, the clipboard contents didn't change, and that the |
|
239 // input value did change (ie. paste succeeded). |
|
240 selectContentInput(); |
|
241 var onpaste_fired = false; |
|
242 contentInput.onpaste = function() { onpaste_fired = true; }; |
|
243 try { |
|
244 synthesizeKey("v", {accelKey: 1}); |
|
245 ok(onpaste_fired, "paste event firing on plaintext editor"); |
|
246 is(getClipboardText(), clipboardInitialValue, |
|
247 "paste on plaintext editor did not modify clipboard contents"); |
|
248 is(contentInput.value, clipboardInitialValue, |
|
249 "paste on plaintext editor did modify editor value"); |
|
250 } finally { |
|
251 contentInput.onpaste = null; |
|
252 } |
|
253 } |
|
254 |
|
255 |
|
256 function test_input_oncopy_abort() { |
|
257 // Setup an oncopy event handler, fire copy. Ensure that the event |
|
258 // handler was called, and that the clipboard value did NOT change. |
|
259 selectContentInput(); |
|
260 var oncopy_fired = false; |
|
261 contentInput.oncopy = function() { oncopy_fired = true; return false; }; |
|
262 try { |
|
263 synthesizeKey("c", {accelKey: 1}); |
|
264 ok(oncopy_fired, "copy event (to-be-cancelled) firing on plaintext editor"); |
|
265 is(getClipboardText(), clipboardInitialValue, |
|
266 "aborted copy on plaintext editor did not modify clipboard"); |
|
267 } finally { |
|
268 contentInput.oncopy = null; |
|
269 } |
|
270 } |
|
271 |
|
272 |
|
273 function test_input_oncut_abort() { |
|
274 // Setup an oncut event handler, and fire cut. Ensure that the event |
|
275 // handler was fired, the clipboard contains the INPUT TEXT, and |
|
276 // that the input itself is empty. |
|
277 selectContentInput(); |
|
278 var oncut_fired = false; |
|
279 contentInput.oncut = function() { oncut_fired = true; return false; }; |
|
280 try { |
|
281 synthesizeKey("x", {accelKey: 1}); |
|
282 ok(oncut_fired, "cut event (to-be-cancelled) firing on plaintext editor"); |
|
283 is(getClipboardText(), clipboardInitialValue, |
|
284 "aborted cut on plaintext editor did not modify clipboard."); |
|
285 is(contentInput.value, "INPUT TEXT", |
|
286 "aborted cut on plaintext editor did not modify editor contents"); |
|
287 } finally { |
|
288 contentInput.oncut = null; |
|
289 } |
|
290 } |
|
291 |
|
292 |
|
293 function test_input_onpaste_abort() { |
|
294 // Setup an onpaste event handler, and fire paste. Ensure that the event |
|
295 // handler was fired, the clipboard contents didn't change, and that the |
|
296 // input value did change (ie. paste succeeded). |
|
297 selectContentInput(); |
|
298 var onpaste_fired = false; |
|
299 contentInput.onpaste = function() { onpaste_fired = true; return false; }; |
|
300 try { |
|
301 synthesizeKey("v", {accelKey: 1}); |
|
302 ok(onpaste_fired, |
|
303 "paste event (to-be-cancelled) firing on plaintext editor"); |
|
304 is(getClipboardText(), clipboardInitialValue, |
|
305 "aborted paste on plaintext editor did not modify clipboard"); |
|
306 is(contentInput.value, "INPUT TEXT", |
|
307 "aborted paste on plaintext editor did not modify modified editor value"); |
|
308 } finally { |
|
309 contentInput.onpaste = null; |
|
310 } |
|
311 } |
|
312 |
|
313 |
|
314 function test_input_cut_dataTransfer() { |
|
315 // Cut using event.dataTransfer. The event is not cancelled so the default |
|
316 // cut should occur |
|
317 selectContentInput(); |
|
318 contentInput.oncut = function(event) { |
|
319 ok(event instanceof ClipboardEvent, "cut event is a ClipboardEvent"); |
|
320 ok(event.clipboardData instanceof DataTransfer, "cut event dataTransfer is a DataTransfer"); |
|
321 is(event.target, contentInput, "cut event target"); |
|
322 is(event.clipboardData.mozItemCount, 0, "cut event mozItemCount"); |
|
323 is(event.clipboardData.getData("text/plain"), "", "cut event getData"); |
|
324 event.clipboardData.setData("text/plain", "This is some dataTransfer text"); |
|
325 cachedCutData = event.clipboardData; |
|
326 }; |
|
327 try { |
|
328 synthesizeKey("x", {accelKey: 1}); |
|
329 is(getClipboardText(), "INPUT TEXT", |
|
330 "cut using dataTransfer on plaintext editor set clipboard correctly"); |
|
331 is(contentInput.value, "", |
|
332 "cut using dataTransfer on plaintext editor cleared input"); |
|
333 } finally { |
|
334 contentInput.oncut = null; |
|
335 } |
|
336 } |
|
337 |
|
338 |
|
339 function test_input_cut_abort_dataTransfer() { |
|
340 // Cut using event.dataTransfer but cancel the event. The data should be |
|
341 // put on the clipboard but since we don't modify the input value, the input |
|
342 // should have the same value. |
|
343 selectContentInput(); |
|
344 contentInput.oncut = function(event) { |
|
345 event.clipboardData.setData("text/plain", "Cut dataTransfer text"); |
|
346 return false; |
|
347 }; |
|
348 try { |
|
349 synthesizeKey("x", {accelKey: 1}); |
|
350 is(getClipboardText(), "Cut dataTransfer text", |
|
351 "aborted cut using dataTransfer on plaintext editor set clipboard correctly"); |
|
352 is(contentInput.value, "INPUT TEXT", |
|
353 "aborted cut using dataTransfer on plaintext editor did not modify input"); |
|
354 } finally { |
|
355 contentInput.oncut = null; |
|
356 } |
|
357 } |
|
358 |
|
359 |
|
360 function test_input_copy_dataTransfer() { |
|
361 // Copy using event.dataTransfer |
|
362 selectContentInput(); |
|
363 contentInput.oncopy = function(event) { |
|
364 ok(event instanceof ClipboardEvent, "copy event is a ClipboardEvent"); |
|
365 ok(event.clipboardData instanceof DataTransfer, "copy event dataTransfer is a DataTransfer"); |
|
366 is(event.target, contentInput, "copy event target"); |
|
367 is(event.clipboardData.mozItemCount, 0, "copy event mozItemCount"); |
|
368 is(event.clipboardData.getData("text/plain"), "", "copy event getData"); |
|
369 event.clipboardData.setData("text/plain", "Copied dataTransfer text"); |
|
370 cachedCopyData = event.clipboardData; |
|
371 }; |
|
372 try { |
|
373 synthesizeKey("c", {accelKey: 1}); |
|
374 is(getClipboardText(), "INPUT TEXT", |
|
375 "copy using dataTransfer on plaintext editor set clipboard correctly"); |
|
376 is(contentInput.value, "INPUT TEXT", |
|
377 "copy using dataTransfer on plaintext editor did not modify input"); |
|
378 } finally { |
|
379 contentInput.oncopy = null; |
|
380 } |
|
381 } |
|
382 |
|
383 |
|
384 function test_input_copy_abort_dataTransfer() { |
|
385 // Copy using event.dataTransfer but cancel the event. |
|
386 selectContentInput(); |
|
387 contentInput.oncopy = function(event) { |
|
388 event.clipboardData.setData("text/plain", "Copy dataTransfer text"); |
|
389 return false; |
|
390 }; |
|
391 try { |
|
392 synthesizeKey("x", {accelKey: 1}); |
|
393 is(getClipboardText(), "Copy dataTransfer text", |
|
394 "aborted copy using dataTransfer on plaintext editor set clipboard correctly"); |
|
395 is(contentInput.value, "INPUT TEXT", |
|
396 "aborted copy using dataTransfer on plaintext editor did not modify input"); |
|
397 } finally { |
|
398 contentInput.oncopy = null; |
|
399 } |
|
400 } |
|
401 |
|
402 |
|
403 function test_input_paste_dataTransfer() { |
|
404 // Paste using event.dataTransfer |
|
405 selectContentInput(); |
|
406 contentInput.onpaste = function(event) { |
|
407 ok(event instanceof ClipboardEvent, "paste event is an ClipboardEvent"); |
|
408 ok(event.clipboardData instanceof DataTransfer, "paste event dataTransfer is a DataTransfer"); |
|
409 is(event.target, contentInput, "paste event target"); |
|
410 is(event.clipboardData.mozItemCount, 1, "paste event mozItemCount"); |
|
411 is(event.clipboardData.getData("text/plain"), clipboardInitialValue, "paste event getData"); |
|
412 cachedPasteData = event.clipboardData; |
|
413 }; |
|
414 try { |
|
415 synthesizeKey("v", {accelKey: 1}); |
|
416 is(getClipboardText(), clipboardInitialValue, |
|
417 "paste using dataTransfer on plaintext editor did not modify clipboard contents"); |
|
418 is(contentInput.value, clipboardInitialValue, |
|
419 "paste using dataTransfer on plaintext editor modified input"); |
|
420 } finally { |
|
421 contentInput.onpaste = null; |
|
422 } |
|
423 } |
|
424 |
|
425 |
|
426 function test_input_paste_abort_dataTransfer() { |
|
427 // Paste using event.dataTransfer but cancel the event |
|
428 selectContentInput(); |
|
429 contentInput.onpaste = function(event) { |
|
430 is(event.clipboardData.getData("text/plain"), clipboardInitialValue, "get data on aborted paste"); |
|
431 contentInput.value = "Alternate Paste"; |
|
432 return false; |
|
433 }; |
|
434 try { |
|
435 synthesizeKey("v", {accelKey: 1}); |
|
436 is(getClipboardText(), clipboardInitialValue, |
|
437 "aborted paste using dataTransfer on plaintext editor did not modify clipboard contents"); |
|
438 is(contentInput.value, "Alternate Paste", |
|
439 "aborted paste using dataTransfer on plaintext editor modified input"); |
|
440 } finally { |
|
441 contentInput.onpaste = null; |
|
442 } |
|
443 } |
|
444 |
|
445 function test_input_copypaste_dataTransfer_multiple() { |
|
446 // Cut several types of data and paste it again |
|
447 contentInput.value = "This is a line of text"; |
|
448 contentInput.oncopy = function(event) { |
|
449 var cd = event.clipboardData; |
|
450 cd.setData("text/plain", "would be a phrase"); |
|
451 |
|
452 var exh = false; |
|
453 try { cd.mozSetDataAt("text/plain", "Text", 1); } catch (ex) { exh = true; } |
|
454 ok(exh, "exception occured mozSetDataAt 1"); |
|
455 exh = false; |
|
456 try { cd.mozTypesAt(1); } catch (ex) { exh = true; } |
|
457 ok(exh, "exception occured mozTypesAt 1"); |
|
458 exh = false; |
|
459 try { cd.mozGetDataAt("text/plain", 1); } catch (ex) { exh = true; } |
|
460 ok(exh, "exception occured mozGetDataAt 1"); |
|
461 exh = false; |
|
462 try { cd.mozClearDataAt("text/plain", 1); } catch (ex) { exh = true; } |
|
463 ok(exh, "exception occured mozClearDataAt 1"); |
|
464 |
|
465 cd.setData("text/x-moz-url", "http://www.mozilla.org"); |
|
466 cd.mozSetDataAt("text/x-custom", "Custom Text", 0); |
|
467 is(cd.mozItemCount, 1, "mozItemCount after set multiple types"); |
|
468 return false; |
|
469 }; |
|
470 |
|
471 try { |
|
472 selectContentInput(); |
|
473 synthesizeKey("c", {accelKey: 1}); |
|
474 } |
|
475 finally { |
|
476 contentInput.oncopy = null; |
|
477 } |
|
478 |
|
479 is(getClipboardText(), "would be a phrase", "copy multiple types text"); |
|
480 |
|
481 contentInput.setSelectionRange(5, 14); |
|
482 |
|
483 contentInput.onpaste = function(event) { |
|
484 var cd = event.clipboardData; |
|
485 is(cd.mozItemCount, 1, "paste after copy multiple types mozItemCount"); |
|
486 is(cd.getData("text/plain"), "would be a phrase", "paste text/plain multiple types"); |
|
487 |
|
488 // Firefox for Android's clipboard code doesn't handle x-moz-url. Therefore |
|
489 // disabling the following test. Enable this once bug #840101 is fixed. |
|
490 if (navigator.appVersion.indexOf("Android") == -1) { |
|
491 is(cd.getData("text/x-moz-url"), "http://www.mozilla.org", "paste text/x-moz-url multiple types"); |
|
492 } |
|
493 // this is empty because only the built-in types are supported at the moment |
|
494 is(cd.getData("text/x-custom"), "", "paste text/custom multiple types"); |
|
495 |
|
496 exh = false; |
|
497 try { cd.setData("text/plain", "Text on Paste"); } catch (ex) { exh = true; } |
|
498 ok(exh, "exception occured setData on paste"); |
|
499 |
|
500 is(cd.getData("text/plain"), "would be a phrase", "text/plain data unchanged"); |
|
501 }; |
|
502 try { |
|
503 synthesizeKey("v", {accelKey: 1}); |
|
504 is(contentInput.value, "This would be a phrase of text", |
|
505 "default paste after copy multiple types"); |
|
506 } finally { |
|
507 contentInput.onpaste = null; |
|
508 } |
|
509 } |
|
510 |
|
511 function test_input_copy_button_dataTransfer() { |
|
512 // Copy using event.dataTransfer when a button is focused. |
|
513 var button = document.getElementById("button"); |
|
514 button.focus(); |
|
515 button.oncopy = function(event) { |
|
516 ok(false, "should not be firing copy event on button"); |
|
517 return false; |
|
518 }; |
|
519 try { |
|
520 // copy should not occur here because buttons don't have any controller |
|
521 // for the copy command |
|
522 synthesizeKey("c", {accelKey: 1}); |
|
523 is(getClipboardText(), clipboardInitialValue, |
|
524 "copy using dataTransfer on plaintext editor set clipboard correctly for button"); |
|
525 |
|
526 selectContentDiv(); |
|
527 synthesizeKey("c", {accelKey: 1}); |
|
528 is(getClipboardText(), "CONTENT TEXT", |
|
529 "copy using dataTransfer with selection on plaintext editor set clipboard correctly for button"); |
|
530 |
|
531 } finally { |
|
532 document.documentElement.oncopy = null; |
|
533 } |
|
534 } |
|
535 |
|
536 function test_eventspref_disabled() { |
|
537 // Disable clipboard events |
|
538 SpecialPowers.setBoolPref("dom.event.clipboardevents.enabled", false); |
|
539 |
|
540 var event_fired = false; |
|
541 contentInput.oncut = function() { event_fired = true; }; |
|
542 contentInput.oncopy = function() { event_fired = true; }; |
|
543 contentInput.onpaste = function() { event_fired = true; }; |
|
544 try { |
|
545 selectContentInput(); |
|
546 contentInput.setSelectionRange(1, 4); |
|
547 synthesizeKey("x", {accelKey: 1}); |
|
548 is(contentInput.value, "IT TEXT", "cut changed text when preference is disabled"); |
|
549 is(getClipboardText(), "NPU", "cut changed clipboard when preference is disabled"); |
|
550 ok(!event_fired, "cut event did not fire when preference is disabled") |
|
551 |
|
552 event_fired = false; |
|
553 contentInput.setSelectionRange(3, 6); |
|
554 synthesizeKey("c", {accelKey: 1}); |
|
555 is(getClipboardText(), "TEX", "copy changed clipboard when preference is disabled"); |
|
556 ok(!event_fired, "copy event did not fire when preference is disabled") |
|
557 |
|
558 event_fired = false; |
|
559 contentInput.setSelectionRange(0, 2); |
|
560 synthesizeKey("v", {accelKey: 1}); |
|
561 is(contentInput.value, "TEX TEXT", "paste changed text when preference is disabled"); |
|
562 ok(!event_fired, "paste event did not fire when preference is disabled") |
|
563 } finally { |
|
564 contentInput.oncut = null; |
|
565 contentInput.oncopy = null; |
|
566 contentInput.onpaste = null; |
|
567 } |
|
568 |
|
569 SpecialPowers.clearUserPref("dom.event.clipboardevents.enabled"); |
|
570 } |
|
571 |
|
572 let expectedData = []; |
|
573 |
|
574 // Check to make that synthetic events do not change the clipboard |
|
575 function checkSyntheticEvents() |
|
576 { |
|
577 let syntheticSpot = document.getElementById("syntheticSpot"); |
|
578 setClipboardText(clipboardInitialValue); |
|
579 |
|
580 // No dataType specified |
|
581 let event = new ClipboardEvent("cut", { data: "something" }); |
|
582 expectedData = { type: "cut", data: null } |
|
583 compareSynthetic(event, "before"); |
|
584 syntheticSpot.dispatchEvent(event); |
|
585 ok(expectedData.eventFired, "cut event fired"); |
|
586 compareSynthetic(event, "after"); |
|
587 |
|
588 event = new ClipboardEvent("cut", { dataType: "text/plain", data: "something" }); |
|
589 expectedData = { type: "cut", dataType: "text/plain", data: "something" } |
|
590 compareSynthetic(event, "before"); |
|
591 syntheticSpot.dispatchEvent(event); |
|
592 ok(expectedData.eventFired, "cut event fired"); |
|
593 compareSynthetic(event, "after"); |
|
594 |
|
595 event = new ClipboardEvent("copy", { dataType: "text/plain", data: "something" }); |
|
596 expectedData = { type: "copy", dataType: "text/plain", data: "something" } |
|
597 compareSynthetic(event, "before"); |
|
598 syntheticSpot.dispatchEvent(event); |
|
599 ok(expectedData.eventFired, "copy event fired"); |
|
600 compareSynthetic(event, "after"); |
|
601 |
|
602 event = new ClipboardEvent("copy", { dataType: "text/plain" }); |
|
603 expectedData = { type: "copy", dataType: "text/plain", data: "" } |
|
604 compareSynthetic(event, "before"); |
|
605 syntheticSpot.dispatchEvent(event); |
|
606 ok(expectedData.eventFired, "copy event fired"); |
|
607 compareSynthetic(event, "after"); |
|
608 |
|
609 event = new ClipboardEvent("paste", { dataType: "text/plain", data: "something" }); |
|
610 expectedData = { type: "paste", dataType: "text/plain", data: "something" } |
|
611 compareSynthetic(event, "before"); |
|
612 syntheticSpot.dispatchEvent(event); |
|
613 ok(expectedData.eventFired, "paste event fired"); |
|
614 compareSynthetic(event, "after"); |
|
615 |
|
616 event = new ClipboardEvent("paste", { dataType: "application/unknown", data: "unknown" }); |
|
617 expectedData = { type: "paste", dataType: "application/unknown", data: "unknown" } |
|
618 compareSynthetic(event, "before"); |
|
619 syntheticSpot.dispatchEvent(event); |
|
620 ok(expectedData.eventFired, "paste event fired"); |
|
621 compareSynthetic(event, "after"); |
|
622 } |
|
623 |
|
624 function compareSynthetic(event, eventtype) |
|
625 { |
|
626 let step = (eventtype == "cut" || eventtype == "copy" || eventtype == "paste") ? "during" : eventtype; |
|
627 if (step == "during") { |
|
628 is(eventtype, expectedData.type, "synthetic " + eventtype + " event fired"); |
|
629 } |
|
630 |
|
631 ok(event.clipboardData instanceof DataTransfer, "clipboardData is assigned"); |
|
632 |
|
633 is(event.type, expectedData.type, "synthetic " + eventtype + " event type"); |
|
634 if (expectedData.data === null) { |
|
635 is(event.clipboardData.mozItemCount, 0, "synthetic " + eventtype + " empty data"); |
|
636 } |
|
637 else { |
|
638 is(event.clipboardData.mozItemCount, 1, "synthetic " + eventtype + " item count"); |
|
639 is(event.clipboardData.types.length, 1, "synthetic " + eventtype + " types length"); |
|
640 is(event.clipboardData.getData(expectedData.dataType), expectedData.data, |
|
641 "synthetic " + eventtype + " data"); |
|
642 } |
|
643 |
|
644 is(getClipboardText(), "empty", "event does not change the clipboard " + step + " dispatch"); |
|
645 |
|
646 if (step == "during") { |
|
647 expectedData.eventFired = true; |
|
648 } |
|
649 } |
|
650 |
|
651 function checkCachedDataTransfer(cd, eventtype) |
|
652 { |
|
653 var testprefix = "cached " + eventtype + " dataTransfer"; |
|
654 |
|
655 setClipboardText("Some Clipboard Text"); |
|
656 |
|
657 var oldtext = cd.getData("text/plain"); |
|
658 ok(oldtext != "Some Clipboard Text", "clipboard get using " + testprefix); |
|
659 |
|
660 var exh = false; |
|
661 try { cd.mozSetDataAt("text/plain", "Test Cache Data", 0); } catch (ex) { exh = true; } |
|
662 ok(eventtype == "paste" ? exh : !exh, "exception occured setting " + testprefix); |
|
663 |
|
664 var newtext = (eventtype == "paste") ? cd.getData("text/plain") : |
|
665 cd.mozGetDataAt("text/plain", 0); |
|
666 is(newtext, (eventtype == "paste") ? "" : "Test Cache Data", |
|
667 " clipboardData not changed using " + testprefix); |
|
668 |
|
669 is(getClipboardText(), "Some Clipboard Text", "clipboard not changed using " + testprefix); |
|
670 |
|
671 var exh = false; |
|
672 try { cd.mozClearDataAt("text/plain", 0); } catch (ex) { exh = true; } |
|
673 ok(eventtype == "paste" ? exh : !exh, "exception occured clearing " + testprefix); |
|
674 |
|
675 is(getClipboardText(), "Some Clipboard Text", "clipboard not changed using " + testprefix); |
|
676 } |
|
677 |
|
678 </script> |
|
679 </pre> |
|
680 </body> |
|
681 </html> |
|
682 |