@@ -6,7 +6,17 @@ import TextInputHandler from 'mobiledoc-kit/editor/text-input-handler'
66import SelectionManager from 'mobiledoc-kit/editor/selection-manager'
77import Browser from 'mobiledoc-kit/utils/browser'
88
9- const ELEMENT_EVENT_TYPES = [ 'keydown' , 'keyup' , 'cut' , 'copy' , 'paste' , 'keypress' , 'drop' ]
9+ const ELEMENT_EVENT_TYPES = [
10+ 'keydown' ,
11+ 'keyup' ,
12+ 'cut' ,
13+ 'copy' ,
14+ 'paste' ,
15+ 'keypress' ,
16+ 'drop' ,
17+ 'compositionstart' ,
18+ 'compositionend' ,
19+ ]
1020
1121export default class EventManager {
1222 constructor ( editor ) {
@@ -143,6 +153,13 @@ export default class EventManager {
143153 event . preventDefault ( )
144154 }
145155
156+ // Handle carriage returns
157+ if ( ! key . isEnter ( ) && key . keyCode === 13 ) {
158+ _textInputHandler . handleNewLine ( )
159+ editor . handleNewline ( event )
160+ return
161+ }
162+
146163 _textInputHandler . handle ( key . toString ( ) )
147164 }
148165
@@ -169,6 +186,10 @@ export default class EventManager {
169186 let range = editor . range
170187
171188 switch ( true ) {
189+ // Ignore keydown events when using an IME
190+ case key . isIME ( ) : {
191+ break
192+ }
172193 // FIXME This should be restricted to only card/atom boundaries
173194 case key . isHorizontalArrowWithoutModifiersOtherThanShift ( ) : {
174195 let newRange
@@ -215,6 +236,59 @@ export default class EventManager {
215236 this . _updateModifiersFromKey ( key , { isDown : false } )
216237 }
217238
239+ // The mutation handler interferes with IMEs when composing
240+ // on a blank line. These two event handlers are for suppressing
241+ // mutation handling in this scenario.
242+ compositionstart ( event ) {
243+ let { editor } = this
244+ // Ignore compositionstart if not on a blank line
245+ if ( editor . range . headMarker ) {
246+ return
247+ }
248+ this . _isComposingOnBlankLine = true
249+
250+ if ( editor . post . isBlank ) {
251+ editor . _insertEmptyMarkupSectionAtCursor ( )
252+ }
253+
254+ // Stop listening for mutations on Chrome browsers and suppress
255+ // mutations by prepending a character for other browsers.
256+ // The reason why we treat these separately is because
257+ // of the way each browser processes IME inputs.
258+ if ( Browser . isChrome ( ) ) {
259+ editor . setPlaceholder ( '' )
260+ editor . _mutationHandler . stopObserving ( )
261+ } else {
262+ this . _textInputHandler . handle ( ' ' )
263+ }
264+ }
265+
266+ compositionend ( event ) {
267+ let { editor } = this
268+
269+ // Ignore compositionend if not composing on blank line
270+ if ( ! this . _isComposingOnBlankLine ) {
271+ return
272+ }
273+ this . _isComposingOnBlankLine = false
274+
275+ // Start listening for mutations on Chrome browsers and
276+ // delete the prepended character introduced by compositionstart
277+ // for other browsers.
278+ if ( Browser . isChrome ( ) ) {
279+ editor . insertText ( event . data )
280+ editor . setPlaceholder ( editor . placeholder )
281+ editor . _mutationHandler . startObserving ( )
282+ } else {
283+ let startOfCompositionLine = editor . range . headSection . toPosition ( 0 )
284+ let endOfCompositionLine = editor . range . headSection . toPosition ( event . data . length )
285+ editor . run ( postEditor => {
286+ postEditor . deleteAtPosition ( startOfCompositionLine , 1 , { unit : 'char' } )
287+ postEditor . setRange ( endOfCompositionLine )
288+ } )
289+ }
290+ }
291+
218292 cut ( event ) {
219293 event . preventDefault ( )
220294
0 commit comments