mirror of
https://github.com/atom/atom.git
synced 2026-01-23 22:08:08 -05:00
Avoid setting hidden input value on textInput
Atom currently sets the `value` of the input on every `textInput` event, in an effort to appropriately handle changes made via the OSX diacritic menu (for accents, umlauts, etc). The drawback of this is approach is that updating the value of the input will trigger layout and a subsequent layer tree update. To resolve this, here is my proposal: - Track a flag for `keypress` events. When the diacritic menu is used, there are two `textInput` events, with no `keypress` in between. Therefore, when no `keypress` has occurred just prior to a `textInput`, the editor model can select the previous character to be replaced by the new accented character. - Track a flag for `compositionstart` events. When a user is in IME mode, the diacritic menu cannot be used, so the editor can skip the backward selection. Test Plan: Tested in a plaintext file. - Type Latin characters, verify proper character insertion. - Press and hold <kbd>a</kbd>. Diacritic menu appears. Select an option using the keyboard or mouse. Verify that the `a` is replaced by an accented `a`, with no extra characters. - Type test strings in Katakana, 2-Set Korean, Telex (Vietnamese), Simplified Pinyin. Verify that characters are inserted correctly while composing, and after committing strings.
This commit is contained in:
@@ -244,6 +244,7 @@ class TextEditorComponent
|
||||
listenForDOMEvents: ->
|
||||
@domNode.addEventListener 'mousewheel', @onMouseWheel
|
||||
@domNode.addEventListener 'textInput', @onTextInput
|
||||
@domNode.addEventListener 'keypress', @onKeyPress
|
||||
@scrollViewNode.addEventListener 'mousedown', @onMouseDown
|
||||
@scrollViewNode.addEventListener 'scroll', @onScrollViewScroll
|
||||
|
||||
@@ -266,6 +267,7 @@ class TextEditorComponent
|
||||
|
||||
checkpoint = null
|
||||
@domNode.addEventListener 'compositionstart', =>
|
||||
@imeMode = true
|
||||
checkpoint = @editor.createCheckpoint()
|
||||
@domNode.addEventListener 'compositionupdate', (event) =>
|
||||
@editor.insertText(event.data, select: true)
|
||||
@@ -319,26 +321,27 @@ class TextEditorComponent
|
||||
if @mounted
|
||||
@presenter.setFocused(false)
|
||||
|
||||
onKeyPress: (event) =>
|
||||
@detectedKeyPress = true
|
||||
|
||||
onTextInput: (event) =>
|
||||
event.stopPropagation()
|
||||
|
||||
# If we prevent the insertion of a space character, then the browser
|
||||
# interprets the spacebar keypress as a page-down command.
|
||||
event.preventDefault() unless event.data is ' '
|
||||
event.preventDefault()
|
||||
|
||||
return unless @isInputEnabled()
|
||||
|
||||
inputNode = event.target
|
||||
# Workaround of the accented character suggestion feature in OS X.
|
||||
# This will only occur when the user is not composing in IME mode.
|
||||
# When the user selects a modified character from the OSX menu, `textInput`
|
||||
# will occur twice, once for the initial character, and once for the
|
||||
# modified character. However, only a single keypress will have fired. If
|
||||
# this is the case, select backward to replace the original character.
|
||||
if not @imeMode and not @detectedKeyPress
|
||||
@editor.selectLeft()
|
||||
|
||||
# Work around of the accented character suggestion feature in OS X.
|
||||
# Text input fires before a character is inserted, and if the browser is
|
||||
# replacing the previous un-accented character with an accented variant, it
|
||||
# will select backward over it.
|
||||
selectedLength = inputNode.selectionEnd - inputNode.selectionStart
|
||||
@editor.selectLeft() if selectedLength is 1
|
||||
|
||||
insertedRange = @editor.insertText(event.data, groupUndo: true)
|
||||
inputNode.value = event.data if insertedRange
|
||||
@editor.insertText(event.data, groupUndo: true)
|
||||
@detectedKeyPress = false
|
||||
@imeMode = false
|
||||
|
||||
onVerticalScroll: (scrollTop) =>
|
||||
return if @updateRequested or scrollTop is @presenter.getScrollTop()
|
||||
|
||||
Reference in New Issue
Block a user