diff --git a/src/components/content-input.js b/src/components/content-input.js index 488a51d..0f15937 100644 --- a/src/components/content-input.js +++ b/src/components/content-input.js @@ -1,10 +1,7 @@ -import * as inputActions from 'actions/input'; -import * as operationActions from 'actions/operation'; - export default class ContentInputComponent { - constructor(target, store) { + constructor(target) { this.pressed = {}; - this.store = store; + this.onKeyListeners = []; target.addEventListener('keypress', this.onKeyPress.bind(this)); target.addEventListener('keydown', this.onKeyDown.bind(this)); @@ -14,6 +11,10 @@ export default class ContentInputComponent { update() { } + onKey(cb) { + this.onKeyListeners.push(cb); + } + onKeyPress(e) { if (this.pressed[e.key] && this.pressed[e.key] !== 'keypress') { return; @@ -44,47 +45,20 @@ export default class ContentInputComponent { if (e.key === 'OS') { return; } - let keymaps = this.keymaps(); - if (!keymaps) { - return; - } - this.store.dispatch(inputActions.keyPress(e.key, e.ctrlKey)); - if (this.mapKeys(keymaps)) { + let stop = false; + for (let listener of this.onKeyListeners) { + stop = stop || listener(e.key, e.ctrlKey); + } + if (stop) { e.preventDefault(); e.stopPropagation(); } } - mapKeys(keymaps) { - let input = this.store.getState().input; - let matched = Object.keys(keymaps).filter((keyStr) => { - return keyStr.startsWith(input.keys); - }); - if (matched.length === 0) { - this.store.dispatch(inputActions.clearKeys()); - return false; - } else if (matched.length > 1 || - matched.length === 1 && input.keys !== matched[0]) { - return true; - } - let operation = keymaps[matched]; - this.store.dispatch(operationActions.exec(operation)); - this.store.dispatch(inputActions.clearKeys()); - return true; - } - fromInput(e) { return e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement; } - - keymaps() { - let settings = this.store.getState().setting.settings; - if (!settings || !settings.json) { - return null; - } - return JSON.parse(settings.json).keymaps; - } } diff --git a/src/components/keymapper.js b/src/components/keymapper.js new file mode 100644 index 0000000..3685a4f --- /dev/null +++ b/src/components/keymapper.js @@ -0,0 +1,43 @@ +import * as inputActions from 'actions/input'; +import * as operationActions from 'actions/operation'; + +export default class KeymapperComponent { + constructor(store) { + this.store = store; + } + + update() { + } + + key(key, ctrl) { + let keymaps = this.keymaps(); + if (!keymaps) { + return; + } + this.store.dispatch(inputActions.keyPress(key, ctrl)); + + let input = this.store.getState().input; + let matched = Object.keys(keymaps).filter((keyStr) => { + return keyStr.startsWith(input.keys); + }); + if (matched.length === 0) { + this.store.dispatch(inputActions.clearKeys()); + return false; + } else if (matched.length > 1 || + matched.length === 1 && input.keys !== matched[0]) { + return true; + } + let operation = keymaps[matched]; + this.store.dispatch(operationActions.exec(operation)); + this.store.dispatch(inputActions.clearKeys()); + return true; + } + + keymaps() { + let settings = this.store.getState().setting.settings; + if (!settings || !settings.json) { + return null; + } + return JSON.parse(settings.json).keymaps; + } +} diff --git a/src/content/index.js b/src/content/index.js index 2c13c70..ad891ca 100644 --- a/src/content/index.js +++ b/src/content/index.js @@ -3,6 +3,7 @@ import * as consoleFrames from './console-frames'; import * as settingActions from 'actions/setting'; import { createStore } from 'store'; import ContentInputComponent from 'components/content-input'; +import KeymapperComponent from 'components/keymapper'; import FollowComponent from 'components/follow'; import reducers from 'reducers'; import messages from './messages'; @@ -11,6 +12,10 @@ const store = createStore(reducers); const followComponent = new FollowComponent(window.document.body, store); const contentInputComponent = new ContentInputComponent(window.document.body, store); +const keymapperComponent = new KeymapperComponent(store); +contentInputComponent.onKey((key, ctrl) => { + return keymapperComponent.key(key, ctrl); +}); store.subscribe(() => { try { followComponent.update();