aboutsummaryrefslogtreecommitdiff
path: root/src/content
diff options
context:
space:
mode:
authorShin'ya Ueoka <ueokande@i-beam.org>2017-11-05 09:47:30 +0900
committerShin'ya Ueoka <ueokande@i-beam.org>2017-11-11 20:34:31 +0900
commit036ede3379285cbe678d79aad3b9442dca8b31e6 (patch)
treee97e4a8a1713c7540db0d3ff82ab0964104d3bad /src/content
parent4e94695c758215a950fe53911e1c1e30e47b9c98 (diff)
support mutliple modifiers for key bindings
Diffstat (limited to 'src/content')
-rw-r--r--src/content/actions/setting.js16
-rw-r--r--src/content/components/common/follow.js2
-rw-r--r--src/content/components/common/input.js21
-rw-r--r--src/content/components/common/keymapper.js23
-rw-r--r--src/content/components/top-content/follow-controller.js2
-rw-r--r--src/content/reducers/input.js6
-rw-r--r--src/content/reducers/setting.js2
7 files changed, 41 insertions, 31 deletions
diff --git a/src/content/actions/setting.js b/src/content/actions/setting.js
index c874294..353dd24 100644
--- a/src/content/actions/setting.js
+++ b/src/content/actions/setting.js
@@ -1,9 +1,23 @@
import actions from 'content/actions';
+import * as keyUtils from 'shared/utils/keys';
const set = (value) => {
+ let maps = new Map();
+ if (value.keymaps) {
+ let entries = Object.entries(value.keymaps).map((entry) => {
+ return [
+ keyUtils.fromMapKeys(entry[0]),
+ entry[1],
+ ];
+ });
+ maps = new Map(entries);
+ }
+
return {
type: actions.SETTING_SET,
- value,
+ value: Object.assign({}, value, {
+ keymaps: maps,
+ })
};
};
diff --git a/src/content/components/common/follow.js b/src/content/components/common/follow.js
index 83aeb0a..7a35105 100644
--- a/src/content/components/common/follow.js
+++ b/src/content/components/common/follow.js
@@ -46,7 +46,7 @@ export default class Follow {
}
this.win.parent.postMessage(JSON.stringify({
type: messages.FOLLOW_KEY_PRESS,
- key,
+ key: key.key,
}), '*');
return true;
}
diff --git a/src/content/components/common/input.js b/src/content/components/common/input.js
index 8b1d35d..22b0a91 100644
--- a/src/content/components/common/input.js
+++ b/src/content/components/common/input.js
@@ -1,22 +1,5 @@
import * as dom from 'shared/utils/dom';
-
-const modifierdKeyName = (name) => {
- if (name.length === 1) {
- return name.toUpperCase();
- } else if (name === 'Escape') {
- return 'Esc';
- }
- return name;
-};
-
-const mapKey = (e) => {
- if (e.ctrlKey) {
- return '<C-' + modifierdKeyName(e.key) + '>';
- } else if (e.shiftKey && e.key.length !== 1) {
- return '<S-' + modifierdKeyName(e.key) + '>';
- }
- return e.key;
-};
+import * as keys from 'shared/utils/keys';
export default class InputComponent {
constructor(target) {
@@ -64,7 +47,7 @@ export default class InputComponent {
return;
}
- let key = mapKey(e);
+ let key = keys.fromKeyboardEvent(e);
for (let listener of this.onKeyListeners) {
let stop = listener(key);
diff --git a/src/content/components/common/keymapper.js b/src/content/components/common/keymapper.js
index 1da3c0d..0abbc91 100644
--- a/src/content/components/common/keymapper.js
+++ b/src/content/components/common/keymapper.js
@@ -1,6 +1,19 @@
import * as inputActions from 'content/actions/input';
import * as operationActions from 'content/actions/operation';
import operations from 'shared/operations';
+import * as keyUtils from 'shared/utils/keys';
+
+const mapStartsWith = (mapping, keys) => {
+ if (mapping.length < keys.length) {
+ return false;
+ }
+ for (let i = 0; i < keys.length; ++i) {
+ if (!keyUtils.equals(mapping[i], keys[i])) {
+ return false;
+ }
+ }
+ return true;
+};
export default class KeymapperComponent {
constructor(store) {
@@ -14,14 +27,14 @@ export default class KeymapperComponent {
let input = state.input;
let keymaps = state.setting.keymaps;
- let matched = Object.keys(keymaps).filter((keyStr) => {
- return keyStr.startsWith(input.keys);
+ let matched = Array.from(keymaps.keys()).filter((mapping) => {
+ return mapStartsWith(mapping, input.keys);
});
if (!state.addon.enabled) {
// available keymaps are only ADDON_ENABLE and ADDON_TOGGLE_ENABLED if
// the addon disabled
matched = matched.filter((keys) => {
- let type = keymaps[keys].type;
+ let type = keymaps.get(keys).type;
return type === operations.ADDON_ENABLE ||
type === operations.ADDON_TOGGLE_ENABLED;
});
@@ -30,10 +43,10 @@ export default class KeymapperComponent {
this.store.dispatch(inputActions.clearKeys());
return false;
} else if (matched.length > 1 ||
- matched.length === 1 && input.keys !== matched[0]) {
+ matched.length === 1 && input.keys.length < matched[0].length) {
return true;
}
- let operation = keymaps[matched];
+ let operation = keymaps.get(matched[0]);
this.store.dispatch(operationActions.exec(operation));
this.store.dispatch(inputActions.clearKeys());
return true;
diff --git a/src/content/components/top-content/follow-controller.js b/src/content/components/top-content/follow-controller.js
index 38869e6..d373177 100644
--- a/src/content/components/top-content/follow-controller.js
+++ b/src/content/components/top-content/follow-controller.js
@@ -76,7 +76,7 @@ export default class FollowController {
this.activate();
this.store.dispatch(followControllerActions.disable());
break;
- case 'Escape':
+ case 'Esc':
this.store.dispatch(followControllerActions.disable());
break;
case 'Backspace':
diff --git a/src/content/reducers/input.js b/src/content/reducers/input.js
index 9457604..134aa95 100644
--- a/src/content/reducers/input.js
+++ b/src/content/reducers/input.js
@@ -1,18 +1,18 @@
import actions from 'content/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 + action.key
+ keys: state.keys.concat([action.key]),
});
case actions.INPUT_CLEAR_KEYS:
return Object.assign({}, state, {
- keys: '',
+ keys: [],
});
default:
return state;
diff --git a/src/content/reducers/setting.js b/src/content/reducers/setting.js
index b6f6c58..a54f5a3 100644
--- a/src/content/reducers/setting.js
+++ b/src/content/reducers/setting.js
@@ -1,7 +1,7 @@
import actions from 'content/actions';
const defaultState = {
- keymaps: {},
+ keymaps: new Map(),
};
export default function reducer(state = defaultState, action = {}) {