selectAtPoint.html (9882B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>nsIDOMWindowUtils::selectAtPoint test</title> 5 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> 6 <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> 7 8 <script type="application/javascript"> 9 var SimpleTest = window.opener.SimpleTest; 10 11 function ok() { window.opener.ok.apply(window.opener, arguments); } 12 function done() { window.opener.done.apply(window.opener, arguments); } 13 14 function dumpLn() { 15 for (let idx = 0; idx < arguments.length; idx++) 16 dump(arguments[idx] + " "); 17 dump("\n"); 18 } 19 20 function getCharacterDims() { 21 let span = document.getElementById("measure"); 22 let rect = span.getBoundingClientRect(); 23 // Subtract 2 from each dimension because of 1px border on all sides 24 // of the frame. 25 return { width: rect.width - 2, height: rect.height - 2 }; 26 } 27 28 function setStart(aDWU, aX, aY, aSelectType) 29 { 30 // Clear any existing selection 31 let selection = document.getSelection(); 32 selection.removeAllRanges(); 33 34 // Select text 35 let result = aDWU.selectAtPoint(aX, aY, aSelectType); 36 ok(result == true, "selectAtPoint succeeded?"); 37 } 38 39 function setEnd(aDWU, aX, aY, aSelectType) 40 { 41 // Select text 42 let result = aDWU.selectAtPoint(aX, aY, aSelectType); 43 ok(result == true, "selectAtPoint succeeded?"); 44 } 45 46 function setSingle(aDWU, aX, aY, aSelectType, aSelectTypeStr, aExpectedSelectionText) { 47 // Clear any existing selection 48 let selection = document.getSelection(); 49 selection.removeAllRanges(); 50 51 // Select text 52 let result = aDWU.selectAtPoint(aX, aY, aSelectType); 53 ok(result == true, "selectAtPoint succeeded?"); 54 } 55 56 function checkSelection(aDoc, aSelectTypeStr, aExpectedSelectionText) { 57 // Retrieve text selected 58 let selection = aDoc.getSelection(); 59 let text = selection.toString(); 60 61 // Test 62 let result = (text == aExpectedSelectionText); 63 ok(result, aSelectTypeStr + " selection text matches?"); 64 if (!result) { 65 dumpLn(aSelectTypeStr + " selection text:", "[" + text + "] expected:[" + aExpectedSelectionText + "]" ); 66 } 67 } 68 69 function doTest() { 70 let dwu = window.windowUtils; 71 72 let os = Cc["@mozilla.org/xre/app-info;1"] 73 .getService(Ci.nsIXULRuntime).OS; 74 let isLinux = (os == "Linux"); 75 let isMac = (os == "Darwin"); 76 let isWindows = (os == "WINNT"); 77 78 if (!isLinux && !isMac && !isWindows) { 79 done(); 80 return; 81 } 82 83 window.scrollTo(0, 0); 84 85 // Trick to get character spacing - get the bounds around a 86 // single character trapped in a div. 87 let charDims = getCharacterDims(); 88 // dumpLn("character dims:", charDims.width, charDims.height); 89 90 // 91 // Root frame selection 92 // 93 94 // First div in the main page 95 96 let div = document.getElementById("div1"); 97 let rect = div.getBoundingClientRect(); 98 rect.x += 1; rect.y += 1; rect.width -= 2; rect.height -= 2; // remove border 99 100 // Centered on the first character in the sentence div 101 let targetPoint = { xPos: rect.left + (charDims.width / 2), 102 yPos: rect.top + (charDims.height / 2) }; 103 104 setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE); 105 checkSelection(document, "SELECT_WORDNOSPACE", "ttestselection1"); 106 setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORD); 107 if (isLinux || isMac) { 108 checkSelection(document, "SELECT_WORD", "ttestselection1"); 109 } else if (isWindows) { 110 checkSelection(document, "SELECT_WORD", "ttestselection1 "); 111 } 112 setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_PARAGRAPH); 113 checkSelection(document, "SELECT_PARAGRAPH", "ttestselection1 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos. Ei munere officiis assentior pro, nibh decore ius at."); 114 115 // Within the 10th character "c" in the sentence div 116 targetPoint = { xPos: rect.left + 9.6 * charDims.width, 117 yPos: rect.top + (charDims.height / 2) }; 118 // The expectations here are incorrect, because selectAtPoint selects two characters 119 // when it should only get one. https://bugzilla.mozilla.org/show_bug.cgi?id=1696176 120 setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CHARACTER); 121 checkSelection(document, "SELECT_CHARACTER", "c"); 122 setSingle(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CLUSTER); 123 checkSelection(document, "SELECT_CLUSTER", "c"); 124 125 // Separate character blocks in a word 'ttestse(l)ection(1)' 126 targetPoint = { xPos: rect.left + 7.6 * charDims.width, 127 yPos: rect.top + (charDims.height / 2) }; 128 setStart(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CHARACTER); 129 targetPoint = { xPos: rect.left + 14.6 * charDims.width, 130 yPos: rect.top + (charDims.height / 2) }; 131 setEnd(dwu, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_CHARACTER); 132 checkSelection(document, "split selection", "l1"); 133 134 // Trying to select where there's no text, should fail but not throw 135 let result = dwu.selectAtPoint(rect.left - 20, rect.top - 20, Ci.nsIDOMWindowUtils.SELECT_CHARACTER, false); 136 ok(result == false, "couldn't select?"); 137 138 // Second div in the main page 139 140 div = document.getElementById("div2"); 141 rect = div.getBoundingClientRect(); 142 rect.x += 1; rect.y += 1; rect.width -= 2; rect.height -= 2; // remove border 143 144 // Centered on the first line, first character in the paragraph div 145 targetPoint = { xPos: rect.left + (charDims.width / 2), 146 yPos: rect.top + (charDims.height / 2) }; 147 setSingle(dwu, targetPoint.xPos + 50, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_PARAGRAPH); 148 checkSelection(document, "SELECT_PARAGRAPH", "Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos."); 149 150 // 151 // Inner IFRAME selection tests 152 // 153 154 let frame = document.getElementById("frame1"); 155 let dwuFrame = frame.contentDocument 156 .defaultView 157 .windowUtils; 158 159 frame.contentWindow.scrollTo(0, 0); 160 161 rect = frame.getBoundingClientRect(); 162 rect.x += 1; rect.y += 1; rect.width -= 2; rect.height -= 2; // remove border 163 164 targetPoint = { xPos: charDims.width / 2, 165 yPos: charDims.height / 2 }; 166 setSingle(dwuFrame, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORDNOSPACE); 167 checkSelection(frame.contentWindow.document, "SELECT_WORDNOSPACE", "ttestselection2"); 168 setSingle(dwuFrame, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_WORD); 169 if (isLinux || isMac) { 170 checkSelection(frame.contentWindow.document, "SELECT_WORD", "ttestselection2"); 171 } else if (isWindows) { 172 checkSelection(frame.contentWindow.document, "SELECT_WORD", "ttestselection2 "); 173 } 174 setSingle(dwuFrame, targetPoint.xPos, targetPoint.yPos, Ci.nsIDOMWindowUtils.SELECT_PARAGRAPH); 175 checkSelection(frame.contentWindow.document, "SELECT_PARAGRAPH", "ttestselection2 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut."); 176 177 // Outside the frame should throw. This is a failure in coordinate setup of 178 // nsDOMWindowUtils::SelectAtPoint. 179 let thr = false; 180 try { 181 dwuFrame.selectAtPoint(rect.right + 50, rect.top, Ci.nsIDOMWindowUtils.SELECT_WORD, false); 182 } catch (ex) { thr = true; } 183 ok(thr == true, "selectAtPoint expected throw?"); 184 185 done(); 186 } 187 188 let frameLoad = false; 189 let pageLoad = false; 190 let painted = false; 191 function testReady() { 192 if (frameLoad && pageLoad && painted) 193 doTest(); 194 } 195 196 function onFrameLoad() { 197 // Exit the onload handler before trying the test, because we need 198 // to ensure that paint unsupression has happened. 199 setTimeout(function() { 200 frameLoad = true; 201 testReady(); 202 }, 0); 203 } 204 205 function onPageLoad() { 206 // Exit the onload handler before trying the test, because we need 207 // to ensure that paint unsupression has happened 208 // XXXroc why do we need to separately test for the loading of the frame 209 // and a paint? That should not be necessary for this test. 210 setTimeout(function() { 211 pageLoad = true; 212 testReady(); 213 }, 0); 214 } 215 216 function onPaint() { 217 window.removeEventListener("MozAfterPaint", onPaint); 218 painted = true; 219 testReady(); 220 } 221 222 window.addEventListener("MozAfterPaint", onPaint); 223 </script> 224 225 <style type="text/css"> 226 227 body { 228 font-family: monospace; 229 margin-left: 40px; 230 margin-top: 40px; 231 padding: 0; 232 } 233 234 #div1 { 235 border: 1px solid red; 236 width: 400px; 237 height: 100px; 238 } 239 240 #frame1 { 241 display: block; 242 height: 100px; 243 width: 300px; 244 border: 1px solid blue; 245 padding: 0; 246 margin: 0; 247 } 248 249 #div2 { 250 border: 1px solid green; 251 } 252 253 #measure { 254 padding: 0px; 255 margin: 0px; 256 border: 1px solid red; 257 } 258 259 </style> 260 </head> 261 <body id="body" onload="onPageLoad();"> 262 263 <div id="div1">ttestselection1 Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos. Ei munere officiis assentior pro, nibh decore ius at.</div> 264 265 <br /> 266 267 <iframe id="frame1" src="selectAtPoint-innerframe.html"></iframe> 268 269 <br/> 270 271 <div id="div2">Lorem ipsum dolor sit amet, at duo debet graeci, vivendum vulputate per ut. Ne labore incorrupte vix. Cu copiosae postulant tincidunt ius, in illud appetere contentiones eos.</div> 272 273 <br /> 274 275 <span id="measure">t</span> 276 277 </body> 278 </html>