| OLD | NEW |
| 1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> | 1 <!doctype html> |
| 2 <html> | 2 <script src="../../resources/testharness.js"></script> |
| 3 <head> | 3 <script src="../../resources/testharnessreport.js"></script> |
| 4 <script src="../../resources/js-test.js"></script> | 4 <script src="../assert_selection.js"></script> |
| 5 </head> | 5 <script src="spellcheck_test.js"></script> |
| 6 <body> | 6 |
| 7 <p id="description"></p> | |
| 8 <div id="console"></div> | |
| 9 <script> | 7 <script> |
| 10 description('For Bug 72939: Asynchronous SpellChecker should consider multiple r
equests.'); | 8 function pasteToAllChildren(text, container) { |
| 11 | 9 const document = container.ownerDocument; |
| 12 jsTestIsAsync = true; | 10 const selection = document.getSelection(); |
| 13 if (window.testRunner) | 11 selection.setClipboardData(text); |
| 14 testRunner.setMockSpellCheckerEnabled(true); | 12 container.childNodes.forEach(child => { |
| 15 | 13 if (child.nodeName === 'DIV') { |
| 16 var testRoot = document.createElement("div"); | 14 selection.selectAllChildren(child); |
| 17 document.body.insertBefore(testRoot, document.body.firstChild); | 15 } else { |
| 18 | 16 child.value = ''; |
| 19 var source1 = document.createElement("div"); | 17 child.focus(); |
| 20 source1.innerHTML = "foo bar"; | 18 } |
| 21 testRoot.appendChild(source1); | 19 document.execCommand('paste'); |
| 22 | 20 }); |
| 23 var source2 = document.createElement("div"); | |
| 24 source2.innerHTML = "zz apple orange"; | |
| 25 testRoot.appendChild(source2); | |
| 26 | |
| 27 function createInput(testRoot) { | |
| 28 var e = document.createElement('input'); | |
| 29 e.setAttribute("type", "text"); | |
| 30 testRoot.appendChild(e); | |
| 31 | |
| 32 return e; | |
| 33 } | 21 } |
| 34 | 22 |
| 35 function createTextArea(testRoot) { | 23 spellcheck_test( |
| 36 var e = document.createElement("textarea"); | 24 [ |
| 37 testRoot.appendChild(e); | 25 '<div id="container">', |
| 38 | 26 '<input>', |
| 39 return e; | 27 '<textarea></textarea>', |
| 40 } | 28 '<div contenteditable></div>', |
| 41 | 29 '<input>', |
| 42 function createContentEditable(testRoot) { | 30 '<textarea></textarea>', |
| 43 var e = document.createElement("div"); | 31 '<div contenteditable></div>', |
| 44 e.setAttribute("contentEditable", "true"); | 32 '<input>', |
| 45 testRoot.appendChild(e); | 33 '<textarea></textarea>', |
| 46 | 34 '<div contenteditable></div>', |
| 47 return e; | 35 '</div>' |
| 48 } | 36 ].join(''), |
| 49 | 37 document => { |
| 50 var destinations = [ | 38 const container = document.getElementById('container'); |
| 51 createInput(testRoot), | 39 pasteToAllChildren('foo bar', container); |
| 52 createTextArea(testRoot), | 40 pasteToAllChildren('zz apple orange', container); |
| 53 createContentEditable(testRoot), | 41 }, |
| 54 createInput(testRoot), | 42 [ |
| 55 createTextArea(testRoot), | 43 '<div id="container">', |
| 56 createContentEditable(testRoot), | 44 '<input value="#zz# apple orange">', |
| 57 createInput(testRoot), | 45 '<textarea>#zz# apple orange</textarea>', |
| 58 createTextArea(testRoot), | 46 '<div contenteditable>#zz# apple orange</div>', |
| 59 createContentEditable(testRoot), | 47 '<input value="#zz# apple orange">', |
| 60 ]; | 48 '<textarea>#zz# apple orange</textarea>', |
| 61 | 49 '<div contenteditable>#zz# apple orange</div>', |
| 62 var sel = window.getSelection(); | 50 '<input value="#zz# apple orange">', |
| 63 | 51 '<textarea>#zz# apple orange</textarea>', |
| 64 var tests = []; | 52 '<div contenteditable>#zz# apple orange</div>', |
| 65 for (var i = 0; i < destinations.length; ++i) { | 53 '</div>' |
| 66 var t = function(i) { | 54 ].join(''), |
| 67 return function() { verify(source2, destinations[i], ["zz"]); } | 55 'Spellchecker handles multiple requests.'); |
| 68 }(i); | |
| 69 tests.push(t); | |
| 70 } | |
| 71 | |
| 72 function verifyIfAny() | |
| 73 { | |
| 74 var next = tests.shift(); | |
| 75 if (next) { | |
| 76 next(); | |
| 77 return; | |
| 78 } | |
| 79 | |
| 80 testRoot.style.display = "none"; | |
| 81 finishJSTest(); | |
| 82 } | |
| 83 | |
| 84 function findFirstTextNode(node) | |
| 85 { | |
| 86 function iterToFindFirstTextNode(node) | |
| 87 { | |
| 88 if (node instanceof Text) | |
| 89 return node; | |
| 90 | |
| 91 var childNodes = node.childNodes; | |
| 92 for (var i = 0; i < childNodes.length; ++i) { | |
| 93 var n = iterToFindFirstTextNode(childNodes[i]); | |
| 94 if (n) | |
| 95 return n; | |
| 96 } | |
| 97 | |
| 98 return null; | |
| 99 } | |
| 100 | |
| 101 | |
| 102 if (node instanceof HTMLInputElement || node instanceof HTMLTextAreaElement) | |
| 103 return iterToFindFirstTextNode(internals.shadowRoot(node)); | |
| 104 else | |
| 105 return iterToFindFirstTextNode(node); | |
| 106 } | |
| 107 | |
| 108 function verifyMarker(node, expectedMarked) | |
| 109 { | |
| 110 if (!window.testRunner || !window.internals) | |
| 111 return false; | |
| 112 | |
| 113 var textNode = findFirstTextNode(node); | |
| 114 | |
| 115 var num = internals.markerCountForNode(textNode, "spelling"); | |
| 116 if (num != expectedMarked.length) | |
| 117 return false; | |
| 118 for (var i = 0; i < num; ++i) { | |
| 119 var range = internals.markerRangeForNode(textNode, "spelling", i); | |
| 120 if (range.toString() != expectedMarked[i]) | |
| 121 return false; | |
| 122 } | |
| 123 | |
| 124 return true; | |
| 125 } | |
| 126 | |
| 127 function copyAndPaste(source, dest) | |
| 128 { | |
| 129 sel.selectAllChildren(source); | |
| 130 document.execCommand("Copy"); | |
| 131 | |
| 132 if (dest instanceof HTMLInputElement || dest instanceof HTMLTextAreaElement)
{ | |
| 133 dest.value = ""; | |
| 134 dest.focus(); | |
| 135 } else { | |
| 136 dest.innerHTML = ""; | |
| 137 sel.selectAllChildren(dest); | |
| 138 } | |
| 139 document.execCommand("Paste"); | |
| 140 } | |
| 141 | |
| 142 function verify(source, dest, expectedMarked) | |
| 143 { | |
| 144 var nretry = 10; | |
| 145 var nsleep = 1; | |
| 146 function trial() { | |
| 147 var verified = verifyMarker(dest, expectedMarked); | |
| 148 if (verified) { | |
| 149 testPassed(dest.tagName + " has a marker on '" + source.innerHTML +
"'"); | |
| 150 verifyIfAny(); | |
| 151 return; | |
| 152 } | |
| 153 | |
| 154 nretry--; | |
| 155 if (0 == nretry) { | |
| 156 testFailed(dest.tagName + " should have a marker on for '" + source.
innerHTML + "'"); | |
| 157 verifyIfAny(); | |
| 158 return; | |
| 159 } | |
| 160 | |
| 161 nsleep *= 2; | |
| 162 window.setTimeout(trial, nsleep); | |
| 163 }; | |
| 164 trial(); | |
| 165 } | |
| 166 | |
| 167 | |
| 168 // paste "foo bar" | |
| 169 for (var i = 0; i < destinations.length; ++i) | |
| 170 copyAndPaste(source1, destinations[i]); | |
| 171 | |
| 172 // paste "zz apple orange" | |
| 173 for (var i = 0; i < destinations.length; ++i) | |
| 174 copyAndPaste(source2, destinations[i]); | |
| 175 | |
| 176 verifyIfAny(); | |
| 177 | |
| 178 var successfullyParsed = true; | |
| 179 | |
| 180 </script> | 56 </script> |
| 181 </body> | |
| 182 </html> | |
| OLD | NEW |