     expected
 
   mutationIsSignificant: ->
-    not @composition?
+    not @composing
 
   events:
     beforeinput: (event) ->
       @handledInput = false
       if @[event.inputType]
         @handledInput = true
+        updateSelectionForEvent(event)
         @[event.inputType](event)
         @requestRender() if event.defaultPrevented
 
+    input: (event) ->
+      updateSelectionForEvent(event)
+
     compositionend: (event) ->
-      if @composition?
-        string = @composition
-        delete @composition
-        @delegate?.inputControllerWillPerformTyping()
-        @responder?.expandSelectionInDirection("backward", length: string.length)
-        @responder?.insertString(string)
-        @requestRender()
+      @composing = false
 
   # https://www.w3.org/TR/input-events-2/#interface-InputEvent-Attributes
 

    @responder?.insertLineBreak()

  insertReplacementText: (event) ->
    string = event.data ? event.dataTransfer.getData("text/plain")
    {length} = getTargetText(event)
    @delegate?.inputControllerWillPerformTyping()
    @responder?.expandSelectionInDirection("backward", {length})
    @responder?.insertString(string)

  insertText: (event) ->
    string = event.data
    @delegate?.inputControllerWillPerformTyping()
    @responder?.insertString(string)

  # insertTranspose: (event) ->
  #
  # insertUnorderedList: (event) ->

getTargetText = (event) ->
  [event.getTargetRanges()...]
    .map(staticRangeToRange)
    .map(rangeToText)
    .join("")

staticRangeToRange = (staticRange) ->
  range = document.createRange()
  range.setStart(staticRange.startContainer, staticRange.startOffset)
  range.setEnd(staticRange.endContainer, staticRange.endOffset)
  range

rangeToText = (range) ->
  return "" if range.collapsed
  element = document.createElement("div")
  element.appendChild(range.cloneContents())
  element.innerText

  # deleteSoftLineForward: (event) ->

  deleteWordBackward: (event) ->
    @delegate?.inputControllerWillPerformTyping()
    @responder?.deleteInDirection("backward")

  deleteWordForward: (event) ->
    @delegate?.inputControllerWillPerformTyping()
    @responder?.deleteInDirection("forward")

  # formatBackColor: (event) ->

