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 );