| <!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> |