all files / ui/ KeyboardManager.js

41.82% Statements 23/55
33.33% Branches 8/24
40% Functions 2/5
41.82% Lines 23/55
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111            206×   206×   206× 206×   206×   615× 615× 615× 615× 615× 615×                                                                                         615× 615×     615× 1230× 1230×                     615× 615×                     615× 615×               615×          
import { keys, parseKeyEvent } from '../util'
import ExecuteCommandHandler from './ExecuteCommandHandler'
 
class KeyboardManager {
 
  constructor(editorSession, bindings, options) {
    this.editorSession = editorSession
 
    this.context = options.context || {}
 
    this.keydownBindings = {}
    this.textinputBindings = {}
 
    bindings.forEach(({ key, spec }) => {
      // default combos are evaluated on keydown
      let type = spec.type || 'keydown'
      Eif(spec.command) {
        let handler = new ExecuteCommandHandler(editorSession, spec.command)
        let hook = handler.execute.bind(handler)
        Eif (type === 'keydown') {
          this.keydownBindings[parseCombo(key)] = hook
        } else if (type === 'textinput') {
          this.textinputBindings[key] = hook
        }
      } else {
        throw new Error('Keyboard binding not supported', spec)
      }
    })
  }
 
  onKeydown(event) {
    let key = parseKeyEvent(event)
    let hook = this.keydownBindings[key]
    if (hook) {
      event.preventDefault()
      event.stopPropagation()
      let params = this._getParams()
      hook(params, this.context)
      return true
    }
  }
 
  onTextInput(text) {
    let hook = this.textinputBindings[text]
    if (hook) {
      let params = this._getParams()
      return hook(params, this.context)
    }
  }
 
  _getParams() {
    let editorSession = this.editorSession
    let selectionState = editorSession.getSelectionState()
    let sel = selectionState.getSelection()
    let surface = this.context.surfaceManager.getFocusedSurface()
    return {
      editorSession: editorSession,
      selectionState: selectionState,
      surface: surface,
      selection: sel,
    }
  }
 
}
 
function parseCombo(combo) {
  let frags = combo.split('+')
  let data = {
    keyCode: -1
  }
  for (var i = 0; i < frags.length; i++) {
    let frag = frags[i].toUpperCase()
    switch(frag) {
      case 'ALT': {
        data.altKey = true
        break
      }
      case 'ALTGR': {
        data.altKey = true
        data.code = 'AltRight'
        break
      }
      case 'CMD': {
        data.metaKey = true
        break
      }
      case 'CTRL': {
        data.ctrlKey = true
        break
      }
      case 'SHIFT': {
        data.shiftKey = true
        break
      }
      default:
        Eif (frag.length === 1) {
          data.keyCode = frag.charCodeAt(0)
        } else if (keys.hasOwnProperty(frag)) {
          data.keyCode = keys[frag]
        } else {
          throw new Error('Unsupported keyboard command: '+ combo)
        }
    }
  }
  return parseKeyEvent(data)
}
 
KeyboardManager.parseCombo = parseCombo
 
export default KeyboardManager