Allow successive accented characters to be inserted in React editor

Refs #2732

Because we're only checking the length of the input element's selection
in the React editor on textinput events and not also its content, we
were mistaking some IME compositions as accented character menu
insertions. Clearing the content of the input on 'compositionend'
prevents this issue.
This commit is contained in:
Nathan Sobo
2014-06-25 11:12:16 -06:00
parent 1c69995bb6
commit 63e8099088
2 changed files with 48 additions and 21 deletions

View File

@@ -1619,61 +1619,87 @@ describe "EditorComponent", ->
expect(editor.lineForBufferRow(0)).toBe 'var quicksort = function () {'
describe "when IME composition is used to insert international characters", ->
buildIMECompositionEvent = (event, {data}={}) ->
inputNode = null
buildIMECompositionEvent = (event, {data, target}={}) ->
event = new Event(event)
event.data = data
Object.defineProperty(event, 'target', get: -> inputNpde)
Object.defineProperty(event, 'target', get: -> target)
event
beforeEach ->
inputNode = inputNode = node.querySelector('.hidden-input')
describe "when nothing is selected", ->
it "inserts the chosen completion", ->
node.dispatchEvent(buildIMECompositionEvent('compositionstart'))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's'))
node.dispatchEvent(buildIMECompositionEvent('compositionstart', target: inputNode))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'svar quicksort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd'))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'sdvar quicksort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionend'))
node.dispatchEvent(buildIMECompositionEvent('compositionend', target: inputNode))
node.dispatchEvent(buildTextInputEvent(data: '速度', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe '速度var quicksort = function () {'
it "reverts back to the original text when the completion helper is dismissed", ->
node.dispatchEvent(buildIMECompositionEvent('compositionstart'))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's'))
node.dispatchEvent(buildIMECompositionEvent('compositionstart', target: inputNode))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'svar quicksort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd'))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'sdvar quicksort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionend'))
node.dispatchEvent(buildIMECompositionEvent('compositionend', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'var quicksort = function () {'
it "allows multiple accented character to be inserted with the ' on a US international layout", ->
inputNode.value = "'"
inputNode.setSelectionRange(0, 1)
node.dispatchEvent(buildIMECompositionEvent('compositionstart', target: inputNode))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: "'", target: inputNode))
expect(editor.lineForBufferRow(0)).toBe "'var quicksort = function () {"
node.dispatchEvent(buildIMECompositionEvent('compositionend', target: inputNode))
node.dispatchEvent(buildTextInputEvent(data: 'á', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe "ávar quicksort = function () {"
inputNode.value = "'"
inputNode.setSelectionRange(0, 1)
node.dispatchEvent(buildIMECompositionEvent('compositionstart', target: inputNode))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: "'", target: inputNode))
expect(editor.lineForBufferRow(0)).toBe "á'var quicksort = function () {"
node.dispatchEvent(buildIMECompositionEvent('compositionend', target: inputNode))
node.dispatchEvent(buildTextInputEvent(data: 'á', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe "áávar quicksort = function () {"
describe "when a string is selected", ->
beforeEach ->
editor.setSelectedBufferRange [[0, 4], [0, 9]] # select 'quick'
it "inserts the chosen completion", ->
node.dispatchEvent(buildIMECompositionEvent('compositionstart'))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's'))
node.dispatchEvent(buildIMECompositionEvent('compositionstart', target: inputNode))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'var ssort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd'))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'var sdsort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionend'))
node.dispatchEvent(buildIMECompositionEvent('compositionend', target: inputNode))
node.dispatchEvent(buildTextInputEvent(data: '速度', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'var 速度sort = function () {'
it "reverts back to the original text when the completion helper is dismissed", ->
node.dispatchEvent(buildIMECompositionEvent('compositionstart'))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's'))
node.dispatchEvent(buildIMECompositionEvent('compositionstart', target: inputNode))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'var ssort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd'))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'var sdsort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionend'))
node.dispatchEvent(buildIMECompositionEvent('compositionend', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'var quicksort = function () {'
describe "commands", ->

View File

@@ -356,12 +356,13 @@ EditorComponent = React.createClass
# 5. textInput fired; event.data == the completion string
selectedText = null
node.addEventListener 'compositionstart', =>
node.addEventListener 'compositionstart', ->
selectedText = editor.getSelectedText()
node.addEventListener 'compositionupdate', (event) =>
node.addEventListener 'compositionupdate', (event) ->
editor.insertText(event.data, select: true, undo: 'skip')
node.addEventListener 'compositionend', =>
node.addEventListener 'compositionend', (event) ->
editor.insertText(selectedText, select: true, undo: 'skip')
event.target.value = ''
listenForCommands: ->
{parentView, editor, mini} = @props