Add handlers for IME composition

This commit is contained in:
Ben Ogle
2014-06-19 15:03:34 -07:00
parent f27b897e91
commit 184068dc55
2 changed files with 85 additions and 0 deletions

View File

@@ -1425,6 +1425,64 @@ describe "EditorComponent", ->
node.dispatchEvent(buildTextInputEvent(data: 'x', target: inputNode))
expect(editor.lineForBufferRow(0)).toBe 'var quicksort = function () {'
describe "when IME composition is used to insert international characters", ->
buildIMECompositionEvent = (event, {data}={}) ->
event = new Event(event)
event.data = data
Object.defineProperty(event, 'target', get: -> inputNpde)
event
describe "when nothing is selected", ->
it "inserts the chosen completion", ->
node.dispatchEvent(buildIMECompositionEvent('compositionstart'))
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 's'))
expect(editor.lineForBufferRow(0)).toBe 'svar quicksort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd'))
expect(editor.lineForBufferRow(0)).toBe 'sdvar quicksort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionend'))
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'))
expect(editor.lineForBufferRow(0)).toBe 'svar quicksort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd'))
expect(editor.lineForBufferRow(0)).toBe 'sdvar quicksort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionend'))
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'))
expect(editor.lineForBufferRow(0)).toBe 'var ssort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd'))
expect(editor.lineForBufferRow(0)).toBe 'var sdsort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionend'))
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'))
expect(editor.lineForBufferRow(0)).toBe 'var ssort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionupdate', data: 'sd'))
expect(editor.lineForBufferRow(0)).toBe 'var sdsort = function () {'
node.dispatchEvent(buildIMECompositionEvent('compositionend'))
expect(editor.lineForBufferRow(0)).toBe 'var quicksort = function () {'
describe "commands", ->
describe "editor:consolidate-selections", ->
it "consolidates selections on the editor model, aborting the key binding if there is only one selection", ->

View File

@@ -281,6 +281,33 @@ EditorComponent = React.createClass
scrollViewNode.addEventListener 'scroll', @onScrollViewScroll
window.addEventListener 'resize', @requestScrollViewMeasurement
@listenForIMEEvents()
listenForIMEEvents: ->
node = @getDOMNode()
{editor} = @props
# The IME composition events work like this:
#
# User types 's', chromium pops up the completion helper
# 1. compositionstart fired
# 2. compositionupdate fired; event.data == 's'
# User hits arrow keys to move around in completion helper
# 3. compositionupdate fired; event.data == 's' for each arry key press
# User escape to cancel
# 4. compositionend fired
# OR User chooses a completion
# 4. compositionend fired
# 5. textInput fired; event.data == the completion string
selectedText = null
node.addEventListener 'compositionstart', =>
selectedText = editor.getSelectedText()
node.addEventListener 'compositionupdate', (event) =>
editor.insertText(event.data, select: true, undo: 'skip')
node.addEventListener 'compositionend', =>
editor.insertText(selectedText, select: true, undo: 'skip')
listenForCommands: ->
{parentView, editor, mini} = @props