Uncommitted Korean IME candidate text ignored when user presses enter, causing CE/DM desync in Firefox
Closed, ResolvedPublic8 Story Points

Description

  1. Load demos/ve/desktop.html#!pages/empty.html
  2. Load debugging mode
  3. Use a "New Romanising IME" like for T72353 (?)
  4. Type 'ganada' (가나 다|). Observe that all is well, but that the IME is still active (no compositionEnd yet?).
  5. Press enter
  6. Observe DM and CE desync.
  7. Sob.
Jdforrester-WMF updated the task description. (Show Details)
Jdforrester-WMF raised the priority of this task from to High.
Jdforrester-WMF assigned this task to dchan.
Jdforrester-WMF set Security to None.
Jdforrester-WMF edited a custom field.
Jdforrester-WMF added subscribers: Ryuch, Elitre, revi and 3 others.
Catrope added a subscriber: Catrope.Dec 3 2015, 1:11 AM

To clarify: between step 4 and step 5, the last character is underlined, probably indicating that it's uncommitted candidate text. My theory is that pressing Enter causes the IME to want to commit the text, while it also causes VE to change the DOM.

Jdforrester-WMF renamed this task from Uncommitted Korean IME candidate text ignored when user presses enter, causing CE/DM desync to Uncommitted Korean IME candidate text ignored when user presses enter, causing CE/DM desync in Firefox.Dec 8 2015, 6:37 PM
dchan added a comment.Dec 9 2015, 10:14 AM

Hi, I can't reproduce this on Ubuntu or Windows 8 - can you type the same keystrokes (g,a,n,a,d,a,<Enter>) into https://rawgit.com/wikimedia/VisualEditor/master/demos/ve/eventLogger.html and then paste the log here? Thanks!

