tor-browser

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

test_spellcheck_after_edit.html (6589B)


      1 <!doctype html>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <title>Spellcheck result after edit</title>
      6  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      7  <link rel="stylesheet" href="/tests/SimpleTest/test.css">
      8 </head>
      9 <body>
     10 <script>
     11 let { maybeOnSpellCheck } = SpecialPowers.ChromeUtils.importESModule(
     12  "resource://testing-common/AsyncSpellCheckTestHelper.sys.mjs"
     13 );
     14 
     15 function waitForTick() {
     16  return new Promise(resolve =>
     17    SimpleTest.executeSoon(
     18      () => requestAnimationFrame(
     19        () => requestAnimationFrame(resolve)
     20      )
     21    )
     22  );
     23 }
     24 
     25 async function waitForOnSpellCheck(
     26  aSpellCheckSelection,
     27  aEditingHost,
     28  aWaitForNumberOfMisspelledWords,
     29  aWhen
     30 ) {
     31  info(`Waiting for onSpellCheck (${aWhen})...`);
     32  for (let retry = 0; retry < 100; retry++) {
     33    await waitForTick();
     34    await new Promise(resolve => maybeOnSpellCheck(aEditingHost, resolve));
     35    if (aWaitForNumberOfMisspelledWords === 0) {
     36      if (aSpellCheckSelection.rangeCount === 0) {
     37        break;
     38      }
     39    } else if (aSpellCheckSelection.rangeCount >= aWaitForNumberOfMisspelledWords) {
     40      break;
     41    }
     42  }
     43 }
     44 
     45 SimpleTest.waitForExplicitFinish();
     46 SimpleTest.waitForFocus(async () => {
     47  /**
     48   * test object should have:
     49   *   init function
     50   *
     51   *     @param normalSel       The normal selection for the editing host
     52   *     @param editingHost     The editing host of the editor
     53   *     @return                Number of misspelled word in the editor
     54   *
     55   *  run function
     56   *
     57   *     @param editingHost     The editing host of the editor
     58   *     @return                Expected number of misspelled word in the editor
     59   *
     60   *  check function
     61   *
     62   *     @param spellCheckSel   The spellcheck selection for the editing host
     63   *     @param editingHost     The editing host of the editor
     64   */
     65  for (const test of [
     66      {
     67        init: (normalSel, editingHost) => {
     68          info("Staring to test spellcheck of misspelled word after joining paragraphs");
     69          editingHost.innerHTML = "<p>It is</p><p>what I want</p>";
     70          normalSel.collapse(editingHost.querySelector("p + p").firstChild, 0);
     71          return 0;
     72        },
     73        run: () => {
     74          document.execCommand("delete");
     75          return 0;
     76        },
     77        check: (spellCheckSel) => {
     78          is(
     79            spellCheckSel.rangeCount,
     80            0,
     81            "The joined misspelled word shouldn't be marked as misspelled word because caret is in the word"
     82          );
     83        },
     84      },
     85      {
     86        init: (normalSel, editingHost) => {
     87          info("Staring to test spellcheck of correct word after joining paragraphs");
     88          editingHost.innerHTML = "<p>It's beco</p><p>ming nicer</p>";
     89          normalSel.collapse(editingHost.querySelector("p + p").firstChild, 0);
     90          return 2;
     91        },
     92        run: () => {
     93          document.execCommand("delete");
     94          return 0;
     95        },
     96        check: (spellCheckSel) => {
     97          is(
     98            spellCheckSel.rangeCount,
     99            0,
    100            "There shouldn't be misspelled word after joining separated word anyway"
    101          );
    102        },
    103      },
    104      {
    105        init: (normalSel, editingHost) => {
    106          info("Staring to test spellcheck of correct words after splitting a paragraph");
    107          editingHost.innerHTML = "<p>It iswhat I want</p>";
    108          normalSel.collapse(editingHost.querySelector("p").firstChild, "It is".length);
    109          return 1;
    110        },
    111        run: () => {
    112          document.execCommand("insertParagraph");
    113          return 0;
    114        },
    115        check: (spellCheckSel) => {
    116          is(
    117            spellCheckSel.rangeCount,
    118            0,
    119            "No word should be marked as misspelled after split"
    120          );
    121        },
    122      },
    123      {
    124        init: (normalSel, editingHost) => {
    125          info("Staring to test spellcheck of misspelled words after splitting a paragraph");
    126          editingHost.innerHTML = "<p>It's becoming nicer</p>";
    127          normalSel.collapse(editingHost.querySelector("p").firstChild, "It's beco".length);
    128          return 0;
    129        },
    130        run: () => {
    131          document.execCommand("insertParagraph");
    132          return 1;
    133        },
    134        check: (spellCheckSel, editingHost) => {
    135          is(
    136            spellCheckSel.rangeCount,
    137            1,
    138            "The split word in the first paragraph should be marked as misspelled, but the second paragraph's should be so because of caret is in it"
    139          );
    140          if (!spellCheckSel.rangeCount) {
    141            return;
    142          }
    143          is(
    144            SpecialPowers.unwrap(spellCheckSel.getRangeAt(0).startContainer),
    145            editingHost.querySelector("p").firstChild,
    146            "First misspelled word should start in the first child of the first <p>"
    147          );
    148          is(
    149            SpecialPowers.unwrap(spellCheckSel.getRangeAt(0).endContainer),
    150            editingHost.querySelector("p").firstChild,
    151            "First misspelled word should end in the first child of the first <p>"
    152          );
    153          is(
    154            spellCheckSel.getRangeAt(0).startOffset,
    155            "It's ".length,
    156            "First misspelled word should start after 'It '"
    157          );
    158          is(
    159            spellCheckSel.getRangeAt(0).endOffset,
    160            "It's beco".length,
    161            "First misspelled word should end by after 'bec'"
    162          );
    163        },
    164      },
    165    ]) {
    166    const editingHost = document.createElement("div");
    167    editingHost.setAttribute("contenteditable", "");
    168    editingHost.setAttribute("spellcheck", "true");
    169    document.body.appendChild(editingHost);
    170    editingHost.focus();
    171    const editor =
    172      SpecialPowers.wrap(window).docShell.editingSession.getEditorForWindow(window);
    173    const nsISelectionController = SpecialPowers.Ci.nsISelectionController;
    174    const normalSel = editor.selectionController.getSelection(
    175        nsISelectionController.SELECTION_NORMAL
    176    );
    177    const spellCheckSel = editor.selectionController.getSelection(
    178      nsISelectionController.SELECTION_SPELLCHECK
    179    );
    180    const initialMisspelledWords = test.init(normalSel, editingHost);
    181    await waitForOnSpellCheck(
    182      spellCheckSel, editingHost, initialMisspelledWords, "before edit"
    183    );
    184    await waitForTick();
    185    const expectedMisspelledWords = test.run(editingHost);
    186    await waitForOnSpellCheck(
    187      spellCheckSel, editingHost, expectedMisspelledWords, "after edit"
    188    );
    189    test.check(spellCheckSel, editingHost);
    190    editingHost.remove();
    191    await waitForTick();
    192  }
    193  SimpleTest.finish();
    194 });
    195 </script>
    196 </body>
    197 </html>