input-events-get-target-ranges-non-collapsed-selection.tentative.html (24646B)
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <meta name="timeout" content="long"> 4 <meta name="variant" content="?Backspace"> 5 <meta name="variant" content="?Delete"> 6 <meta name="variant" content="?TypingA"> 7 <title>InputEvent.getTargetRanges() with non-collapsed selection</title> 8 <div contenteditable></div> 9 <script src="input-events-get-target-ranges.js"></script> 10 <script src="/resources/testharness.js"></script> 11 <script src="/resources/testharnessreport.js"></script> 12 <script src="/resources/testdriver.js"></script> 13 <script src="/resources/testdriver-vendor.js"></script> 14 <script src="/resources/testdriver-actions.js"></script> 15 <script> 16 "use strict"; 17 18 let action = location.search.substring(1); 19 function run() { 20 switch (action) { 21 case "Backspace": 22 return sendBackspaceKey(); 23 case "Delete": 24 return sendDeleteKey(); 25 case "TypingA": 26 return sendKeyA(); 27 default: 28 throw "Unhandled variant"; 29 } 30 } 31 32 let insertedHTML = action === "TypingA" ? "a" : ""; 33 34 // If text node is selected, target range should be shrunken to the edge of 35 // text node. 36 promise_test(async (t) => { 37 initializeTest("<p>abc</p>"); 38 let p = gEditor.firstChild; 39 let abc = p.firstChild; 40 gSelection.setBaseAndExtent(p, 0, p, 1); 41 await run(); 42 checkEditorContentResultAsSubTest( 43 `<p>${insertedHTML !== "" ? insertedHTML : "<br>"}</p>`, 44 t.name 45 ); 46 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 47 startContainer: abc, 48 startOffset: 0, 49 endContainer: abc, 50 endOffset: 3, 51 }); 52 checkGetTargetRangesOfInputOnDeleteSomething(); 53 }, `${action} at "<p>{abc}</p>"`); 54 55 promise_test(async (t) => { 56 initializeTest("<p>abc<br></p>"); 57 let p = gEditor.firstChild; 58 let abc = p.firstChild; 59 gSelection.setBaseAndExtent(p, 0, p, 1); 60 await run(); 61 checkEditorContentResultAsSubTest( 62 [ 63 `<p>${insertedHTML !== "" ? insertedHTML : "<br>"}</p>`, 64 `<p>${insertedHTML}<br></p>`, 65 ], 66 t.name 67 ); 68 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 69 startContainer: abc, 70 startOffset: 0, 71 endContainer: abc, 72 endOffset: 3, 73 }); 74 checkGetTargetRangesOfInputOnDeleteSomething(); 75 }, `${action} at "<p>{abc}<br></p>"`); 76 77 promise_test(async (t) => { 78 initializeTest(`<p><img src="${kImgSrc}"></p>`); 79 let p = gEditor.firstChild; 80 gSelection.setBaseAndExtent(p, 0, p, 1); 81 await run(); 82 checkEditorContentResultAsSubTest( 83 `<p>${insertedHTML !== "" ? insertedHTML : "<br>"}</p>`, 84 t.name 85 ); 86 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 87 startContainer: p, 88 startOffset: 0, 89 endContainer: p, 90 endOffset: 1, 91 }); 92 checkGetTargetRangesOfInputOnDeleteSomething(); 93 }, `${action} at "<p>{<img>}</p>"`); 94 95 promise_test(async (t) => { 96 initializeTest(`<p><img src="${kImgSrc}"><br></p>`); 97 let p = gEditor.firstChild; 98 gSelection.setBaseAndExtent(p, 0, p, 1); 99 await run(); 100 checkEditorContentResultAsSubTest( 101 [ 102 `<p>${insertedHTML !== "" ? insertedHTML : "<br>"}</p>`, 103 `<p>${insertedHTML}<br></p>`, 104 ], 105 t.name 106 ); 107 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 108 startContainer: p, 109 startOffset: 0, 110 endContainer: p, 111 endOffset: 1, 112 }); 113 checkGetTargetRangesOfInputOnDeleteSomething(); 114 }, `${action} at "<p>{<img>}<br></p>"`); 115 116 promise_test(async (t) => { 117 initializeTest("<p> abc </p>"); 118 let p = gEditor.firstChild; 119 let abc = p.firstChild; 120 gSelection.setBaseAndExtent(p, 0, p, 1); 121 await run(); 122 checkEditorContentResultAsSubTest( 123 `<p>${insertedHTML !== "" ? insertedHTML : "<br>"}</p>`, 124 t.name, 125 ); 126 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 127 startContainer: abc, 128 startOffset: 0, 129 endContainer: abc, 130 endOffset: 5, 131 }); 132 checkGetTargetRangesOfInputOnDeleteSomething(); 133 }, `${action} at "<p>{ abc }</p>"`); 134 135 // Invisible leading white-spaces in current block and invisible trailing 136 // white-spaces in the previous block should be deleted for avoiding they 137 // becoming visible when the blocks are joined. Perhaps, they should be 138 // contained by the range of `getTargetRanges()`, but needs discussion. 139 // https://github.com/w3c/input-events/issues/112 140 promise_test(async (t) => { 141 initializeTest("<p>abc </p><p> def</p>"); 142 let p1 = gEditor.firstChild; 143 let abc = p1.firstChild; 144 let p2 = p1.nextSibling; 145 let def = p2.firstChild; 146 gSelection.setBaseAndExtent(abc, 6, def, 0); 147 await run(); 148 checkEditorContentResultAsSubTest(`<p>abc${insertedHTML}def</p>`, t.name); 149 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 150 startContainer: abc, 151 startOffset: 3, 152 endContainer: def, 153 endOffset: 3, 154 }); 155 checkGetTargetRangesOfInputOnDeleteSomething(); 156 }, `${action} at "<p>abc [</p><p>] def</p>"`); 157 158 promise_test(async (t) => { 159 initializeTest("<p>abc</p><p>def</p>"); 160 let abc = gEditor.querySelector("p").firstChild; 161 let def = gEditor.querySelector("p + p").firstChild; 162 gSelection.setBaseAndExtent(abc, 2, def, 1); 163 await run(); 164 checkEditorContentResultAsSubTest(`<p>ab${insertedHTML}ef</p>`, t.name); 165 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 166 startContainer: abc, 167 startOffset: 2, 168 endContainer: def, 169 endOffset: 1, 170 }); 171 checkGetTargetRangesOfInputOnDeleteSomething(); 172 }, `${action} at "<p>ab[c</p><p>d]ef</p>"`); 173 174 promise_test(async (t) => { 175 initializeTest("<p>abc </p><p> def</p>"); 176 let abc = gEditor.querySelector("p").firstChild; 177 let def = gEditor.querySelector("p + p").firstChild; 178 gSelection.setBaseAndExtent(abc, 2, def, 2); 179 await run(); 180 checkEditorContentResultAsSubTest(`<p>ab${insertedHTML}ef</p>`, t.name); 181 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 182 startContainer: abc, 183 startOffset: 2, 184 endContainer: def, 185 endOffset: 2, 186 }); 187 checkGetTargetRangesOfInputOnDeleteSomething(); 188 }, `${action} at "<p>ab[c </p><p> d]ef</p>"`); 189 190 promise_test(async (t) => { 191 initializeTest("<p>abc </p><p> def</p>"); 192 let abc = gEditor.querySelector("p").firstChild; 193 let def = gEditor.querySelector("p + p").firstChild; 194 gSelection.setBaseAndExtent(abc, 2, def, 0); 195 await run(); 196 checkEditorContentResultAsSubTest(`<p>ab${insertedHTML}def</p>`, t.name); 197 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 198 startContainer: abc, 199 startOffset: 2, 200 endContainer: def, 201 endOffset: 1, 202 }); 203 checkGetTargetRangesOfInputOnDeleteSomething(); 204 }, `${action} at "<p>ab[c </p><p>] def</p>"`); 205 206 promise_test(async (t) => { 207 initializeTest("<p>abc </p><p> def</p>"); 208 let abc = gEditor.querySelector("p").firstChild; 209 let def = gEditor.querySelector("p + p").firstChild; 210 gSelection.setBaseAndExtent(abc, 4, def, 0); 211 await run(); 212 checkEditorContentResultAsSubTest(`<p>abc${insertedHTML}def</p>`, t.name); 213 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 214 startContainer: abc, 215 startOffset: 3, 216 endContainer: def, 217 endOffset: 1, 218 }); 219 checkGetTargetRangesOfInputOnDeleteSomething(); 220 }, `${action} at "<p>abc [</p><p>] def</p>"`); 221 222 promise_test(async (t) => { 223 initializeTest("<p>abc </p><p> def</p>"); 224 let abc = gEditor.querySelector("p").firstChild; 225 let def = gEditor.querySelector("p + p").firstChild; 226 gSelection.setBaseAndExtent(abc, 4, def, 1); 227 await run(); 228 checkEditorContentResultAsSubTest(`<p>abc${insertedHTML}def</p>`, t.name); 229 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 230 startContainer: abc, 231 startOffset: 3, 232 endContainer: def, 233 endOffset: 1, 234 }); 235 checkGetTargetRangesOfInputOnDeleteSomething(); 236 }, `${action} at "<p>abc [</p><p> ]def</p>"`); 237 238 // Different from collapsed range around an atomic content, non-collapsed 239 // range may not be shrunken to select only the atomic content for avoid 240 // to waste runtime cost. 241 promise_test(async (t) => { 242 initializeTest(`<p>abc<img src="${kImgSrc}">def</p>`); 243 let p = gEditor.querySelector("p"); 244 let abc = p.firstChild; 245 let def = p.lastChild; 246 gSelection.setBaseAndExtent(abc, 3, def, 0); 247 await run(); 248 checkEditorContentResultAsSubTest(`<p>abc${insertedHTML}def</p>`, t.name); 249 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 250 startContainer: abc, 251 startOffset: 3, 252 endContainer: def, 253 endOffset: 0, 254 }); 255 checkGetTargetRangesOfInputOnDeleteSomething(); 256 }, `${action} at "<p>abc[<img>]def</p>"`); 257 258 promise_test(async (t) => { 259 initializeTest(`<div>abc<hr>def</div>`); 260 let div = gEditor.querySelector("div"); 261 let abc = div.firstChild; 262 let def = div.lastChild; 263 gSelection.setBaseAndExtent(abc, 3, def, 0); 264 await run(); 265 checkEditorContentResultAsSubTest(`<div>abc${insertedHTML}def</div>`, t.name); 266 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 267 startContainer: abc, 268 startOffset: 3, 269 endContainer: def, 270 endOffset: 0, 271 }); 272 checkGetTargetRangesOfInputOnDeleteSomething(); 273 }, `${action} at "<div>abc[<hr>]def</div>"`); 274 275 promise_test(async (t) => { 276 initializeTest(`<div>abc <hr>def</div>`); 277 let div = gEditor.querySelector("div"); 278 let abc = div.firstChild; 279 let def = div.lastChild; 280 gSelection.setBaseAndExtent(abc, 4, def, 0); 281 await run(); 282 checkEditorContentResultAsSubTest(`<div>abc${insertedHTML}def</div>`, t.name); 283 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 284 startContainer: abc, 285 startOffset: 3, 286 endContainer: def, 287 endOffset: 0, 288 }); 289 checkGetTargetRangesOfInputOnDeleteSomething(); 290 }, `${action} at "<div>abc [<hr>]def</div>"`); 291 292 promise_test(async (t) => { 293 initializeTest(`<div>abc <hr> def</div>`); 294 let div = gEditor.querySelector("div"); 295 let abc = div.firstChild; 296 let def = div.lastChild; 297 gSelection.setBaseAndExtent(abc, 4, def, 0); 298 await run(); 299 checkEditorContentResultAsSubTest(`<div>abc${insertedHTML}def</div>`, t.name); 300 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 301 startContainer: abc, 302 startOffset: 3, 303 endContainer: def, 304 endOffset: 1, 305 }); 306 checkGetTargetRangesOfInputOnDeleteSomething(); 307 }, `${action} at "<div>abc [<hr>] def</div>"`); 308 309 promise_test(async (t) => { 310 initializeTest(`<div>abc <hr> def</div>`); 311 let div = gEditor.querySelector("div"); 312 let abc = div.firstChild; 313 let def = div.lastChild; 314 gSelection.setBaseAndExtent(div, 1, div, 2); 315 await run(); 316 checkEditorContentResultAsSubTest(`<div>abc${insertedHTML}def</div>`, t.name); 317 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 318 startContainer: abc, 319 startOffset: 3, 320 endContainer: def, 321 endOffset: 1, 322 }); 323 checkGetTargetRangesOfInputOnDeleteSomething(); 324 }, `${action} at "<div>abc {<hr>} def</div>"`); 325 326 // Deleting visible `<br>` element should be contained by a range of 327 // `getTargetRanges()`. However, when only the `<br>` element is selected, 328 // the range shouldn't start from nor end by surrounding text nodes? 329 // https://github.com/w3c/input-events/issues/112 330 promise_test(async (t) => { 331 initializeTest("<p>abc<br>def</p>"); 332 gSelection.setBaseAndExtent(gEditor.firstChild, 1, gEditor.firstChild, 2); 333 await run(); 334 checkEditorContentResultAsSubTest(`<p>abc${insertedHTML}def</p>`, t.name); 335 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 336 startContainer: gEditor.firstChild, 337 startOffset: 1, 338 endContainer: gEditor.firstChild, 339 endOffset: 2, 340 }); 341 checkGetTargetRangesOfInputOnDeleteSomething(); 342 }, `${action} at "<p>abc{<br>}def</p>"`); 343 344 promise_test(async (t) => { 345 initializeTest("<div>abc<p>def<br>ghi</p></div>"); 346 let p = gEditor.querySelector("p"); 347 let def = p.firstChild; 348 let abc = gEditor.firstChild.firstChild; 349 gSelection.setBaseAndExtent(abc, 3, def, 0); 350 await run(); 351 checkEditorContentResultAsSubTest( 352 [ 353 `<div>abc${insertedHTML}def<p>ghi</p></div>`, 354 `<div>abc${insertedHTML}def<br><p>ghi</p></div>`, 355 ], 356 t.name 357 ); 358 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 359 startContainer: abc, 360 startOffset: 3, 361 endContainer: def, 362 endOffset: 0, 363 }); 364 checkGetTargetRangesOfInputOnDeleteSomething(); 365 }, `${action} at "<div>abc[<p>]def<br>ghi</p></div>"`); 366 367 promise_test(async (t) => { 368 initializeTest("<div>abc <p> def<br>ghi</p></div>"); 369 let p = gEditor.querySelector("p"); 370 let def = p.firstChild; 371 let abc = gEditor.firstChild.firstChild; 372 gSelection.setBaseAndExtent(abc, abc.length, def, 0); 373 await run(); 374 checkEditorContentResultAsSubTest( 375 [ 376 `<div>abc${insertedHTML}def<p>ghi</p></div>`, 377 `<div>abc${insertedHTML}def<br><p>ghi</p></div>`, 378 ], 379 t.name 380 ); 381 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 382 startContainer: abc, 383 startOffset: 3, 384 endContainer: def, 385 endOffset: 3, 386 }); 387 checkGetTargetRangesOfInputOnDeleteSomething(); 388 }, `${action} at "<div>abc [<p>] def<br>ghi</p></div>"`); 389 390 promise_test(async (t) => { 391 initializeTest("<div><p>abc</p>def</div>"); 392 let abc = gEditor.querySelector("p").firstChild; 393 let def = gEditor.querySelector("p").nextSibling; 394 gSelection.setBaseAndExtent(abc, 3, def, 0); 395 await run(); 396 checkEditorContentResultAsSubTest( 397 [ 398 `<div><p>abc${insertedHTML}def</p></div>`, 399 `<div><p>abc${insertedHTML}def<br></p></div>`, 400 ], 401 t.name 402 ); 403 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 404 startContainer: abc, 405 startOffset: 3, 406 endContainer: def, 407 endOffset: 0, 408 }); 409 checkGetTargetRangesOfInputOnDeleteSomething(); 410 }, `${action} at "<div><p>abc[</p>]def</div>"`); 411 412 promise_test(async (t) => { 413 initializeTest("<div><p>abc </p> def</div>"); 414 let abc = gEditor.querySelector("p").firstChild; 415 let def = gEditor.querySelector("p").nextSibling; 416 gSelection.setBaseAndExtent(abc, abc.length, def, 0); 417 await run(); 418 checkEditorContentResultAsSubTest( 419 [ 420 `<div><p>abc${insertedHTML}def</p></div>`, 421 `<div><p>abc${insertedHTML}def<br></p></div>`, 422 ], 423 t.name 424 ); 425 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 426 startContainer: abc, 427 startOffset: 3, 428 endContainer: def, 429 endOffset: 3, 430 }); 431 checkGetTargetRangesOfInputOnDeleteSomething(); 432 }, `${action} at "<div><p>abc [</p>] def</div>"`); 433 434 promise_test(async (t) => { 435 initializeTest("<div>abc<ul><li>def</li></ul>ghi</div>"); 436 let abc = gEditor.querySelector("div").firstChild; 437 let def = gEditor.querySelector("li").firstChild; 438 gSelection.setBaseAndExtent(abc, 3, def, 0); 439 await run(); 440 checkEditorContentResultAsSubTest( 441 `<div>abc${insertedHTML}defghi</div>`, 442 t.name 443 ); 444 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 445 startContainer: abc, 446 startOffset: 3, 447 endContainer: def, 448 endOffset: 0, 449 }); 450 checkGetTargetRangesOfInputOnDeleteSomething(); 451 }, `${action} at "<div>abc[<ul><li>]def</li></ul>ghi</div>"`); 452 453 promise_test(async (t) => { 454 initializeTest("<div>abc <ul><li> def </li></ul> ghi</div>"); 455 let abc = gEditor.querySelector("div").firstChild; 456 let def = gEditor.querySelector("li").firstChild; 457 gSelection.setBaseAndExtent(abc, abc.length, def, 0); 458 await run(); 459 checkEditorContentResultAsSubTest( 460 `<div>abc${insertedHTML}defghi</div>`, 461 t.name 462 ); 463 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 464 startContainer: abc, 465 startOffset: 3, 466 endContainer: def, 467 endOffset: 1, 468 }); 469 checkGetTargetRangesOfInputOnDeleteSomething(); 470 }, `${action} at "<div>abc [<ul><li>] def </li></ul> ghi</div>"`); 471 472 promise_test(async (t) => { 473 initializeTest("<div>abc<ul><li>def</li></ul>ghi</div>"); 474 let def = gEditor.querySelector("li").firstChild; 475 let ghi = gEditor.querySelector("ul").nextSibling; 476 gSelection.setBaseAndExtent(def, 3, ghi, 0); 477 await run(); 478 checkEditorContentResultAsSubTest( 479 `<div>abc<ul><li>def${insertedHTML}ghi</li></ul></div>`, 480 t.name 481 ); 482 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 483 startContainer: def, 484 startOffset: 3, 485 endContainer: ghi, 486 endOffset: 0, 487 }); 488 checkGetTargetRangesOfInputOnDeleteSomething(); 489 }, `${action} at "<div>abc<ul><li>def[</li></ul>]ghi</div>"`); 490 491 promise_test(async (t) => { 492 initializeTest("<div>abc <ul><li> def </li></ul> ghi</div>"); 493 let def = gEditor.querySelector("li").firstChild; 494 let ghi = gEditor.querySelector("ul").nextSibling; 495 gSelection.setBaseAndExtent(def, def.length, ghi, 0); 496 await run(); 497 checkEditorContentResultAsSubTest( 498 [ 499 `<div>abc <ul><li> def${insertedHTML}ghi</li></ul></div>`, 500 `<div>abc <ul><li>def${insertedHTML}ghi</li></ul></div>`, 501 `<div>abc<ul><li>def${insertedHTML}ghi</li></ul></div>`, 502 ], 503 t.name 504 ); 505 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 506 startContainer: def, 507 startOffset: 5, 508 endContainer: ghi, 509 endOffset: 1, 510 }); 511 checkGetTargetRangesOfInputOnDeleteSomething(); 512 }, `${action} at "<div>abc <ul><li> def [</li></ul>] ghi</div>"`); 513 514 promise_test(async (t) => { 515 initializeTest("<div>abc<ul><li>def</li><li>ghi</li></ul>jkl</div>"); 516 let abc = gEditor.querySelector("div").firstChild; 517 let def = gEditor.querySelector("li").firstChild; 518 gSelection.setBaseAndExtent(abc, 3, def, 0); 519 await run(); 520 checkEditorContentResultAsSubTest( 521 `<div>abc${insertedHTML}def<ul><li>ghi</li></ul>jkl</div>`, 522 t.name 523 ); 524 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 525 startContainer: abc, 526 startOffset: 3, 527 endContainer: def, 528 endOffset: 0, 529 }); 530 checkGetTargetRangesOfInputOnDeleteSomething(); 531 }, `${action} at "<div>abc[<ul><li>]def</li><li>ghi</li></ul>jkl</div>"`); 532 533 promise_test(async (t) => { 534 initializeTest("<div>abc<ul><li>def</li><li>ghi</li></ul>jkl</div>"); 535 let abc = gEditor.querySelector("div").firstChild; 536 let def = gEditor.querySelector("li").firstChild; 537 let ghi = gEditor.querySelector("li + li").firstChild; 538 gSelection.setBaseAndExtent(abc, 3, ghi, 0); 539 await run(); 540 checkEditorContentResultAsSubTest( 541 [ 542 `<div>abc${insertedHTML}ghijkl</div>`, 543 `<div>abc${insertedHTML}ghijkl<br></div>`, 544 ], 545 t.name 546 ); 547 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 548 startContainer: abc, 549 startOffset: 3, 550 endContainer: ghi, 551 endOffset: 0, 552 }); 553 checkGetTargetRangesOfInputOnDeleteSomething(); 554 }, `${action} at "<div>abc[<ul><li>def</li><li>]ghi</li></ul>jkl</div>"`); 555 556 promise_test(async (t) => { 557 initializeTest("<div>abc<ul><li>def</li><li>ghi</li></ul>jkl</div>"); 558 let def = gEditor.querySelector("li").firstChild; 559 let ghi = gEditor.querySelector("li + li").firstChild; 560 gSelection.setBaseAndExtent(def, 3, ghi, 0); 561 await run(); 562 checkEditorContentResultAsSubTest( 563 `<div>abc<ul><li>def${insertedHTML}ghi</li></ul>jkl</div>`, 564 t.name 565 ); 566 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 567 startContainer: def, 568 startOffset: 3, 569 endContainer: ghi, 570 endOffset: 0, 571 }); 572 checkGetTargetRangesOfInputOnDeleteSomething(); 573 }, `${action} at "<div>abc<ul><li>def[</li><li>]ghi</li></ul>jkl</div>"`); 574 575 promise_test(async (t) => { 576 initializeTest("<div>abc<ul><li>def</li><li>ghi</li></ul>jkl</div>"); 577 let ghi = gEditor.querySelector("li + li").firstChild; 578 let jkl = gEditor.querySelector("ul").nextSibling; 579 gSelection.setBaseAndExtent(ghi, 3, jkl, 0); 580 await run(); 581 checkEditorContentResultAsSubTest( 582 `<div>abc<ul><li>def</li><li>ghi${insertedHTML}jkl</li></ul></div>`, 583 t.name 584 ); 585 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 586 startContainer: ghi, 587 startOffset: 3, 588 endContainer: jkl, 589 endOffset: 0, 590 }); 591 checkGetTargetRangesOfInputOnDeleteSomething(); 592 }, `${action} at "<div>abc<ul><li>def</li><li>ghi[</li></ul>]jkl</div>"`); 593 594 promise_test(async (t) => { 595 initializeTest("<div>abc<ul><li>def</li><li>ghi</li></ul>jkl</div>"); 596 let def = gEditor.querySelector("li").firstChild; 597 let jkl = gEditor.querySelector("ul").nextSibling; 598 gSelection.setBaseAndExtent(def, 3, jkl, 0); 599 await run(); 600 checkEditorContentResultAsSubTest( 601 `<div>abc<ul><li>def${insertedHTML}jkl</li></ul></div>`, 602 t.name 603 ); 604 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 605 startContainer: def, 606 startOffset: 3, 607 endContainer: jkl, 608 endOffset: 0, 609 }); 610 checkGetTargetRangesOfInputOnDeleteSomething(); 611 }, `${action} at "<div>abc<ul><li>def[</li><li>ghi</li></ul>]jkl</div>"`); 612 613 promise_test(async (t) => { 614 initializeTest("<p>abc</p><p><br></p>"); 615 let p1 = gEditor.querySelector("p"); 616 let abc = p1.firstChild; 617 let p2 = p1.nextSibling; 618 gSelection.setBaseAndExtent(abc, 3, p2, 0); 619 await run(); 620 checkEditorContentResultAsSubTest( 621 [ 622 `<p>abc${insertedHTML}</p>`, 623 `<p>abc${insertedHTML}<br></p>`, 624 ], 625 t.name 626 ); 627 if (gEditor.innerHTML === "<p>abc</p>") { 628 // Include the invisible `<br>` element if it's deleted. 629 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 630 startContainer: abc, 631 startOffset: 3, 632 endContainer: p2, 633 endOffset: 1, 634 }); 635 } else { 636 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 637 startContainer: abc, 638 startOffset: 3, 639 endContainer: p2, 640 endOffset: 0, 641 }); 642 } 643 checkGetTargetRangesOfInputOnDeleteSomething(); 644 }, `${action} at "<p>abc[</p><p>}<br></p>"`); 645 646 promise_test(async (t) => { 647 initializeTest("<p>abc<span contenteditable=\"false\">def</span>ghi</p>"); 648 let p = gEditor.querySelector("p"); 649 let abc = p.firstChild; 650 let ghi = p.lastChild; 651 gSelection.setBaseAndExtent(abc, 3, ghi, 0); 652 await run(); 653 checkEditorContentResultAsSubTest( 654 [ 655 "<p>abc<span contenteditable=\"false\">def</span>ghi</p>", 656 `<p>abc${insertedHTML}ghi</p>`, 657 `<p>abc${insertedHTML}ghi<br></p>`, 658 ], 659 t.name 660 ); 661 // Don't need to shrink the range for avoiding to waste runtime cost. 662 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 663 startContainer: abc, 664 startOffset: 3, 665 endContainer: ghi, 666 endOffset: 0, 667 }); 668 if (gEditor.innerHTML === "<p>abc<span contenteditable=\"false\">def</span>ghi</p>") { 669 checkGetTargetRangesOfInputOnDoNothing(); 670 } else { 671 checkGetTargetRangesOfInputOnDeleteSomething(); 672 } 673 }, `${action} at "<p>abc[<span contenteditable=\"false\">def</span>]ghi</p>"`); 674 675 // The table structure shouldn't be modified when deleting cell contents, 676 // in this case, getTargetRanges() should return multiple ranges in each 677 // cell? 678 promise_test(async (t) => { 679 initializeTest("<table><tr><td>abc</td><td>def</td></tr></table>"); 680 let abc = gEditor.querySelector("td").firstChild; 681 let def = gEditor.querySelector("td + td").firstChild; 682 gSelection.setBaseAndExtent(abc, 2, def, 1); 683 await run(); 684 checkEditorContentResultAsSubTest( 685 `<table><tbody><tr><td>ab${insertedHTML}</td><td>ef</td></tr></tbody></table>`, 686 t.name 687 ); 688 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 689 startContainer: abc, 690 startOffset: 2, 691 endContainer: def, 692 endOffset: 1, 693 }); 694 checkGetTargetRangesOfInputOnDeleteSomething(); 695 }, `${action} at "<table><tr><td>ab[c</td><td>d]ef</td></tr></table>"`); 696 697 promise_test(async (t) => { 698 initializeTest("<table><tr><td>abc</td><td>def</td></tr><tr><td>ghi</td><td>jkl</td></tr></table>"); 699 let abc = gEditor.querySelector("td").firstChild; 700 let jkl = gEditor.querySelector("tr + tr > td + td").firstChild; 701 gSelection.setBaseAndExtent(abc, 2, jkl, 1); 702 await run(); 703 checkEditorContentResultAsSubTest( 704 [ 705 `<table><tbody><tr><td>ab${insertedHTML}</td><td></td></tr><tr><td></td><td>kl</td></tr></tbody></table>`, 706 `<table><tbody><tr><td>ab${insertedHTML}</td><td><br></td></tr><tr><td><br></td><td>kl</td></tr></tbody></table>`, 707 ], 708 t.name 709 ); 710 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 711 startContainer: abc, 712 startOffset: 2, 713 endContainer: jkl, 714 endOffset: 1, 715 }); 716 checkGetTargetRangesOfInputOnDeleteSomething(); 717 }, `${action} at "<table><tr><td>ab[c</td><td>def</td></tr><tr><td>ghi</td><td>j]kl</td></tr></table>"`); 718 719 promise_test(async (t) => { 720 initializeTest("<table><tr><td>abc</td><td>def</td></tr></table><table><tr><td>ghi</td><td>jkl</td></tr></table>"); 721 let abc = gEditor.querySelector("td").firstChild; 722 let jkl = gEditor.querySelector("table + table td + td").firstChild; 723 gSelection.setBaseAndExtent(abc, 2, jkl, 1); 724 await run(); 725 checkEditorContentResultAsSubTest( 726 [ 727 `<table><tbody><tr><td>ab${insertedHTML}</td><td></td></tr></tbody></table><table><tbody><tr><td></td><td>kl</td></tr></tbody></table>`, 728 `<table><tbody><tr><td>ab${insertedHTML}</td><td><br></td></tr></tbody></table><table><tbody><tr><td><br></td><td>kl</td></tr></tbody></table>`, 729 ], 730 t.name 731 ); 732 checkGetTargetRangesOfBeforeinputOnDeleteSomething({ 733 startContainer: abc, 734 startOffset: 2, 735 endContainer: jkl, 736 endOffset: 1, 737 }); 738 checkGetTargetRangesOfInputOnDeleteSomething(); 739 }, `${action} at "<table><tr><td>ab[c</td><td>def</td></tr></table><table><tr><td>ghi</td><td>j]kl</td></tr></table>"`); 740 741 </script>