test_selection_move_commands.html (8093B)
1 <!doctype html> 2 <title>Test for nsSelectionMoveCommands</title> 3 <link rel=stylesheet href="/tests/SimpleTest/test.css"> 4 <script src="/tests/SimpleTest/SimpleTest.js"></script> 5 <script type="text/javascript" src="/tests/gfx/layers/apz/test/mochitest/apz_test_utils.js"></script> 6 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=454004">Mozilla Bug 454004</a> 7 8 <iframe id="edit" width="200" height="100" src="about:blank"></iframe> 9 10 <script> 11 SimpleTest.waitForExplicitFinish(); 12 13 async function setup() { 14 await SpecialPowers.pushPrefEnv({set: [["general.smoothScroll", false]]}); 15 } 16 17 async function* runTests() { 18 var e = document.getElementById("edit"); 19 var doc = e.contentDocument; 20 var win = e.contentWindow; 21 var root = doc.documentElement; 22 var body = doc.body; 23 24 var sel = win.getSelection(); 25 26 function testScrollCommand(cmd, expectTop) { 27 const { top } = root.getBoundingClientRect(); 28 29 // XXX(krosylight): Android scrolls slightly more inside 30 // geckoview-test-verify-e10s CI job 31 const isAndroid = SpecialPowers.Services.appinfo.widgetToolkit == "android"; 32 const delta = isAndroid ? .150 : 0; 33 isfuzzy(top, -expectTop, delta, cmd); 34 } 35 36 function testMoveCommand(cmd, expectNode, expectOffset) { 37 SpecialPowers.doCommand(window, cmd); 38 is(sel.isCollapsed, true, "collapsed after " + cmd); 39 is(sel.anchorNode, expectNode, "node after " + cmd); 40 is(sel.anchorOffset, expectOffset, "offset after " + cmd); 41 } 42 43 function findChildNum(element, child) { 44 var i = 0; 45 var n = element.firstChild; 46 while (n && n != child) { 47 n = n.nextSibling; 48 ++i; 49 } 50 if (!n) 51 return -1; 52 return i; 53 } 54 55 function testPageMoveCommand(cmd, expectOffset) { 56 SpecialPowers.doCommand(window, cmd); 57 is(sel.isCollapsed, true, "collapsed after " + cmd); 58 is(sel.anchorOffset, expectOffset, "offset after " + cmd); 59 return findChildNum(body, sel.anchorNode); 60 } 61 62 function testSelectCommand(cmd, expectNode, expectOffset) { 63 var anchorNode = sel.anchorNode; 64 var anchorOffset = sel.anchorOffset; 65 SpecialPowers.doCommand(window, cmd); 66 is(sel.isCollapsed, false, "not collapsed after " + cmd); 67 is(sel.anchorNode, anchorNode, "anchor not moved after " + cmd); 68 is(sel.anchorOffset, anchorOffset, "anchor not moved after " + cmd); 69 is(sel.focusNode, expectNode, "node after " + cmd); 70 is(sel.focusOffset, expectOffset, "offset after " + cmd); 71 } 72 73 function testPageSelectCommand(cmd, expectOffset) { 74 var anchorNode = sel.anchorNode; 75 var anchorOffset = sel.anchorOffset; 76 SpecialPowers.doCommand(window, cmd); 77 is(sel.isCollapsed, false, "not collapsed after " + cmd); 78 is(sel.anchorNode, anchorNode, "anchor not moved after " + cmd); 79 is(sel.anchorOffset, anchorOffset, "anchor not moved after " + cmd); 80 is(sel.focusOffset, expectOffset, "offset after " + cmd); 81 return findChildNum(body, sel.focusNode); 82 } 83 84 function node(i) { 85 var n = body.firstChild; 86 while (i > 0) { 87 n = n.nextSibling; 88 --i; 89 } 90 return n; 91 } 92 93 SpecialPowers.doCommand(window, "cmd_scrollBottom"); 94 yield; 95 testScrollCommand("cmd_scrollBottom", root.scrollHeight - 100); 96 SpecialPowers.doCommand(window, "cmd_scrollTop"); 97 yield; 98 testScrollCommand("cmd_scrollTop", 0); 99 100 SpecialPowers.doCommand(window, "cmd_scrollPageDown"); 101 yield; 102 var pageHeight = -root.getBoundingClientRect().top; 103 ok(pageHeight > 0, "cmd_scrollPageDown works"); 104 ok(pageHeight <= 100, "cmd_scrollPageDown doesn't scroll too much"); 105 SpecialPowers.doCommand(window, "cmd_scrollBottom"); 106 yield; 107 SpecialPowers.doCommand(window, "cmd_scrollPageUp"); 108 yield; 109 testScrollCommand("cmd_scrollPageUp", root.scrollHeight - 100 - pageHeight); 110 111 SpecialPowers.doCommand(window, "cmd_scrollTop"); 112 yield; 113 SpecialPowers.doCommand(window, "cmd_scrollLineDown"); 114 yield; 115 var lineHeight = -root.getBoundingClientRect().top; 116 ok(lineHeight > 0, "Can scroll by lines"); 117 SpecialPowers.doCommand(window, "cmd_scrollBottom"); 118 yield; 119 SpecialPowers.doCommand(window, "cmd_scrollLineUp"); 120 yield; 121 testScrollCommand("cmd_scrollLineUp", root.scrollHeight - 100 - lineHeight); 122 123 var runSelectionTests = function() { 124 testMoveCommand("cmd_moveBottom", body, 23); 125 testMoveCommand("cmd_moveTop", node(0), 0); 126 testSelectCommand("cmd_selectBottom", body, 23); 127 SpecialPowers.doCommand(window, "cmd_moveBottom"); 128 testSelectCommand("cmd_selectTop", node(0), 0); 129 130 SpecialPowers.doCommand(window, "cmd_moveTop"); 131 testMoveCommand("cmd_lineNext", node(2), 0); 132 testMoveCommand("cmd_linePrevious", node(0), 0); 133 testSelectCommand("cmd_selectLineNext", node(2), 0); 134 SpecialPowers.doCommand(window, "cmd_moveBottom"); 135 testSelectCommand("cmd_selectLinePrevious", node(20), 2); 136 137 SpecialPowers.doCommand(window, "cmd_moveBottom"); 138 testMoveCommand("cmd_charPrevious", node(22), 1); 139 testMoveCommand("cmd_charNext", node(22), 2); 140 testSelectCommand("cmd_selectCharPrevious", node(22), 1); 141 SpecialPowers.doCommand(window, "cmd_moveTop"); 142 testSelectCommand("cmd_selectCharNext", node(0), 1); 143 144 SpecialPowers.doCommand(window, "cmd_moveTop"); 145 testMoveCommand("cmd_endLine", node(0), 1); 146 testMoveCommand("cmd_beginLine", node(0), 0); 147 testSelectCommand("cmd_selectEndLine", node(0), 1); 148 SpecialPowers.doCommand(window, "cmd_moveBottom"); 149 testSelectCommand("cmd_selectBeginLine", node(22), 0); 150 151 SpecialPowers.doCommand(window, "cmd_moveBottom"); 152 testMoveCommand("cmd_wordPrevious", node(22), 0); 153 testMoveCommand("cmd_wordNext", body, 23); 154 testSelectCommand("cmd_selectWordPrevious", node(22), 0); 155 SpecialPowers.doCommand(window, "cmd_moveTop"); 156 testSelectCommand("cmd_selectWordNext", body, 1); 157 158 SpecialPowers.doCommand(window, "cmd_moveTop"); 159 var lineNum = testPageMoveCommand("cmd_movePageDown", 0); 160 ok(lineNum > 0, "cmd_movePageDown works"); 161 SpecialPowers.doCommand(window, "cmd_moveBottom"); 162 SpecialPowers.doCommand(window, "cmd_beginLine"); 163 is(testPageMoveCommand("cmd_movePageUp", 0), 22 - lineNum, "cmd_movePageUp"); 164 165 SpecialPowers.doCommand(window, "cmd_moveTop"); 166 is(testPageSelectCommand("cmd_selectPageDown", 0), lineNum, "cmd_selectPageDown"); 167 SpecialPowers.doCommand(window, "cmd_moveBottom"); 168 SpecialPowers.doCommand(window, "cmd_beginLine"); 169 is(testPageSelectCommand("cmd_selectPageUp", 0), 22 - lineNum, "cmd_selectPageUp"); 170 }; 171 172 await SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", false]]}); 173 runSelectionTests(); 174 await SpecialPowers.pushPrefEnv({set: [["layout.word_select.eat_space_to_next_word", true]]}); 175 runSelectionTests(); 176 } 177 178 function cleanup() { 179 SimpleTest.finish(); 180 } 181 182 async function testRunner() { 183 var e = document.getElementById("edit"); 184 var doc = e.contentDocument; 185 var win = e.contentWindow; 186 var body = doc.body; 187 188 body.style.fontSize = "16px"; 189 body.style.lineHeight = "16px"; 190 body.style.height = "400px"; 191 body.style.padding = "0px"; 192 body.style.margin = "0px"; 193 body.style.borderWidth = "0px"; 194 195 doc.designMode = "on"; 196 body.innerHTML = "1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>"; 197 win.focus(); 198 // Flush out layout to make sure that the subdocument will be the size we 199 // expect by the time we try to scroll it. 200 is(body.getBoundingClientRect().height, 400, 201 "Body height should be what we set it to"); 202 203 await waitToClearOutAnyPotentialScrolls(win); 204 205 let curTest = runTests(); 206 while (true) { 207 let promise = new Promise(resolve => { win.addEventListener("scroll", () => { SimpleTest.executeSoon(resolve); }, {once: true, capture: true}); }); 208 if ((await curTest.next()).done) { 209 break; 210 } 211 // wait for the scroll 212 await promise; 213 // clear out any other pending scrolls 214 await waitToClearOutAnyPotentialScrolls(win); 215 } 216 } 217 218 SimpleTest.waitForFocus(function() { 219 setup() 220 .then(() => testRunner()) 221 .then(() => cleanup()) 222 .catch(err => ok(false, err)); 223 }, window); 224 225 </script>