| <!DOCTYPE html> |
| <script src="../../resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <script src="../assert_selection.js"></script> |
| <script src="spellcheck_test.js"></script> |
| <script> |
| spellcheck_test( |
| '<div contenteditable>|</div>', |
| 'insertText Spell wellcome. Is it broken?', |
| '<div contenteditable>Spell #wellcome#. Is it broken?</div>', |
| { |
| title: '1 Setup a content editable div with spelling marker', |
| callback: sample => spellcheck_test( |
| sample, |
| document => { |
| assert_not_equals(window.eventSender, undefined, 'This test requires eventSender.'); |
| |
| const destination = document.querySelector('div'); |
| const textNode = destination.firstChild; |
| |
| // Select the text "Is it broken?". |
| const deleteRange = document.createRange(); |
| deleteRange.setStart(textNode, 15); |
| deleteRange.setEnd(textNode, 29); |
| document.getSelection().removeAllRanges(); |
| document.getSelection().addRange(deleteRange); |
| |
| // Del key to delete the text "Is it broken?". |
| eventSender.keyDown("Delete", null); |
| |
| // Context click to show the context menu. |
| var x = destination.offsetParent.offsetLeft + destination.offsetLeft + 50; |
| var y = destination.offsetParent.offsetTop + destination.offsetTop + destination.offsetHeight / 2; |
| eventSender.mouseMoveTo(x, y); |
| contextMenuElements = eventSender.contextClick(); |
| |
| // Esc key to hide the context menu. |
| eventSender.keyDown("Escape", null); |
| }, |
| '<div contenteditable>Spell #wellcome#.</div>', |
| '1 Spellcheck should not crash after the text has changed.') |
| }); |
| |
| spellcheck_test( |
| '<div contenteditable>zz.|</div>', |
| '', |
| '<div contenteditable>#zz#.</div>', |
| { |
| title: '2 Setup a content editable div with spelling marker', |
| callback: sample => spellcheck_test( |
| sample, |
| document => { |
| // Send out a new request that rechecks the entire div. |
| document.execCommand('insertText', false, ' zz.'); |
| if (window.internals) |
| internals.runIdleTimeSpellChecker(document); |
| |
| // Mutate the text node to cancel the previous request. |
| const text = document.querySelector('div').firstChild; |
| text.deleteData(text.length - 2, 2); |
| }, |
| '<div contenteditable>#zz#. z</div>', |
| '2 Canceled spellcheck request should not remove existing marker') |
| }); |
| |
| // Must be at least 1024 characters to force spellchecker to compute checking |
| // range with TextIterator. |
| const longText = 'bla. '.repeat(255) + 'bla.'; |
| spellcheck_test( |
| `<div contenteditable>${longText}|</div>`, |
| document => { |
| document.execCommand('insertText', false, 'zz..'); |
| |
| // Invalidate the ending selection of InsertText command in the undo stack. |
| const textNode = document.getSelection().anchorNode; |
| textNode.deleteData(textNode.length - 1, 1); |
| |
| // Clear selection, so that if spellchecker can only use the ending |
| // selection of InsertText command to compute checking range. |
| document.getSelection().removeAllRanges(); |
| }, |
| `<div contenteditable>${longText}zz.</div>`, |
| '3 No spellcheck due to invalid ending selection in the undo stack'); |
| </script> |
| </body> |
| </html> |