initial-selection-on-focus.tentative.html (25218B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <meta name="variant" content="?div"> 4 <meta name="variant" content="?span"> 5 <title>initial selection on focus of contenteditable</title> 6 <script src="/resources/testharness.js"></script> 7 <script src="/resources/testharnessreport.js"></script> 8 <script>var testsJsLibraryOnly = true</script> 9 <script src="../../editing/include/tests.js"></script> 10 <body> 11 <script> 12 "use strict"; 13 14 (function() { 15 const editingHostTagName = document.location.search.substr(1); 16 const editor = document.createElement(editingHostTagName); 17 editor.style.minHeight = "1em"; 18 editor.setAttribute("contenteditable", ""); 19 document.body.insertBefore(editor, document.body.firstChild); 20 editor.focus(); 21 editor.getBoundingClientRect(); 22 23 const tests = [ 24 { description: "empty editor should set focus to start of it", 25 content: "{}", 26 canTestInInlineEditingHost: true, 27 }, 28 { description: "editor should set selection to start of the text node", 29 content: "[]abc", 30 canTestInInlineEditingHost: true, 31 }, 32 { description: "editor should set selection to before the <br> node", 33 content: "{}<br>", 34 canTestInInlineEditingHost: true, 35 }, 36 { description: "editor should set selection to before the first <br> node", 37 content: "{}<br><br>", 38 canTestInInlineEditingHost: true, 39 }, 40 41 { description: "editor should set selection to start of the text node in the <p> node", 42 content: "<p>[]abc</p>", 43 canTestInInlineEditingHost: false, 44 }, 45 { description: "editor should set selection to start of the first visible character in the text node in the <p> node", 46 content: "<p> []abc</p>", 47 canTestInInlineEditingHost: false, 48 }, 49 { description: "editor should set selection to start of the text node in the <p> node because of preformatted white-space", 50 content: "<p style=\"white-space: pre\">[] abc</p>", 51 canTestInInlineEditingHost: false, 52 }, 53 { description: "editor should set selection to start of the text node in the <p> node because of preformatted line break", 54 content: "<p style=\"white-space: pre\">[]\nabc</p>", 55 canTestInInlineEditingHost: false, 56 }, 57 { description: "editor should set selection to before the <br> node in the <p> node", 58 content: "<p>{}<br></p>", 59 canTestInInlineEditingHost: false, 60 }, 61 { description: "editor should set selection to before the first <br> node in the <p> node", 62 content: "<p>{}<br><br></p>", 63 canTestInInlineEditingHost: false, 64 }, 65 66 { description: "editor should set selection to start of the text node in the <span> node", 67 content: "<span>[]abc</span>", 68 canTestInInlineEditingHost: true, 69 }, 70 { description: "editor should set selection to before the <br> node in the <span> node", 71 content: "<span>{}<br></span>", 72 canTestInInlineEditingHost: true, 73 }, 74 { description: "editor should set selection to before the first <br> node in the <span> node", 75 content: "<span>{}<br><br></span>", 76 canTestInInlineEditingHost: true, 77 }, 78 79 { description: "editor should set selection to before the empty <span> node", 80 content: "{}<span></span>", 81 canTestInInlineEditingHost: true, 82 }, 83 { description: "editor should set selection to before the empty <b> node", 84 content: "{}<b></b>", 85 canTestInInlineEditingHost: true, 86 }, 87 { description: "editor should set selection to before the empty <i> node", 88 content: "{}<i></i>", 89 canTestInInlineEditingHost: true, 90 }, 91 { description: "editor should set selection to before the empty <u> node", 92 content: "{}<u></u>", 93 canTestInInlineEditingHost: true, 94 }, 95 { description: "editor should set selection to before the empty <s> node", 96 content: "{}<s></s>", 97 canTestInInlineEditingHost: true, 98 }, 99 { description: "editor should set selection to before the empty <code> node", 100 content: "{}<code></code>", 101 canTestInInlineEditingHost: true, 102 }, 103 { description: "editor should set selection to before the empty <a> node", 104 content: "{}<a href=\"foo.html\"></a>", 105 canTestInInlineEditingHost: true, 106 }, 107 { description: "editor should set selection to before the empty <foobar> node", 108 content: "{}<foobar></foobar>", 109 canTestInInlineEditingHost: true, 110 }, 111 { description: "editor should set selection to before the <input> node", 112 content: "{}<input>", 113 canTestInInlineEditingHost: true, 114 }, 115 { description: "editor should set selection to before the <img> node", 116 content: "{}<img alt=\"foo\">", 117 canTestInInlineEditingHost: true, 118 }, 119 120 { description: "editor should set selection to start of the text node in the second <span> node", 121 content: "<span></span><span>[]abc</span>", 122 canTestInInlineEditingHost: true, 123 }, 124 { description: "editor should set selection to before the <br> node in the second <span> node", 125 content: "<span></span><span>{}<br></span>", 126 canTestInInlineEditingHost: true, 127 }, 128 { description: "editor should set selection to start of the text node in the first <span> node #1", 129 content: "<span>[]abc</span><span>abc</span>", 130 canTestInInlineEditingHost: true, 131 }, 132 { description: "editor should set selection to start of the text node in the first <span> node #2", 133 content: "<span>[]abc</span><span><br></span>", 134 canTestInInlineEditingHost: true, 135 }, 136 { description: "editor should set selection to before the <br> node in the first <span> node #1", 137 content: "<span>{}<br></span><span><br></span>", 138 canTestInInlineEditingHost: true, 139 }, 140 { description: "editor should set selection to before the <br> node in the first <span> node #2", 141 content: "<span>{}<br></span><span>abc</span>", 142 canTestInInlineEditingHost: true, 143 }, 144 145 { description: "editor should set selection to start of the text node in the second <span> node since the text node in the first <span> node is only whitespaces", 146 content: "<span> </span><span>[]abc</span>", 147 canTestInInlineEditingHost: true, 148 }, 149 { description: "editor should set selection to before the <br> node in the second <span> node since the text node in the first <span> node is only whitespaces", 150 content: "<span> </span><span>{}<br></span>", 151 canTestInInlineEditingHost: true, 152 }, 153 { description: "editor should set selection to start of the text node in the second <span> node even if there is a whitespace only text node before the first <span> node", 154 content: " <span></span><span>[]abc</span>", 155 canTestInInlineEditingHost: true, 156 }, 157 { description: "editor should set selection to before the <br> node in the second <span> node even if there is a whitespace only text node before the first <span> node", 158 content: " <span></span><span>{}<br></span>", 159 canTestInInlineEditingHost: true, 160 }, 161 162 { description: "editor should set selection to start of the text node in the second <p> node following the empty <p> node", 163 content: "<p></p><p>[]abc</p>", 164 canTestInInlineEditingHost: false, 165 }, 166 { description: "editor should set selection to start of the text node in the second <p> node following another <p> node containing only a comment node", 167 content: "<p><!-- comment --></p><p>[]abc</p>", 168 canTestInInlineEditingHost: false, 169 }, 170 { description: "editor should set selection to before the <br> node in the second <p> node", 171 content: "<p></p><p>{}<br></p>", 172 canTestInInlineEditingHost: false, 173 }, 174 { description: "editor should set selection to start of the text node in the first <p> node #1", 175 content: "<p>[]abc</p><p>abc</p>", 176 canTestInInlineEditingHost: false, 177 }, 178 { description: "editor should set selection to start of the text node in the first <p> node #2", 179 content: "<p>[]abc</p><p><br></p>", 180 canTestInInlineEditingHost: false, 181 }, 182 { description: "editor should set selection to before the <br> node in the first <p> node #1", 183 content: "<p>{}<br></p><p><br></p>", 184 canTestInInlineEditingHost: false, 185 }, 186 { description: "editor should set selection to before the <br> node in the first <p> node #2", 187 content: "<p>{}<br></p><p>abc</p>", 188 canTestInInlineEditingHost: false, 189 }, 190 191 { description: "editor should set selection to start of the text node in the second <p> node since the text node in the first <p> node is only whitespaces", 192 content: "<p> </p><p>[]abc</p>", 193 canTestInInlineEditingHost: false, 194 }, 195 { description: "editor should set selection to start of the text node in the first <p> node whose white-spaces are preformatted", 196 content: "<p style=\"white-space: pre\">[] </p><p>abc</p>", 197 canTestInInlineEditingHost: false, 198 }, 199 { description: "editor should set selection to start of the text node in the first <p> node whose line breaks are preformatted", 200 content: "<p style=\"white-space: pre\">[]\n</p><p>abc</p>", 201 canTestInInlineEditingHost: false, 202 }, 203 { description: "editor should set selection to before the <br> node in the second <p> node since the text node in the first <p> node is only whitespaces", 204 content: "<p> </p><p>{}<br></p>", 205 canTestInInlineEditingHost: false, 206 }, 207 { description: "editor should set selection to start of the text node in the second <p> node even if there is a whitespace only text node before the first <p> node", 208 content: " <p></p><p>[]abc</p>", 209 canTestInInlineEditingHost: false, 210 }, 211 { description: "editor should set selection to before the <br> node in the second <p> node even if there is a whitespace only text node before the first <p> node", 212 content: " <p></p><p>{}<br></p>", 213 canTestInInlineEditingHost: false, 214 }, 215 216 { description: "editor should set selection to start of the text node in the <span> node in the second <p> node", 217 content: "<p><span></span></p><p><span>[]abc</span></p>", 218 canTestInInlineEditingHost: false, 219 }, 220 { description: "editor should set selection to before the <br> node in the <span> node in the second <p> node", 221 content: "<p><span></span></p><p><span>{}<br></span></p>", 222 canTestInInlineEditingHost: false, 223 }, 224 { description: "editor should set selection to start of the text node in the <span> node in the first <p> node #1", 225 content: "<p><span>[]abc</span></p><p><span>abc</span></p>", 226 canTestInInlineEditingHost: false, 227 }, 228 { description: "editor should set selection to start of the text node in the <span> node in the first <p> node #2", 229 content: "<p><span>[]abc</span></p><p><span><br></span></p>", 230 canTestInInlineEditingHost: false, 231 }, 232 { description: "editor should set selection to before the <br> node in the <span> node in the first <p> node #1", 233 content: "<p><span>{}<br></span></p><p><span><br></span></p>", 234 canTestInInlineEditingHost: false, 235 }, 236 { description: "editor should set selection to before the <br> node in the <span> node in the first <p> node #2", 237 content: "<p><span>{}<br></span></p><p><span>abc</span></p>", 238 canTestInInlineEditingHost: false, 239 }, 240 241 { description: "editor should collapse selection before the non-editable <span> node", 242 content: "{}<span contenteditable=\"false\"></span>", 243 canTestInInlineEditingHost: true, 244 }, 245 { description: "editor should collapse selection before the non-editable <span> node even if it has a text node", 246 content: "{}<span contenteditable=\"false\">abc</span>", 247 canTestInInlineEditingHost: true, 248 }, 249 { description: "editor should collapse selection before the non-editable <span> node even if it has a <br> node", 250 content: "{}<span contenteditable=\"false\"><br></span>", 251 canTestInInlineEditingHost: true, 252 }, 253 254 { description: "editor should collapse selection before the non-editable empty <span> node followed by a text node", 255 content: "{}<span contenteditable=\"false\"></span><span>abc</span>", 256 canTestInInlineEditingHost: true, 257 }, 258 { description: "editor should collapse selection before the non-editable <span> node having a text node and followed by another text node", 259 content: "{}<span contenteditable=\"false\">abc</span><span>def</span>", 260 canTestInInlineEditingHost: true, 261 }, 262 { description: "editor should collapse selection before the non-editable <span> node having a <br> node and followed by a text node", 263 content: "{}<span contenteditable=\"false\"><br></span><span>abc</span>", 264 canTestInInlineEditingHost: true, 265 }, 266 { description: "editor should collapse selection before the non-editable empty <span> node followed by a <br> node", 267 content: "{}<span contenteditable=\"false\"></span><span><br></span>", 268 canTestInInlineEditingHost: true, 269 }, 270 { description: "editor should collapse selection before the non-editable <span> node having text node and followed by a <br> node", 271 content: "{}<span contenteditable=\"false\">abc</span><span><br></span>", 272 canTestInInlineEditingHost: true, 273 }, 274 { description: "editor should collapse selection before the non-editable <span> node having a <br> node and followed by another <br> node", 275 content: "{}<span contenteditable=\"false\"><br></span><span><br></span>", 276 canTestInInlineEditingHost: true, 277 }, 278 279 { description: "editor should collapse selection before the non-editable empty <p> node followed by a text node", 280 content: "{}<p contenteditable=\"false\"></p><p>abc</p>", 281 canTestInInlineEditingHost: false, 282 }, 283 { description: "editor should collapse selection before the non-editable <p> node having a text node and followed by another text node", 284 content: "{}<p contenteditable=\"false\">abc</p><p>def</p>", 285 canTestInInlineEditingHost: false, 286 }, 287 { description: "editor should collapse selection before the non-editable <p> node having a <br> node and followed by a text node", 288 content: "{}<p contenteditable=\"false\"><br></p><p>abc</p>", 289 canTestInInlineEditingHost: false, 290 }, 291 { description: "editor should collapse selection before the non-editable empty <p> node followed by a <br> node", 292 content: "{}<p contenteditable=\"false\"></p><p><br></p>", 293 canTestInInlineEditingHost: false, 294 }, 295 { description: "editor should collapse selection before the non-editable <p> node having text node and followed by a <br> node", 296 content: "{}<p contenteditable=\"false\">abc</p><p><br></p>", 297 canTestInInlineEditingHost: false, 298 }, 299 { description: "editor should collapse selection before the non-editable <p> node having a <br> node and followed by another <br> node", 300 content: "{}<p contenteditable=\"false\"><br></p><p><br></p>", 301 canTestInInlineEditingHost: false, 302 }, 303 304 { description: "editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node before first editable text node", 305 content: "{}<span></span><span contenteditable=\"false\"></span><span>abc</span>", 306 canTestInInlineEditingHost: true, 307 }, 308 { description: "editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node having a text node before first editable text node", 309 content: "{}<span></span><span contenteditable=\"false\">abc</span><span>def</span>", 310 canTestInInlineEditingHost: true, 311 }, 312 { description: "editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node having a <br> node before first editable text node", 313 content: "{}<span></span><span contenteditable=\"false\"><br></span><span>abc</span>", 314 canTestInInlineEditingHost: true, 315 }, 316 { description: "editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node before first editable <br> node", 317 content: "{}<span></span><span contenteditable=\"false\"></span><span><br></span>", 318 canTestInInlineEditingHost: true, 319 }, 320 { description: "editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node having a text node before first editable <br> node", 321 content: "{}<span></span><span contenteditable=\"false\">abc</span><span><br></span>", 322 canTestInInlineEditingHost: true, 323 }, 324 { description: "editor should collapse selection to start of itself when there is only empty inline elements before the non-editable node having a <br> node before first editable <br> node", 325 content: "{}<span></span><span contenteditable=\"false\"><br></span><span><br></span>", 326 canTestInInlineEditingHost: true, 327 }, 328 329 { description: "editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node before first editable text node", 330 content: "<div>{}<span></span><span contenteditable=\"false\"></span><span>abc</span></div>", 331 canTestInInlineEditingHost: false, 332 }, 333 { description: "editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node having a text node before first editable text node", 334 content: "<div>{}<span></span><span contenteditable=\"false\">abc</span><span>def</span></div>", 335 canTestInInlineEditingHost: false, 336 }, 337 { description: "editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node having a <br> node before first editable text node", 338 content: "<div>{}<span></span><span contenteditable=\"false\"><br></span><span>abc</span></div>", 339 canTestInInlineEditingHost: false, 340 }, 341 { description: "editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node before first editable <br> node", 342 content: "<div>{}<span></span><span contenteditable=\"false\"></span><span><br></span></div>", 343 canTestInInlineEditingHost: false, 344 }, 345 { description: "editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node having a text node before first editable <br> node", 346 content: "<div>{}<span></span><span contenteditable=\"false\">abc</span><span><br></span></div>", 347 canTestInInlineEditingHost: false, 348 }, 349 { description: "editor should collapse selection to start of the first dive element when there is only empty inline elements before the non-editable node having a <br> node before first editable <br> node", 350 content: "<div>{}<span></span><span contenteditable=\"false\"><br></span><span><br></span></div>", 351 canTestInInlineEditingHost: false, 352 }, 353 354 { description: "editor should collapse selection to the first editable text node in the first <span> node even if followed by a non-editable node", 355 content: "<span>[]abc</span><span contenteditable=\"false\"></span>", 356 canTestInInlineEditingHost: true, 357 }, 358 { description: "editor should collapse selection to the first editable text node in the first <span> node even if followed by a non-editable node having another text node", 359 content: "<span>[]abc</span><span contenteditable=\"false\">def</span>", 360 canTestInInlineEditingHost: true, 361 }, 362 { description: "editor should collapse selection to the first editable text node in the first <span> node even if followed by a non-editable node having a <br> node", 363 content: "<span>[]abc</span><span contenteditable=\"false\"><br></span>", 364 canTestInInlineEditingHost: true, 365 }, 366 { description: "editor should collapse selection to the first editable <br> node in the first <span> node even if followed by a non-editable node", 367 content: "<span>{}<br></span><span contenteditable=\"false\"></span>", 368 canTestInInlineEditingHost: true, 369 }, 370 { description: "editor should collapse selection to the first editable <br> node in the first <span> node even if followed by a non-editable node having a text node", 371 content: "<span>{}<br></span><span contenteditable=\"false\">abc</span>", 372 canTestInInlineEditingHost: true, 373 }, 374 { description: "editor should collapse selection to the first editable <br> node in the first <span> node even if followed by a non-editable node having a <br> node", 375 content: "<span>{}<br></span><span contenteditable=\"false\"><br></span>", 376 canTestInInlineEditingHost: true, 377 }, 378 379 { description: "editor should collapse selection to the first editable text node in the first <p> node even if followed by a non-editable node", 380 content: "<p>[]abc</p><p contenteditable=\"false\"></p>", 381 canTestInInlineEditingHost: false, 382 }, 383 { description: "editor should collapse selection to the first editable text node in the first <p> node even if followed by a non-editable node having another text node", 384 content: "<p>[]abc</p><p contenteditable=\"false\">def</p>", 385 canTestInInlineEditingHost: false, 386 }, 387 { description: "editor should collapse selection to the first editable text node in the first <p> node even if followed by a non-editable node having a <br> node", 388 content: "<p>[]abc</p><p contenteditable=\"false\"><br></p>", 389 canTestInInlineEditingHost: false, 390 }, 391 { description: "editor should collapse selection to the first editable <br> node in the first <p> node even if followed by a non-editable node", 392 content: "<p>{}<br></p><p contenteditable=\"false\"></p>", 393 canTestInInlineEditingHost: false, 394 }, 395 { description: "editor should collapse selection to the first editable <br> node in the first <p> node even if followed by a non-editable node having a text node", 396 content: "<p>{}<br></p><p contenteditable=\"false\">abc</p>", 397 canTestInInlineEditingHost: false, 398 }, 399 { description: "editor should collapse selection to the first editable <br> node in the first <p> node even if followed by a non-editable node having a <br> node", 400 content: "<p>{}<br></p><p contenteditable=\"false\"><br></p>", 401 canTestInInlineEditingHost: false, 402 }, 403 404 { description: "editor should collapse selection to start of itself if first content is an input element", 405 content: "{}<input>abc", 406 canTestInInlineEditingHost: true, 407 }, 408 { description: "editor should collapse selection to start of itself if first content is an hr element", 409 content: "{}<hr>abc", 410 canTestInInlineEditingHost: false, 411 }, 412 { description: "editor should collapse selection to start of itself if first content is an textarea element", 413 content: "{}<textarea>abc</textarea>def", 414 canTestInInlineEditingHost: true, 415 }, 416 { description: "editor should collapse selection to the input element", 417 content: "<div>{}<input>abc</div>", 418 canTestInInlineEditingHost: false, 419 }, 420 { description: "editor should collapse selection to the hr element", 421 content: "<div>{}<hr>abc</div>", 422 canTestInInlineEditingHost: false, 423 }, 424 { description: "editor should collapse selection to the textarea element", 425 content: "<div>{}<textarea>abc</textarea>def</div>", 426 canTestInInlineEditingHost: false, 427 }, 428 ]; 429 430 const isInlineEditingHost = editingHostTagName == "span"; 431 432 const selection = document.getSelection(); 433 for (const testData of tests) { 434 if (isInlineEditingHost && !testData.canTestInInlineEditingHost) { 435 continue; 436 } 437 test(function() { 438 editor.blur(); 439 selection.removeAllRanges(); 440 editor.innerHTML = testData.content.replace(/[{}\[\]]/g, ""); 441 editor.focus(); 442 editor.getBoundingClientRect(); 443 444 assert_equals(selection.rangeCount, 1, "Only one caret should be in the editor"); 445 if (selection.rangeCount) { 446 addBrackets(selection.getRangeAt(0)); 447 assert_equals(editor.innerHTML, testData.content); 448 } 449 }, testData.description); 450 } 451 452 test(function() { 453 // Check if selection is initialized after temporarily blurred. 454 editor.innerHTML = 455 `<${editingHostTagName}>abc</${editingHostTagName}><${editingHostTagName}>def</${editingHostTagName}>`; 456 editor.focus(); 457 // Move selection to the second paragraph. 458 selection.collapse(editor.firstChild.nextSibling.firstChild); 459 // Reset focus. 460 editor.blur(); 461 editor.focus(); 462 // Then, selection should still be in the second paragraph. 463 assert_equals(selection.rangeCount, 1, "Only one caret should be in the editor"); 464 if (selection.rangeCount) { 465 addBrackets(selection.getRangeAt(0)); 466 assert_equals( 467 editor.innerHTML, 468 `<${editingHostTagName}>abc</${editingHostTagName}><${editingHostTagName}>[]def</${editingHostTagName}>` 469 ); 470 } 471 }, "editor shouldn't reset selection when it gets focus again"); 472 })(); 473 </script>