tor-browser

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

initial-selection-on-focus.tentative.html (25218B)


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