tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

input-events-get-target-ranges-backspace.tentative.html (75627B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <meta name="timeout" content="long">
      4 <title>InputEvent.getTargetRanges() at Backspace</title>
      5 <div contenteditable></div>
      6 <script src="input-events-get-target-ranges.js"></script>
      7 <script src="/resources/testharness.js"></script>
      8 <script src="/resources/testharnessreport.js"></script>
      9 <script src="/resources/testdriver.js"></script>
     10 <script src="/resources/testdriver-vendor.js"></script>
     11 <script src="/resources/testdriver-actions.js"></script>
     12 <script>
     13 "use strict";
     14 
     15 promise_test(async (t) => {
     16  initializeTest("<p>abc</p>");
     17  gSelection.collapse(gEditor.firstChild.firstChild, 0);
     18  await sendBackspaceKey();
     19  checkEditorContentResultAsSubTest("<p>abc</p>", t.name);
     20  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
     21    startContainer: gEditor.firstChild.firstChild,
     22    startOffset: 0,
     23    endContainer: gEditor.firstChild.firstChild,
     24    endOffset: 0,
     25  });
     26  checkGetTargetRangesOfInputOnDoNothing();
     27 }, 'Backspace at "<p>[]abc</p>"');
     28 
     29 // Simply deletes the previous ASCII character of caret position.
     30 promise_test(async (t) => {
     31  initializeTest("<p>abc</p>");
     32  gSelection.collapse(gEditor.firstChild.firstChild, 1);
     33  await sendBackspaceKey();
     34  checkEditorContentResultAsSubTest("<p>bc</p>", t.name);
     35  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
     36    startContainer: gEditor.firstChild.firstChild,
     37    startOffset: 0,
     38    endContainer: gEditor.firstChild.firstChild,
     39    endOffset: 1,
     40  });
     41  checkGetTargetRangesOfInputOnDeleteSomething();
     42 }, 'Backspace at "<p>a[]bc</p>"');
     43 
     44 // Simply deletes the previous ASCII character of caret position.
     45 promise_test(async (t) => {
     46  initializeTest("<p>abc</p>");
     47  gSelection.collapse(gEditor.firstChild.firstChild, 2);
     48  await sendBackspaceKey();
     49  checkEditorContentResultAsSubTest("<p>ac</p>", t.name);
     50  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
     51    startContainer: gEditor.firstChild.firstChild,
     52    startOffset: 1,
     53    endContainer: gEditor.firstChild.firstChild,
     54    endOffset: 2,
     55  });
     56  checkGetTargetRangesOfInputOnDeleteSomething();
     57 }, 'Backspace at "<p>ab[]c</p>"');
     58 
     59 // Simply deletes the previous ASCII character of caret position.
     60 promise_test(async (t) => {
     61  initializeTest("<p>abc</p>");
     62  gSelection.collapse(gEditor.firstChild.firstChild, 3);
     63  await sendBackspaceKey();
     64  checkEditorContentResultAsSubTest("<p>ab</p>", t.name);
     65  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
     66    startContainer: gEditor.firstChild.firstChild,
     67    startOffset: 2,
     68    endContainer: gEditor.firstChild.firstChild,
     69    endOffset: 3,
     70  });
     71  checkGetTargetRangesOfInputOnDeleteSomething();
     72 }, 'Backspace at "<p>abc[]</p>"');
     73 
     74 // Should delete the `<span>` element because it becomes empty.
     75 // However, we need discussion whether the `<span>` element should be
     76 // contained by a range of `getTargetRanges()`.
     77 // https://github.com/w3c/input-events/issues/112
     78 promise_test(async (t) => {
     79  initializeTest("<p>a<span>b</span>c</p>");
     80  let c = gEditor.querySelector("span").nextSibling;
     81  gSelection.collapse(c, 0);
     82  await sendBackspaceKey();
     83  checkEditorContentResultAsSubTest("<p>ac</p>", t.name);
     84  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
     85    startContainer: gEditor.firstChild,
     86    startOffset: 1,
     87    endContainer: c,
     88    endOffset: 0,
     89  });
     90  checkGetTargetRangesOfInputOnDeleteSomething();
     91 }, 'Backspace at "<p>a<span>b</span>[]c</p>"');
     92 
     93 // Should delete the `<span>` element because it becomes empty.
     94 // However, we need discussion whether the `<span>` element should be
     95 // contained by a range of `getTargetRanges()`.
     96 // https://github.com/w3c/input-events/issues/112
     97 promise_test(async (t) => {
     98  initializeTest("<p>a<span>b</span>c</p>");
     99  let b = gEditor.querySelector("span").firstChild;
    100  gSelection.collapse(b, 1);
    101  await sendBackspaceKey();
    102  checkEditorContentResultAsSubTest("<p>ac</p>", t.name);
    103  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    104    startContainer: gEditor.firstChild,
    105    startOffset: 1,
    106    endContainer: gEditor.firstChild,
    107    endOffset: 2,
    108  });
    109  checkGetTargetRangesOfInputOnDeleteSomething();
    110 }, 'Backspace at "<p>a<span>b[]</span>c</p>"');
    111 
    112 // Invisible leading white-space may be deleted when the first visible
    113 // character is deleted.  If it's deleted, it should be contained by
    114 // the range of `getTargetRanges()`, but needs discussion.
    115 // https://github.com/w3c/input-events/issues/112
    116 promise_test(async (t) => {
    117  initializeTest("<p> abc</p>");
    118  gSelection.collapse(gEditor.firstChild.firstChild, 2);
    119  await sendBackspaceKey();
    120  checkEditorContentResultAsSubTest(
    121    [
    122      "<p>bc</p>",
    123      "<p> bc</p>",
    124    ],
    125    t.name
    126  );
    127  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    128    startContainer: gEditor.firstChild.firstChild,
    129    startOffset: gEditor.firstChild.firstChild.length == 2 ? 0 : 1,
    130    endContainer: gEditor.firstChild.firstChild,
    131    endOffset: 2,
    132  });
    133  checkGetTargetRangesOfInputOnDeleteSomething();
    134 }, 'Backspace at "<p> a[]bc</p>"');
    135 
    136 promise_test(async (t) => {
    137  initializeTest("<p>abc</p><p>def</p>");
    138  let p1 = gEditor.firstChild;
    139  let abc = p1.firstChild;
    140  let p2 = p1.nextSibling;
    141  let def = p2.firstChild;
    142  gSelection.collapse(def, 0);
    143  await sendBackspaceKey();
    144  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    145  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    146    startContainer: abc,
    147    startOffset: 3,
    148    endContainer: def,
    149    endOffset: 0,
    150  });
    151  checkGetTargetRangesOfInputOnDeleteSomething();
    152 }, 'Backspace at "<p>abc</p><p>[]def</p>"');
    153 
    154 // Invisible leading white-spaces in current block and invisible trailing
    155 // white-spaces in the previous block should be deleted for avoiding they
    156 // becoming visible when the blocks are joined.  Perhaps, they should be
    157 // contained by the range of `getTargetRanges()`, but needs discussion.
    158 // https://github.com/w3c/input-events/issues/112
    159 promise_test(async (t) => {
    160  initializeTest("<p>abc   </p><p>   def</p>");
    161  let p1 = gEditor.firstChild;
    162  let abc = p1.firstChild;
    163  let p2 = p1.nextSibling;
    164  let def = p2.firstChild;
    165  gSelection.collapse(def, 3);
    166  await sendBackspaceKey();
    167  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    168  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    169    startContainer: abc,
    170    startOffset: 3,
    171    endContainer: def,
    172    endOffset: 3,
    173  });
    174  checkGetTargetRangesOfInputOnDeleteSomething();
    175 }, 'Backspace at "<p>abc   </p><p>   []def</p>"');
    176 
    177 // Invisible leading white-spaces in current block and invisible trailing
    178 // white-spaces in the previous block should be deleted for avoiding they
    179 // becoming visible when the blocks are joined.  Perhaps, they should be
    180 // contained by the range of `getTargetRanges()`, but needs discussion.
    181 // https://github.com/w3c/input-events/issues/112
    182 promise_test(async (t) => {
    183  initializeTest("<p>abc   </p><p>   def</p>");
    184  let p1 = gEditor.firstChild;
    185  let abc = p1.firstChild;
    186  let p2 = p1.nextSibling;
    187  let def = p2.firstChild;
    188  gSelection.collapse(def, 2);
    189  await sendBackspaceKey();
    190  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    191  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    192    startContainer: abc,
    193    startOffset: 3,
    194    endContainer: def,
    195    endOffset: 3,
    196  });
    197  checkGetTargetRangesOfInputOnDeleteSomething();
    198 }, 'Backspace at "<p>abc   </p><p>  [] def</p>"');
    199 
    200 // Invisible leading white-spaces in current block and invisible trailing
    201 // white-spaces in the previous block should be deleted for avoiding they
    202 // becoming visible when the blocks are joined.  Perhaps, they should be
    203 // contained by the range of `getTargetRanges()`, but needs discussion.
    204 // https://github.com/w3c/input-events/issues/112
    205 promise_test(async (t) => {
    206  initializeTest("<p>abc   </p><p>   def</p>");
    207  let p1 = gEditor.firstChild;
    208  let abc = p1.firstChild;
    209  let p2 = p1.nextSibling;
    210  let def = p2.firstChild;
    211  gSelection.collapse(def, 1);
    212  await sendBackspaceKey();
    213  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    214  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    215    startContainer: abc,
    216    startOffset: 3,
    217    endContainer: def,
    218    endOffset: 3,
    219  });
    220  checkGetTargetRangesOfInputOnDeleteSomething();
    221 }, 'Backspace at "<p>abc   </p><p> []  def</p>"');
    222 
    223 // Invisible leading white-spaces in current block and invisible trailing
    224 // white-spaces in the previous block should be deleted for avoiding they
    225 // becoming visible when the blocks are joined.  Perhaps, they should be
    226 // contained by the range of `getTargetRanges()`, but needs discussion.
    227 // https://github.com/w3c/input-events/issues/112
    228 promise_test(async (t) => {
    229  initializeTest("<p>abc   </p><p>   def</p>");
    230  let p1 = gEditor.firstChild;
    231  let abc = p1.firstChild;
    232  let p2 = p1.nextSibling;
    233  let def = p2.firstChild;
    234  gSelection.collapse(def, 0);
    235  await sendBackspaceKey();
    236  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    237  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    238    startContainer: abc,
    239    startOffset: 3,
    240    endContainer: def,
    241    endOffset: 3,
    242  });
    243  checkGetTargetRangesOfInputOnDeleteSomething();
    244 }, 'Backspace at "<p>abc   </p><p>[]   def</p>"');
    245 
    246 promise_test(async (t) => {
    247  initializeTest("<p>abc</p><p><b>def</b></p>");
    248  let abc = gEditor.querySelector("p").firstChild;
    249  let def = gEditor.querySelector("b").firstChild;
    250  gSelection.collapse(def, 0);
    251  await sendBackspaceKey();
    252  checkEditorContentResultAsSubTest("<p>abc<b>def</b></p>", t.name);
    253  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    254    startContainer: abc,
    255    startOffset: 3,
    256    endContainer: def,
    257    endOffset: 0,
    258  });
    259  checkGetTargetRangesOfInputOnDeleteSomething();
    260 }, 'Backspace at "<p>abc</p><p><b>[]def</b></p>"');
    261 
    262 promise_test(async (t) => {
    263  initializeTest("<p><b>abc</b></p><p><b>def</b></p>");
    264  let abc = gEditor.querySelector("p > b").firstChild;
    265  let def = gEditor.querySelector("P + p > b").firstChild;
    266  gSelection.collapse(def, 0);
    267  await sendBackspaceKey();
    268  checkEditorContentResultAsSubTest(
    269    [
    270      "<p><b>abc</b><b>def</b></p>",
    271      "<p><b>abcdef</b></p>",
    272    ],
    273    t.name
    274  );
    275  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    276    startContainer: abc,
    277    startOffset: 3,
    278    endContainer: def,
    279    endOffset: 0,
    280  });
    281  checkGetTargetRangesOfInputOnDeleteSomething();
    282 }, 'Backspace at "<p><b>abc</b></p><p><b>[]def</b></p>"');
    283 
    284 promise_test(async (t) => {
    285  initializeTest("<p><i>abc</i></p><p><b>def</b></p>");
    286  let abc = gEditor.querySelector("i").firstChild;
    287  let def = gEditor.querySelector("b").firstChild;
    288  gSelection.collapse(def, 0);
    289  await sendBackspaceKey();
    290  checkEditorContentResultAsSubTest("<p><i>abc</i><b>def</b></p>", t.name);
    291  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    292    startContainer: abc,
    293    startOffset: 3,
    294    endContainer: def,
    295    endOffset: 0,
    296  });
    297  checkGetTargetRangesOfInputOnDeleteSomething();
    298 }, 'Backspace at "<p><i>abc</i></p><p><b>[]def</b></p>"');
    299 
    300 // Invisible leading white-spaces in the current block should be deleted
    301 // for avoiding they becoming visible when the blocks are joined, but
    302 // preformatted trailing white-spaces in the first block shouldn't be
    303 // deleted.  Perhaps, the invisible white-spaces should be contained by
    304 // the range of `getTargetRanges()`, but needs discussion.
    305 // https://github.com/w3c/input-events/issues/112
    306 promise_test(async (t) => {
    307  initializeTest("<pre>abc   </pre><p>   def</p>");
    308  let pre = gEditor.firstChild;
    309  let abc = pre.firstChild;
    310  let p = pre.nextSibling;
    311  let def = p.firstChild;
    312  gSelection.collapse(def, 3);
    313  await sendBackspaceKey();
    314  // https://github.com/w3c/input-events/issues/112
    315  // Shouldn't make the invisible white-spaces visible.
    316  checkEditorContentResultAsSubTest("<pre>abc   def</pre>", t.name);
    317  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    318    startContainer: abc,
    319    startOffset: 6,
    320    endContainer: def,
    321    endOffset: 3,
    322  });
    323  checkGetTargetRangesOfInputOnDeleteSomething();
    324 }, 'Backspace at "<pre>abc   </pre><p>   []def</p>"');
    325 
    326 // Invisible leading/trailing white-spaces in the current block should be
    327 // deleted for avoiding they becoming visible when the blocks are joined, but
    328 // preformatted trailing white-spaces in the first block shouldn't be
    329 // deleted.  Perhaps, the invisible leading white-spaces should be contained
    330 // by the range of `getTargetRanges()`, but needs discussion.
    331 // And also not sure whether the trailing white-spaces should be contained
    332 // by additional range of `getTargetRanges()` or not because of the
    333 // implementation cost and runtime cost.  Needs discuss.
    334 // https://github.com/w3c/input-events/issues/112
    335 promise_test(async (t) => {
    336  initializeTest("<pre>abc   </pre><p>   def   </p>");
    337  let pre = gEditor.firstChild;
    338  let abc = pre.firstChild;
    339  let p = pre.nextSibling;
    340  let def = p.firstChild;
    341  gSelection.collapse(def, 3);
    342  await sendBackspaceKey();
    343  checkEditorContentResultAsSubTest("<pre>abc   def   </pre>", t.name);
    344  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    345    startContainer: abc,
    346    startOffset: 6,
    347    endContainer: def,
    348    endOffset: 3,
    349  });
    350  checkGetTargetRangesOfInputOnDeleteSomething();
    351 }, 'Backspace at "<pre>abc   </pre><p>   []def   </p>"');
    352 
    353 // Invisible trailing white-spaces in the first block should be deleted
    354 // when the block is joined with the preformatted following block, but
    355 // the leading white-spaces in the preformatted block shouldn't be
    356 // removed.  So, in this case, the invisible trailing white-spaces should
    357 // be in the range of `getTargetRanges()`, but not so for the preformatted
    358 // visible leading white-spaces.  But needs discussion.
    359 // https://github.com/w3c/input-events/issues/112
    360 promise_test(async (t) => {
    361  initializeTest("<p>abc   </p><pre>   def</pre>");
    362  let p = gEditor.firstChild;
    363  let abc = p.firstChild;
    364  let pre = p.nextSibling;
    365  let def = pre.firstChild;
    366  gSelection.collapse(def, 0);
    367  await sendBackspaceKey();
    368  checkEditorContentResultAsSubTest(
    369    [
    370      "<p>abc &nbsp; def</p>",
    371      "<p>abc&nbsp;&nbsp; def</p>",
    372      "<p>abc&nbsp; &nbsp;def</p>",
    373      "<p>abc &nbsp;&nbsp;def</p>",
    374    ],
    375    t.name
    376  );
    377  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    378    startContainer: abc,
    379    startOffset: 6,
    380    endContainer: def,
    381    endOffset: 0,
    382  });
    383  checkGetTargetRangesOfInputOnDeleteSomething();
    384 }, 'Backspace at "<p>abc   </p><pre>[]   def</pre>"');
    385 
    386 promise_test(async (t) => {
    387  initializeTest('<p style="white-space:pre-line">abc\ndef</p>');
    388  const p = gEditor.firstChild;
    389  const text = p.firstChild;
    390  gSelection.collapse(text, "abc\n".length);
    391  await sendBackspaceKey();
    392  checkEditorContentResultAsSubTest(
    393    '<p style="white-space:pre-line">abcdef</p>',
    394    t.name
    395  );
    396  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    397    startContainer: text,
    398    startOffset: "abc".length,
    399    endContainer: text,
    400    endOffset: "abc\n".length,
    401  });
    402  checkGetTargetRangesOfInputOnDeleteSomething();
    403 }, 'Backspace at "<p style="white-space:pre-line">abc\\n[]def</p>"');
    404 
    405 promise_test(async (t) => {
    406  initializeTest('<p style="white-space:pre-line">abc \ndef</p>');
    407  const p = gEditor.firstChild;
    408  const text = p.firstChild;
    409  gSelection.collapse(text, "abc \n".length);
    410  await sendBackspaceKey();
    411  checkEditorContentResultAsSubTest(
    412    '<p style="white-space:pre-line">abcdef</p>',
    413    t.name
    414  );
    415  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    416    startContainer: text,
    417    startOffset: "abc".length,
    418    endContainer: text,
    419    endOffset: "abc \n".length,
    420  });
    421  checkGetTargetRangesOfInputOnDeleteSomething();
    422 }, 'Backspace at "<p style="white-space:pre-line">abc \\n[]def</p>"');
    423 
    424 promise_test(async (t) => {
    425  initializeTest('<p style="white-space:pre-line">abc\n def</p>');
    426  const p = gEditor.firstChild;
    427  const text = p.firstChild;
    428  gSelection.collapse(text, "abc\n ".length);
    429  await sendBackspaceKey();
    430  checkEditorContentResultAsSubTest(
    431    '<p style="white-space:pre-line">abcdef</p>',
    432    t.name
    433  );
    434  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    435    startContainer: text,
    436    startOffset: "abc".length,
    437    endContainer: text,
    438    endOffset: "abc\n ".length,
    439  });
    440  checkGetTargetRangesOfInputOnDeleteSomething();
    441 }, 'Backspace at "<p style="white-space:pre-line">abc\\n []def</p>"');
    442 
    443 promise_test(async (t) => {
    444  initializeTest('<p style="white-space:pre-line">abc \n def</p>');
    445  const p = gEditor.firstChild;
    446  const text = p.firstChild;
    447  gSelection.collapse(text, "abc \n ".length);
    448  await sendBackspaceKey();
    449  checkEditorContentResultAsSubTest(
    450    '<p style="white-space:pre-line">abcdef</p>',
    451    t.name
    452  );
    453  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    454    startContainer: text,
    455    startOffset: "abc".length,
    456    endContainer: text,
    457    endOffset: "abc \n ".length,
    458  });
    459  checkGetTargetRangesOfInputOnDeleteSomething();
    460 }, 'Backspace at "<p style="white-space:pre-line">abc \\n []def</p>"');
    461 
    462 promise_test(async (t) => {
    463  initializeTest('<p style="white-space:pre-line">abc \n \n def</p>');
    464  const p = gEditor.firstChild;
    465  const text = p.firstChild;
    466  gSelection.collapse(text, "abc \n \n ".length);
    467  await sendBackspaceKey();
    468  checkEditorContentResultAsSubTest(
    469    '<p style="white-space:pre-line">abc \ndef</p>',
    470    t.name
    471  );
    472  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    473    startContainer: text,
    474    startOffset: "abc \n".length,
    475    endContainer: text,
    476    endOffset: "abc \n \n ".length,
    477  });
    478  checkGetTargetRangesOfInputOnDeleteSomething();
    479 }, 'Backspace at "<p style="white-space:pre-line">abc \\n \\n []def</p>"');
    480 
    481 // If the first block has invisible `<br>` element and joining it with
    482 // the following block, the invisible trailing `<br>` element should be
    483 // deleted and join the blocks.  Therefore, the target range should contain
    484 // the `<br>` element and block boundaries. But maybe needs discussion.
    485 // https://github.com/w3c/input-events/issues/112
    486 promise_test(async (t) => {
    487  initializeTest("<p>abc<br></p><p>def</p>");
    488  let p1 = gEditor.firstChild;
    489  let abc = p1.firstChild;
    490  let p2 = p1.nextSibling;
    491  let def = p2.firstChild;
    492  gSelection.collapse(def, 0);
    493  await sendBackspaceKey();
    494  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    495  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    496    startContainer: p1,
    497    startOffset: 1,
    498    endContainer: def,
    499    endOffset: 0,
    500  });
    501  checkGetTargetRangesOfInputOnDeleteSomething();
    502 }, 'Backspace at "<p>abc<br></p><p>[]def</p>"');
    503 
    504 // If the first block has invisible `<br>` element for empty last line and
    505 // joining it with the following block, the invisible trailing `<br>` element
    506 // should be deleted and join the blocks.  Therefore, the target range should
    507 // contain the `<br>` element and block boundaries. But maybe needs discussion.
    508 // https://github.com/w3c/input-events/issues/112
    509 promise_test(async (t) => {
    510  initializeTest("<p>abc<br><br></p><p>def</p>");
    511  let p1 = gEditor.firstChild;
    512  let abc = p1.firstChild;
    513  let p2 = p1.nextSibling;
    514  let def = p2.firstChild;
    515  gSelection.collapse(def, 0);
    516  await sendBackspaceKey();
    517  checkEditorContentResultAsSubTest("<p>abc<br>def</p>", t.name);
    518  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    519    startContainer: p1,
    520    startOffset: 2,
    521    endContainer: def,
    522    endOffset: 0,
    523  });
    524  checkGetTargetRangesOfInputOnDeleteSomething();
    525 }, 'Backspace at "<p>abc<br><br></p><p>[]def</p>"');
    526 
    527 // Deleting visible `<br>` element should be contained by a range of
    528 // `getTargetRanges()`.
    529 promise_test(async (t) => {
    530  initializeTest("<p>abc<br>def</p>");
    531  let p = document.querySelector("p");
    532  let def = gEditor.querySelector("br").nextSibling;
    533  gSelection.collapse(def, 0);
    534  await sendBackspaceKey();
    535  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    536  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    537    startContainer: p,
    538    startOffset: 1,
    539    endContainer: p,
    540    endOffset: 2,
    541  });
    542  checkGetTargetRangesOfInputOnDeleteSomething();
    543 }, 'Backspace at "<p>abc<br>[]def</p>"');
    544 
    545 // Deleting visible `<br>` element following white-space should not include
    546 // the preceding white-space in the range.
    547 promise_test(async (t) => {
    548  initializeTest("<p>abc <br>def</p>");
    549  let p = gEditor.querySelector("p");
    550  let def = gEditor.querySelector("br").nextSibling;
    551  gSelection.collapse(def, 0);
    552  await sendBackspaceKey();
    553  checkEditorContentResultAsSubTest("<p>abc def</p>", t.name);
    554  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    555    startContainer: p,
    556    startOffset: 1,
    557    endContainer: p,
    558    endOffset: 2,
    559  });
    560  checkGetTargetRangesOfInputOnDeleteSomething();
    561 }, 'Backspace at "<p>abc <br>[]def</p>"');
    562 
    563 promise_test(async (t) => {
    564  initializeTest(`<p>abc<img src="${kImgSrc}">def</p>`);
    565  let p = gEditor.querySelector("p");
    566  let def = p.lastChild;
    567  gSelection.collapse(def, 0);
    568  await sendBackspaceKey();
    569  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    570  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    571    startContainer: p,
    572    startOffset: 1,
    573    endContainer: p,
    574    endOffset: 2,
    575  });
    576  checkGetTargetRangesOfInputOnDeleteSomething();
    577 }, 'Backspace at "<p>abc<img>[]def</p>"');
    578 
    579 // White-spaces around `<img>` element are visible so that they shouldn't
    580 // be included into the target ranges.
    581 promise_test(async (t) => {
    582  initializeTest(`<p>abc <img src="${kImgSrc}">def</p>`);
    583  let p = gEditor.querySelector("p");
    584  let def = p.lastChild;
    585  gSelection.collapse(def, 0);
    586  await sendBackspaceKey();
    587 
    588  // If the browser does not join `Text` nodes around <img>, it's fine to
    589  // convert the preceding white-space to an NBSP.
    590  if (
    591    gEditor.querySelector("p")?.childNodes.length == 2 &&
    592    gEditor.querySelector("p").childNodes[0].length == "abc ".length
    593  ) {
    594    checkEditorContentResultAsSubTest([
    595      "<p>abc&nbsp;def</p>",
    596      "<p>abc def</p>",
    597    ], t.name);
    598  } else {
    599    checkEditorContentResultAsSubTest("<p>abc def</p>", t.name);
    600  }
    601  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    602    startContainer: p,
    603    startOffset: 1,
    604    endContainer: p,
    605    endOffset: 2,
    606  });
    607  checkGetTargetRangesOfInputOnDeleteSomething();
    608 }, 'Backspace at "<p>abc <img>[]def</p>"');
    609 
    610 // White-spaces around `<img>` element are visible so that they shouldn't
    611 // be included into the target ranges.
    612 promise_test(async (t) => {
    613  initializeTest(`<p>abc<img src="${kImgSrc}"> def</p>`);
    614  let p = gEditor.querySelector("p");
    615  let def = p.lastChild;
    616  gSelection.collapse(def, 0);
    617  await sendBackspaceKey();
    618  // If the browser does not join `Text` nodes around <img>, it's fine to
    619  // convert the preceding white-space to an NBSP.
    620  if (
    621    gEditor.querySelector("p")?.childNodes.length == 2 &&
    622    gEditor.querySelector("p").childNodes[0].length == "abc".length
    623  ) {
    624    checkEditorContentResultAsSubTest([
    625      "<p>abc&nbsp;def</p>",
    626      "<p>abc def</p>",
    627    ], t.name);
    628  } else {
    629    checkEditorContentResultAsSubTest("<p>abc def</p>", t.name);
    630  }
    631  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    632    startContainer: p,
    633    startOffset: 1,
    634    endContainer: p,
    635    endOffset: 2,
    636  });
    637  checkGetTargetRangesOfInputOnDeleteSomething();
    638 }, 'Backspace at "<p>abc<img>[] def</p>"');
    639 
    640 promise_test(async (t) => {
    641  initializeTest(`<p>abc<img src="${kImgSrc}"><img src="${kImgSrc}">def</p>`);
    642  let p = gEditor.querySelector("p");
    643  let abc = p.firstChild;
    644  gSelection.collapse(p, 2);
    645  await sendBackspaceKey();
    646  checkEditorContentResultAsSubTest(
    647    `<p>abc<img src="${kImgSrc}">def</p>`,
    648    t.name
    649  );
    650  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    651    startContainer: p,
    652    startOffset: 1,
    653    endContainer: p,
    654    endOffset: 2,
    655  });
    656  checkGetTargetRangesOfInputOnDeleteSomething();
    657 }, 'Backspace at "<p>abc<img>{}<img>def</p>"');
    658 
    659 promise_test(async (t) => {
    660  initializeTest(`<p>abc<img src="${kImgSrc}"><img src="${kImgSrc}">def</p>`);
    661  let p = gEditor.querySelector("p");
    662  let def = p.lastChild;
    663  gSelection.collapse(def, 0);
    664  await sendBackspaceKey();
    665  checkEditorContentResultAsSubTest(
    666    `<p>abc<img src="${kImgSrc}">def</p>`,
    667    t.name
    668  );
    669  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    670    startContainer: p,
    671    startOffset: 2,
    672    endContainer: p,
    673    endOffset: 3,
    674  });
    675  checkGetTargetRangesOfInputOnDeleteSomething();
    676 }, 'Backspace at "<p>abc<img><img>[]def</p>"');
    677 
    678 promise_test(async (t) => {
    679  initializeTest(`<div>abc<hr>def</div>`);
    680  let div = gEditor.querySelector("div");
    681  let hr = gEditor.querySelector("hr");
    682  let def = hr.nextSibling;
    683  gSelection.collapse(def, 0);
    684  await sendBackspaceKey();
    685  checkEditorContentResultAsSubTest("<div>abcdef</div>", t.name);
    686  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    687    startContainer: div,
    688    startOffset: 1,
    689    endContainer: div,
    690    endOffset: 2,
    691  });
    692  checkGetTargetRangesOfInputOnDeleteSomething();
    693 }, 'Backspace at "<div>abc<hr>[]def</div>"');
    694 
    695 // White-spaces around block element are invisible white-spaces so that
    696 // they should be included into the target ranges to avoid they bcome
    697 // visible.
    698 // https://github.com/w3c/input-events/issues/112
    699 promise_test(async (t) => {
    700  initializeTest(`<div>abc <hr>def</div>`);
    701  let div = gEditor.querySelector("div");
    702  let abc = div.firstChild;
    703  let hr = gEditor.querySelector("hr");
    704  let def = hr.nextSibling;
    705  gSelection.collapse(def, 0);
    706  await sendBackspaceKey();
    707  checkEditorContentResultAsSubTest("<div>abcdef</div>", t.name);
    708  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    709    startContainer: abc,
    710    startOffset: 3,
    711    endContainer: div,
    712    endOffset: 2,
    713  });
    714  checkGetTargetRangesOfInputOnDeleteSomething();
    715 }, 'Backspace at "<div>abc <hr>[]def</div>"');
    716 
    717 // White-spaces around block element are invisible white-spaces so that
    718 // they should be included into the target ranges to avoid they bcome
    719 // visible.
    720 // https://github.com/w3c/input-events/issues/112
    721 promise_test(async (t) => {
    722  initializeTest(`<div>abc<hr> def</div>`);
    723  let div = gEditor.querySelector("div");
    724  let hr = gEditor.querySelector("hr");
    725  let def = hr.nextSibling;
    726  gSelection.collapse(def, 1);
    727  await sendBackspaceKey();
    728  checkEditorContentResultAsSubTest("<div>abcdef</div>", t.name);
    729  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    730    startContainer: div,
    731    startOffset: 1,
    732    endContainer: def,
    733    endOffset: 1,
    734  });
    735  checkGetTargetRangesOfInputOnDeleteSomething();
    736 }, 'Backspace at "<div>abc<hr> []def</div>"');
    737 
    738 // Invisible `<br>` element immediately before `<hr>` element should be
    739 // deleted once, and both of them should be included in the target range.
    740 promise_test(async (t) => {
    741  initializeTest(`<div>abc<br><hr>def</div>`);
    742  let div = gEditor.querySelector("div");
    743  let def = div.lastChild;
    744  gSelection.collapse(def, 0);
    745  await sendBackspaceKey();
    746  checkEditorContentResultAsSubTest("<div>abcdef</div>", t.name);
    747  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    748    startContainer: div,
    749    startOffset: 1,
    750    endContainer: div,
    751    endOffset: 3,
    752  });
    753  checkGetTargetRangesOfInputOnDeleteSomething();
    754 }, 'Backspace at "<div>abc<br><hr>[]def</div>"');
    755 
    756 // Deleting visible `<br>` element followed by white-space should include
    757 // the following white-space in the range because it shouldn't become
    758 // visible and should be deleted for avoiding it.
    759 // https://github.com/w3c/input-events/issues/112
    760 promise_test(async (t) => {
    761  initializeTest("<p>abc<br> def</p>");
    762  let p = gEditor.querySelector("p");
    763  let def = gEditor.querySelector("br").nextSibling;
    764  gSelection.collapse(def, 0);
    765  await sendBackspaceKey();
    766  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    767  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    768    startContainer: p,
    769    startOffset: 1,
    770    endContainer: def,
    771    endOffset: 1,
    772  });
    773  checkGetTargetRangesOfInputOnDeleteSomething();
    774 }, 'Backspace at "<p>abc<br>[] def</p>"');
    775 promise_test(async (t) => {
    776  initializeTest("<p>abc<br> def</p>");
    777  let p = gEditor.querySelector("p");
    778  let def = gEditor.querySelector("br").nextSibling;
    779  gSelection.collapse(def, 1);
    780  await sendBackspaceKey();
    781  checkEditorContentResultAsSubTest("<p>abcdef</p>", t.name);
    782  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    783    startContainer: p,
    784    startOffset: 1,
    785    endContainer: def,
    786    endOffset: 1,
    787  });
    788  checkGetTargetRangesOfInputOnDeleteSomething();
    789 }, 'Backspace at "<p>abc<br> []def</p>"');
    790 
    791 promise_test(async (t) => {
    792  initializeTest("<div>abc<p>def<br>ghi</p></div>");
    793  let p = gEditor.querySelector("p");
    794  let def = p.firstChild;
    795  let abc = gEditor.firstChild.firstChild;
    796  gSelection.collapse(def, 0);
    797  await sendBackspaceKey();
    798  checkEditorContentResultAsSubTest(
    799    [
    800      "<div>abcdef<p>ghi</p></div>",
    801      "<div>abcdef<br><p>ghi</p></div>",
    802    ],
    803    t.name
    804  );
    805  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    806    startContainer: abc,
    807    startOffset: 3,
    808    endContainer: def,
    809    endOffset: 0,
    810  });
    811  checkGetTargetRangesOfInputOnDeleteSomething();
    812 }, 'Backspace at "<div>abc<p>[]def<br>ghi</p></div>"');
    813 
    814 // Joining parent block and child block should remove invisible preceding
    815 // white-spaces of the child block and invisible leading white-spaces in
    816 // the child block, and they should be contained in a range of
    817 // `getTargetRanges()`, but maybe needs discussion.
    818 // https://github.com/w3c/input-events/issues/112
    819 promise_test(async (t) => {
    820  initializeTest("<div>abc   <p>   def<br>ghi</p></div>");
    821  let p = gEditor.querySelector("p");
    822  let def = p.firstChild;
    823  let abc = gEditor.firstChild.firstChild;
    824  gSelection.collapse(def, 3);
    825  await sendBackspaceKey();
    826  checkEditorContentResultAsSubTest(
    827    [
    828      "<div>abcdef<p>ghi</p></div>",
    829      "<div>abcdef<br><p>ghi</p></div>",
    830    ],
    831    t.name
    832  );
    833  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    834    startContainer: abc,
    835    startOffset: 3,
    836    endContainer: def,
    837    endOffset: 3,
    838  });
    839  checkGetTargetRangesOfInputOnDeleteSomething();
    840 }, 'Backspace at "<div>abc   <p>   []def<br>ghi</p></div>"');
    841 
    842 promise_test(async (t) => {
    843  initializeTest("<div>abc<p><b>def</b></p></div>");
    844  let abc = gEditor.querySelector("div").firstChild;
    845  let def = gEditor.querySelector("b").firstChild;
    846  gSelection.collapse(def, 0);
    847  await sendBackspaceKey();
    848  checkEditorContentResultAsSubTest("<div>abc<b>def</b></div>", t.name);
    849  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    850    startContainer: abc,
    851    startOffset: 3,
    852    endContainer: def,
    853    endOffset: 0,
    854  });
    855  checkGetTargetRangesOfInputOnDeleteSomething();
    856 }, 'Backspace at "<div>abc<p><b>[]def</b></p></div>"');
    857 
    858 promise_test(async (t) => {
    859  initializeTest("<div><b>abc</b><p><b>def</b></p></div>");
    860  let abc = gEditor.querySelector("b").firstChild;
    861  let def = gEditor.querySelector("p > b").firstChild;
    862  gSelection.collapse(def, 0);
    863  await sendBackspaceKey();
    864  checkEditorContentResultAsSubTest(
    865    [
    866      "<div><b>abc</b><b>def</b></div>",
    867      "<div><b>abcdef</b></div>",
    868    ],
    869    t.name
    870  );
    871  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    872    startContainer: abc,
    873    startOffset: 3,
    874    endContainer: def,
    875    endOffset: 0,
    876  });
    877  checkGetTargetRangesOfInputOnDeleteSomething();
    878 }, 'Backspace at "<div><b>abc</b><p><b>[]def</b></p></div>"');
    879 
    880 promise_test(async (t) => {
    881  initializeTest("<div><i>abc</i><p><b>def</b></p></div>");
    882  let abc = gEditor.querySelector("i").firstChild;
    883  let def = gEditor.querySelector("b").firstChild;
    884  gSelection.collapse(def, 0);
    885  await sendBackspaceKey();
    886  checkEditorContentResultAsSubTest("<div><i>abc</i><b>def</b></div>", t.name);
    887  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    888    startContainer: abc,
    889    startOffset: 3,
    890    endContainer: def,
    891    endOffset: 0,
    892  });
    893  checkGetTargetRangesOfInputOnDeleteSomething();
    894 }, 'Backspace at "<div><i>abc</i><p><b>[]def</b></p></div>"');
    895 
    896 promise_test(async (t) => {
    897  initializeTest("<div><p>abc</p>def</div>");
    898  let abc = gEditor.querySelector("p").firstChild;
    899  let def = gEditor.querySelector("p").nextSibling;
    900  gSelection.collapse(def, 0);
    901  await sendBackspaceKey();
    902  checkEditorContentResultAsSubTest(
    903    [
    904      "<div><p>abcdef</p></div>",
    905      "<div><p>abcdef<br></p></div>",
    906    ],
    907    t.name
    908  );
    909  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    910    startContainer: abc,
    911    startOffset: 3,
    912    endContainer: def,
    913    endOffset: 0,
    914  });
    915  checkGetTargetRangesOfInputOnDeleteSomething();
    916 }, 'Backspace at "<div><p>abc</p>[]def</div>"');
    917 
    918 // Joining child block and parent block should remove invisible trailing
    919 // white-spaces of the child block and invisible following white-spaces
    920 // in the parent block, and they should be contained by a range of
    921 // `getTargetRanges()`, but maybe needs discussion.
    922 // https://github.com/w3c/input-events/issues/112
    923 promise_test(async (t) => {
    924  initializeTest("<div><p>abc   </p>   def</div>");
    925  let abc = gEditor.querySelector("p").firstChild;
    926  let def = gEditor.querySelector("p").nextSibling;
    927  gSelection.collapse(def, 3);
    928  await sendBackspaceKey();
    929  checkEditorContentResultAsSubTest(
    930    [
    931      "<div><p>abcdef</p></div>",
    932      "<div><p>abcdef<br></p></div>",
    933    ],
    934    t.name
    935  );
    936  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    937    startContainer: abc,
    938    startOffset: 3,
    939    endContainer: def,
    940    endOffset: 3,
    941  });
    942  checkGetTargetRangesOfInputOnDeleteSomething();
    943 }, 'Backspace at "<div><p>abc   </p>   []def</div>"');
    944 
    945 promise_test(async (t) => {
    946  initializeTest("<div><p><b>abc</b></p>def</div>");
    947  let abc = gEditor.querySelector("b").firstChild;
    948  let def = gEditor.querySelector("p").nextSibling;
    949  gSelection.collapse(def, 0);
    950  await sendBackspaceKey();
    951  checkEditorContentResultAsSubTest("<div><p><b>abc</b>def</p></div>", t.name);
    952  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    953    startContainer: abc,
    954    startOffset: 3,
    955    endContainer: def,
    956    endOffset: 0,
    957  });
    958  checkGetTargetRangesOfInputOnDeleteSomething();
    959 }, 'Backspace at "<div><p><b>abc</b></p>[]def</div>"');
    960 
    961 promise_test(async (t) => {
    962  initializeTest("<div><p><b>abc</b></p><b>def</b></div>");
    963  let abc = gEditor.querySelector("b").firstChild;
    964  let def = gEditor.querySelector("div > b").firstChild;
    965  gSelection.collapse(def, 0);
    966  await sendBackspaceKey();
    967  checkEditorContentResultAsSubTest(
    968    [
    969      "<div><p><b>abc</b><b>def</b></p></div>",
    970      "<div><p><b>abcdef</b></p></div>",
    971    ],
    972    t.name
    973  );
    974  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    975    startContainer: abc,
    976    startOffset: 3,
    977    endContainer: def,
    978    endOffset: 0,
    979  });
    980  checkGetTargetRangesOfInputOnDeleteSomething();
    981 }, 'Backspace at "<div><p><b>abc</b></p><b>[]def</b></div>"');
    982 
    983 promise_test(async (t) => {
    984  initializeTest("<div><p><b>abc</b></p><i>def</i></div>");
    985  let abc = gEditor.querySelector("b").firstChild;
    986  let def = gEditor.querySelector("i").firstChild;
    987  gSelection.collapse(def, 0);
    988  await sendBackspaceKey();
    989  checkEditorContentResultAsSubTest(
    990    "<div><p><b>abc</b><i>def</i></p></div>",
    991    t.name
    992  );
    993  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
    994    startContainer: abc,
    995    startOffset: 3,
    996    endContainer: def,
    997    endOffset: 0,
    998  });
    999  checkGetTargetRangesOfInputOnDeleteSomething();
   1000 }, 'Backspace at "<div><p><b>abc</b></p><i>[]def</i></div>"');
   1001 
   1002 promise_test(async (t) => {
   1003  initializeTest("<div>abc<ul><li>def</li></ul>ghi</div>");
   1004  let abc = gEditor.querySelector("div").firstChild;
   1005  let def = gEditor.querySelector("li").firstChild;
   1006  gSelection.collapse(def, 0);
   1007  await sendBackspaceKey();
   1008  checkEditorContentResultAsSubTest("<div>abcdefghi</div>", t.name);
   1009  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1010    startContainer: abc,
   1011    startOffset: 3,
   1012    endContainer: def,
   1013    endOffset: 0,
   1014  });
   1015  checkGetTargetRangesOfInputOnDeleteSomething();
   1016 }, 'Backspace at "<div>abc<ul><li>[]def</li></ul>ghi</div>"');
   1017 
   1018 promise_test(async (t) => {
   1019  initializeTest("<div>abc  <ul><li> def </li></ul>  ghi</div>");
   1020  let abc = gEditor.querySelector("div").firstChild;
   1021  let def = gEditor.querySelector("li").firstChild;
   1022  gSelection.collapse(def, 1);
   1023  await sendBackspaceKey();
   1024  checkEditorContentResultAsSubTest("<div>abcdefghi</div>", t.name);
   1025  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1026    startContainer: abc,
   1027    startOffset: 3,
   1028    endContainer: def,
   1029    endOffset: 1,
   1030  });
   1031  checkGetTargetRangesOfInputOnDeleteSomething();
   1032 }, 'Backspace at "<div>abc  <ul><li> []def </li></ul>  ghi</div>"');
   1033 
   1034 promise_test(async (t) => {
   1035  initializeTest("<div>abc  <ul><li> def </li></ul>  ghi</div>");
   1036  let abc = gEditor.querySelector("div").firstChild;
   1037  let def = gEditor.querySelector("li").firstChild;
   1038  gSelection.collapse(def, 0);
   1039  await sendBackspaceKey();
   1040  checkEditorContentResultAsSubTest("<div>abcdefghi</div>", t.name);
   1041  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1042    startContainer: abc,
   1043    startOffset: 3,
   1044    endContainer: def,
   1045    endOffset: 1,
   1046  });
   1047  checkGetTargetRangesOfInputOnDeleteSomething();
   1048 }, 'Backspace at "<div>abc  <ul><li>[] def </li></ul>  ghi</div>"');
   1049 
   1050 promise_test(async (t) => {
   1051  initializeTest("<div>abc<ul><li>def</li></ul>ghi</div>");
   1052  let def = gEditor.querySelector("li").firstChild;
   1053  let ghi = gEditor.querySelector("ul").nextSibling;
   1054  gSelection.collapse(ghi, 0);
   1055  await sendBackspaceKey();
   1056  checkEditorContentResultAsSubTest(
   1057    "<div>abc<ul><li>defghi</li></ul></div>",
   1058    t.name
   1059  );
   1060  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1061    startContainer: def,
   1062    startOffset: 3,
   1063    endContainer: ghi,
   1064    endOffset: 0,
   1065  });
   1066  checkGetTargetRangesOfInputOnDeleteSomething();
   1067 }, 'Backspace at "<div>abc<ul><li>def</li></ul>[]ghi</div>"');
   1068 
   1069 promise_test(async (t) => {
   1070  initializeTest("<div>abc <ul><li>  def  </li></ul> ghi</div>");
   1071  let def = gEditor.querySelector("li").firstChild;
   1072  let ghi = gEditor.querySelector("ul").nextSibling;
   1073  gSelection.collapse(ghi, 1);
   1074  await sendBackspaceKey();
   1075  checkEditorContentResultAsSubTest(
   1076    [
   1077      "<div>abc <ul><li>  defghi</li></ul></div>",
   1078      "<div>abc <ul><li>defghi</li></ul></div>",
   1079      "<div>abc<ul><li>defghi</li></ul></div>",
   1080    ],
   1081    t.name
   1082  );
   1083  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1084    startContainer: def,
   1085    startOffset: 5,
   1086    endContainer: ghi,
   1087    endOffset: 1,
   1088  });
   1089  checkGetTargetRangesOfInputOnDeleteSomething();
   1090 }, 'Backspace at "<div>abc <ul><li>  def  </li></ul> []ghi</div>"');
   1091 
   1092 promise_test(async (t) => {
   1093  initializeTest("<div>abc <ul><li>  def  </li></ul> ghi</div>");
   1094  let def = gEditor.querySelector("li").firstChild;
   1095  let ghi = gEditor.querySelector("ul").nextSibling;
   1096  gSelection.collapse(ghi, 0);
   1097  await sendBackspaceKey();
   1098  checkEditorContentResultAsSubTest(
   1099    [
   1100      "<div>abc <ul><li>  defghi</li></ul></div>",
   1101      "<div>abc <ul><li>defghi</li></ul></div>",
   1102      "<div>abc<ul><li>defghi</li></ul></div>",
   1103    ],
   1104    t.name
   1105  );
   1106  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1107    startContainer: def,
   1108    startOffset: 5,
   1109    endContainer: ghi,
   1110    endOffset: 1,
   1111  });
   1112  checkGetTargetRangesOfInputOnDeleteSomething();
   1113 }, 'Backspace at "<div>abc <ul><li>  def  </li></ul>[] ghi</div>"');
   1114 
   1115 promise_test(async (t) => {
   1116  initializeTest("<div>abc<ul><li>def</li><li>ghi</li></ul>jkl</div>");
   1117  let abc = gEditor.querySelector("div").firstChild;
   1118  let def = gEditor.querySelector("li").firstChild;
   1119  gSelection.collapse(def, 0);
   1120  await sendBackspaceKey();
   1121  checkEditorContentResultAsSubTest(
   1122    "<div>abcdef<ul><li>ghi</li></ul>jkl</div>",
   1123    t.name
   1124  );
   1125  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1126    startContainer: abc,
   1127    startOffset: 3,
   1128    endContainer: def,
   1129    endOffset: 0,
   1130  });
   1131  checkGetTargetRangesOfInputOnDeleteSomething();
   1132 }, 'Backspace at "<div>abc<ul><li>[]def</li><li>ghi</li></ul>jkl</div>"');
   1133 
   1134 promise_test(async (t) => {
   1135  initializeTest("<div>abc<ul><li>def</li><li>ghi</li></ul>jkl</div>");
   1136  let def = gEditor.querySelector("li").firstChild;
   1137  let ghi = gEditor.querySelector("li + li").firstChild;
   1138  gSelection.collapse(ghi, 0);
   1139  await sendBackspaceKey();
   1140  checkEditorContentResultAsSubTest(
   1141    "<div>abc<ul><li>defghi</li></ul>jkl</div>",
   1142    t.name
   1143  );
   1144  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1145    startContainer: def,
   1146    startOffset: 3,
   1147    endContainer: ghi,
   1148    endOffset: 0,
   1149  });
   1150  checkGetTargetRangesOfInputOnDeleteSomething();
   1151 }, 'Backspace at "<div>abc<ul><li>def</li><li>[]ghi</li></ul>jkl</div>"');
   1152 
   1153 promise_test(async (t) => {
   1154  initializeTest("<div>abc<ul><li>def</li><li>ghi</li></ul>jkl</div>");
   1155  let ghi = gEditor.querySelector("li + li").firstChild;
   1156  let jkl = gEditor.querySelector("ul").nextSibling;
   1157  gSelection.collapse(jkl, 0);
   1158  await sendBackspaceKey();
   1159  assert_equals(gEditor.innerHTML,
   1160    "<div>abc<ul><li>def</li><li>ghijkl</li></ul></div>",
   1161    t.name
   1162  );
   1163  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1164    startContainer: ghi,
   1165    startOffset: 3,
   1166    endContainer: jkl,
   1167    endOffset: 0,
   1168  });
   1169  checkGetTargetRangesOfInputOnDeleteSomething();
   1170 }, 'Backspace at "<div>abc<ul><li>def</li><li>ghi</li></ul>[]jkl</div>"');
   1171 
   1172 // Backspace in empty paragraph should remove the empty paragraph.  In this
   1173 // case, it should be treated as joining with the previous paragraph.
   1174 // The target range should include the invisible <br> element in the empty
   1175 // paragraph.
   1176 promise_test(async (t) => {
   1177  initializeTest("<p>abc</p><p><br></p>");
   1178  let p1 = gEditor.querySelector("p");
   1179  let abc = p1.firstChild;
   1180  let p2 = p1.nextSibling;
   1181  gSelection.collapse(p2, 0);
   1182  await sendBackspaceKey();
   1183  checkEditorContentResultAsSubTest("<p>abc</p>", t.name);
   1184  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1185    startContainer: abc,
   1186    startOffset: 3,
   1187    endContainer: p2,
   1188    endOffset: 1,
   1189  });
   1190  checkGetTargetRangesOfInputOnDeleteSomething();
   1191 }, 'Backspace at "<p>abc</p><p>{}<br></p>"');
   1192 
   1193 // Delete ignore the empty span and the other things must be same as the
   1194 // previous test.
   1195 promise_test(async (t) => {
   1196  initializeTest("<p>abc</p><p><span></span><br></p>");
   1197  let p1 = gEditor.querySelector("p");
   1198  let abc = p1.firstChild;
   1199  let p2 = p1.nextSibling;
   1200  let span = p2.firstChild;
   1201  gSelection.collapse(span, 0);
   1202  await sendBackspaceKey();
   1203  checkEditorContentResultAsSubTest("<p>abc</p>", t.name);
   1204  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1205    startContainer: abc,
   1206    startOffset: 3,
   1207    endContainer: p2,
   1208    endOffset: 2,
   1209  });
   1210  checkGetTargetRangesOfInputOnDeleteSomething();
   1211 }, 'Backspace at "<p>abc</p><p><span>{}</span><br></p>"');
   1212 
   1213 // If invisible white-spaces are removed with same action as above tests,
   1214 // the range should be included in the target ranges.
   1215 promise_test(async (t) => {
   1216  initializeTest("<p>abc  </p><p><br></p>");
   1217  let p1 = gEditor.querySelector("p");
   1218  let abc = p1.firstChild;
   1219  let p2 = p1.nextSibling;
   1220  gSelection.collapse(p2, 0);
   1221  await sendBackspaceKey();
   1222  checkEditorContentResultAsSubTest(
   1223    [
   1224      "<p>abc  </p>",
   1225      "<p>abc</p>",
   1226    ],
   1227    t.name
   1228  );
   1229  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1230    startContainer: abc,
   1231    startOffset: abc.length,
   1232    endContainer: p2,
   1233    endOffset: 1,
   1234  });
   1235  checkGetTargetRangesOfInputOnDeleteSomething();
   1236 }, 'Backspace at "<p>abc  </p><p>{}<br></p>"');
   1237 
   1238 // If the previous block ends with non-editable content, target range
   1239 // should be after the non-editable content node.
   1240 promise_test(async (t) => {
   1241  initializeTest("<p>abc<span contenteditable=\"false\">def</span></p><p><br></p>");
   1242  let p1 = gEditor.querySelector("p");
   1243  let span = gEditor.querySelector("span");
   1244  let p2 = p1.nextSibling;
   1245  gSelection.collapse(p2, 0);
   1246  await sendBackspaceKey();
   1247  checkEditorContentResultAsSubTest(
   1248    "<p>abc<span contenteditable=\"false\">def</span></p>",
   1249    t.name
   1250  );
   1251  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1252    startContainer: p1,
   1253    startOffset: 2,
   1254    endContainer: p2,
   1255    endOffset: 1,
   1256  });
   1257  checkGetTargetRangesOfInputOnDeleteSomething();
   1258 }, 'Backspace at "<p>abc<span contenteditable="false">def</span></p><p>{}<br></p>"');
   1259 
   1260 // If previous non-editable paragraph is deleted, target range should begin
   1261 // with end of the text node in the first paragraph.  Otherwise, start from
   1262 // after the non-editable paragraph.
   1263 promise_test(async (t) => {
   1264  initializeTest("<p>abc</p><p contenteditable=\"false\">def</p><p><br></p>");
   1265  let p1 = gEditor.querySelector("p");
   1266  let abc = p1.firstChild;
   1267  let p2 = p1.nextSibling;
   1268  let p3 = p2.nextSibling;
   1269  gSelection.collapse(p3, 0);
   1270  await sendBackspaceKey();
   1271  checkEditorContentResultAsSubTest(
   1272    [
   1273      "<p>abc</p>",
   1274      "<p>abc</p><p contenteditable=\"false\">def</p>",
   1275    ],
   1276    t.name
   1277  );
   1278  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1279    startContainer: p2.isConnected ? gEditor : abc,
   1280    startOffset: p2.isConnected ? 2 : abc.length,
   1281    endContainer: p3,
   1282    endOffset: 1,
   1283  });
   1284  checkGetTargetRangesOfInputOnDeleteSomething();
   1285 }, 'Backspace at "<p>abc</p><p contenteditable=\"false\">def</p><p>{}<br></p>"');
   1286 
   1287 promise_test(async (t) => {
   1288  initializeTest("<p>abc<span contenteditable=\"false\">def</span>ghi</p>");
   1289  let p = gEditor.querySelector("p");
   1290  let ghi = p.lastChild;
   1291  gSelection.collapse(ghi, 0);
   1292  await sendBackspaceKey();
   1293  checkEditorContentResultAsSubTest(
   1294    [
   1295      "<p>abc<span contenteditable=\"false\">def</span>ghi</p>",
   1296      "<p>abcghi</p>",
   1297      "<p>abcghi<br></p>",
   1298    ],
   1299    t.name
   1300  );
   1301  if (gEditor.innerHTML === "<p>abc<span contenteditable=\"false\">def</span>ghi</p>") {
   1302    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1303      startContainer: ghi,
   1304      startOffset: 0,
   1305      endContainer: ghi,
   1306      endOffset: 0,
   1307    });
   1308    checkGetTargetRangesOfInputOnDoNothing();
   1309  } else {
   1310    // If the non-editable `<span>` is deleted, it should be treated as
   1311    // an atomic node.
   1312    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1313      startContainer: p,
   1314      startOffset: 1,
   1315      endContainer: p,
   1316      endOffset: 2,
   1317    });
   1318    checkGetTargetRangesOfInputOnDeleteSomething();
   1319  }
   1320 }, 'Backspace at "<p>abc<span contenteditable=\"false\">def</span>[]ghi</p>"');
   1321 
   1322 // If just removes the paragraph, target range should start from after the
   1323 // table element.
   1324 promise_test(async (t) => {
   1325  initializeTest("<table><tr><td>cell</td></tr></table><p><br></p>");
   1326  let table = gEditor.querySelector("table");
   1327  let p = table.nextSibling;
   1328  gSelection.collapse(p, 0);
   1329  await sendBackspaceKey();
   1330  checkEditorContentResultAsSubTest(
   1331    [
   1332      "<table><tbody><tr><td>cell</td></tr></tbody></table>",
   1333      "<table><tbody><tr><td>cell</td></tr></tbody></table><p><br></p>",
   1334    ],
   1335    t.name
   1336  );
   1337  if (p.isConnected) {
   1338    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1339      startContainer: p,
   1340      startOffset: 0,
   1341      endContainer: p,
   1342      endOffset: 0,
   1343    });
   1344    checkGetTargetRangesOfInputOnDoNothing();
   1345  } else {
   1346    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1347      startContainer: gEditor,
   1348      startOffset: 1,
   1349      endContainer: p,
   1350      endOffset: 1,
   1351    });
   1352    checkGetTargetRangesOfInputOnDeleteSomething();
   1353  }
   1354 }, 'Backspace at "<table><tr><td>cell</td></tr></table><p>{}<br></p>"');
   1355 
   1356 // If table cell won't be joined, target range should be collapsed in the
   1357 // cell.
   1358 promise_test(async (t) => {
   1359  initializeTest("<table><tr><td>cell1</td><td><br></td></tr></table>");
   1360  let cell1 = gEditor.querySelector("td");
   1361  let cell2 = cell1.nextSibling;
   1362  gSelection.collapse(cell2, 0);
   1363  await sendBackspaceKey();
   1364  assert_equals(gEditor.innerHTML,
   1365    "<table><tbody><tr><td>cell1</td><td><br></td></tr></tbody></table>",
   1366    t.name
   1367  );
   1368  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1369    startContainer: cell2,
   1370    startOffset: 0,
   1371    endContainer: cell2,
   1372    endOffset: 0,
   1373  });
   1374  checkGetTargetRangesOfInputOnDoNothing();
   1375 }, 'Backspace at "<table><tr><td>cell1</td><td>{}<br></td></tr></table>"');
   1376 
   1377 // If table caption won't be deleted, target range should be collapsed in the
   1378 // caption element.
   1379 promise_test(async (t) => {
   1380  initializeTest("<p>abc</p><table><caption><br></caption><tr><td>cell</td></tr></table>");
   1381  let caption = gEditor.querySelector("caption");
   1382  gSelection.collapse(caption, 0);
   1383  await sendBackspaceKey();
   1384  assert_equals(gEditor.innerHTML,
   1385    "<p>abc</p><table><caption><br></caption><tbody><tr><td>cell</td></tr></tbody></table>",
   1386    t.name
   1387  );
   1388  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1389    startContainer: caption,
   1390    startOffset: 0,
   1391    endContainer: caption,
   1392    endOffset: 0,
   1393  });
   1394  checkGetTargetRangesOfInputOnDoNothing();
   1395 }, 'Backspace at "<p>abc</p><table><caption>{}<br></caption><tr><td>cell</td></tr></table>"');
   1396 
   1397 // If a table cell element is selected, only its content should be deleted.
   1398 promise_test(async (t) => {
   1399  initializeTest("<table><tr><td>cell1</td><td>cell2</td></tr></table>");
   1400  let cell1 = gEditor.querySelector("td");
   1401  let tr = cell1.parentNode;
   1402  gSelection.setBaseAndExtent(tr, 0, tr, 1);
   1403  await sendBackspaceKey();
   1404  checkEditorContentResultAsSubTest(
   1405    [
   1406      "<table><tbody><tr><td></td><td>cell2</td></tr></tbody></table>",
   1407      "<table><tbody><tr><td><br></td><td>cell2</td></tr></tbody></table>",
   1408    ],
   1409    t.name
   1410  );
   1411  // XXX Perhaps, target range should be selecting only all children of
   1412  //     cell1 instead.
   1413  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1414    startContainer: tr,
   1415    startOffset: 0,
   1416    endContainer: tr,
   1417    endOffset: 1,
   1418  });
   1419  checkGetTargetRangesOfInputOnDeleteSomething();
   1420 }, 'Backspace at "<table><tr>{<td>cell1</td>}<td>cell2</td></tr></table>"');
   1421 
   1422 promise_test(async (t) => {
   1423  initializeTest("<table><tr><td>cell1</td><td>cell2</td></tr></table>");
   1424  let cell2 = gEditor.querySelector("td + td");
   1425  let tr = cell2.parentNode;
   1426  gSelection.setBaseAndExtent(tr, 1, tr, 2);
   1427  await sendBackspaceKey();
   1428  checkEditorContentResultAsSubTest(
   1429    [
   1430      "<table><tbody><tr><td>cell1</td><td></td></tr></tbody></table>",
   1431      "<table><tbody><tr><td>cell1</td><td><br></td></tr></tbody></table>",
   1432    ],
   1433    t.name
   1434  );
   1435  // XXX Perhaps, target range should be selecting only all children of
   1436  //     cell1 instead.
   1437  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1438    startContainer: tr,
   1439    startOffset: 1,
   1440    endContainer: tr,
   1441    endOffset: 2,
   1442  });
   1443  checkGetTargetRangesOfInputOnDeleteSomething();
   1444 }, 'Backspace at "<table><tr><td>cell1</td>{<td>cell2</td>}</tr></table>"');
   1445 
   1446 // If the last table cell element is selected, what browsers should do?
   1447 promise_test(async (t) => {
   1448  initializeTest("<table><tr><td>cell</td></tr></table>");
   1449  let cell = gEditor.querySelector("td");
   1450  let tr = cell.parentNode;
   1451  let table = gEditor.querySelector("table");
   1452  gSelection.setBaseAndExtent(tr, 0, tr, 1);
   1453  await sendBackspaceKey();
   1454  checkEditorContentResultAsSubTest(
   1455    [
   1456      "<table><tbody><tr><td></td></tr></tbody></table>",
   1457      "<table><tbody><tr><td><br></td></tr></tbody></table>",
   1458      "<br>",
   1459    ],
   1460    t.name
   1461  );
   1462  if (gEditor.querySelector("table")) {
   1463    // XXX Perhaps, target range should be selecting only all children of
   1464    //     cell1 instead.
   1465    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1466      startContainer: tr,
   1467      startOffset: 0,
   1468      endContainer: tr,
   1469      endOffset: 1,
   1470    });
   1471  } else {
   1472    // If it causes deleting entire the table, the `<table>` element should
   1473    // be in the target range.
   1474    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1475      startContainer: gEditor,
   1476      startOffset: 0,
   1477      endContainer: gEditor,
   1478      endOffset: 1,
   1479    });
   1480  }
   1481  checkGetTargetRangesOfInputOnDeleteSomething();
   1482 }, 'Backspace at "<table><tr>{<td>cell</td>}</tr></table>"');
   1483 
   1484 // Testing multiple cell selection mode.
   1485 promise_test(async (t) => {
   1486  initializeTest("<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>");
   1487  let cell1 = gEditor.querySelector("td");
   1488  let cell4 = gEditor.querySelector("tr + tr > td + td");
   1489  let tr1 = cell1.parentNode;
   1490  let tr2 = cell4.parentNode;
   1491  gSelection.removeAllRanges();
   1492  let range = document.createRange();
   1493  range.selectNode(cell1);
   1494  gSelection.addRange(range);
   1495  range = document.createRange();
   1496  range.selectNode(cell4);
   1497  gSelection.addRange(range);
   1498  assert_equals(gSelection.rangeCount, 2, "Should support multiple cell selection");
   1499  await sendBackspaceKey();
   1500  checkEditorContentResultAsSubTest(
   1501    [
   1502      "<table><tbody><tr><td></td><td>cell2</td></tr><tr><td>cell3</td><td></td></tr></tbody></table>",
   1503      "<table><tbody><tr><td><br></td><td>cell2</td></tr><tr><td>cell3</td><td><br></td></tr></tbody></table>",
   1504    ],
   1505    t.name
   1506  );
   1507  // XXX Perhaps, target range should be selecting only all children of
   1508  //     cell1 and cell4 instead.
   1509  checkGetTargetRangesOfBeforeinputOnDeleteSomething([
   1510    {
   1511      startContainer: tr1,
   1512      startOffset: 0,
   1513      endContainer: tr1,
   1514      endOffset: 1,
   1515    },
   1516    {
   1517      startContainer: tr2,
   1518      startOffset: 1,
   1519      endContainer: tr2,
   1520      endOffset: 2,
   1521    },
   1522  ]);
   1523  checkGetTargetRangesOfInputOnDeleteSomething();
   1524 }, 'Backspace at "<table><tr>{<td>cell1</td>}<td>cell2</td></tr><tr><td>cell3</td>{<td>cell4</td>}</tr></table>"');
   1525 
   1526 promise_test(async (t) => {
   1527  initializeTest("<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>");
   1528  let cell1 = gEditor.querySelector("td");
   1529  let cell3 = gEditor.querySelector("tr + tr > td");
   1530  let tr1 = cell1.parentNode;
   1531  let tr2 = cell3.parentNode;
   1532  gSelection.removeAllRanges();
   1533  let range = document.createRange();
   1534  range.selectNode(cell1);
   1535  gSelection.addRange(range);
   1536  range = document.createRange();
   1537  range.selectNode(cell3);
   1538  gSelection.addRange(range);
   1539  assert_equals(gSelection.rangeCount, 2, "Should support multiple cell selection");
   1540  await sendBackspaceKey();
   1541  checkEditorContentResultAsSubTest(
   1542    [
   1543      "<table><tbody><tr><td></td><td>cell2</td></tr><tr><td></td><td>cell4</td></tr></tbody></table>",
   1544      "<table><tbody><tr><td><br></td><td>cell2</td></tr><tr><td><br></td><td>cell4</td></tr></tbody></table>",
   1545      "<table><tbody><tr><td>cell2</td></tr><tr><td>cell4</td></tr></tbody></table>",
   1546    ],
   1547    t.name
   1548  );
   1549  // XXX Perhaps, target range should be selecting only all children of
   1550  //     cell1 and cell3 instead.
   1551  checkGetTargetRangesOfBeforeinputOnDeleteSomething([
   1552    {
   1553      startContainer: tr1,
   1554      startOffset: 0,
   1555      endContainer: tr1,
   1556      endOffset: 1,
   1557    },
   1558    {
   1559      startContainer: tr2,
   1560      startOffset: 0,
   1561      endContainer: tr2,
   1562      endOffset: 1,
   1563    },
   1564  ]);
   1565  checkGetTargetRangesOfInputOnDeleteSomething();
   1566 }, 'Backspace at "<table><tr>{<td>cell1</td>}<td>cell2</td></tr><tr>{<td>cell3</td>}<td>cell4</td></tr></table>"');
   1567 
   1568 promise_test(async (t) => {
   1569  initializeTest("<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>");
   1570  let cell1 = gEditor.querySelector("td");
   1571  let cell2 = gEditor.querySelector("td + td");
   1572  let tr1 = cell1.parentNode;
   1573  let tbody = tr1.parentNode;
   1574  gSelection.removeAllRanges();
   1575  let range = document.createRange();
   1576  range.selectNode(cell1);
   1577  gSelection.addRange(range);
   1578  range = document.createRange();
   1579  range.selectNode(cell2);
   1580  gSelection.addRange(range);
   1581  assert_equals(gSelection.rangeCount, 2, "Should support multiple cell selection");
   1582  await sendBackspaceKey();
   1583  checkEditorContentResultAsSubTest(
   1584    [
   1585      "<table><tbody><tr><td></td><td></td></tr><tr><td>cell3</td><td>cell4</td></tr></tbody></table>",
   1586      "<table><tbody><tr><td><br></td><td><br></td></tr><tr><td>cell3</td><td>cell4</td></tr></tbody></table>",
   1587      "<table><tbody><tr><td>cell3</td><td>cell4</td></tr></tbody></table>",
   1588    ],
   1589    t.name
   1590  );
   1591  if (gEditor.querySelector("tr + tr")) {
   1592    // XXX Perhaps, target range should be selecting only all children of
   1593    //     cell1 and cell2 instead.
   1594    checkGetTargetRangesOfBeforeinputOnDeleteSomething([
   1595      {
   1596        startContainer: tr1,
   1597        startOffset: 0,
   1598        endContainer: tr1,
   1599        endOffset: 1,
   1600      },
   1601      {
   1602        startContainer: tr1,
   1603        startOffset: 1,
   1604        endContainer: tr1,
   1605        endOffset: 2,
   1606      },
   1607    ]);
   1608  } else {
   1609    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1610      startContainer: tbody,
   1611      startOffset: 0,
   1612      endContainer: tbody,
   1613      endOffset: 1,
   1614    });
   1615  }
   1616  checkGetTargetRangesOfInputOnDeleteSomething();
   1617 }, 'Backspace at "<table><tr>{<td>cell1</td>}{<td>cell2</td>}</tr><tr><td>cell3</td><td>cell4</td></tr></table>"');
   1618 
   1619 promise_test(async (t) => {
   1620  initializeTest("<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>");
   1621  let cell3 = gEditor.querySelector("tr + tr > td");
   1622  let cell4 = gEditor.querySelector("tr + tr > td + td");
   1623  let tr2 = cell3.parentNode;
   1624  gSelection.removeAllRanges();
   1625  let range = document.createRange();
   1626  range.selectNode(cell3);
   1627  gSelection.addRange(range);
   1628  range = document.createRange();
   1629  range.selectNode(cell4);
   1630  gSelection.addRange(range);
   1631  assert_equals(gSelection.rangeCount, 2, "Should support multiple cell selection");
   1632  await sendBackspaceKey();
   1633  checkEditorContentResultAsSubTest(
   1634    [
   1635      "<table><tbody><tr><td>cell1</td><td>cell2</td></tr><tr><td></td><td></td></tr></tbody></table>",
   1636      "<table><tbody><tr><td>cell1</td><td>cell2</td></tr><tr><td><br></td><td><br></td></tr></tbody></table>",
   1637      "<table><tbody><tr><td>cell1</td><td>cell2</td></tr></tbody></table>",
   1638    ],
   1639    t.name
   1640  );
   1641  if (gEditor.querySelector("tr + tr")) {
   1642    // XXX Perhaps, target range should be selecting only all children of
   1643    //     cell3 and cell4 instead.
   1644    checkGetTargetRangesOfBeforeinputOnDeleteSomething([
   1645      {
   1646        startContainer: tr2,
   1647        startOffset: 0,
   1648        endContainer: tr2,
   1649        endOffset: 1,
   1650      },
   1651      {
   1652        startContainer: tr2,
   1653        startOffset: 1,
   1654        endContainer: tr2,
   1655        endOffset: 2,
   1656      },
   1657    ]);
   1658  } else {
   1659    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1660      startContainer: tbody,
   1661      startOffset: 1,
   1662      endContainer: tbody,
   1663      endOffset: 2,
   1664    });
   1665  }
   1666  checkGetTargetRangesOfInputOnDeleteSomething();
   1667 }, 'Backspace at "<table><tr><td>cell1</td><td>cell2</td></tr><tr>{<td>cell3</td>}{<td>cell4</td>}</tr></table>"');
   1668 
   1669 promise_test(async (t) => {
   1670  initializeTest("<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>");
   1671  let cell1 = gEditor.querySelector("td");
   1672  let cell2 = gEditor.querySelector("td + td");
   1673  let cell3 = gEditor.querySelector("tr + tr > td");
   1674  let cell4 = gEditor.querySelector("tr + tr > td + td");
   1675  let tr1 = cell1.parentNode;
   1676  let tr2 = cell3.parentNode;
   1677  gSelection.removeAllRanges();
   1678  let range = document.createRange();
   1679  range.selectNode(cell1);
   1680  gSelection.addRange(range);
   1681  range = document.createRange();
   1682  range.selectNode(cell2);
   1683  gSelection.addRange(range);
   1684  range = document.createRange();
   1685  range.selectNode(cell3);
   1686  gSelection.addRange(range);
   1687  range = document.createRange();
   1688  range.selectNode(cell4);
   1689  gSelection.addRange(range);
   1690  assert_equals(gSelection.rangeCount, 4, "Should support multiple cell selection");
   1691  await sendBackspaceKey();
   1692  checkEditorContentResultAsSubTest(
   1693    [
   1694      "<table><tbody><tr><td></td><td></td></tr><tr><td></td><td></td></tr></tbody></table>",
   1695      "<table><tbody><tr><td><br></td><td><br></td></tr><tr><td><br></td><td><br></td></tr></tbody></table>",
   1696      "<br>",
   1697    ],
   1698    t.name
   1699  );
   1700  if (gEditor.querySelector("table")) {
   1701    // XXX Perhaps, target range should be selecting only all children of
   1702    //     cell1, cell2, cell3 and cell4 instead.
   1703    checkGetTargetRangesOfBeforeinputOnDeleteSomething([
   1704      {
   1705        startContainer: tr1,
   1706        startOffset: 0,
   1707        endContainer: tr1,
   1708        endOffset: 1,
   1709      },
   1710      {
   1711        startContainer: tr1,
   1712        startOffset: 1,
   1713        endContainer: tr1,
   1714        endOffset: 2,
   1715      },
   1716      {
   1717        startContainer: tr2,
   1718        startOffset: 0,
   1719        endContainer: tr2,
   1720        endOffset: 1,
   1721      },
   1722      {
   1723        startContainer: tr2,
   1724        startOffset: 1,
   1725        endContainer: tr2,
   1726        endOffset: 2,
   1727      },
   1728    ]);
   1729  } else {
   1730    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1731      startContainer: gEditor,
   1732      startOffset: 0,
   1733      endContainer: gEditor,
   1734      endOffset: 1,
   1735    });
   1736  }
   1737  checkGetTargetRangesOfInputOnDeleteSomething();
   1738 }, 'Backspace at "<table><tr>{<td>cell1</td>}{<td>cell2</td>}</tr><tr>{<td>cell3</td>}{<td>cell4</td>}</tr></table>"');
   1739 
   1740 promise_test(async (t) => {
   1741  initializeTest("<table><tr><td>cell1</td><td>cell2</td></tr><tr><td>cell3</td><td>cell4</td></tr></table>");
   1742  let cell1 = gEditor.querySelector("td");
   1743  let cell2 = gEditor.querySelector("td + td");
   1744  let cell4 = gEditor.querySelector("tr + tr > td + td");
   1745  let tr1 = cell1.parentNode;
   1746  let tr2 = cell4.parentNode;
   1747  gSelection.removeAllRanges();
   1748  let range = document.createRange();
   1749  range.selectNode(cell1);
   1750  gSelection.addRange(range);
   1751  range = document.createRange();
   1752  range.setStart(cell2.firstChild, 1);
   1753  range.setEnd(cell2.firstChild, 4);
   1754  gSelection.addRange(range);
   1755  range = document.createRange();
   1756  range.selectNode(cell4);
   1757  gSelection.addRange(range);
   1758  assert_equals(gSelection.rangeCount, 3, "Should support multiple cell selection");
   1759  await sendBackspaceKey();
   1760  checkEditorContentResultAsSubTest(
   1761    [
   1762      "<table><tbody><tr><td></td><td>cell2</td></tr><tr><td>cell3</td><td></td></tr></tbody></table>",
   1763      "<table><tbody><tr><td><br></td><td>cell2</td></tr><tr><td>cell3</td><td><br></td></tr></tbody></table>",
   1764      "<table><tbody><tr><td></td><td>c2</td></tr><tr><td>cell3</td><td></td></tr></tbody></table>",
   1765      "<table><tbody><tr><td><br></td><td>c2</td></tr><tr><td>cell3</td><td><br></td></tr></tbody></table>",
   1766    ],
   1767    t.name
   1768  );
   1769  if (cell2.firstChild.length == "cell2".length) {
   1770    // XXX Perhaps, target range should be selecting only all children of
   1771    //     cell1 and cell4 instead.
   1772    checkGetTargetRangesOfBeforeinputOnDeleteSomething([
   1773      {
   1774        startContainer: tr1,
   1775        startOffset: 0,
   1776        endContainer: tr1,
   1777        endOffset: 1,
   1778      },
   1779      {
   1780        startContainer: tr2,
   1781        startOffset: 1,
   1782        endContainer: tr2,
   1783        endOffset: 2,
   1784      },
   1785    ]);
   1786  } else {
   1787    checkGetTargetRangesOfBeforeinputOnDeleteSomething([
   1788      {
   1789        startContainer: tr1,
   1790        startOffset: 0,
   1791        endContainer: tr1,
   1792        endOffset: 1,
   1793      },
   1794      {
   1795        startContainer: cell2.firstChild,
   1796        startOffset: 1,
   1797        endContainer: cell2.firstChild,
   1798        endOffset: 4,
   1799      },
   1800      {
   1801        startContainer: tr2,
   1802        startOffset: 1,
   1803        endContainer: tr2,
   1804        endOffset: 2,
   1805      },
   1806    ]);
   1807  }
   1808  checkGetTargetRangesOfInputOnDeleteSomething();
   1809 }, 'Backspace at "<table><tr>{<td>cell1</td>}<td>c[ell]2</td></tr><tr>{<td>cell3</td>}<td>cell4</td></tr></table>"');
   1810 
   1811 // If caret is not adjacent of deleting character, browser may not delete the
   1812 // character, but update the caret position for next deletion.
   1813 promise_test(async (t) => {
   1814  initializeTest("<p>&#x5E9;&#x5DC;&#x5D5;&#x5DD;hello</p>");
   1815  let text1 = gEditor.querySelector("p").firstChild;
   1816  let text2 = text1.nextSibling;
   1817  gSelection.collapse(text2 ? text2 : text1, text2 ? 1 : 5);
   1818  await sendArrowLeftKey();
   1819  await sendBackspaceKey();
   1820  checkEditorContentResultAsSubTest(
   1821    [
   1822      "<p>\u05E9\u05DC\u05D5\u05DDhello</p>",
   1823      "<p>\u05DC\u05D5\u05DDhello</p>",
   1824      "<p>\u05E9\u05DC\u05D5hello</p>",
   1825    ],
   1826    t.name
   1827  );
   1828  if (gEditor.innerHTML === "<p>\u05E9\u05DC\u05D5\u05DDhello</p>") {
   1829    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1830      startContainer: text2 ? text2 : text1,
   1831      startOffset: text2 ? 0 : 4,
   1832      endContainer: text2 ? text2 : text1,
   1833      endOffset: text2 ? 0 : 4,
   1834    });
   1835    checkGetTargetRangesOfInputOnDoNothing();
   1836  } else if (gEditor.innerHTML === "<p>\u05DC\u05D5\u05DDhello</p>") {
   1837    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1838      startContainer: text1,
   1839      startOffset: 0,
   1840      endContainer: text1,
   1841      endOffset: 1,
   1842    });
   1843    checkGetTargetRangesOfInputOnDeleteSomething();
   1844  } else {
   1845    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1846      startContainer: text1,
   1847      startOffset: 3,
   1848      endContainer: text1,
   1849      endOffset: 4,
   1850    });
   1851    checkGetTargetRangesOfInputOnDeleteSomething();
   1852  }
   1853 }, 'Backspace at "<p>&#x5E9;&#x5DC;&#x5D5;&#x5DD;[]hello</p>"');
   1854 
   1855 // The following tests check whether the range returned from
   1856 // `beforeinput[0].getTargetRanges()` is modified or different range is
   1857 // modified instead.  I.e., they don't test which type of deletion should
   1858 // occur.  Therefore, their result depends on browser's key bindings,
   1859 // system settings and running OS.
   1860 
   1861 function getFirstDifferentOffset(currentString, originalString) {
   1862  for (let i = 0; i < currentString.length; i++) {
   1863    if (currentString.charAt(i) !== originalString.charAt(i) &&
   1864        (originalString.charAt(i) !== " " || !currentString.charAt("\u00A0"))) {
   1865      return i;
   1866    }
   1867  }
   1868  return currentString.length;
   1869 }
   1870 
   1871 promise_test(async (t) => {
   1872  const kText = "abc def ghi";
   1873  initializeTest(`<p>${kText}</p>`);
   1874  let p = gEditor.querySelector("p");
   1875  gSelection.collapse(p.firstChild, "abc def".length);
   1876  await sendBackspaceKey(kShift);
   1877  let startOffset = getFirstDifferentOffset(p.firstChild.data, kText);
   1878  let length = kText.length - p.firstChild.data.length;
   1879  checkEditorContentResultAsSubTest(
   1880    `<p>${kText.substr(0, startOffset) + kText.substr(startOffset + length)}</p>`,
   1881    t.name,
   1882    { ignoreWhiteSpaceDifference: true }
   1883  );
   1884  if (startOffset === kText.length) {
   1885    checkBeforeinputAndInputEventsOnNOOP();
   1886    return;
   1887  }
   1888  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1889    startContainer: p.firstChild,
   1890    startOffset: startOffset,
   1891    endContainer: p.firstChild,
   1892    endOffset: startOffset + length,
   1893  });
   1894  checkGetTargetRangesOfInputOnDeleteSomething();
   1895 }, 'Shift + Backspace at "<p>abc def[] ghi</p>"');
   1896 
   1897 promise_test(async (t) => {
   1898  const kText = "abc def ghi";
   1899  initializeTest(`<p>${kText}</p>`);
   1900  let p = gEditor.querySelector("p");
   1901  gSelection.collapse(p.firstChild, "abc def".length);
   1902  await sendBackspaceKey(kControl);
   1903  let startOffset = getFirstDifferentOffset(p.firstChild.data, kText);
   1904  let length = kText.length - p.firstChild.data.length;
   1905  checkEditorContentResultAsSubTest(
   1906    `<p>${kText.substr(0, startOffset) + kText.substr(startOffset + length)}</p>`,
   1907    t.name,
   1908    { ignoreWhiteSpaceDifference: true }
   1909  );
   1910  if (startOffset === kText.length) {
   1911    checkBeforeinputAndInputEventsOnNOOP();
   1912    return;
   1913  }
   1914  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1915    startContainer: p.firstChild,
   1916    startOffset: startOffset,
   1917    endContainer: p.firstChild,
   1918    endOffset: startOffset + length,
   1919  });
   1920  checkGetTargetRangesOfInputOnDeleteSomething();
   1921 }, 'Control + Backspace at "<p>abc def[] ghi</p>"');
   1922 
   1923 promise_test(async (t) => {
   1924  const kText = "abc def ghi";
   1925  initializeTest(`<p>${kText}</p>`);
   1926  let p = gEditor.querySelector("p");
   1927  gSelection.collapse(p.firstChild, "abc def".length);
   1928  await sendBackspaceKey(kAlt);
   1929  let startOffset = getFirstDifferentOffset(p.firstChild.data, kText);
   1930  let length = kText.length - p.firstChild.data.length;
   1931  checkEditorContentResultAsSubTest(
   1932    `<p>${kText.substr(0, startOffset) + kText.substr(startOffset + length)}</p>`,
   1933    t.name,
   1934    { ignoreWhiteSpaceDifference: true }
   1935  );
   1936  if (startOffset === kText.length) {
   1937    checkBeforeinputAndInputEventsOnNOOP();
   1938    return;
   1939  }
   1940  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1941    startContainer: p.firstChild,
   1942    startOffset: startOffset,
   1943    endContainer: p.firstChild,
   1944    endOffset: startOffset + length,
   1945  });
   1946  checkGetTargetRangesOfInputOnDeleteSomething();
   1947 }, 'Alt + Backspace at "<p>abc def[] ghi</p>"');
   1948 
   1949 promise_test(async (t) => {
   1950  const kText = "abc def ghi";
   1951  initializeTest(`<p>${kText}</p>`);
   1952  let p = gEditor.querySelector("p");
   1953  gSelection.collapse(p.firstChild, "abc def".length);
   1954  await sendBackspaceKey(kMeta);
   1955  let startOffset = getFirstDifferentOffset(p.firstChild.data, kText);
   1956  let length = kText.length - p.firstChild.data.length;
   1957  checkEditorContentResultAsSubTest(
   1958    `<p>${kText.substr(0, startOffset) + kText.substr(startOffset + length)}</p>`,
   1959    t.name,
   1960    { ignoreWhiteSpaceDifference: true }
   1961  );
   1962  if (startOffset === kText.length) {
   1963    checkBeforeinputAndInputEventsOnNOOP();
   1964    return;
   1965  }
   1966  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1967    startContainer: p.firstChild,
   1968    startOffset: startOffset,
   1969    endContainer: p.firstChild,
   1970    endOffset: startOffset + length,
   1971  });
   1972  checkGetTargetRangesOfInputOnDeleteSomething();
   1973 }, 'Meta + Backspace at "<p>abc def[] ghi</p>"');
   1974 
   1975 promise_test(async (t) => {
   1976  const kText = "abc def";
   1977  initializeTest(`<p>   ${kText}</p>`);
   1978  let p = gEditor.querySelector("p");
   1979  gSelection.collapse(p.firstChild, "abc".length);
   1980  await sendBackspaceKey(kShift);
   1981  let visibleText = p.firstChild.data.replace(/^\s+/, "");
   1982  let invisibleWhiteSpaces = " ".repeat(p.firstChild.data.length - visibleText.length);
   1983  let startOffset = invisibleWhiteSpaces.length + getFirstDifferentOffset(visibleText, kText);
   1984  let length = kText.length + 3 - p.firstChild.data.length;
   1985  // If invisible white-spaces are deleted, they should be contained in the target range.
   1986  checkEditorContentResultAsSubTest(
   1987    `<p>${invisibleWhiteSpaces + kText.substr(0, startOffset) + kText.substr(startOffset + length)}</p>`,
   1988    t.name,
   1989    { ignoreWhiteSpaceDifference: true }
   1990  );
   1991  if (startOffset === kText.length) {
   1992    checkBeforeinputAndInputEventsOnNOOP();
   1993    return;
   1994  }
   1995  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   1996    startContainer: p.firstChild,
   1997    startOffset: startOffset,
   1998    endContainer: p.firstChild,
   1999    endOffset: startOffset + length,
   2000  });
   2001  checkGetTargetRangesOfInputOnDeleteSomething();
   2002 }, 'Shift + Backspace at "<p>   abc[] def</p>"');
   2003 
   2004 promise_test(async (t) => {
   2005  const kText = "abc def";
   2006  initializeTest(`<p>   ${kText}</p>`);
   2007  let p = gEditor.querySelector("p");
   2008  gSelection.collapse(p.firstChild, "abc".length);
   2009  await sendBackspaceKey(kControl);
   2010  let visibleText = p.firstChild.data.replace(/^\s+/, "");
   2011  let invisibleWhiteSpaces = " ".repeat(p.firstChild.data.length - visibleText.length);
   2012  let startOffset = invisibleWhiteSpaces.length + getFirstDifferentOffset(visibleText, kText);
   2013  let length = kText.length + 3 - p.firstChild.data.length;
   2014  // If invisible white-spaces are deleted, they should be contained in the target range.
   2015  checkEditorContentResultAsSubTest(
   2016    `<p>${invisibleWhiteSpaces + kText.substr(0, startOffset) + kText.substr(startOffset + length)}</p>`,
   2017    t.name,
   2018    { ignoreWhiteSpaceDifference: true }
   2019  );
   2020  if (startOffset === kText.length) {
   2021    checkBeforeinputAndInputEventsOnNOOP();
   2022    return;
   2023  }
   2024  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   2025    startContainer: p.firstChild,
   2026    startOffset: startOffset,
   2027    endContainer: p.firstChild,
   2028    endOffset: startOffset + length,
   2029  });
   2030  checkGetTargetRangesOfInputOnDeleteSomething();
   2031 }, 'Control + Backspace at "<p>   abc[] def</p>"');
   2032 
   2033 promise_test(async (t) => {
   2034  const kText = "abc def";
   2035  initializeTest(`<p>   ${kText}</p>`);
   2036  let p = gEditor.querySelector("p");
   2037  gSelection.collapse(p.firstChild, "abc".length);
   2038  await sendBackspaceKey(kAlt);
   2039  let visibleText = p.firstChild.data.replace(/^\s+/, "");
   2040  let invisibleWhiteSpaces = " ".repeat(p.firstChild.data.length - visibleText.length);
   2041  let startOffset = invisibleWhiteSpaces.length + getFirstDifferentOffset(visibleText, kText);
   2042  let length = kText.length + 3 - p.firstChild.data.length;
   2043  // If invisible white-spaces are deleted, they should be contained in the target range.
   2044  checkEditorContentResultAsSubTest(
   2045    `<p>${invisibleWhiteSpaces + kText.substr(0, startOffset) + kText.substr(startOffset + length)}</p>`,
   2046    t.name,
   2047    { ignoreWhiteSpaceDifference: true }
   2048  );
   2049  if (startOffset === kText.length) {
   2050    checkBeforeinputAndInputEventsOnNOOP();
   2051    return;
   2052  }
   2053  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   2054    startContainer: p.firstChild,
   2055    startOffset: startOffset,
   2056    endContainer: p.firstChild,
   2057    endOffset: startOffset + length,
   2058  });
   2059  checkGetTargetRangesOfInputOnDeleteSomething();
   2060 }, 'Alt + Backspace at "<p>   abc[] def</p>"');
   2061 
   2062 promise_test(async (t) => {
   2063  const kText = "abc def";
   2064  initializeTest(`<p>   ${kText}</p>`);
   2065  let p = gEditor.querySelector("p");
   2066  gSelection.collapse(p.firstChild, "abc".length);
   2067  await sendBackspaceKey(kMeta);
   2068  let visibleText = p.firstChild.data.replace(/^\s+/, "");
   2069  let invisibleWhiteSpaces = " ".repeat(p.firstChild.data.length - visibleText.length);
   2070  let startOffset = invisibleWhiteSpaces.length + getFirstDifferentOffset(visibleText, kText);
   2071  let length = kText.length + 3 - p.firstChild.data.length;
   2072  // If invisible white-spaces are deleted, they should be contained in the target range.
   2073  checkEditorContentResultAsSubTest(
   2074    `<p>${invisibleWhiteSpaces + kText.substr(0, startOffset) + kText.substr(startOffset + length)}</p>`,
   2075    t.name
   2076  );
   2077  if (startOffset === kText.length) {
   2078    checkBeforeinputAndInputEventsOnNOOP();
   2079    return;
   2080  }
   2081  checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   2082    startContainer: p.firstChild,
   2083    startOffset: startOffset,
   2084    endContainer: p.firstChild,
   2085    endOffset: startOffset + length,
   2086  });
   2087  checkGetTargetRangesOfInputOnDeleteSomething();
   2088 }, 'Meta + Backspace at "<p>   abc[] def</p>"');
   2089 
   2090 // If editing host is nested, editing in the nested one shouldn't cause
   2091 // target ranges extended to outside of it.
   2092 promise_test(async t => {
   2093  const innerHTML = "<div contenteditable=\"false\"><div contenteditable=\"\"><p><br></p></div></div>";
   2094  initializeTest(innerHTML);
   2095  const p = gEditor.querySelector("p");
   2096  const innerEditingHost = p.parentNode;
   2097  document.activeElement?.blur();
   2098  p.parentNode.focus();
   2099  gSelection.collapse(p, 0);
   2100  await sendBackspaceKey();
   2101  if (gEditor.innerHTML == innerHTML) {
   2102    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   2103      startContainer: p,
   2104      startOffset: 0,
   2105      endContainer: p,
   2106      endOffset: 0,
   2107    });
   2108    checkGetTargetRangesOfInputOnDoNothing();
   2109  } else {
   2110    checkEditorContentResultAsSubTest(
   2111      "<div contenteditable=\"false\"><div contenteditable=\"\"><br></div></div>",
   2112      t.name
   2113    );
   2114    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   2115      startContainer: innerEditingHost,
   2116      startOffset: 0,
   2117      endContainer: p,
   2118      endOffset: 1,
   2119    });
   2120    checkGetTargetRangesOfInputOnDeleteSomething();
   2121  }
   2122 }, 'Backspace at "<div contenteditable="false"><div contenteditable=""><p>{}<br></p></div></div>');
   2123 
   2124 promise_test(async t => {
   2125  const innerHTML = "<div contenteditable=\"false\">\n  <div contenteditable=\"\"><p><br></p></div></div>";
   2126  initializeTest(innerHTML);
   2127  const p = gEditor.querySelector("p");
   2128  const innerEditingHost = p.parentNode;
   2129  document.activeElement?.blur();
   2130  p.parentNode.focus();
   2131  gSelection.collapse(p, 0);
   2132  await sendBackspaceKey();
   2133  if (gEditor.innerHTML == innerHTML) {
   2134    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   2135      startContainer: p,
   2136      startOffset: 0,
   2137      endContainer: p,
   2138      endOffset: 0,
   2139    });
   2140    checkGetTargetRangesOfInputOnDoNothing();
   2141  } else {
   2142    checkEditorContentResultAsSubTest(
   2143      "<div contenteditable=\"false\">\n  <div contenteditable=\"\"><br></div></div>",
   2144      t.name
   2145    );
   2146    checkGetTargetRangesOfBeforeinputOnDeleteSomething({
   2147      startContainer: innerEditingHost,
   2148      startOffset: 0,
   2149      endContainer: p,
   2150      endOffset: 1,
   2151    });
   2152    checkGetTargetRangesOfInputOnDeleteSomething();
   2153  }
   2154 }, 'Backspace at "<div contenteditable="false">\n  <div contenteditable=""><p>{}<br></p></div></div>');
   2155 
   2156 </script>