| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="../../resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| </head> |
| <body> |
| <div id="editable" contenteditable>Some text.</div> |
| <div id="outside">Not editable.</div> |
| <script> |
| test(() => { |
| assert_own_property(window, "textInputController", "this test needs textInputController to start a composition"); |
| |
| let events = []; |
| for (const type of ["compositionstart", "compositionupdate", "compositionend"]) |
| editable.addEventListener(type, event => events.push({ type: event.type, data: event.data })); |
| |
| editable.focus(); |
| getSelection().setPosition(editable.firstChild, editable.firstChild.length); |
| |
| textInputController.setMarkedText("^", 1, 0); |
| assert_true(textInputController.hasMarkedText(), "the dead key should start a composition"); |
| |
| getSelection().setPosition(outside.firstChild, 0); |
| |
| assert_false(textInputController.hasMarkedText(), "moving the selection out of the editable element should end the composition"); |
| assert_equals(editable.textContent, "Some text.^", "the composition text should be left behind in the document"); |
| |
| let compositionEndEvents = events.filter(event => event.type === "compositionend"); |
| assert_equals(compositionEndEvents.length, 1, "exactly one compositionend event should be fired"); |
| assert_equals(compositionEndEvents[0].data, "^", "compositionend data should be the composition text left behind in the document"); |
| }, "compositionend reports the text left behind in the document when a composition is aborted"); |
| </script> |
| </body> |
| </html> |