diff --git a/app/components/SimpleEditor/ContainerEditor.js b/app/components/SimpleEditor/ContainerEditor.js
index 532f0d7bca9e4b386d0adc752b1cb596334c21af..04c849ac82ce74a6f70995296866c56c80567e49 100644
--- a/app/components/SimpleEditor/ContainerEditor.js
+++ b/app/components/SimpleEditor/ContainerEditor.js
@@ -10,7 +10,7 @@ import {
 
 class ContainerEditor extends SubstanceContainerEditor {
   render ($$) {
-    // TODO -- better ways to write this in es6
+    // TODO -- call with super
     var el = Surface.prototype.render.call(this, $$)
 
     var doc = this.getDocument()
@@ -83,6 +83,17 @@ class ContainerEditor extends SubstanceContainerEditor {
     })
   }
 
+  onTextInputShim (event) {
+    if (!this.props.trackChanges) return super.onTextInputShim(event)
+
+    this.handleTracking({
+      event: event,
+      status: 'add',
+      surfaceEvent: 'input',
+      keypress: true
+    })
+  }
+
   _handleDeleteKey (event) {
     if (!this.props.trackChanges) return super._handleDeleteKey(event)
 
@@ -103,15 +114,48 @@ class ContainerEditor extends SubstanceContainerEditor {
     })
   }
 
+  shouldIgnoreKeypress (event) {
+    // see Surface's onTextInputShim for comments
+    if (
+      event.which === 0 ||
+      event.charCode === 0 ||
+      event.keyCode === keys.TAB ||
+      event.keyCode === keys.ESCAPE ||
+      Boolean(event.metaKey) ||
+      (Boolean(event.ctrlKey) ^ Boolean(event.altKey))
+    ) {
+      return true
+    }
+
+    return false
+  }
+
+  getTextFromKeypress (event) {
+    let character = String.fromCharCode(event.which)
+    if (!event.shiftKey) character = character.toLowerCase()
+    if (character.length === 0) return null
+    return character
+  }
+
   handleTracking (options) {
     const trackChangesProvider = this.context.trackChangesProvider
-    const { event, surfaceEvent } = options
+    const { event, keypress, surfaceEvent } = options
 
-    event.preventDefault()
-    event.stopPropagation()
+    if (!keypress) {
+      event.preventDefault()
+      event.stopPropagation()
+    }
 
     if (surfaceEvent === 'input') {
-      if (!event.data) return
+      if (keypress) {
+        if (this.shouldIgnoreKeypress(event)) return
+        const text = this.getTextFromKeypress(event)
+        event.data = text
+        event.preventDefault()
+        event.stopPropagation()
+      }
+
+      if (!keypress && !event.data) return
       this._state.skipNextObservation = true
     }
 
diff --git a/app/components/SimpleEditor/elements/track_change/TrackChangeComponent.js b/app/components/SimpleEditor/elements/track_change/TrackChangeComponent.js
index 83897555f14679ad6bbdd1692803d7db87a9d385..9ba3c897e1f8ccfda6ffda8334bcacf97e1a0e05 100644
--- a/app/components/SimpleEditor/elements/track_change/TrackChangeComponent.js
+++ b/app/components/SimpleEditor/elements/track_change/TrackChangeComponent.js
@@ -1,5 +1,6 @@
+import { pickBy, clone, map, sortBy, findIndex } from 'lodash'
 import { AnnotationComponent, createAnnotation, deleteNode } from 'substance'
-import {pickBy, clone, map, sortBy, findIndex} from 'lodash'
+
 class TrackChangeComponent extends AnnotationComponent {
   render ($$) {
     const { status } = this.props.node