substance.io IME input broken |
||||
Issue descriptionVersion: 51.0.2680.0 1. Visit substance.io and focus the textbox. Move cursor to the end of a word, like "Define". 2. Press backspace, "a" then "space". 3. Observe the word "Define" is broken. Note that this is some kind of fancy Javascript-based textbox, which customizes "contenteditable" in some way.
,
Mar 22 2016
Google Keyboard version: 4.1.23163.2622203, English. By "broken", I mean the word is duplicated, it looks like "DefinDefina e".
,
Mar 30 2016
I did some investigation, and here's the scenario I suspect is happening: http://substance.io/examples/notepad/app.js This file listens to DOM mutations by window.MutationObserver, and I think it tries to apply the currently selected style whenever there is a DOM mutation of character data, except we're composing something. It detects composition only through compositionstart. When we move cursor to the end of "Define", Google Latin IME calls setComposingRegion(). This only triggers keydown, compositionupdate, and keyup events. Therefore, the JavaScript does not understand composition correctly and do something funky. According to 5.7.2. Composition Event Order of the UI Events section of W3C document (and throughout the rest of the doc), compositionstart should occur first. I am planning to try changing Blink to trigger compositionstart() if it was not composing before and see if that fixes this problem. In the meantime, could you start reviewing https://codereview.chromium.org/1840993002/ ? That can help ease out testing / diagnosing the event triggering. Thanks.
,
Dec 29 2016
Found the root cause: there is a bug in http://substance.io/examples/lib/substance/substance.js Things start going wrong when calling commitText(), not setComposingRegion(). In TypingCommand::insertText(), it dispatchs TextInputEvent, which is handled by substance.js: ''' Surface.prototype.onTextInput = function onTextInput (event) { // console.log("TextInput:", event); event.preventDefault() event.stopPropagation() if (!event.data) { return } // necessary for handling dead keys properly this._state.skipNextObservation=true this.transaction(function(tx, args) { if (this.domSelection) { // trying to remove the DOM selection to reduce flickering this.domSelection.clear() } args.text = event.data return this.insertText(tx, args) }.bind(this), { action: 'type' }) }; ''' Note that it calls event.preventDefault(), so DispatchEventResult will not be NotCanceled. Thus, blink will simply return and JS will take over. JS is supposed to delete the selection and insert new text by calling this.insertText(tx, args). But somehow the selection is always collapsed (not correct), so we get the wrong result. BTW, It's easy to fix the JS bug. We only need to replace one line: this.domSelection.clear() --> args.selection = this.domSelection.getSelection() Reply to comment#3: I checked, and found that setComposingRegion() triggers no event. See https://cdn.rawgit.com/w3c/uievents/gh-pages/tools/key-event-viewer.html
,
Jan 3 2017
cc'ing michael@substance.io. We're working to fix bugs in IME on Chrome for Android and discovered the issue above. Does the change to "args.selection = this.domSelection.getSelection()" seem reasonable to you? |
||||
►
Sign in to add a comment |
||||
Comment 1 by aelias@chromium.org
, Mar 22 2016