tor-browser

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

browser_text_spelling.js (4492B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 /* import-globals-from ../../mochitest/text.js */
      8 /* import-globals-from ../../mochitest/attributes.js */
      9 loadScripts({ name: "attributes.js", dir: MOCHITESTS_DIR });
     10 
     11 const boldAttrs = { "font-weight": "700" };
     12 
     13 /*
     14 * Given a text accessible and a list of ranges
     15 * check if those ranges match the misspelled ranges in the accessible.
     16 */
     17 function misspelledRangesMatch(acc, ranges) {
     18  return textAttrRangesMatch(acc, ranges, { invalid: "spelling" });
     19 }
     20 
     21 /*
     22 * Returns a promise that resolves after a text attribute changed event
     23 * brings us to a state where the misspelled ranges match.
     24 */
     25 async function waitForMisspelledRanges(acc, ranges) {
     26  await waitForEvent(EVENT_TEXT_ATTRIBUTE_CHANGED);
     27  await untilCacheOk(
     28    () => misspelledRangesMatch(acc, ranges),
     29    `Misspelled ranges match: ${JSON.stringify(ranges)}`
     30  );
     31 }
     32 
     33 /**
     34 * Test spelling errors.
     35 */
     36 addAccessibleTask(
     37  `
     38 <textarea id="textarea" spellcheck="true">test tset tset test</textarea>
     39 <div contenteditable id="editable" spellcheck="true">plain<span> ts</span>et <b>bold</b></div>
     40  `,
     41  async function (browser, docAcc) {
     42    const textarea = findAccessibleChildByID(docAcc, "textarea", [
     43      nsIAccessibleText,
     44    ]);
     45    info("Focusing textarea");
     46    let spellingChanged = waitForMisspelledRanges(textarea, [
     47      [5, 9],
     48      [10, 14],
     49    ]);
     50    textarea.takeFocus();
     51    await spellingChanged;
     52 
     53    // Test removal of a spelling error.
     54    info('textarea: Changing first "tset" to "test"');
     55    // setTextRange fires multiple EVENT_TEXT_ATTRIBUTE_CHANGED, so replace by
     56    // selecting and typing instead.
     57    spellingChanged = waitForMisspelledRanges(textarea, [[10, 14]]);
     58    await invokeContentTask(browser, [], () => {
     59      content.document.getElementById("textarea").setSelectionRange(5, 9);
     60    });
     61    EventUtils.sendString("test");
     62    // Move the cursor to trigger spell check.
     63    EventUtils.synthesizeKey("KEY_ArrowRight");
     64    await spellingChanged;
     65 
     66    // Test addition of a spelling error.
     67    info('textarea: Changing it back to "tset"');
     68    spellingChanged = waitForMisspelledRanges(textarea, [
     69      [5, 9],
     70      [10, 14],
     71    ]);
     72    await invokeContentTask(browser, [], () => {
     73      content.document.getElementById("textarea").setSelectionRange(5, 9);
     74    });
     75    EventUtils.sendString("tset");
     76    EventUtils.synthesizeKey("KEY_ArrowRight");
     77    await spellingChanged;
     78 
     79    // Ensure that changing the text without changing any spelling errors
     80    // correctly updates offsets.
     81    info('textarea: Changing first "test" to "the"');
     82    // Spelling errors don't change, so we won't get
     83    // EVENT_TEXT_ATTRIBUTE_CHANGED. We change the text, wait for the insertion
     84    // and then select a character so we know when the change is done.
     85    let inserted = waitForEvent(EVENT_TEXT_INSERTED, textarea);
     86    await invokeContentTask(browser, [], () => {
     87      content.document.getElementById("textarea").setSelectionRange(0, 4);
     88    });
     89    EventUtils.sendString("the");
     90    await inserted;
     91    let selected = waitForEvent(EVENT_TEXT_SELECTION_CHANGED, textarea);
     92    EventUtils.synthesizeKey("KEY_ArrowRight", { shiftKey: true });
     93    await selected;
     94    const expectedRanges = [
     95      [4, 8],
     96      [9, 13],
     97    ];
     98    await untilCacheOk(
     99      () => misspelledRangesMatch(textarea, expectedRanges),
    100      `Misspelled ranges match: ${JSON.stringify(expectedRanges)}`
    101    );
    102 
    103    const editable = findAccessibleChildByID(docAcc, "editable", [
    104      nsIAccessibleText,
    105    ]);
    106    info("Focusing editable");
    107    spellingChanged = waitForMisspelledRanges(editable, [[6, 10]]);
    108    editable.takeFocus();
    109    await spellingChanged;
    110    // Test normal text and spelling errors crossing text nodes.
    111    testTextAttrs(editable, 0, {}, {}, 0, 6, true); // "plain "
    112    // Ensure we detect the spelling error even though there is a style change
    113    // after it.
    114    testTextAttrs(editable, 6, { invalid: "spelling" }, {}, 6, 10, true); // "tset"
    115    testTextAttrs(editable, 10, {}, {}, 10, 11, true); // " "
    116    // Ensure a style change is still detected in the presence of a spelling
    117    // error.
    118    testTextAttrs(editable, 11, boldAttrs, {}, 11, 15, true); // "bold"
    119  },
    120  {
    121    chrome: true,
    122    topLevel: true,
    123    iframe: true,
    124    remoteIframe: true,
    125  }
    126 );