From 6f9b217df86c72ba5c8187cc192f90639488cee3 Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka <ueokande@i-beam.org>
Date: Sun, 8 Oct 2017 09:24:09 +0900
Subject: make content-input more simple

---
 src/components/content-input.js | 48 ++++++++++-------------------------------
 src/components/keymapper.js     | 43 ++++++++++++++++++++++++++++++++++++
 src/content/index.js            |  5 +++++
 3 files changed, 59 insertions(+), 37 deletions(-)
 create mode 100644 src/components/keymapper.js

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();
-- 
cgit v1.2.3