test_selection_multiclick_drag.html (5987B)
1 <!DOCTYPE> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>multi-click selection extension test</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <script src="/tests/SimpleTest/EventUtils.js"></script> 8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 9 <style> 10 .testingDiv { font: 16px/1.25 monospace; width: -moz-fit-content; } 11 p { margin: 0; unicode-bidi: bidi-override; } 12 </style> 13 </head> 14 15 <body> 16 <div id="testDiv" class="testingDiv"> 17 <p>one two three</p> 18 <p>un deux trois</p> 19 <p>ein zwei drei</p> 20 </div> 21 <br> 22 <div id="rtlTestDiv" class="testingDiv" dir="rtl"> 23 <p>one two three</p> 24 <p>un deux trois</p> 25 <p>ein zwei drei</p> 26 </div> 27 28 <pre id="test"> 29 <script class="testbody" type="text/javascript"> 30 31 function test() { 32 const testDiv = document.getElementById("testDiv"); 33 const rtlTestDiv = document.getElementById("rtlTestDiv"); 34 35 // Expected line height (CSS 'lh' unit), given that font-size = 16px and 36 // line-height = 1.25. 37 const lh = 20; 38 39 // Width of one character in the monospace font (the CSS 'ch' unit), 40 // calculated by measuring the test text that contains 13 chars per line. 41 const ch = testDiv.offsetWidth / 13; 42 43 const platformIsWindows = !navigator.platform.indexOf("Win"); 44 const eatSpaceAfterWord = SpecialPowers.getBoolPref("layout.word_select.eat_space_to_next_word"); 45 46 // Y-coordinates that will fall within each line: 47 const firstLine = 0.5 * lh; 48 const secondLine = 1.5 * lh; 49 const thirdLine = 2.5 * lh; 50 51 // Return the character offset of "^", representing the position to click/drag 52 // within the test string. 53 function xPosForClick(s) { 54 return s.indexOf("^") * ch; 55 } 56 57 // Test expectation strings use "_" to represent a space that is only expected 58 // to be present on Windows, where layout.word_select.eat_space_to_next_word 59 // is set by default, and <PAR> to denote a paragraph separator sequence (two 60 // platform-specific newlines). 61 function expectation(s) { 62 let result = s.replace("_", eatSpaceAfterWord ? " " : ""); 63 result = result.replace("<PAR>", platformIsWindows ? "\r\n\r\n" : "\n\n"); 64 return result; 65 } 66 67 // Sanity-check that we're hitting what we expect with our clicks: 68 synthesizeMouse(testDiv, xPosForClick("un de^ux trois"), secondLine, { clickCount: 2 }); 69 is(window.getSelection().toString(), expectation("deux_"), "Double-click middle word"); 70 71 // Each entry in the array specifies which line to drag to, the character position 72 // within that line (indicated by the caret ^ in the given string), and what the 73 // expected selection should then be. 74 const wordSelectTests = [ 75 [secondLine, "un^ deux trois", "un deux_", "Drag left to extend by word"], 76 [secondLine, "un ^deux trois", "deux_", "Return to edge of anchor word"], 77 [secondLine, "un d^eux trois", "deux_", "Return to within anchor word"], 78 [secondLine, "un deux t^rois", "deux trois", "Drag right to extend by word"], 79 [firstLine, "one t^wo three", "two three<PAR>un deux_", "Drag into previous line"], 80 [secondLine, "un ^deux trois", "deux_", "Drag back to start of anchor word"], 81 [secondLine, "un de^ux trois", "deux_", "Drag back to middle of anchor word"], 82 [thirdLine, "ein zw^ei drei", "deux trois<PAR>ein zwei_", "Drag into next line"], 83 [secondLine, "un de^ux trois", "deux_", "Return to anchor word"], 84 ]; 85 86 const lineSelectTests = [ 87 [secondLine, "un de^ux trois", "un deux trois", "Triple-click selected whole line"], 88 [firstLine, "one t^wo three", "one two three<PAR>un deux trois", "Drag up into previous line"], 89 [secondLine, "un de^ux trois", "un deux trois", "Return to middle line"], 90 [thirdLine, "ein z^wei drei", "un deux trois<PAR>ein zwei drei", "Drag down into next line"], 91 [secondLine, "un de^ux trois", "un deux trois", "Return to middle line"], 92 ]; 93 94 // The RTL tests use monospaced latin text with bidi-override applied; 95 // we specify caret positions by counting characters in a reversed string. 96 const rtlWordSelectTests = [ 97 [secondLine, "siort xued ^nu", "un deux_", "Drag right to extend by word"], 98 [secondLine, "siort xued^ nu", "deux_", "Return to edge of anchor word"], 99 [secondLine, "siort xu^ed nu", "deux_", "Return to within anchor word"], 100 [secondLine, "siort^ xued nu", "deux trois", "Drag left to extend by word"], 101 [firstLine, "eerht ow^t eno", "two three<PAR>un deux_", "Drag into previous line"], 102 [secondLine, "siort xued^ nu", "deux_", "Drag back to start of anchor word"], 103 [secondLine, "siort xu^ed nu", "deux_", "Drag back to middle of anchor word"], 104 [thirdLine, "ierd ie^wz nie", "deux trois<PAR>ein zwei_", "Drag into next line"], 105 [secondLine, "siort xu^ed nu", "deux_", "Return to anchor word"], 106 ]; 107 108 function testMultiClickAndDrag(elem, initialPos, clickCount, tests) { 109 // Initial multi-click in the middle word of the middle line: 110 synthesizeMouse(elem, xPosForClick(initialPos), secondLine, { type: "mousedown", clickCount: clickCount }); 111 112 // Now drag to each test position and check the resulting selection: 113 tests.forEach(function(t) { 114 synthesizeMouse(elem, xPosForClick(t[1]), t[0], { type: "mousemove" }); 115 is(window.getSelection().toString(), expectation(t[2]), t[3]); 116 }); 117 118 // Finish the test sequence with mouseUp. 119 synthesizeMouse(elem, xPosForClick(initialPos), secondLine, { type: "mouseup" }); 120 } 121 122 testMultiClickAndDrag(testDiv, "un de^ux trois", 2, wordSelectTests); 123 124 testMultiClickAndDrag(testDiv, "un de^ux trois", 3, lineSelectTests); 125 126 testMultiClickAndDrag(rtlTestDiv, "siort xu^ed nu", 2, rtlWordSelectTests); 127 128 SimpleTest.finish(); 129 } 130 window.onload = function() { 131 setTimeout(test, 0); 132 }; 133 SimpleTest.waitForExplicitFinish(); 134 </script> 135 </pre> 136 </body> 137 </html>