Skip to content

Commit

Permalink
Android: Ignore Chrome 65’s new composition events during cursor move…
Browse files Browse the repository at this point in the history
…ment
  • Loading branch information
javan committed Feb 26, 2018
1 parent 0c448e0 commit e5ca869
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 18 deletions.
45 changes: 27 additions & 18 deletions src/trix/controllers/input/composition_input.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,41 @@ class Trix.CompositionInput extends Trix.BasicObject
start: (data) ->
@data.start = data

if @inputSummary.eventName is "keypress" and @inputSummary.textAdded
@responder?.deleteInDirection("left")
if @isSignificant()
if @inputSummary.eventName is "keypress" and @inputSummary.textAdded
@responder?.deleteInDirection("left")

unless @selectionIsExpanded()
@insertPlaceholder()
@requestRender()
unless @selectionIsExpanded()
@insertPlaceholder()
@requestRender()

@range = @responder?.getSelectedRange()
@range = @responder?.getSelectedRange()

update: (data) ->
@data.update = data

if range = @selectPlaceholder()
@forgetPlaceholder()
@range = range
if @isSignificant()
if range = @selectPlaceholder()
@forgetPlaceholder()
@range = range

end: (data) ->
@data.end = data
@forgetPlaceholder()

if @canApplyToDocument()
@setInputSummary(preferDocument: true)
@delegate?.inputControllerWillPerformTyping()
@responder?.setSelectedRange(@range)
@responder?.insertString(@data.end)
@responder?.setSelectedRange(@range[0] + @data.end.length)
if @isSignificant()
@forgetPlaceholder()

if @canApplyToDocument()
@setInputSummary(preferDocument: true)
@delegate?.inputControllerWillPerformTyping()
@responder?.setSelectedRange(@range)
@responder?.insertString(@data.end)
@responder?.setSelectedRange(@range[0] + @data.end.length)

else if @data.start? or @data.update?
@requestReparse()
else if @data.start? or @data.update?
@requestReparse()
@inputController.reset()
else
@inputController.reset()

getEndData: ->
Expand All @@ -43,6 +49,9 @@ class Trix.CompositionInput extends Trix.BasicObject
isEnded: ->
@getEndData()?

isSignificant: ->
@inputSummary.didInput

# Private

canApplyToDocument: ->
Expand Down
5 changes: 5 additions & 0 deletions src/trix/controllers/input_controller.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ class Trix.InputController extends Trix.BasicObject
events:
keydown: (event) ->
@resetInputSummary() unless @isComposing()
@inputSummary.didInput = true

if keyName = @constructor.keyNames[event.keyCode]
context = @keys
Expand Down Expand Up @@ -297,7 +298,11 @@ class Trix.InputController extends Trix.BasicObject
compositionend: (event) ->
@getCompositionInput().end(event.data)

beforeinput: (event) ->
@inputSummary.didInput = true

input: (event) ->
@inputSummary.didInput = true
event.stopPropagation()

keys:
Expand Down
34 changes: 34 additions & 0 deletions test/src/system/composition_input_test.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,11 @@ testGroup "Composition input", template: "editor_empty", ->

triggerEvent(element, "keydown", charCode: 0, keyCode: 229, which: 229)
triggerEvent(element, "compositionupdate", data: "ca")
triggerEvent(element, "input")
removeCharacters -1, ->
triggerEvent(element, "keydown", charCode: 0, keyCode: 229, which: 229)
triggerEvent(element, "compositionupdate", data: "c")
triggerEvent(element, "input")
triggerEvent(element, "compositionend", data: "c")
removeCharacters -1, ->
pressKey "backspace", ->
Expand All @@ -83,9 +85,11 @@ testGroup "Composition input", template: "editor_empty", ->
triggerEvent(element, "keydown", charCode: 0, keyCode: 229, which: 229)
triggerEvent(element, "compositionstart", data: "cat")
triggerEvent(element, "compositionupdate", data: "cat")
triggerEvent(element, "input")
removeCharacters -1, ->
triggerEvent(element, "keydown", charCode: 0, keyCode: 229, which: 229)
triggerEvent(element, "compositionupdate", data: "car")
triggerEvent(element, "input")
triggerEvent(element, "compositionend", data: "car")
insertNode document.createTextNode("r"), ->
expectDocument("car\n")
Expand All @@ -97,32 +101,62 @@ testGroup "Composition input", template: "editor_empty", ->
triggerEvent(element, "keydown", charCode: 0, keyCode: 229, which: 229)
triggerEvent(element, "compositionstart", data: "")
triggerEvent(element, "compositionupdate", data: "c")
triggerEvent(element, "input")
node = document.createTextNode("c")
insertNode(node)
defer ->
triggerEvent(element, "keydown", charCode: 0, keyCode: 229, which: 229)
triggerEvent(element, "compositionupdate", data: "ca")
triggerEvent(element, "input")
node.data = "ca"
defer ->
triggerEvent(element, "compositionend", data: "")
defer ->
expectDocument("ca\n")

# Simulates the sequence of events when moving the cursor through a word on Android
# Introduced in Chrome 65:
# - https://bugs.chromium.org/p/chromium/issues/detail?id=812674
# - https://bugs.chromium.org/p/chromium/issues/detail?id=764439#c9
test "composition events from cursor movement are ignored", (expectDocument) ->
element = getEditorElement()
element.editor.insertString("ab ")

element.editor.setSelectedRange(0)
triggerEvent(element, "compositionstart", data: "")
triggerEvent(element, "compositionupdate", data: "ab")
defer ->
element.editor.setSelectedRange(1)
triggerEvent(element, "compositionupdate", data: "ab")
defer ->
element.editor.setSelectedRange(2)
triggerEvent(element, "compositionupdate", data: "ab")
defer ->
element.editor.setSelectedRange(3)
triggerEvent(element, "compositionend", data: "ab")
defer ->
expectDocument("ab \n")

# Simulates compositions in Firefox where the final composition data is
# dispatched as both compositionupdate and compositionend.
test "composition ending with same data as last update", (expectDocument) ->
element = getEditorElement()

triggerEvent(element, "keydown", charCode: 0, keyCode: 229, which: 229)
triggerEvent(element, "compositionstart", data: "")
triggerEvent(element, "compositionupdate", data: "´")
node = document.createTextNode("´")
insertNode(node)
selectNode(node)
defer ->
triggerEvent(element, "keydown", charCode: 0, keyCode: 229, which: 229)
triggerEvent(element, "compositionupdate", data: "é")
triggerEvent(element, "input")
node.data = "é"
defer ->
triggerEvent(element, "keydown", charCode: 0, keyCode: 229, which: 229)
triggerEvent(element, "compositionupdate", data: "éé")
triggerEvent(element, "input")
node.data = "éé"
defer ->
triggerEvent(element, "compositionend", data: "éé")
Expand Down

0 comments on commit e5ca869

Please sign in to comment.