tor-browser

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

modify-around-inline-element-boundary.tentative.html (10339B)


      1 <!doctype html>
      2 <html>
      3 <head>
      4 <meta charset="utf-8">
      5 <title>Test Selection.modify("move", "left" or "right", "character") around inline element boundaries</title>
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <script src="../../editing/include/editor-test-utils.js"></script>
      9 <script>
     10 "use strict";
     11 
     12 addEventListener("load", () => {
     13  const testContainer = document.getElementById("testBody");
     14  function stringifySelectionRanges() {
     15    let result = "[";
     16    for (let i = 0; i < getSelection().rangeCount; i++) {
     17      const range = getSelection().getRangeAt(i);
     18      if (result != "[") {
     19        result += ", "
     20      }
     21      result += EditorTestUtils.getRangeDescription(range);
     22    }
     23    return result + "]";
     24  }
     25  function stringifyExpectedRange(expectedRange) {
     26    return `[${EditorTestUtils.getRangeDescription({
     27      startContainer: expectedRange.container,
     28      startOffset: expectedRange.offset,
     29      endContainer: expectedRange.container,
     30      endOffset: expectedRange.offset,
     31    })}]`;
     32  }
     33  for (const data of [
     34    // Basic tests. If moving caret from middle of a Text, shouldn't go out different Text.
     35    // This allows users preserve style at previous cursor position for the new text.
     36    {
     37      innerHTML: "ab[]c<span>def</span>",
     38      direction: "right",
     39      expectedResult: function () {
     40        return { container: testContainer.firstChild, offset: "abc".length };
     41      },
     42    },
     43    {
     44      innerHTML: "abc[]<span>def</span>",
     45      direction: "right",
     46      expectedResult: function () {
     47        return { container: testContainer.querySelector("span").firstChild, offset: "d".length };
     48      },
     49    },
     50    {
     51      innerHTML: "<b>ab[]c</b><i>def</i>",
     52      direction: "right",
     53      expectedResult: function () {
     54        return { container: testContainer.querySelector("b").firstChild, offset: "abc".length };
     55      },
     56    },
     57    {
     58      innerHTML: "<b>abc[]</b><i>def</i>",
     59      direction: "right",
     60      expectedResult: function () {
     61        return { container: testContainer.querySelector("i").firstChild, offset: "d".length };
     62      },
     63    },
     64    {
     65      innerHTML: "abc<span>d[]ef</span>",
     66      direction: "left",
     67      expectedResult: function () {
     68        return { container: testContainer.querySelector("span").firstChild, offset: 0 };
     69      },
     70    },
     71    {
     72      innerHTML: "abc<span>[]def</span>",
     73      direction: "left",
     74      expectedResult: function () {
     75        return { container: testContainer.firstChild, offset: "ab".length };
     76      },
     77    },
     78    {
     79      innerHTML: "<b>abc</b><i>d[]ef</i>",
     80      direction: "left",
     81      expectedResult: function () {
     82        return { container: testContainer.querySelector("i").firstChild, offset: 0 };
     83      },
     84    },
     85    {
     86      innerHTML: "<b>abc</b><i>[]def</i>",
     87      direction: "left",
     88      expectedResult: function () {
     89        return { container: testContainer.querySelector("b").firstChild, offset: "ab".length };
     90      },
     91    },
     92    // Don't skip visible white-space around the inline element boundaries.
     93    {
     94      innerHTML: "abc[] <span>def</span>",
     95      direction: "right",
     96      expectedResult: function () {
     97        return { container: testContainer.firstChild, offset: "abc ".length };
     98      },
     99    },
    100    {
    101      innerHTML: "abc[]<span> def</span>",
    102      direction: "right",
    103      expectedResult: function () {
    104        return { container: testContainer.querySelector("span").firstChild, offset: " ".length };
    105      },
    106    },
    107    {
    108      innerHTML: "abc <span>[]def</span>",
    109      direction: "left",
    110      expectedResult: function () {
    111        return { container: testContainer.firstChild, offset: "abc".length };
    112      },
    113    },
    114    {
    115      innerHTML: "abc<span> []def</span>",
    116      direction: "left",
    117      expectedResult: function () {
    118        return { container: testContainer.querySelector("span").firstChild, offset: 0 };
    119      },
    120    },
    121 
    122    // Skip invisible white-spaces around the inline element boundaries.
    123 
    124    // Only the first white-space should be visible when multiple spaces are collapsed.
    125    // Therefore, the following tests expect that selection is collapsed after the first white-space.
    126    {
    127      innerHTML: "abc[]  <span>def</span>",
    128      direction: "right",
    129      expectedResult: function () {
    130        return { container: testContainer.firstChild, offset: "abc ".length };
    131      },
    132    },
    133    {
    134      innerHTML: "abc[] <span> def</span>",
    135      direction: "right",
    136      expectedResult: function () {
    137        return { container: testContainer.firstChild, offset: "abc ".length };
    138      },
    139    },
    140    {
    141      innerHTML: "abc[]<span>  def</span>",
    142      direction: "right",
    143      expectedResult: function () {
    144        return { container: testContainer.querySelector("span").firstChild, offset: " ".length };
    145      },
    146    },
    147    {
    148      innerHTML: "<span>abc[]  </span>def",
    149      direction: "right",
    150      expectedResult: function () {
    151        return { container: testContainer.querySelector("span").firstChild, offset: "abc ".length };
    152      },
    153    },
    154    {
    155      innerHTML: "<span>abc[] </span> def",
    156      direction: "right",
    157      expectedResult: function () {
    158        return { container: testContainer.querySelector("span").firstChild, offset: "abc ".length };
    159      },
    160    },
    161    {
    162      innerHTML: "<span>abc[]</span>  def",
    163      direction: "right",
    164      expectedResult: function () {
    165        return { container: testContainer.lastChild, offset: " ".length };
    166      },
    167    },
    168    // Similarly, these tests expect that selection is collapsed before the first white-space.
    169    {
    170      innerHTML: "abc  <span>[]def</span>",
    171      direction: "left",
    172      expectedResult: function () {
    173        return { container: testContainer.firstChild, offset: "abc".length };
    174      },
    175    },
    176    {
    177      innerHTML: "abc <span> []def</span>",
    178      direction: "left",
    179      expectedResult: function () {
    180        return { container: testContainer.firstChild, offset: "abc".length };
    181      },
    182    },
    183    {
    184      innerHTML: "abc<span>  []def</span>",
    185      direction: "left",
    186      expectedResult: function () {
    187        return { container: testContainer.querySelector("span").firstChild, offset: 0 };
    188      },
    189    },
    190    {
    191      innerHTML: "<span>abc  </span>[]def",
    192      direction: "left",
    193      expectedResult: function () {
    194        return { container: testContainer.querySelector("span").firstChild, offset: "abc".length };
    195      },
    196    },
    197    {
    198      innerHTML: "<span>abc </span> []def",
    199      direction: "left",
    200      expectedResult: function () {
    201        return { container: testContainer.querySelector("span").firstChild, offset: "abc".length };
    202      },
    203    },
    204    {
    205      innerHTML: "<span>abc</span>  []def",
    206      direction: "left",
    207      expectedResult: function () {
    208        return { container: testContainer.lastChild, offset: 0 };
    209      },
    210    },
    211    // Invisible white-spaces must be skipped by modify().
    212    {
    213      innerHTML: "abc[]  <span>def</span>",
    214      direction: "right",
    215      repeat: 2,
    216      expectedResult: function () {
    217        return { container: testContainer.querySelector("span").firstChild, offset: "d".length };
    218      },
    219    },
    220    {
    221      innerHTML: "abc[] <span> def</span>",
    222      direction: "right",
    223      repeat: 2,
    224      expectedResult: function () {
    225        return { container: testContainer.querySelector("span").firstChild, offset: " d".length };
    226      },
    227    },
    228    {
    229      innerHTML: "abc[]<span>  def</span>",
    230      direction: "right",
    231      repeat: 2,
    232      expectedResult: function () {
    233        return { container: testContainer.querySelector("span").firstChild, offset: "  d".length };
    234      },
    235    },
    236    {
    237      innerHTML: "<span>abc[]  </span>def",
    238      direction: "right",
    239      repeat: 2,
    240      expectedResult: function () {
    241        return { container: testContainer.lastChild, offset: "d".length };
    242      },
    243    },
    244    {
    245      innerHTML: "<span>abc[] </span> def",
    246      direction: "right",
    247      repeat: 2,
    248      expectedResult: function () {
    249        return { container: testContainer.lastChild, offset: " d".length };
    250      },
    251    },
    252    {
    253      innerHTML: "<span>abc[]</span>  def",
    254      direction: "right",
    255      repeat: 2,
    256      expectedResult: function () {
    257        return { container: testContainer.lastChild, offset: "  d".length };
    258      },
    259    },
    260    {
    261      innerHTML: "abc  <span>[]def</span>",
    262      direction: "left",
    263      repeat: 2,
    264      expectedResult: function () {
    265        return { container: testContainer.firstChild, offset: "ab".length };
    266      },
    267    },
    268    {
    269      innerHTML: "abc <span> []def</span>",
    270      direction: "left",
    271      repeat: 2,
    272      expectedResult: function () {
    273        return { container: testContainer.firstChild, offset: "ab".length };
    274      },
    275    },
    276    {
    277      innerHTML: "abc<span>  []def</span>",
    278      direction: "left",
    279      repeat: 2,
    280      expectedResult: function () {
    281        return { container: testContainer.firstChild, offset: "ab".length };
    282      },
    283    },
    284    {
    285      innerHTML: "<span>abc  </span>[]def",
    286      direction: "left",
    287      repeat: 2,
    288      expectedResult: function () {
    289        return { container: testContainer.querySelector("span").firstChild, offset: "ab".length };
    290      },
    291    },
    292    {
    293      innerHTML: "<span>abc </span> []def",
    294      direction: "left",
    295      repeat: 2,
    296      expectedResult: function () {
    297        return { container: testContainer.querySelector("span").firstChild, offset: "ab".length };
    298      },
    299    },
    300    {
    301      innerHTML: "<span>abc</span>  []def",
    302      direction: "left",
    303      repeat: 2,
    304      expectedResult: function () {
    305        return { container: testContainer.querySelector("span").firstChild, offset: "ab".length };
    306      },
    307    },
    308  ]) {
    309    test(() => {
    310      const utils = new EditorTestUtils(testContainer);
    311      utils.setupEditingHost(data.innerHTML);
    312      for (let i = 0; i < (data.repeat ?? 1); i++) {
    313        getSelection().modify("move", data.direction, "character");
    314      }
    315      assert_equals(
    316        stringifySelectionRanges(),
    317        stringifyExpectedRange(data.expectedResult())
    318      );
    319    }, `Selection.modify("move", "${data.direction}", "character")${
    320      data.repeat > 1 ? ` (${data.repeat} times)` : ""
    321    } when "${data.innerHTML}"`);
    322  }
    323 }, {once: true});
    324 </script>
    325 </head>
    326 <body>
    327  <div id="testBody" contenteditable></div>
    328 </body>
    329 </html>