dom/tests/mochitest/general/test_clipboard_events.html

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial