content_editable_extractor_test.unitjs revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Include test fixture. 6GEN_INCLUDE(['../testing/chromevox_unittest_base.js']); 7 8/** 9 * Test fixture. 10 * @constructor 11 * @extends {ChromeVoxUnitTestBase} 12 */ 13function CvoxContentEditableExtractorUnitTest() {} 14 15CvoxContentEditableExtractorUnitTest.prototype = { 16 __proto__: ChromeVoxUnitTestBase.prototype, 17 18 /** @override */ 19 closureModuleDeps: [ 20 'cvox.ContentEditableExtractor', 21 ] 22}; 23 24/** 25 * Helper function to set the selection 26 * @param {Node} startNode The base/start node of the range. 27 * @param {number} startOffset The 0-based character index of the start. 28 * @param {Node} endNode The extent/end node of the range. 29 * @param {number} endOffset The 0-based character index of the end. 30 */ 31function setSelection(startNode, startOffset, endNode, endOffset) { 32 var r = document.createRange(); 33 r.setStart(startNode, startOffset); 34 r.setEnd(endNode, endOffset); 35 var sel = window.getSelection(); 36 sel.removeAllRanges(); 37 sel.addRange(r); 38} 39 40TEST_F('CvoxContentEditableExtractorUnitTest', 'EmptyElement', function() { 41 this.loadDoc(function() {/*! 42 <div> 43 <div id="textbox" contentEditable="true"></div> 44 </div> 45 */}); 46 47 var textbox = $('textbox'); 48 var extractor = new cvox.ContentEditableExtractor(); 49 extractor.update(textbox); 50 assertEquals('', extractor.getText()); 51 assertEquals(0, extractor.getStartIndex()); 52 assertEquals(0, extractor.getEndIndex(0)); 53 assertEquals(0, extractor.getLineIndex(0)); 54 assertEquals(0, extractor.getLineStart(0)); 55 assertEquals(0, extractor.getLineEnd(0)); 56}); 57 58/** 59 * Test getting text and selections from a single contenteditable node. 60 */ 61TEST_F('CvoxContentEditableExtractorUnitTest', 'SingleTextNode', function() { 62 this.loadDoc(function() {/*! 63 <div> 64 <div id="textbox" contentEditable="true">Hello</div> 65 </div> 66 */}); 67 var textbox = $('textbox'); 68 69 var extractor = new cvox.ContentEditableExtractor(); 70 extractor.update(textbox); 71 assertEquals('Hello', extractor.getText()); 72 assertEquals(0, extractor.getLineIndex(0)); 73 assertEquals(0, extractor.getLineStart(0)); 74 assertEquals(5, extractor.getLineEnd(0)); 75 assertEquals(5, extractor.getStartIndex()); 76 assertEquals(5, extractor.getEndIndex()); 77 78 // Test all possible cursor positions. 79 for (var i = 0; i <= 5; i++) { 80 setSelection(textbox.firstChild, i, textbox.firstChild, i); 81 extractor.update(textbox); 82 assertEquals(i, extractor.getStartIndex()); 83 assertEquals(i, extractor.getEndIndex()); 84 } 85 86 // Test all possible ways to select one character. 87 for (i = 0; i < 5; i++) { 88 setSelection(textbox.firstChild, i, textbox.firstChild, i + 1); 89 extractor.update(textbox); 90 assertEquals(i, extractor.getStartIndex()); 91 assertEquals(i + 1, extractor.getEndIndex()); 92 } 93 94 // Test selecting everything. 95 setSelection(textbox.firstChild, 0, textbox.firstChild, 5); 96 extractor.update(textbox); 97 assertEquals(0, extractor.getStartIndex()); 98 assertEquals(5, extractor.getEndIndex()); 99}); 100 101/** 102 * Test getting text and selections from a contenteditable node with 103 * nonprinted whitespace. 104 */ 105TEST_F('CvoxContentEditableExtractorUnitTest', 'TextWithWhitespace', 106 function() { 107 this.loadDoc(function() {/*! 108 <div> 109 <div id="textbox" contentEditable="true"> Hello World </div> 110 </div> 111 */}); 112 var textbox = $('textbox'); 113 114 var extractor = new cvox.ContentEditableExtractor(); 115 extractor.update(textbox); 116 assertEquals('Hello World', extractor.getText()); 117 assertEquals(0, extractor.getLineIndex(0)); 118 assertEquals(0, extractor.getLineStart(0)); 119 assertEquals(11, extractor.getLineEnd(0)); 120 assertEquals(11, extractor.getStartIndex()); 121 assertEquals(11, extractor.getEndIndex()); 122 123 // Test all *reasonable* indexes of a selection into this text node 124 // and the logical index into the text that these should result in. 125 var expectedIndexMap = { 126 0: 0, 127 1: 0, 128 2: 1, 129 3: 2, 130 4: 3, 131 5: 4, 132 6: 5, 133 // Note: index=7 should never happen 134 8: 6, 135 9: 7, 136 10: 8, 137 11: 9, 138 12: 10, 139 13: 11, 140 14: 11 141 }; 142 for (var srcIndex in expectedIndexMap) { 143 var dstIndex = expectedIndexMap[srcIndex]; 144 setSelection(textbox.firstChild, srcIndex, textbox.firstChild, srcIndex); 145 extractor.update(textbox); 146 assertEquals(dstIndex, extractor.getStartIndex()); 147 assertEquals(dstIndex, extractor.getEndIndex()); 148 } 149}); 150 151/** 152 * Test getting text and selections from a contenteditable node with 153 * preformatted text. 154 */ 155TEST_F('CvoxContentEditableExtractorUnitTest', 'Preformatted', function() { 156 this.loadDoc(function() {/*! 157 <div> 158 <pre id="textbox" contentEditable="true">aaaaaaaaaa 159bbbbbbbbbb 160cccccccccc</pre> 161 </div> 162 */}); 163 var textbox = $('textbox'); 164 165 var extractor = new cvox.ContentEditableExtractor(); 166 extractor.update(textbox); 167 assertEquals('aaaaaaaaaa\nbbbbbbbbbb\ncccccccccc', extractor.getText()); 168 assertEquals(0, extractor.getLineStart(0)); 169 assertEquals(11, extractor.getLineEnd(0)); 170 assertEquals(11, extractor.getLineStart(1)); 171 assertEquals(22, extractor.getLineEnd(1)); 172 assertEquals(22, extractor.getLineStart(2)); 173 assertEquals(32, extractor.getLineEnd(2)); 174 175 // Test all possible cursor positions. 176 for (var i = 0; i <= 32; i++) { 177 setSelection(textbox.firstChild, i, textbox.firstChild, i); 178 extractor.update(textbox); 179 assertEquals(i, extractor.getStartIndex()); 180 assertEquals(i, extractor.getEndIndex()); 181 } 182}); 183 184/** 185 * Test getting text and selections from a contenteditable node with 186 * wrapping. 187 */ 188TEST_F('CvoxContentEditableExtractorUnitTest', 'WordWrap', function() { 189 this.loadDoc(function() {/*! 190 <div> 191 <div id="textbox" 192 style="width: 1em; word-wrap: normal" 193 contentEditable="true">One two three</div> 194 </div> 195 */}); 196 var textbox = $('textbox'); 197 198 var extractor = new cvox.ContentEditableExtractor(); 199 extractor.update(textbox); 200 assertEquals('One\ntwo\nthree', extractor.getText()); 201 assertEquals(0, extractor.getLineStart(0)); 202 assertEquals(4, extractor.getLineEnd(0)); 203 assertEquals(4, extractor.getLineStart(1)); 204 assertEquals(8, extractor.getLineEnd(1)); 205 assertEquals(8, extractor.getLineStart(2)); 206 assertEquals(13, extractor.getLineEnd(2)); 207 208 // Test all possible cursor positions. 209 for (var i = 0; i <= 13; i++) { 210 setSelection(textbox.firstChild, i, textbox.firstChild, i); 211 extractor.update(textbox); 212 assertEquals(i, extractor.getStartIndex()); 213 assertEquals(i, extractor.getEndIndex()); 214 } 215}); 216 217/** 218 * Test getting text and lines from a contenteditable region 219 * containing two paragraphs and an explicit line break. 220 */ 221TEST_F('CvoxContentEditableExtractorUnitTest', 'TwoParas', function() { 222 this.loadDoc(function() {/*! 223 <div> 224 <div id="textbox" contentEditable="true"> 225 <p>One</p> 226 <p>Two<br>Three</p> 227 </div> 228 </div> 229 */}); 230 var textbox = $('textbox'); 231 232 var extractor = new cvox.ContentEditableExtractor(); 233 extractor.update(textbox); 234 assertEquals('One\nTwo\nThree', 235 extractor.getText()); 236 assertEquals(0, extractor.getLineStart(0)); 237 assertEquals(4, extractor.getLineEnd(0)); 238 assertEquals(4, extractor.getLineStart(1)); 239 assertEquals(8, extractor.getLineEnd(1)); 240 assertEquals(8, extractor.getLineStart(2)); 241 assertEquals(13, extractor.getLineEnd(2)); 242}); 243 244/** 245 * Test getting text and lines from a contenteditable region 246 * containing two paragraphs, this time with added whitespace. 247 */ 248TEST_F('CvoxContentEditableExtractorUnitTest', 'TwoParasWithWhitespace', 249 function() { 250 this.loadDoc(function() {/*! 251 <div> 252 <div id="textbox" contentEditable="true"> 253 <p> One </p> 254 <p> Two <br> Three </p> 255 </div> 256 </div> 257 */}); 258 var textbox = $('textbox'); 259 260 var extractor = new cvox.ContentEditableExtractor(); 261 extractor.update(textbox); 262 assertEquals('One\nTwo Three', 263 extractor.getText()); 264 assertEquals(0, extractor.getLineStart(0)); 265 assertEquals(4, extractor.getLineEnd(0)); 266 assertEquals(4, extractor.getLineStart(1)); 267 assertEquals(8, extractor.getLineEnd(1)); 268 assertEquals(8, extractor.getLineStart(2)); 269 assertEquals(13, extractor.getLineEnd(2)); 270}); 271 272/** 273 * Test getting text and lines from a contenteditable region 274 * containing some raw text and then some text in a block-level element. 275 */ 276TEST_F('CvoxContentEditableExtractorUnitTest', 'NodePlusElement', function() { 277 this.loadDoc(function() {/*! 278 <div> 279 <div id="textbox" 280 contentEditable="true">One<div>Two<br>Three</div></div> 281 </div> 282 */}); 283 var textbox = $('textbox'); 284 285 var extractor = new cvox.ContentEditableExtractor(); 286 extractor.update(textbox); 287 assertEquals('One\nTwo\nThree', 288 extractor.getText()); 289 assertEquals(0, extractor.getLineStart(0)); 290 assertEquals(4, extractor.getLineEnd(0)); 291 assertEquals(4, extractor.getLineStart(1)); 292 assertEquals(8, extractor.getLineEnd(1)); 293 assertEquals(8, extractor.getLineStart(2)); 294 assertEquals(13, extractor.getLineEnd(2)); 295 296 var oneTextNode = textbox.firstChild; 297 assertEquals('One', oneTextNode.data); 298 var twoTextNode = textbox.firstElementChild.firstChild; 299 assertEquals('Two', twoTextNode.data); 300 var threeTextNode = twoTextNode.nextSibling.nextSibling; 301 assertEquals('Three', threeTextNode.data); 302 303 // End of first line. 304 setSelection(oneTextNode, 3, oneTextNode, 3); 305 extractor.update(textbox); 306 assertEquals(3, extractor.getStartIndex()); 307 assertEquals(3, extractor.getEndIndex()); 308 309 // Beginning of second line. 310 setSelection(twoTextNode, 0, twoTextNode, 0); 311 extractor.update(textbox); 312 assertEquals(4, extractor.getStartIndex()); 313 assertEquals(4, extractor.getEndIndex()); 314 315 // End of second line. 316 setSelection(twoTextNode, 3, twoTextNode, 3); 317 extractor.update(textbox); 318 assertEquals(7, extractor.getStartIndex()); 319 assertEquals(7, extractor.getEndIndex()); 320 321 // Beginning of third line. 322 setSelection(threeTextNode, 0, threeTextNode, 0); 323 extractor.update(textbox); 324 assertEquals(8, extractor.getStartIndex()); 325 assertEquals(8, extractor.getEndIndex()); 326}); 327