tor-browser

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

insert-text-in-void-element.tentative.html (10742B)


      1 <!doctype html>
      2 <meta charset=utf-8>
      3 <title>Test insertText when selection collapsed in void element</title>
      4 <meta name="timeout" content="long">
      5 <script src=/resources/testharness.js></script>
      6 <script src=/resources/testharnessreport.js></script>
      7 <div contenteditable></div>
      8 <script>
      9 "use strict";
     10 
     11 const voidElements = [
     12  "br",
     13  "embed",
     14  "hr",
     15  "img",
     16  "input",
     17  "wbr",
     18 ];
     19 
     20 // This test tests whether the inserted text is inserted into, when selection
     21 // is collapsed in the void element.  The expected results are based on Blink,
     22 // but the results of <embed> and <wbr> elements are not consistent with the
     23 // other elements'.  Therefore, Blink also does not pass some of the following
     24 // tests.
     25 // FYI: This cannot be tested by editing/run because there is no way to collapse
     26 //      selection into a void element with the framework.
     27 
     28 const editor = document.querySelector("div[contenteditable]");
     29 for (const tag of voidElements) {
     30  test(() => {
     31    editor.innerHTML = `<div></div>`;
     32    const element = document.createElement(tag);
     33    editor.firstChild.appendChild(element);
     34    editor.focus();
     35    const selection = getSelection();
     36    selection.collapse(element, 0);
     37    document.execCommand("insertText", false, "abc");
     38    if (tag == "br") {
     39      assert_in_array(
     40        editor.innerHTML,
     41        [
     42          "<div>abc</div>",
     43          "<div>abc<br></div>",
     44        ],
     45        `The text should be inserted before the <br> element`
     46      );
     47    } else {
     48      assert_in_array(
     49        editor.innerHTML,
     50        [
     51          `<div>abc<${tag}></div>`,
     52          `<div>abc<${tag}><br></div>`,
     53        ],
     54        `The text should be inserted before the <${tag}> element`
     55      );
     56    }
     57  }, `Inserting text when selection is collapsed in <${tag}> which is only child`);
     58 
     59  test(() => {
     60    editor.innerHTML = `<div></div>`;
     61    const element = document.createElement(tag);
     62    editor.firstChild.appendChild(element);
     63    editor.focus();
     64    const selection = getSelection();
     65    selection.collapse(element, 0);
     66    element.getBoundingClientRect();
     67    document.execCommand("insertText", false, "abc");
     68    if (tag == "br") {
     69      assert_in_array(
     70        editor.innerHTML,
     71        [
     72          "<div>abc</div>",
     73          "<div>abc<br></div>",
     74        ],
     75        `The text should be inserted before the <br> element`
     76      );
     77    } else {
     78      assert_in_array(
     79        editor.innerHTML,
     80        [
     81          `<div>abc<${tag}></div>`,
     82          `<div>abc<${tag}><br></div>`,
     83        ],
     84        `The text should be inserted before the <${tag}> element`
     85      );
     86    }
     87  }, `Inserting text when selection is collapsed in <${tag}> which is only child (explicitly flushes maybe pending layout)`);
     88 
     89  test(() => {
     90    editor.innerHTML = `<div>abc</div>`;
     91    const element = document.createElement(tag);
     92    editor.firstChild.appendChild(element);
     93    editor.focus();
     94    const selection = getSelection();
     95    selection.collapse(element, 0);
     96    document.execCommand("insertText", false, "def");
     97    if (tag == "br") {
     98      assert_in_array(
     99        editor.innerHTML,
    100        [
    101          "<div>abcdef</div>",
    102          "<div>abcdef<br></div>",
    103        ],
    104        `The text should be inserted before the <br> element`
    105      );
    106    } else {
    107      assert_in_array(
    108        editor.innerHTML,
    109        [
    110          `<div>abcdef<${tag}></div>`,
    111          `<div>abcdef<${tag}><br></div>`,
    112        ],
    113        `The text should be inserted before the <${tag}> element`
    114      );
    115    }
    116  }, `Inserting text when selection is collapsed in <${tag}> which follows a text node`);
    117 
    118  test(() => {
    119    editor.innerHTML = `<div>def</div>`;
    120    const element = document.createElement(tag);
    121    editor.firstChild.insertBefore(element, editor.firstChild.firstChild);
    122    editor.focus();
    123    const selection = getSelection();
    124    selection.collapse(element, 0);
    125    document.execCommand("insertText", false, "abc");
    126    if (tag == "br") {
    127      assert_in_array(
    128        editor.innerHTML,
    129        [
    130          "<div>abc<br>def</div>",
    131          "<div>abc<br>def<br></div>",
    132        ],
    133        `The text should be inserted before the <br> element`
    134      );
    135    } else {
    136      assert_in_array(
    137        editor.innerHTML,
    138        [
    139          `<div>abc<${tag}>def</div>`,
    140          `<div>abc<${tag}>def<br></div>`,
    141        ],
    142        `The text should be inserted before the <${tag}> element`
    143      );
    144    }
    145  }, `Inserting text when selection is collapsed in <${tag}> which is followed by a text node`);
    146 
    147  test(() => {
    148    editor.innerHTML = `<div><span></span></div>`;
    149    const element = document.createElement(tag);
    150    editor.firstChild.appendChild(element);
    151    editor.focus();
    152    const selection = getSelection();
    153    selection.collapse(element, 0);
    154    document.execCommand("insertText", false, "abc");
    155    if (tag == "br") {
    156      assert_in_array(
    157        editor.innerHTML,
    158        [
    159          "<div><span></span>abc</div>",
    160          "<div><span></span>abc<br></div>",
    161        ],
    162        `The text should be inserted after the previous empty inline element of <br>`
    163      );
    164    } else if (tag == "input") { // visible inline?
    165      assert_in_array(
    166        editor.innerHTML,
    167        [
    168          `<div><span></span>abc<${tag}></div>`,
    169          `<div><span></span>abc<${tag}><br></div>`,
    170        ],
    171        `The text should be inserted after the previous empty inline element of <${tag}>`
    172      );
    173    } else if (tag == "hr") { // block
    174      assert_in_array(
    175        editor.innerHTML,
    176        [
    177          `<div><span></span>abc<${tag}></div>`,
    178          `<div><span></span>abc<br><${tag}></div>`,
    179        ],
    180        `The text should be inserted after the previous empty inline element of <${tag}>`
    181      );
    182    } else {
    183      assert_in_array(
    184        editor.innerHTML,
    185        [
    186          `<div>abc<span></span><${tag}></div>`,
    187          `<div>abc<span></span><${tag}><br></div>`,
    188        ],
    189        `The text should be inserted before the previous empty inline element of <${tag}>`
    190      );
    191    }
    192  }, `Inserting text when selection is collapsed in <${tag}> which follows an empty <span> element`);
    193 
    194  test(() => {
    195    editor.innerHTML = `<div>abc<span></span></div>`;
    196    const element = document.createElement(tag);
    197    editor.firstChild.appendChild(element);
    198    editor.focus();
    199    const selection = getSelection();
    200    selection.collapse(element, 0);
    201    document.execCommand("insertText", false, "def");
    202    if (tag == "br") {
    203      assert_in_array(
    204        editor.innerHTML,
    205        [
    206          "<div>abcdef<span></span></div>",
    207          "<div>abcdef<span></span><br></div>",
    208        ],
    209        `The text should be inserted at end of the first text node before empty <span> and <br>`
    210      );
    211    } else if (tag == "hr") { // block
    212      assert_in_array(
    213        editor.innerHTML,
    214        [
    215          `<div>abc<span></span>def<${tag}></div>`,
    216          `<div>abc<span></span>def<br><${tag}></div>`,
    217        ],
    218        `The text should be inserted after the previous empty inline element of <${tag}> even if the empty element follows a text node`
    219      );
    220    } else {
    221      assert_in_array(
    222        editor.innerHTML,
    223        [
    224          `<div>abcdef<span></span><${tag}></div>`,
    225          `<div>abcdef<span></span><${tag}><br></div>`,
    226        ],
    227        `The text should be inserted before the previous empty inline element of <${tag}>`
    228      );
    229    }
    230  }, `Inserting text when selection is collapsed in <${tag}> which follows a text node and an empty <span> element`);
    231 
    232  test(() => {
    233    editor.innerHTML = `<div><span>abc</span></div>`;
    234    const element = document.createElement(tag);
    235    editor.firstChild.appendChild(element);
    236    editor.focus();
    237    const selection = getSelection();
    238    selection.collapse(element, 0);
    239    document.execCommand("insertText", false, "def");
    240    if (tag == "br") {
    241      assert_in_array(
    242        editor.innerHTML,
    243        [
    244          "<div><span>abcdef</span></div>",
    245          "<div><span>abcdef</span><br></div>",
    246        ],
    247        `The text should be inserted at end of the text node in <span>`
    248      );
    249    } else if (tag == "hr") { // block
    250      assert_in_array(
    251        editor.innerHTML,
    252        [
    253          `<div><span>abc</span>def<${tag}></div>`,
    254          `<div><span>abc</span>def<br><${tag}></div>`,
    255        ],
    256        `The text should be inserted at after the span and before <${tag}>`
    257      );
    258    } else {
    259      assert_in_array(
    260        editor.innerHTML,
    261        [
    262          `<div><span>abcdef</span><${tag}></div>`,
    263          `<div><span>abcdef</span><${tag}><br></div>`,
    264        ],
    265        `The text should be inserted at end of the text node in <span> before <${tag}>`
    266      );
    267    }
    268  }, `Inserting text when selection is collapsed in <${tag}> which follows a non-empty <span> element`);
    269 
    270  test(() => {
    271    editor.innerHTML = `<div>abc<span></span>\n</div>`;
    272    const element = document.createElement(tag);
    273    editor.firstChild.appendChild(element);
    274    editor.focus();
    275    const selection = getSelection();
    276    selection.collapse(element, 0);
    277    document.execCommand("insertText", false, "def");
    278    if (tag == "br") {
    279      assert_in_array(
    280        editor.innerHTML.replace(/\n/g, " "),
    281        [
    282          "<div>abcdef<span></span></div>",
    283          "<div>abcdef<span></span><br></div>",
    284          "<div>abcdef<span></span> </div>",
    285          "<div>abcdef<span></span> <br></div>",
    286        ],
    287        `The text should be inserted at end of the first text node with ignoring the empty <span> and invisible text node before <br>`
    288      );
    289    } else if (tag == "img" || tag == "input") { // visible inline
    290      assert_in_array(
    291        editor.innerHTML.replace(/\n/g, " "),
    292        [
    293          `<div>abc<span></span> def<${tag}></div>`,
    294          `<div>abc<span></span> def<${tag}><br></div>`,
    295          `<div>abc<span></span>&nbsp;def<${tag}></div>`,
    296          `<div>abc<span></span>&nbsp;def<${tag}><br></div>`,
    297        ],
    298        `The text should be inserted at end of the last visible text node`
    299      );
    300    } else if (tag == "hr") { // block
    301      assert_in_array(
    302        editor.innerHTML,
    303        [
    304          `<div>abc<span></span>def<${tag}></div>`,
    305          `<div>abc<span></span>def<br><${tag}></div>`,
    306        ],
    307        `The text should be inserted after the previous empty inline element`
    308      );
    309    } else {
    310      assert_in_array(
    311        editor.innerHTML.replace(/\n/g, " "),
    312        [
    313          `<div>abcdef<span></span> <${tag}></div>`,
    314          `<div>abcdef<span></span> <${tag}><br></div>`,
    315        ],
    316        `The text should be inserted before the previous empty inline element`
    317      );
    318    }
    319  }, `Inserting text when selection is collapsed in <${tag}> which follows a text node, an empty <span> element and white-space only text node`);
    320 }
    321 
    322 </script>