Firefox (where it doesn't work):

[
	{"imeIdentifier":"OS X \"New Romansing\" OS Korean IME on Firefox","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:42.0) Gecko/20100101 Firefox/42.0","startDom":""},
	{"seq":0,"time":4.246,"action":"sendEvent","args":["keydown",{"keyCode":71}]},
	{"seq":1,"time":4.253,"action":"sendEvent","args":["compositionstart",{}]},
	{"seq":2,"time":4.264,"action":"changeText","args":["ㄱ"]},
	{"seq":3,"time":4.264,"action":"changeSel","args":[1,1]},
	{"seq":4,"time":4.264,"action":"sendEvent","args":["input",{}]},
	{"seq":5,"time":4.294,"action":"endLoop","args":[]},
	{"seq":6,"time":4.543,"action":"changeText","args":["가"]},
	{"seq":7,"time":4.543,"action":"sendEvent","args":["input",{}]},
	{"seq":8,"time":4.552,"action":"endLoop","args":[]},
	{"seq":9,"time":4.818,"action":"changeText","args":["간"]},
	{"seq":10,"time":4.818,"action":"sendEvent","args":["input",{}]},
	{"seq":11,"time":4.853,"action":"endLoop","args":[]},
	{"seq":12,"time":5.008,"action":"changeText","args":["가"]},
	{"seq":13,"time":5.008,"action":"sendEvent","args":["input",{}]},
	{"seq":14,"time":5.011,"action":"sendEvent","args":["compositionend",{}]},
	{"seq":15,"time":5.012,"action":"sendEvent","args":["input",{}]},
	{"seq":16,"time":5.014,"action":"sendEvent","args":["compositionstart",{}]},
	{"seq":17,"time":5.016,"action":"changeText","args":["가나"]},
	{"seq":18,"time":5.016,"action":"changeSel","args":[2,2]},
	{"seq":19,"time":5.016,"action":"sendEvent","args":["input",{}]},
	{"seq":20,"time":5.026,"action":"endLoop","args":[]},
	{"seq":21,"time":5.271,"action":"changeText","args":["가낟"]},
	{"seq":22,"time":5.271,"action":"sendEvent","args":["input",{}]},
	{"seq":23,"time":5.275,"action":"endLoop","args":[]},
	{"seq":24,"time":5.455,"action":"changeText","args":["가나"]},
	{"seq":25,"time":5.455,"action":"sendEvent","args":["input",{}]},
	{"seq":26,"time":5.459,"action":"sendEvent","args":["compositionend",{}]},
	{"seq":27,"time":5.46,"action":"sendEvent","args":["input",{}]},
	{"seq":28,"time":5.462,"action":"sendEvent","args":["compositionstart",{}]},
	{"seq":29,"time":5.464,"action":"changeText","args":["가나다"]},
	{"seq":30,"time":5.464,"action":"changeSel","args":[3,3]},
	{"seq":31,"time":5.464,"action":"sendEvent","args":["input",{}]},
	{"seq":32,"time":5.484,"action":"endLoop","args":[]},
	{"seq":33,"time":5.794,"action":"sendEvent","args":["compositionend",{}]},
	{"seq":34,"time":5.796,"action":"sendEvent","args":["input",{}]},
	{"seq":35,"time":5.799,"action":"sendEvent","args":["keypress",{"keyCode":13}]},
	{"seq":36,"time":5.802,"action":"changeText","args":["가나다<br><br>"]},
	{"seq":37,"time":5.802,"action":"changeSel","args":[2,2]},
	{"seq":38,"time":5.802,"action":"sendEvent","args":["input",{}]},
	{"seq":39,"time":5.815,"action":"endLoop","args":[]},
	{"seq":40,"time":5.85,"action":"sendEvent","args":["keyup",{"keyCode":13}]},
	{"seq":41,"time":5.862,"action":"endLoop","args":[]}
]

Chrome (where it does; identical behaviour on Opera, as expected):

[
	{"imeIdentifier":"OS X "New Romansing" OS Korean IME on Chrome","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36","startDom":""},
	{"seq":0,"time":6.009,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":1,"time":6.011,"action":"sendEvent","args":["compositionstart",{}]},
	{"seq":2,"time":6.012,"action":"changeText","args":["ㄱ"]},
	{"seq":3,"time":6.012,"action":"changeSel","args":[0,1]},
	{"seq":4,"time":6.012,"action":"sendEvent","args":["input",{}]},
	{"seq":5,"time":6.016,"action":"changeSel","args":[1,1]},
	{"seq":6,"time":6.016,"action":"endLoop","args":[]},
	{"seq":7,"time":6.091,"action":"sendEvent","args":["keyup",{"keyCode":71}]},
	{"seq":8,"time":6.094,"action":"endLoop","args":[]},
	{"seq":9,"time":6.28,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":10,"time":6.281,"action":"changeText","args":["가"]},
	{"seq":11,"time":6.281,"action":"changeSel","args":[0,1]},
	{"seq":12,"time":6.281,"action":"sendEvent","args":["input",{}]},
	{"seq":13,"time":6.285,"action":"changeSel","args":[1,1]},
	{"seq":14,"time":6.285,"action":"endLoop","args":[]},
	{"seq":15,"time":6.317,"action":"sendEvent","args":["keyup",{"keyCode":65}]},
	{"seq":16,"time":6.32,"action":"endLoop","args":[]},
	{"seq":17,"time":6.571,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":18,"time":6.572,"action":"changeText","args":["간"]},
	{"seq":19,"time":6.572,"action":"changeSel","args":[0,1]},
	{"seq":20,"time":6.572,"action":"sendEvent","args":["input",{}]},
	{"seq":21,"time":6.577,"action":"changeSel","args":[1,1]},
	{"seq":22,"time":6.577,"action":"endLoop","args":[]},
	{"seq":23,"time":6.621,"action":"sendEvent","args":["keyup",{"keyCode":78}]},
	{"seq":24,"time":6.624,"action":"endLoop","args":[]},
	{"seq":25,"time":6.784,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":26,"time":6.785,"action":"changeSel","args":[0,1]},
	{"seq":27,"time":6.785,"action":"sendEvent","args":["compositionend",{}]},
	{"seq":28,"time":6.787,"action":"changeText","args":["가"]},
	{"seq":29,"time":6.787,"action":"changeSel","args":[1,1]},
	{"seq":30,"time":6.787,"action":"sendEvent","args":["input",{}]},
	{"seq":31,"time":6.79,"action":"sendEvent","args":["compositionstart",{}]},
	{"seq":32,"time":6.791,"action":"changeText","args":["가나"]},
	{"seq":33,"time":6.791,"action":"changeSel","args":[1,2]},
	{"seq":34,"time":6.791,"action":"sendEvent","args":["input",{}]},
	{"seq":35,"time":6.795,"action":"changeSel","args":[2,2]},
	{"seq":36,"time":6.795,"action":"endLoop","args":[]},
	{"seq":37,"time":6.845,"action":"sendEvent","args":["keyup",{"keyCode":65}]},
	{"seq":38,"time":6.849,"action":"endLoop","args":[]},
	{"seq":39,"time":7.105,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":40,"time":7.107,"action":"changeText","args":["가낟"]},
	{"seq":41,"time":7.107,"action":"changeSel","args":[1,2]},
	{"seq":42,"time":7.107,"action":"sendEvent","args":["input",{}]},
	{"seq":43,"time":7.112,"action":"changeSel","args":[2,2]},
	{"seq":44,"time":7.112,"action":"endLoop","args":[]},
	{"seq":45,"time":7.157,"action":"sendEvent","args":["keyup",{"keyCode":68}]},
	{"seq":46,"time":7.161,"action":"endLoop","args":[]},
	{"seq":47,"time":7.304,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":48,"time":7.306,"action":"changeSel","args":[1,2]},
	{"seq":49,"time":7.306,"action":"sendEvent","args":["compositionend",{}]},
	{"seq":50,"time":7.309,"action":"changeText","args":["가나"]},
	{"seq":51,"time":7.309,"action":"changeSel","args":[2,2]},
	{"seq":52,"time":7.309,"action":"sendEvent","args":["input",{}]},
	{"seq":53,"time":7.312,"action":"sendEvent","args":["compositionstart",{}]},
	{"seq":54,"time":7.313,"action":"changeText","args":["가나다"]},
	{"seq":55,"time":7.313,"action":"changeSel","args":[2,3]},
	{"seq":56,"time":7.313,"action":"sendEvent","args":["input",{}]},
	{"seq":57,"time":7.319,"action":"changeSel","args":[3,3]},
	{"seq":58,"time":7.319,"action":"endLoop","args":[]},
	{"seq":59,"time":7.358,"action":"sendEvent","args":["keyup",{"keyCode":65}]},
	{"seq":60,"time":7.363,"action":"endLoop","args":[]},
	{"seq":61,"time":7.714,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":62,"time":7.715,"action":"changeSel","args":[2,3]},
	{"seq":63,"time":7.715,"action":"sendEvent","args":["compositionend",{}]},
	{"seq":64,"time":7.718,"action":"changeSel","args":[3,3]},
	{"seq":65,"time":7.718,"action":"sendEvent","args":["input",{}]},
	{"seq":66,"time":7.721,"action":"sendEvent","args":["keyup",{"keyCode":13}]},
	{"seq":67,"time":7.722,"action":"sendEvent","args":["keydown",{"keyCode":13}]},
	{"seq":68,"time":7.723,"action":"sendEvent","args":["keypress",{"keyCode":13}]},
	{"seq":69,"time":7.725,"action":"changeText","args":["가나다<div><br></div>"]},
	{"seq":70,"time":7.725,"action":"changeSel","args":[0,0]},
	{"seq":71,"time":7.725,"action":"sendEvent","args":["input",{}]},
	{"seq":72,"time":7.733,"action":"endLoop","args":[]},
	{"seq":73,"time":7.757,"action":"sendEvent","args":["keyup",{"keyCode":13}]},
	{"seq":74,"time":7.761,"action":"endLoop","args":[]}
]

And Safari:

[
	{"imeIdentifier":"OS X \"New Romansing\" OS Korean IME on Safari","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11) AppleWebKit/601.1.56 (KHTML, like Gecko) Version/9.0 Safari/601.1.56","startDom":""},
	{"seq":0,"time":6.22,"action":"changeText","args":["ㄱ"]},
	{"seq":1,"time":6.22,"action":"changeSel","args":[1,1]},
	{"seq":2,"time":6.22,"action":"sendEvent","args":["input",{}]},
	{"seq":3,"time":6.273,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":4,"time":6.274,"action":"endLoop","args":[]},
	{"seq":5,"time":6.305,"action":"endLoop","args":[]},
	{"seq":6,"time":6.308,"action":"sendEvent","args":["keyup",{"keyCode":71}]},
	{"seq":7,"time":6.339,"action":"endLoop","args":[]},
	{"seq":8,"time":6.382,"action":"changeText","args":["가"]},
	{"seq":9,"time":6.382,"action":"sendEvent","args":["input",{}]},
	{"seq":10,"time":6.414,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":11,"time":6.415,"action":"endLoop","args":[]},
	{"seq":12,"time":6.421,"action":"endLoop","args":[]},
	{"seq":13,"time":6.442,"action":"sendEvent","args":["keyup",{"keyCode":65}]},
	{"seq":14,"time":6.455,"action":"endLoop","args":[]},
	{"seq":15,"time":6.57,"action":"changeText","args":["간"]},
	{"seq":16,"time":6.57,"action":"sendEvent","args":["input",{}]},
	{"seq":17,"time":6.606,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":18,"time":6.627,"action":"endLoop","args":[]},
	{"seq":19,"time":6.639,"action":"sendEvent","args":["keyup",{"keyCode":78}]},
	{"seq":20,"time":6.656,"action":"endLoop","args":[]},
	{"seq":21,"time":6.713,"action":"changeText","args":["가"]},
	{"seq":22,"time":6.713,"action":"sendEvent","args":["input",{}]},
	{"seq":23,"time":6.737,"action":"endLoop","args":[]},
	{"seq":24,"time":6.776,"action":"changeText","args":["가나"]},
	{"seq":25,"time":6.776,"action":"changeSel","args":[2,2]},
	{"seq":26,"time":6.776,"action":"sendEvent","args":["input",{}]},
	{"seq":27,"time":6.8,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":28,"time":6.802,"action":"endLoop","args":[]},
	{"seq":29,"time":6.824,"action":"sendEvent","args":["keyup",{"keyCode":65}]},
	{"seq":30,"time":6.826,"action":"endLoop","args":[]},
	{"seq":31,"time":6.832,"action":"endLoop","args":[]},
	{"seq":32,"time":6.925,"action":"changeText","args":["가낟"]},
	{"seq":33,"time":6.925,"action":"sendEvent","args":["input",{}]},
	{"seq":34,"time":6.954,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":35,"time":6.968,"action":"endLoop","args":[]},
	{"seq":36,"time":7.005,"action":"sendEvent","args":["keyup",{"keyCode":68}]},
	{"seq":37,"time":7.012,"action":"endLoop","args":[]},
	{"seq":38,"time":7.043,"action":"changeText","args":["가나"]},
	{"seq":39,"time":7.043,"action":"sendEvent","args":["input",{}]},
	{"seq":40,"time":7.058,"action":"endLoop","args":[]},
	{"seq":41,"time":7.089,"action":"changeText","args":["가나다"]},
	{"seq":42,"time":7.089,"action":"changeSel","args":[3,3]},
	{"seq":43,"time":7.089,"action":"sendEvent","args":["input",{}]},
	{"seq":44,"time":7.145,"action":"sendEvent","args":["keydown",{"keyCode":229}]},
	{"seq":45,"time":7.157,"action":"sendEvent","args":["keyup",{"keyCode":65}]},
	{"seq":46,"time":7.177,"action":"endLoop","args":[]},
	{"seq":47,"time":7.324,"action":"sendEvent","args":["input",{}]},
	{"seq":48,"time":7.356,"action":"sendEvent","args":["keydown",{"keyCode":13}]},
	{"seq":49,"time":7.358,"action":"sendEvent","args":["keypress",{"keyCode":13}]},
	{"seq":50,"time":7.361,"action":"changeText","args":["가나다<div><br></div>"]},
	{"seq":51,"time":7.361,"action":"changeSel","args":[0,0]},
	{"seq":52,"time":7.361,"action":"sendEvent","args":["input",{}]},
	{"seq":53,"time":7.372,"action":"endLoop","args":[]},
	{"seq":54,"time":7.404,"action":"endLoop","args":[]},
	{"seq":55,"time":7.406,"action":"sendEvent","args":["keyup",{"keyCode":13}]},
	{"seq":56,"time":7.442,"action":"endLoop","args":[]}
]

Change 268316 had a related patch set uploaded (by Jforrester):
IME tests: Add failing Korean IME test

https://gerrit.wikimedia.org/r/268316

dchan added a comment.Feb 10 2016, 1:31 AM

@Jforrester , thanks for https://phabricator.wikimedia.org/F3328523 . It's striking that the 'na' of 'ganada' gets swallowed, and that the Enter succesfully creates a new paragraph but then the cursor jumps back from position 5 to position 3 when you continue typing.

I wonder whether the Enter keyPress is uncancellable in that context. We already know there's no keyDown, presumably because of the IME interaction, and IME-related events are often uncancellable, so it seems possible.

From testing with @Tchanders and @Esanders , it looks like the syllable swallowing ('gan' + 'a' --> 'ga') is a separate bug (now filed as T127108 ). When that bug doesn't happen, the Enter bug appears to be fixed by https://gerrit.wikimedia.org/r/268316 .