test_selection_at_beforeinput_insertReplacementText.html (5046B)
1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Selection should select the target misspelled word before `beforeinput` event</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <script src="/tests/SimpleTest/EventUtils.js"></script> 8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"> 9 <script> 10 "use strict"; 11 12 SimpleTest.waitForExplicitFinish(); 13 SimpleTest.waitForFocus(async () => { 14 const { maybeOnSpellCheck } = SpecialPowers.ChromeUtils.importESModule( 15 "resource://testing-common/AsyncSpellCheckTestHelper.sys.mjs" 16 ); 17 18 function testTextEditor(aTextControl) { 19 const description = aTextControl.localName; 20 aTextControl.setAttribute("spellcheck", "true"); 21 aTextControl.value = "abc abx abc"; 22 aTextControl.focus(); 23 24 const textEditor = SpecialPowers.wrap(aTextControl).editor; 25 const inlineSpellChecker = textEditor.getInlineSpellChecker(true); 26 27 return new Promise(resolve => { 28 maybeOnSpellCheck(aTextControl, () => { 29 aTextControl.addEventListener("beforeinput", event => { 30 is( 31 `${event.type} (inputType=${event.inputType}), selectionStart=${ 32 aTextControl.selectionStart 33 }, selectionEnd=${aTextControl.selectionEnd}`, 34 "beforeinput (inputType=insertReplacementText), selectionStart=4, selectionEnd=7", 35 `${description}: Selection should select the replacing word` 36 ); 37 resolve(); 38 }, {once: true}); 39 aTextControl.selectionStart = aTextControl.selectionEnd = 5; 40 const misspelledWord = inlineSpellChecker.getMisspelledWord(textEditor.rootElement.firstChild, 5); 41 is( 42 `${misspelledWord.startOffset}-${misspelledWord.endOffset}`, 43 "4-7", 44 `${description}: misspelled word range should be "abc [abx] abc"` 45 ); 46 info(`${description}: Replacing "abx" with "aux"...`); 47 inlineSpellChecker.replaceWord(textEditor.rootElement.firstChild, 5, "aux"); 48 }); 49 }); 50 } 51 await testTextEditor(document.querySelector("input")); 52 await testTextEditor(document.querySelector("textarea")); 53 54 function testContentEditable(aEditingHost) { 55 const description = "contenteditable"; 56 aEditingHost.setAttribute("spellcheck", "true"); 57 aEditingHost.textContent = "abc abx abc"; 58 aEditingHost.focus(); 59 60 const htmlEditor = SpecialPowers.wrap(window).docShell.editingSession.getEditorForWindow(window); 61 const inlineSpellChecker = htmlEditor.getInlineSpellChecker(true); 62 63 return new Promise(resolve => { 64 maybeOnSpellCheck(aEditingHost, async () => { 65 await new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r))); 66 function getRangeDescription(range) { 67 function getNodeDescription(node) { 68 if (!node) { 69 return "null"; 70 } 71 switch (node.nodeType) { 72 case Node.TEXT_NODE: 73 return `${node.nodeName} "${node.data}"`; 74 case Node.ELEMENT_NODE: 75 return `<${node.nodeName.toLowerCase()}>`; 76 default: 77 return `${node.nodeName}`; 78 } 79 } 80 if (range === null) { 81 return "null"; 82 } 83 if (range === undefined) { 84 return "undefined"; 85 } 86 return range.startContainer == range.endContainer && 87 range.startOffset == range.endOffset 88 ? `(${getNodeDescription(range.startContainer)}, ${range.startOffset})` 89 : `(${getNodeDescription(range.startContainer)}, ${ 90 range.startOffset 91 }) - (${getNodeDescription(range.endContainer)}, ${range.endOffset})`; 92 } 93 aEditingHost.addEventListener("beforeinput", event => { 94 is( 95 `${event.type} (inputType=${event.inputType}), selection=${getRangeDescription(getSelection().getRangeAt(0))}`, 96 `beforeinput (inputType=insertReplacementText), selection=${getRangeDescription({ 97 startContainer: aEditingHost.firstChild, 98 startOffset: 4, 99 endContainer: aEditingHost.firstChild, 100 endOffset: 7, 101 })}`, 102 `${description}: Selection should select the replacing word` 103 ); 104 resolve(); 105 }, {once: true}); 106 getSelection().collapse(aEditingHost.firstChild, 5); 107 const misspelledWord = inlineSpellChecker.getMisspelledWord(aEditingHost.firstChild, 5); 108 is( 109 `${misspelledWord.startOffset}-${misspelledWord.endOffset}`, 110 "4-7", 111 `${description}: misspelled word range should be "abc [abx] abc"` 112 ); 113 info(`${description}: Replacing "abx" with "aux"...`); 114 inlineSpellChecker.replaceWord(aEditingHost.firstChild, 5, "aux"); 115 }); 116 }); 117 } 118 await testContentEditable(document.querySelector("div[contenteditable]")); 119 120 SimpleTest.finish(); 121 }); 122 </script> 123 </head> 124 <body> 125 <input> 126 <textarea></textarea> 127 <div contenteditable></div> 128 </body> 129 </html>