test_bug1230473.html (4920B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=1230473 5 --> 6 <head> 7 <meta charset="utf-8"> 8 <title>Test for Bug 1230473</title> 9 <script src="/tests/SimpleTest/SimpleTest.js"></script> 10 <script src="/tests/SimpleTest/EventUtils.js"></script> 11 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 12 </head> 13 <body> 14 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1230473">Mozilla Bug 1230473</a> 15 <input id="input"> 16 <textarea id="textarea"></textarea> 17 <div id="div" contenteditable></div> 18 <script type="application/javascript"> 19 /** Test for Bug 1230473 */ 20 SimpleTest.waitForExplicitFinish(); 21 SimpleTest.waitForFocus(() => { 22 function runTest(aEditor) { 23 function committer() { 24 aEditor.blur(); 25 aEditor.focus(); 26 } 27 function isNSEditableElement() { 28 return aEditor.tagName.toLowerCase() == "input" || aEditor.tagName.toLowerCase() == "textarea"; 29 } 30 function value() { 31 return isNSEditableElement() ? aEditor.value : aEditor.textContent; 32 } 33 function isComposing() { 34 return isNSEditableElement() ? SpecialPowers.wrap(aEditor) 35 .editor 36 .composing : 37 SpecialPowers.wrap(window) 38 .docShell 39 .editor 40 .composing; 41 } 42 function clear() { 43 if (isNSEditableElement()) { 44 aEditor.value = ""; 45 } else { 46 aEditor.textContent = ""; 47 } 48 } 49 50 clear(); 51 52 // FYI: Chrome commits composition if blur() and focus() are called during 53 // composition. But note that if they are called by compositionupdate 54 // listener, the behavior is unstable. On Windows, composition is 55 // canceled. On Linux and macOS, the composition is committed 56 // internally but the string keeps underlined. If they are called 57 // by input event listener, committed on any platforms though. 58 // On the other hand, Edge and Safari keeps composition even with 59 // calling both blur() and focus(). 60 61 // Committing at compositionstart 62 aEditor.focus(); 63 aEditor.addEventListener("compositionstart", committer, true); 64 synthesizeCompositionChange({ composition: { string: "a", clauses: [{length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }] }, 65 caret: { start: 1, length: 0 }, key: { key: "a" }}); 66 aEditor.removeEventListener("compositionstart", committer, true); 67 ok(!isComposing(), "composition in " + aEditor.id + " should be committed by compositionstart event handler"); 68 is(value(), "", "composition in " + aEditor.id + " shouldn't insert any text since it's committed at compositionstart"); 69 clear(); 70 71 // Committing at first compositionupdate 72 aEditor.focus(); 73 aEditor.addEventListener("compositionupdate", committer, true); 74 synthesizeCompositionChange({ composition: { string: "a", clauses: [{length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }] }, 75 caret: { start: 1, length: 0 }, key: { key: "a" }}); 76 aEditor.removeEventListener("compositionupdate", committer, true); 77 ok(!isComposing(), "composition in " + aEditor.id + " should be committed by compositionupdate event handler"); 78 is(value(), "a", "composition in " + aEditor.id + " should have \"a\" since IME committed with it"); 79 clear(); 80 81 // Committing at second compositionupdate 82 aEditor.focus(); 83 // FYI: "compositionstart" will be dispatched automatically. 84 synthesizeCompositionChange({ composition: { string: "a", clauses: [{length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }] }, 85 caret: { start: 1, length: 0 }, key: { key: "a" }}); 86 ok(isComposing(), "composition should be in " + aEditor.id + " before dispatching second compositionupdate"); 87 is(value(), "a", "composition in " + aEditor.id + " should be 'a' before dispatching second compositionupdate"); 88 aEditor.addEventListener("compositionupdate", committer, true); 89 synthesizeCompositionChange({ composition: { string: "ab", clauses: [{length: 2, attr: COMPOSITION_ATTR_RAW_CLAUSE }] }, 90 caret: { start: 2, length: 0 }, key: { key: "b" }}); 91 aEditor.removeEventListener("compositionupdate", committer, true); 92 ok(!isComposing(), "composition in " + aEditor.id + " should be committed by compositionupdate event handler"); 93 is(value(), "ab", "composition in " + aEditor.id + " should have \"ab\" since IME committed with it"); 94 clear(); 95 } 96 runTest(document.getElementById("input")); 97 runTest(document.getElementById("textarea")); 98 runTest(document.getElementById("div")); 99 SimpleTest.finish(); 100 }); 101 </script> 102 </body> 103 </html>