aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/actions/input.js12
-rw-r--r--src/components/background-input.js6
-rw-r--r--src/components/background.js2
-rw-r--r--src/components/content-input.js44
-rw-r--r--src/content/index.js19
-rw-r--r--src/reducers/input.js11
-rw-r--r--src/shared/keys.js21
-rw-r--r--test/actions/input.test.js11
-rw-r--r--test/reducers/input.test.js22
-rw-r--r--test/shared/keys.test.js31
10 files changed, 77 insertions, 102 deletions
diff --git a/src/actions/input.js b/src/actions/input.js
index 07948a1..67788dd 100644
--- a/src/actions/input.js
+++ b/src/actions/input.js
@@ -1,10 +1,16 @@
import actions from '../actions';
-const keyPress = (code, ctrl) => {
+const asKeymapChars = (key, ctrl) => {
+ if (ctrl) {
+ return '<C-' + key.toUpperCase() + '>';
+ }
+ return key;
+};
+
+const keyPress = (key, ctrl) => {
return {
type: actions.INPUT_KEY_PRESS,
- code,
- ctrl
+ key: asKeymapChars(key, ctrl),
};
};
diff --git a/src/components/background-input.js b/src/components/background-input.js
index 9c6ef1c..4735d5a 100644
--- a/src/components/background-input.js
+++ b/src/components/background-input.js
@@ -1,5 +1,4 @@
import * as inputActions from '../actions/input';
-import * as keys from '../shared/keys';
import * as operationActions from '../actions/operation';
export default class BackgroundInputComponent {
@@ -37,15 +36,14 @@ export default class BackgroundInputComponent {
}
handleKeysChanged(sender, input) {
- let prefix = keys.asKeymapChars(input.keys);
let matched = Object.keys(this.keymaps).filter((keyStr) => {
- return keyStr.startsWith(prefix);
+ return keyStr.startsWith(input.keys);
});
if (matched.length === 0) {
this.store.dispatch(inputActions.clearKeys(), sender);
return Promise.resolve();
} else if (matched.length > 1 ||
- matched.length === 1 && prefix !== matched[0]) {
+ matched.length === 1 && input.keys !== matched[0]) {
return Promise.resolve();
}
let operation = this.keymaps[matched];
diff --git a/src/components/background.js b/src/components/background.js
index 4c5bb19..0585a04 100644
--- a/src/components/background.js
+++ b/src/components/background.js
@@ -35,7 +35,7 @@ export default class BackgroundComponent {
switch (message.type) {
case messages.KEYDOWN:
return this.store.dispatch(
- inputActions.keyPress(message.code, message.ctrl), sender);
+ inputActions.keyPress(message.key, message.ctrl), sender);
case messages.OPEN_URL:
if (message.newTab) {
return this.store.dispatch(
diff --git a/src/components/content-input.js b/src/components/content-input.js
new file mode 100644
index 0000000..6437128
--- /dev/null
+++ b/src/components/content-input.js
@@ -0,0 +1,44 @@
+import messages from '../content/messages';
+
+export default class ContentInputComponent {
+ constructor(target) {
+ this.pressed = {};
+
+ target.addEventListener('keypress', this.onKeyPress.bind(this));
+ target.addEventListener('keydown', this.onKeyDown.bind(this));
+ target.addEventListener('keyup', this.onKeyUp.bind(this));
+ }
+
+ onKeyPress(e) {
+ this.capture(e);
+ }
+
+ onKeyDown(e) {
+ this.capture(e);
+ }
+
+ onKeyUp(e) {
+ this.pressed[e.key] = false;
+ }
+
+ capture(e) {
+ if (this.pressed[e.key]) {
+ return;
+ }
+ this.pressed[e.key] = true;
+
+ if (e.target instanceof HTMLInputElement ||
+ e.target instanceof HTMLTextAreaElement ||
+ e.target instanceof HTMLSelectElement) {
+ if (e.key === 'Escape' && e.target.blur) {
+ e.target.blur();
+ }
+ return;
+ }
+ browser.runtime.sendMessage({
+ type: messages.KEYDOWN,
+ key: e.key,
+ ctrl: e.ctrlKey
+ });
+ }
+}
diff --git a/src/content/index.js b/src/content/index.js
index 0dbc8c1..655bea4 100644
--- a/src/content/index.js
+++ b/src/content/index.js
@@ -4,6 +4,7 @@ import * as scrolls from '../content/scrolls';
import * as navigates from '../content/navigates';
import * as followActions from '../actions/follow';
import * as store from '../store';
+import ContentInputComponent from '../components/content-input';
import FollowComponent from '../components/follow';
import followReducer from '../reducers/follow';
import operations from '../operations';
@@ -18,25 +19,11 @@ followStore.subscribe(() => {
console.error(e);
}
});
+// eslint-disable-next-line no-unused-vars
+const contentInputComponent = new ContentInputComponent(window);
consoleFrames.initialize(window.document);
-window.addEventListener('keypress', (e) => {
- if (e.target instanceof HTMLInputElement ||
- e.target instanceof HTMLTextAreaElement ||
- e.target instanceof HTMLSelectElement) {
- if (e.key === 'Escape' && e.target.blur) {
- e.target.blur();
- }
- return;
- }
- browser.runtime.sendMessage({
- type: messages.KEYDOWN,
- code: e.which,
- ctrl: e.ctrlKey
- });
-});
-
const execOperation = (operation) => {
switch (operation.type) {
case operations.SCROLL_LINES:
diff --git a/src/reducers/input.js b/src/reducers/input.js
index eb7ff24..8be701e 100644
--- a/src/reducers/input.js
+++ b/src/reducers/input.js
@@ -1,23 +1,18 @@
import actions from '../actions';
const defaultState = {
- keys: [],
+ keys: '',
};
export default function reducer(state = defaultState, action = {}) {
switch (action.type) {
case actions.INPUT_KEY_PRESS:
return Object.assign({}, state, {
- keys: state.keys.concat([
- {
- code: action.code,
- ctrl: action.ctrl
- }
- ])
+ keys: state.keys + action.key
});
case actions.INPUT_CLEAR_KEYS:
return Object.assign({}, state, {
- keys: [],
+ keys: '',
});
default:
return state;
diff --git a/src/shared/keys.js b/src/shared/keys.js
deleted file mode 100644
index aca050e..0000000
--- a/src/shared/keys.js
+++ /dev/null
@@ -1,21 +0,0 @@
-const asKeymapChars = (keys) => {
- return keys.map((k) => {
- let c = String.fromCharCode(k.code);
- if (k.ctrl) {
- return '<C-' + c.toUpperCase() + '>';
- }
- return c;
- }).join('');
-};
-
-const asCaretChars = (keys) => {
- return keys.map((k) => {
- let c = String.fromCharCode(k.code);
- if (k.ctrl) {
- return '^' + c.toUpperCase();
- }
- return c;
- }).join('');
-};
-
-export { asKeymapChars, asCaretChars };
diff --git a/test/actions/input.test.js b/test/actions/input.test.js
index 9ec6de4..904d3e7 100644
--- a/test/actions/input.test.js
+++ b/test/actions/input.test.js
@@ -5,10 +5,15 @@ import * as inputActions from '../../src/actions/input';
describe("input actions", () => {
describe("keyPress", () => {
it('create INPUT_KEY_PRESS action', () => {
- let action = inputActions.keyPress(123, true);
+ let action = inputActions.keyPress('a', false);
expect(action.type).to.equal(actions.INPUT_KEY_PRESS);
- expect(action.code).to.equal(123);
- expect(action.ctrl).to.be.true;
+ expect(action.key).to.equal('a');
+ });
+
+ it('create INPUT_KEY_PRESS action from key with ctrl', () => {
+ let action = inputActions.keyPress('b', true);
+ expect(action.type).to.equal(actions.INPUT_KEY_PRESS);
+ expect(action.key).to.equal('<C-B>');
});
});
diff --git a/test/reducers/input.test.js b/test/reducers/input.test.js
index d7a0855..3c3bf39 100644
--- a/test/reducers/input.test.js
+++ b/test/reducers/input.test.js
@@ -5,30 +5,22 @@ import inputReducer from '../../src/reducers/input';
describe("input reducer", () => {
it('return the initial state', () => {
let state = inputReducer(undefined, {});
- expect(state).to.have.deep.property('keys', []);
+ expect(state).to.have.deep.property('keys', '');
});
it('return next state for INPUT_KEY_PRESS', () => {
- let action = { type: actions.INPUT_KEY_PRESS, code: 123, ctrl: true };
+ let action = { type: actions.INPUT_KEY_PRESS, key: 'a' };
let state = inputReducer(undefined, action);
- expect(state).to.have.deep.property('keys', [{ code: 123, ctrl: true }]);
+ expect(state).to.have.deep.property('keys', 'a');
- action = { type: actions.INPUT_KEY_PRESS, code: 456, ctrl: false };
+ action = { type: actions.INPUT_KEY_PRESS, key: '<C-B>' };
state = inputReducer(state, action);
- expect(state).to.have.deep.property('keys', [
- { code: 123, ctrl: true },
- { code: 456, ctrl: false }
- ]);
+ expect(state).to.have.deep.property('keys', 'a<C-B>');
});
it('return next state for INPUT_CLEAR_KEYS', () => {
let action = { type: actions.INPUT_CLEAR_KEYS };
- let state = inputReducer({
- keys: [
- { code: 123, ctrl: true },
- { code: 456, ctrl: false }
- ]
- }, action);
- expect(state).to.have.deep.property('keys', []);
+ let state = inputReducer({ keys: 'abc' }, action);
+ expect(state).to.have.deep.property('keys', '');
});
});
diff --git a/test/shared/keys.test.js b/test/shared/keys.test.js
deleted file mode 100644
index 53c953d..0000000
--- a/test/shared/keys.test.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { expect } from "chai";
-import * as keys from '../../src/shared/keys';
-
-describe("keys", () => {
- const KEYMAP = {
- 'g<C-X>GG': [],
- 'gg': { type: 'scroll.top' },
- };
-
- const g = 'g'.charCodeAt(0);
- const G = 'G'.charCodeAt(0);
- const x = 'x'.charCodeAt(0);
-
- describe('#asKeymapChars', () => {
- let keySequence = [
- { code: g },
- { code: x, ctrl: true },
- { code: G }
- ];
- expect(keys.asKeymapChars(keySequence)).to.equal('g<C-X>G');
- });
-
- describe('#asCaretChars', () => {
- let keySequence = [
- { code: g },
- { code: x, ctrl: true },
- { code: G }
- ];
- expect(keys.asCaretChars(keySequence)).to.equal('g^XG');
- });
-});