frameSelectEvents.html (31742B)
1 <!doctype html> 2 <html> 3 <head> 4 <title>Testing Selection Events</title> 5 <script src="/tests/SimpleTest/EventUtils.js"></script> 6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 7 </head> 8 9 <body> 10 <div id="normal"> 11 <span id="inner">A bunch of text in a span inside of a div which should be selected</span> 12 </div> 13 14 <div id="ce"> 15 This is a random block of text 16 </div> 17 18 <input type="text" id="input" value="XXXXXXXXXXXXXXXXXXX" width="200"> <br> 19 20 <textarea id="textarea" width="200">XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</textarea> 21 22 <script> 23 // Call the testing methods from the parent window 24 var is = parent.is; 25 var ok = parent.ok; 26 27 // spin() spins the event loop for two cycles, giving time for 28 // selectionchange events to be fired, and handled by our listeners. 29 function spin() { 30 return new Promise(function(a) { 31 parent.SimpleTest.executeSoon(function() { 32 parent.SimpleTest.executeSoon(a) 33 }); 34 }); 35 } 36 37 /** 38 * @param {Node} node 39 */ 40 function isProperSelectionChangeTarget(node) { 41 return node === document || node === input || node === textarea; 42 } 43 44 // The main test 45 parent.add_task(async function() { 46 await spin(); 47 48 var selectstart = 0; 49 var selectionchange = 0; 50 var inputSelectionchange = 0; 51 var textareaSelectionchange = 0; 52 53 var cancel = false; 54 var selectstartTarget = null; 55 56 async function UpdateSelectEventsOnTextControlsPref({ selectstart, selectionchange }) { 57 await SpecialPowers.pushPrefEnv({ 58 'set': [ 59 ['dom.select_events.textcontrols.selectstart.enabled', !!selectstart], 60 ['dom.select_events.textcontrols.selectionchange.enabled', !!selectionchange], 61 ] 62 }); 63 } 64 await UpdateSelectEventsOnTextControlsPref({ 65 selectstart: false, 66 selectionchange: false, 67 }); 68 69 document.addEventListener('selectstart', function(aEvent) { 70 console.log("originaltarget", aEvent.originalTarget, "new", selectstartTarget); 71 is(aEvent.originalTarget, selectstartTarget, 72 "The original target of selectstart"); 73 selectstartTarget = null; 74 75 console.log(selectstart); 76 selectstart++; 77 78 if (cancel) { 79 aEvent.preventDefault(); 80 } 81 }); 82 document.addEventListener('selectionchange', function(aEvent) { 83 ok(isProperSelectionChangeTarget(aEvent.target), 84 "The target of selectionchange should be one of document, input, or textarea"); 85 console.log(selectionchange); 86 selectionchange++; 87 }); 88 89 function elt(aId) { return document.getElementById(aId); } 90 function reset() { 91 selectstart = 0; 92 selectionchange = 0; 93 inputSelectionchange = 0; 94 textareaSelectionchange = 0; 95 cancel = false; 96 } 97 98 elt("input").addEventListener('selectionchange', function(aEvent) { 99 is (aEvent.originalTarget, elt("input"), 100 "The original target of selectionchange should be the input"); 101 console.log(inputSelectionchange); 102 inputSelectionchange++; 103 }); 104 elt("textarea").addEventListener('selectionchange', function(aEvent) { 105 is (aEvent.originalTarget, elt("textarea"), 106 "The original target of selectionchange should be the textarea"); 107 console.log(textareaSelectionchange); 108 textareaSelectionchange++; 109 }); 110 111 function checkEventCounts( 112 aTestDescription, 113 aSituationDescription, 114 aExpectedEventCounts 115 ) { 116 let { 117 selectstartOnDocument = 0, 118 selectionchangeOnDocument = 0, 119 selectionchangeOnInput = 0, 120 selectionchangeOnTextarea = 0, 121 } = aExpectedEventCounts; 122 123 is( 124 selectstart, 125 selectstartOnDocument, 126 `${ 127 aTestDescription 128 }: "selectstart" event on the document node should be fired ${ 129 selectstartOnDocument 130 } times ${aSituationDescription}` 131 ); 132 is( 133 selectionchange, 134 selectionchangeOnDocument, 135 `${ 136 aTestDescription 137 }: "selectionchange" event on the document node should be fired ${ 138 selectionchangeOnDocument 139 } times ${aSituationDescription}` 140 ); 141 is( 142 inputSelectionchange, 143 selectionchangeOnInput, 144 `${ 145 aTestDescription 146 }: "selectionchange" event on the <input> should be fired ${ 147 selectionchangeOnInput 148 } times ${aSituationDescription}` 149 ); 150 is( 151 textareaSelectionchange, 152 selectionchangeOnTextarea, 153 `${ 154 aTestDescription 155 }: "selectionchange" event on the <textarea> should be fired ${ 156 selectionchangeOnTextarea 157 } times ${aSituationDescription}` 158 ); 159 } 160 161 async function testWithSynthesizingMouse( 162 aDescription, 163 aElement, 164 aOffset, 165 aType, 166 aExpectedEventCounts 167 ) { 168 const eventObject = aType == "click" ? {} : { type: aType }; 169 if (aOffset.y === undefined || aOffset.y === null) { 170 aOffset.y = 10; 171 } 172 synthesizeMouse(aElement, aOffset.x, aOffset.y, eventObject); 173 await spin(); 174 175 checkEventCounts( 176 aDescription, 177 `after synthesizing ${aType} at ${aOffset.x}, ${aOffset.y}`, 178 aExpectedEventCounts 179 ); 180 reset(); 181 } 182 183 async function testWithSynthesizingKey( 184 aDescription, 185 aKey, 186 aEventObject, 187 aExpectedEventCounts 188 ) { 189 synthesizeKey(aKey, aEventObject); 190 await spin(); 191 192 checkEventCounts( 193 aDescription, 194 `after synthesizing a key press of "${aKey}"`, 195 aExpectedEventCounts 196 ); 197 reset(); 198 } 199 200 async function testWithSettingContentEditableAttribute( 201 aDescription, 202 aElement, 203 aContentEditableValue, 204 aExpectedEventCounts 205 ) { 206 aElement.setAttribute("contenteditable", 207 aContentEditableValue ? "true" : "false"); 208 await spin(); 209 210 checkEventCounts( 211 aDescription, 212 `after setting contenteditable attribute to ${ 213 aElement.getAttribute("contenteditable") 214 }`, 215 aExpectedEventCounts 216 ); 217 reset(); 218 } 219 220 var selection = document.getSelection(); 221 function isCollapsed() { 222 is(selection.isCollapsed, true, "Selection is collapsed"); 223 } 224 function isNotCollapsed() { 225 is(selection.isCollapsed, false, "Selection is not collapsed"); 226 } 227 228 // Make sure setting the element to contentEditable doesn't cause any selectionchange events 229 await testWithSettingContentEditableAttribute( 230 "Setting contenteditable attribute to true of <div> should not change selection", 231 elt("ce"), 232 true, 233 {} 234 ); 235 236 // Make sure setting the element to not be contentEditable doesn't cause any selectionchange events 237 await testWithSettingContentEditableAttribute( 238 'Setting contenteditable attribute to false of <div contenteditable="true"> should not change selection', 239 elt("ce"), 240 false, 241 {} 242 ); 243 244 // Now make the div contentEditable and proceed with the test 245 await testWithSettingContentEditableAttribute( 246 'Setting contenteditable attribute to true of <div contenteditable="false"> should not change selection', 247 elt("ce"), 248 true, 249 {} 250 ); 251 252 // Focus the contenteditable text 253 await testWithSynthesizingMouse( 254 'Clicking in <div contenteditable="true"> should change selection', 255 elt("ce"), 256 { x: 100 }, 257 "click", 258 { selectionchangeOnDocument: 1 } 259 ); 260 isCollapsed(); 261 262 // Move the selection to the right, this should only fire selectstart once 263 selectstartTarget = elt("ce").firstChild; 264 await testWithSynthesizingKey( 265 'Synthesizing Shift-ArrowRight to select a character in the text node of <div contenteditable="true"> should start to select again and change selection', 266 "KEY_ArrowRight", 267 { shiftKey: true }, 268 { selectstartOnDocument: 1, selectionchangeOnDocument: 1 } 269 ); 270 isNotCollapsed(); 271 await testWithSynthesizingKey( 272 'Synthesizing Shift-ArrowRight again to select 2 characters in the text node of <div contenteditable="true"> should change selection', 273 "KEY_ArrowRight", 274 { shiftKey: true }, 275 { selectionchangeOnDocument: 1 } 276 ); 277 isNotCollapsed(); 278 279 // Move it back so that the selection is empty again 280 await testWithSynthesizingKey( 281 'Synthesizing Shift-ArrowLeft to shrink selection in the text node of <div contenteditable="true"> should change selection', 282 "KEY_ArrowLeft", 283 { shiftKey: true }, 284 { selectionchangeOnDocument: 1 } 285 ); 286 isNotCollapsed(); 287 await testWithSynthesizingKey( 288 'Synthesizing Shift-ArrowLeft again to collapse selection in the text node of <div contenteditable="true"> should change selection', 289 "KEY_ArrowLeft", 290 { shiftKey: true }, 291 { selectionchangeOnDocument: 1 } 292 ); 293 isCollapsed(); 294 295 // Going from empty to non-empty should fire selectstart again 296 selectstartTarget = elt("ce").firstChild; 297 await testWithSynthesizingKey( 298 'Synthesizing Shift-ArrowLeft again to select a character on the other side in the text node of <div contenteditable="true"> should start to select and change selection', 299 "KEY_ArrowLeft", 300 { shiftKey: true }, 301 { selectstartOnDocument: 1, selectionchangeOnDocument: 1 } 302 ); 303 isNotCollapsed(); 304 305 async function testWithSynthesizingMouseDrag( 306 aDescription, 307 aElement, 308 aSelectstartTarget 309 ) { 310 // Select a region 311 await testWithSynthesizingMouse( 312 `Pressing left mouse button ${ 313 aDescription 314 } should not start to select but should change selection`, 315 aElement, 316 { x: 50 }, 317 "mousedown", 318 { selectionchangeOnDocument: 1 } 319 ); 320 isCollapsed(); 321 322 selectstartTarget = aSelectstartTarget; 323 await testWithSynthesizingMouse( 324 `Dragging mouse to right to extend selection ${ 325 aDescription 326 } should start to select and change selection`, 327 aElement, 328 { x: 100 }, 329 "mousemove", 330 { selectstartOnDocument: 1, selectionchangeOnDocument: 1 } 331 ); 332 isNotCollapsed(); 333 334 // Moving it more shouldn't trigger a start (move back to empty) 335 await testWithSynthesizingMouse( 336 `Dragging mouse to left to shrink selection ${ 337 aDescription 338 } should change selection`, 339 aElement, 340 { x: 75 }, 341 "mousemove", 342 { selectionchangeOnDocument: 1 } 343 ); 344 isNotCollapsed(); 345 await testWithSynthesizingMouse( 346 `Dragging mouse to left to collapse selection ${ 347 aDescription 348 } should change selection`, 349 aElement, 350 { x: 50 }, 351 "mousemove", 352 { selectionchangeOnDocument: 1 } 353 ); 354 isCollapsed(); 355 356 // Wiggling the mouse a little such that it doesn't select any 357 // characters shouldn't trigger a selection 358 await testWithSynthesizingMouse( 359 `Dragging mouse to bottom a bit ${ 360 aDescription 361 } should not cause selection change`, 362 aElement, 363 { x: 50, y: 11 }, 364 "mousemove", 365 {} 366 ); 367 isCollapsed(); 368 369 // Moving the mouse again from an empty selection should trigger a 370 // selectstart 371 selectstartTarget = aSelectstartTarget; 372 await testWithSynthesizingMouse( 373 `Dragging mouse to left to extend selection ${ 374 aDescription 375 } should start to select and change selection`, 376 aElement, 377 { x: 25 }, 378 "mousemove", 379 { selectstartOnDocument: 1, selectionchangeOnDocument: 1 } 380 ); 381 isNotCollapsed(); 382 383 // Releasing the mouse shouldn't do anything 384 await testWithSynthesizingMouse( 385 `Releasing left mouse button to stop dragging ${ 386 aDescription 387 } should not change selection`, 388 aElement, 389 { x: 25 }, 390 "mouseup", 391 {} 392 ); 393 isNotCollapsed(); 394 395 // And neither should moving your mouse around when the mouse 396 // button isn't pressed 397 await testWithSynthesizingMouse( 398 `Just moving mouse to right ${ 399 aDescription 400 } should not start to select nor change selection`, 401 aElement, 402 { x: 50 }, 403 "mousemove", 404 {} 405 ); 406 isNotCollapsed(); 407 408 // Clicking in an random location should move the selection, but not perform a 409 // selectstart 410 await testWithSynthesizingMouse( 411 `Clicking to collapse selection ${ 412 aDescription 413 } should cause only selection change`, 414 aElement, 415 { x: 50 }, 416 "click", 417 { selectionchangeOnDocument: 1 } 418 ); 419 isCollapsed(); 420 421 // Clicking there again should do nothing 422 await testWithSynthesizingMouse( 423 `Clicking same position again ${ 424 aDescription 425 } should not change selection`, 426 aElement, 427 { x: 50 }, 428 "click", 429 {} 430 ); 431 isCollapsed(); 432 433 // Selecting a region, and canceling the selectstart should mean that the 434 // selection remains collapsed 435 await testWithSynthesizingMouse( 436 `Pressing left mouse button on different character to move caret ${ 437 aDescription 438 } should cause only selection change`, 439 aElement, 440 { x: 75 }, 441 "mousedown", 442 { selectionchangeOnDocument: 1 } 443 ); 444 isCollapsed(); 445 cancel = true; 446 selectstartTarget = aSelectstartTarget; 447 await testWithSynthesizingMouse( 448 `Moving mouse to right to extend selection but selectstart event will be prevented default ${ 449 aDescription 450 } should start to select and change selection`, 451 aElement, 452 { x: 100 }, 453 "mousemove", 454 { selectstartOnDocument: 1, selectionchangeOnDocument: 1 } 455 ); 456 isCollapsed(); 457 await testWithSynthesizingMouse( 458 `Releasing the left mouse button after dragging but selectstart was prevented the default ${ 459 aDescription 460 } should not change selection`, 461 aElement, 462 { x: 100 }, 463 "mouseup", 464 {} 465 ); 466 isCollapsed(); 467 } 468 469 // Should work both on normal 470 await testWithSynthesizingMouseDrag( 471 "on the text node in the non-editable <div>", 472 elt("inner"), 473 elt("inner").firstChild 474 ); 475 // and contenteditable fields 476 await testWithSynthesizingMouseDrag( 477 'on the text node in the editable <div contenteditable="true">', 478 elt("ce"), 479 elt("ce").firstChild 480 ); 481 // and fields with elements in them 482 await testWithSynthesizingMouseDrag( 483 "on the text node in the non-editable <div>'s child", 484 elt("normal"), 485 elt("inner").firstChild 486 ); 487 488 await testWithSynthesizingMouse( 489 "Clicking in the text node in the `<div>` should change selection", 490 elt("inner"), 491 { x: 50 }, 492 "click", 493 { selectionchangeOnDocument: 1 } 494 ); 495 isCollapsed(); 496 497 reset(); 498 // Select all should fire both selectstart and change 499 selectstartTarget = document.body; 500 await testWithSynthesizingKey( 501 "Select All when no editor has focus should start to select and select all content", 502 "a", { accelKey: true }, 503 { selectstartOnDocument: 1, selectionchangeOnDocument: 1 } 504 ); 505 isNotCollapsed(); 506 507 // Clear the selection 508 await testWithSynthesizingMouse( 509 "Clicking in the non-editable <div> should clear selection", 510 elt("inner"), 511 { x: 50 }, 512 "click", 513 { selectionchangeOnDocument: 1 } 514 ); 515 isCollapsed(); 516 517 // Even if we already have a selection 518 await testWithSynthesizingMouse( 519 "Pressing the left mouse button in non-editable <div> should change selection", 520 elt("inner"), 521 { x: 75 }, 522 "mousedown", 523 { selectionchangeOnDocument: 1 } 524 ); 525 isCollapsed(); 526 selectstartTarget = elt("inner").firstChild; 527 await testWithSynthesizingMouse( 528 "Dragging mouse to right to extend selection should start and change selection", 529 elt("inner"), 530 { x: 100 }, 531 "mousemove", 532 { selectstartOnDocument: 1, selectionchangeOnDocument: 1 } 533 ); 534 isNotCollapsed(); 535 await testWithSynthesizingMouse( 536 "Releasing the left mouse button should not change selection", 537 elt("inner"), 538 { x: 100 }, 539 "mouseup", 540 {} 541 ); 542 isNotCollapsed(); 543 544 selectstartTarget = document.body; 545 await testWithSynthesizingKey( 546 "Select All when no editor has focus should start to select and select all content (again)", 547 "a", 548 { accelKey: true }, 549 { selectstartOnDocument: 1, selectionchangeOnDocument: 1 } 550 ); 551 isNotCollapsed(); 552 553 // Clear the selection 554 await testWithSynthesizingMouse( 555 "Clicking in the non-editable <div> should clear selection (again)", 556 elt("inner"), 557 { x: 50 }, 558 "click", 559 {selectionchangeOnDocument: 1 } 560 ); 561 isCollapsed(); 562 563 // Make sure that a synthesized selection change doesn't fire selectstart 564 getSelection().removeAllRanges(); 565 await spin(); 566 is( 567 selectstart, 568 0, 569 "Selection.removeAllRanges() should not cause selectstart event" 570 ); 571 is( 572 selectionchange, 573 1, 574 "Selection.removeAllRanges() should cause selectionchange event" 575 ); 576 reset(); 577 isCollapsed(); 578 579 await (async function test_Selection_selectNode() { 580 const range = document.createRange(); 581 range.selectNode(elt("inner")); 582 getSelection().addRange(range); 583 await spin(); 584 is( 585 selectstart, 586 0, 587 "Selection.addRange() should not cause selectstart event" 588 ); 589 is( 590 selectionchange, 591 1, 592 "Selection.addRange() should cause selectionchange event" 593 ); 594 reset(); 595 isNotCollapsed(); 596 })(); 597 598 // Change the range, without replacing 599 await (async function test_Selection_getRangeAt_selectNode() { 600 getSelection().getRangeAt(0).selectNode(elt("ce")); 601 await spin(); 602 is( 603 selectstart, 604 0, 605 "Selection.getRangeAt(0).selectNode() should not cause selectstart event" 606 ); 607 is( 608 selectionchange, 609 1, 610 "Selection.getRangeAt(0).selectNode() should cause selectionchange event" 611 ); 612 reset(); 613 isNotCollapsed(); 614 })(); 615 616 // Remove the range 617 getSelection().removeAllRanges(); 618 await spin(); 619 is( 620 selectstart, 621 0, 622 "Selection.removeAllRanges() should not cause selectstart event (again)" 623 ); 624 is( 625 selectionchange, 626 1, 627 "Selection.removeAllRanges() should cause selectionchange event (again)" 628 ); 629 reset(); 630 isCollapsed(); 631 632 for (const textControl of [elt("input"), elt("textarea")]) { 633 await UpdateSelectEventsOnTextControlsPref({ 634 selectstart: false, 635 selectionchange: false, 636 }); 637 638 // Without the dom.select_events.textcontrols.enabled pref, 639 // pressing the mouse shouldn't do anything. 640 await testWithSynthesizingMouse( 641 `Pressing the left mouse button in <${ 642 textControl.tagName.toLocaleLowerCase() 643 }> should change selection of the document`, 644 textControl, 645 { x: 50 }, 646 "mousedown", 647 { 648 selectionchangeOnDocument: 1, 649 } 650 ); 651 652 // Releasing the mouse shouldn't do anything 653 await testWithSynthesizingMouse( 654 `Releasing the left mouse button in <${ 655 textControl.tagName.toLocaleLowerCase() 656 }> should not change any selection`, 657 textControl, 658 { x: 50 }, 659 "mouseup", 660 {} 661 ); 662 663 for (const selectstart of [1, 0]) { 664 await UpdateSelectEventsOnTextControlsPref({ 665 selectstart, 666 selectionchange: true, 667 }); 668 669 const selectstartEventSetting = `selectstart in text controls is ${ 670 selectstart ? "enabled" : "disabled" 671 }`; 672 673 const isInput = textControl.tagName.toLocaleLowerCase() == "input"; 674 675 await testWithSynthesizingMouse( 676 `Pressing the left mouse button in <${ 677 textControl.tagName.toLocaleLowerCase() 678 }> should change selection (${selectstartEventSetting})`, 679 textControl, 680 { x: 40 }, 681 "mousedown", 682 { 683 selectionchangeOnDocument: 1, 684 selectionchangeOnInput: isInput ? 1 : 0, 685 selectionchangeOnTextarea: isInput ? 0 : 1, 686 } 687 ); 688 689 selectstartTarget = textControl; 690 await testWithSynthesizingMouse( 691 `Dragging mouse to right to extend selection in <${ 692 textControl.tagName.toLocaleLowerCase() 693 }> should start to select and change selection (${ 694 selectstartEventSetting 695 })`, 696 textControl, 697 { x: 100 }, 698 "mousemove", 699 { 700 selectstartOnDocument: selectstart, 701 selectionchangeOnDocument: 1, 702 selectionchangeOnInput: isInput ? 1 : 0, 703 selectionchangeOnTextarea: isInput ? 0 : 1, 704 } 705 ); 706 707 // Moving it more shouldn't trigger a start (move back to empty) 708 await testWithSynthesizingMouse( 709 `Dragging mouse to left to shrink selection in <${ 710 textControl.tagName.toLocaleLowerCase() 711 }> should change selection (${selectstartEventSetting})`, 712 textControl, 713 { x: 75 }, 714 "mousemove", 715 { 716 selectionchangeOnDocument: 1, 717 selectionchangeOnInput: isInput ? 1 : 0, 718 selectionchangeOnTextarea: isInput ? 0 : 1, 719 } 720 ); 721 await testWithSynthesizingMouse( 722 `Dragging mouse to left to collapse selection in <${ 723 textControl.tagName.toLocaleLowerCase() 724 }> should change selection (${selectstartEventSetting})`, 725 textControl, 726 { x: 40 }, 727 "mousemove", 728 { 729 selectionchangeOnDocument: 1, 730 selectionchangeOnInput: isInput ? 1 : 0, 731 selectionchangeOnTextarea: isInput ? 0 : 1, 732 } 733 ); 734 735 // Wiggling the mouse a little such that it doesn't select any 736 // characters shouldn't trigger a selection 737 await testWithSynthesizingMouse( 738 `Pressing the left mouse button at caret in <${ 739 textControl.tagName.toLocaleLowerCase() 740 }> should not change selection (${selectstartEventSetting})`, 741 textControl, 742 { 743 x: 40, 744 y: 11, 745 }, 746 "mousemove", 747 {} 748 ); 749 750 // Moving the mouse again from an empty selection should trigger a 751 // selectstart 752 selectstartTarget = textControl; 753 await testWithSynthesizingMouse( 754 `Dragging mouse to left to extend selection in <${ 755 textControl.tagName.toLocaleLowerCase() 756 }> should start to select and change selection (${ 757 selectstartEventSetting 758 })`, 759 textControl, 760 { x: 25 }, 761 "mousemove", 762 { 763 selectstartOnDocument: selectstart, 764 selectionchangeOnDocument: 1, 765 selectionchangeOnInput: isInput ? 1 : 0, 766 selectionchangeOnTextarea: isInput ? 0 : 1, 767 } 768 ); 769 770 // Releasing the mouse shouldn't do anything 771 await testWithSynthesizingMouse( 772 `Releasing the left mouse button in <${ 773 textControl.tagName.toLocaleLowerCase() 774 }> should not change selection (${selectstartEventSetting})`, 775 textControl, 776 { x: 25 }, 777 "mouseup", 778 {} 779 ); 780 781 // And neither should moving your mouse around when the mouse 782 // button isn't pressed 783 await testWithSynthesizingMouse( 784 `Just moving mouse to right in <${ 785 textControl.tagName.toLocaleLowerCase() 786 }> should not start to select nor change selection (${ 787 selectstartEventSetting 788 })`, 789 textControl, 790 { x: 50 }, 791 "mousemove", 792 {} 793 ); 794 795 // Clicking in an random location should move the selection, but 796 // not perform a selectstart 797 await testWithSynthesizingMouse( 798 `Clicking in <${ 799 textControl.tagName.toLocaleLowerCase() 800 }> should change selection, but should not start selection (${ 801 selectstartEventSetting 802 })`, 803 textControl, 804 { x: 50 }, 805 "click", 806 { 807 selectionchangeOnDocument: 1, 808 selectionchangeOnInput: isInput ? 1 : 0, 809 selectionchangeOnTextarea: isInput ? 0 : 1, 810 } 811 ); 812 813 // Clicking there again should do nothing 814 await testWithSynthesizingMouse( 815 `Clicking at caret in <${ 816 textControl.tagName.toLocaleLowerCase() 817 }> should not change selection (${selectstartEventSetting})`, 818 textControl, 819 { x: 50 }, 820 "click", 821 {} 822 ); 823 824 // Selecting a region, and canceling the selectstart should mean that the 825 // selection remains collapsed 826 await testWithSynthesizingMouse( 827 `Pressing the left mouse button at different character in <${ 828 textControl.tagName.toLocaleLowerCase() 829 }> should change selection (${selectstartEventSetting})`, 830 textControl, 831 { x: 75 }, 832 "mousedown", 833 { 834 selectionchangeOnDocument: 1, 835 selectionchangeOnInput: isInput ? 1 : 0, 836 selectionchangeOnTextarea: isInput ? 0 : 1, 837 } 838 ); 839 cancel = true; 840 selectstartTarget = textControl; 841 await testWithSynthesizingMouse( 842 `Dragging mouse to right to extend selection in <${ 843 textControl.tagName.toLocaleLowerCase() 844 }> but the default of selectstart is prevented should cause selectstart and selectionchange events (${ 845 selectstartEventSetting 846 })`, 847 textControl, 848 { x: 100 }, 849 "mousemove", 850 { 851 selectstartOnDocument: selectstart, 852 selectionchangeOnDocument: 1, 853 selectionchangeOnInput: isInput ? 1 : 0, 854 selectionchangeOnTextarea: isInput ? 0 : 1, 855 } 856 ); 857 await testWithSynthesizingMouse( 858 `Releasing the left mouse button in <${ 859 textControl.tagName.toLocaleLowerCase() 860 }> should not cause changing selection (${selectstartEventSetting})`, 861 textControl, 862 { x: 100 }, 863 "mouseup", 864 {} 865 ); 866 } 867 } 868 869 // Marking the input and textarea as display: none and then as visible again 870 // shouldn't trigger any changes, although the nodes will be re-framed 871 for (const textControl of [elt("input"), elt("textarea")]) { 872 await (async function test_set_display_of_text_control_to_none() { 873 textControl.setAttribute("style", "display: none;"); 874 await spin(); 875 checkEventCounts( 876 `Setting display of <${ 877 textControl.tagName.toLocaleLowerCase() 878 }> to none`, 879 "", 880 {} 881 ); 882 reset(); 883 })(); 884 885 await (async function test_remove_display_none_of_text_control() { 886 textControl.setAttribute("style", ""); 887 await spin(); 888 checkEventCounts( 889 `Removing display:none of <${ 890 textControl.tagName.toLocaleLowerCase() 891 }>`, 892 "", 893 {} 894 ); 895 reset(); 896 })(); 897 } 898 899 // When selection is at the end of contentEditable's content, 900 // clearing the content should trigger selection events. 901 await (async function test_removing_contenteditable() { 902 const savedContent = elt("ce").innerHTML; 903 document.getSelection().setBaseAndExtent(elt("ce"), 1, elt("ce"), 1); 904 await spin(); 905 reset(); 906 907 elt("ce").firstChild.remove(); 908 await spin(); 909 checkEventCounts( 910 'Removing <div contenteditable="true"> from the DOM tree', 911 "", 912 { selectionchangeOnDocument: 1 } 913 ); 914 915 elt("ce").innerHTML = savedContent; 916 await spin(); 917 reset(); 918 })(); 919 }); 920 </script> 921 </body> 922 </html>