aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShin'ya Ueoka <ueokande@i-beam.org>2017-09-30 16:20:16 +0900
committerShin'ya Ueoka <ueokande@i-beam.org>2017-09-30 16:20:16 +0900
commit1145eb34784c1450b920f8e7d672934ef6a98d45 (patch)
treef076a7f2366af89177f2bbc45a6cf8866407f3d5
parentc2a5a41cb6bc7780db580e6325e25b6a81729851 (diff)
parentc5efeda78cdf39e3eda1eabc5f89b601b1fcdb6e (diff)
Merge branch 'configurable-keymap'
-rw-r--r--manifest.json10
-rw-r--r--src/actions/index.js1
-rw-r--r--src/actions/input.js9
-rw-r--r--src/actions/operation.js18
-rw-r--r--src/background/default-settings.js39
-rw-r--r--src/background/index.js20
-rw-r--r--src/background/keys.js42
-rw-r--r--src/content/index.js4
-rw-r--r--src/messages/index.js4
-rw-r--r--src/operations/index.js31
-rw-r--r--src/reducers/input.js6
-rw-r--r--src/settings/index.js22
-rw-r--r--src/settings/settings.html18
-rw-r--r--src/settings/settings.scss8
-rw-r--r--webpack.config.js6
15 files changed, 167 insertions, 71 deletions
diff --git a/manifest.json b/manifest.json
index dfb4ae9..7c60cdd 100644
--- a/manifest.json
+++ b/manifest.json
@@ -15,11 +15,15 @@
]
},
"permissions": [
+ "history",
"sessions",
- "tabs",
- "history"
+ "storage",
+ "tabs"
],
"web_accessible_resources": [
"build/console.html"
- ]
+ ],
+ "options_ui": {
+ "page": "build/settings.html"
+ }
}
diff --git a/src/actions/index.js b/src/actions/index.js
index 977b3c2..7b79864 100644
--- a/src/actions/index.js
+++ b/src/actions/index.js
@@ -8,4 +8,5 @@ export default {
// User input
INPUT_KEY_PRESS: 'input.key,press',
INPUT_CLEAR_KEYS: 'input.clear.keys',
+ INPUT_SET_KEYMAPS: 'input.set,keymaps',
};
diff --git a/src/actions/input.js b/src/actions/input.js
index 07948a1..de6de4e 100644
--- a/src/actions/input.js
+++ b/src/actions/input.js
@@ -14,4 +14,11 @@ const clearKeys = () => {
};
};
-export { keyPress, clearKeys };
+const setKeymaps = (keymaps) => {
+ return {
+ type: actions.INPUT_SET_KEYMAPS,
+ keymaps: keymaps
+ };
+};
+
+export { keyPress, clearKeys, setKeymaps };
diff --git a/src/actions/operation.js b/src/actions/operation.js
index 50329f8..5646c1c 100644
--- a/src/actions/operation.js
+++ b/src/actions/operation.js
@@ -6,15 +6,15 @@ import * as zooms from '../background/zooms';
const exec = (operation, tab) => {
switch (operation.type) {
- case operations.TABS_CLOSE:
+ case operations.TAB_CLOSE:
return tabs.closeTab(tab.id);
- case operations.TABS_REOPEN:
+ case operations.TAB_REOPEN:
return tabs.reopenTab();
- case operations.TABS_PREV:
+ case operations.TAB_PREV:
return tabs.selectPrevTab(tab.index, operation.count);
- case operations.TABS_NEXT:
+ case operations.TAB_NEXT:
return tabs.selectNextTab(tab.index, operation.count);
- case operations.TABS_RELOAD:
+ case operations.TAB_RELOAD:
return tabs.reload(tab, operation.cache);
case operations.ZOOM_IN:
return zooms.zoomIn();
@@ -22,21 +22,21 @@ const exec = (operation, tab) => {
return zooms.zoomOut();
case operations.ZOOM_NEUTRAL:
return zooms.neutral();
- case operations.COMMAND_OPEN:
+ case operations.COMMAND_SHOW:
return consoleActions.showCommand('');
- case operations.COMMAND_TABS_OPEN:
+ case operations.COMMAND_SHOW_OPEN:
if (operation.alter) {
// alter url
return consoleActions.showCommand('open ' + tab.url);
}
return consoleActions.showCommand('open ');
- case operations.COMMAND_TABS_NEW:
+ case operations.COMMAND_SHOW_TABOPEN:
if (operation.alter) {
// alter url
return consoleActions.showCommand('tabopen ' + tab.url);
}
return consoleActions.showCommand('tabopen ');
- case operations.COMMAND_BUFFER:
+ case operations.COMMAND_SHOW_BUFFER:
return consoleActions.showCommand('buffer ');
default:
return browser.tabs.sendMessage(tab.id, {
diff --git a/src/background/default-settings.js b/src/background/default-settings.js
new file mode 100644
index 0000000..ea6318b
--- /dev/null
+++ b/src/background/default-settings.js
@@ -0,0 +1,39 @@
+export default `{
+ "keymaps": {
+ "0": { "type": "scroll.home" },
+ ":": { "type": "command.show" },
+ "o": { "type": "command.show.open", "alter": false },
+ "O": { "type": "command.show.open", "alter": true },
+ "t": { "type": "command.show.tabopen", "alter": false },
+ "T": { "type": "command.show.tabopen", "alter": true },
+ "b": { "type": "command.show.buffer" },
+ "k": { "type": "scroll.lines", "count": -1 },
+ "j": { "type": "scroll.lines", "count": 1 },
+ "<C-E>": { "type": "scroll.lines", "count": -1 },
+ "<C-Y>": { "type": "scroll.lines", "count": 1 },
+ "<C-U>": { "type": "scroll.pages", "count": -0.5 },
+ "<C-D>": { "type": "scroll.pages", "count": 0.5 },
+ "<C-B>": { "type": "scroll.pages", "count": -1 },
+ "<C-F>": { "type": "scroll.pages", "count": 1 },
+ "gg": { "type": "scroll.top" },
+ "G": { "type": "scroll.bottom" },
+ "$": { "type": "scroll.end" },
+ "d": { "type": "tabs.close" },
+ "u": { "type": "tabs.reopen" },
+ "h": { "type": "tabs.prev", "count": 1 },
+ "l": { "type": "tabs.next", "count": 1 },
+ "r": { "type": "tabs.reload", "cache": false },
+ "R": { "type": "tabs.reload", "cache": true },
+ "zi": { "type": "zoom.in" },
+ "zo": { "type": "zoom.out" },
+ "zz": { "type": "zoom.neutral" },
+ "f": { "type": "follow.start", "newTab": false },
+ "F": { "type": "follow.start", "newTab": true },
+ "H": { "type": "navigate.history.prev" },
+ "L": { "type": "navigate.history.next" },
+ "[[": { "type": "navigate.link.prev" },
+ "]]": { "type": "navigate.link.next" },
+ "gu": { "type": "navigate.parent" },
+ "gU": { "type": "navigate.root" }
+ }
+}`;
diff --git a/src/background/index.js b/src/background/index.js
index 9df22fd..5ae967c 100644
--- a/src/background/index.js
+++ b/src/background/index.js
@@ -41,7 +41,7 @@ backgroundStore.subscribe((sender) => {
const keyQueueChanged = (state, sender) => {
let prefix = keys.asKeymapChars(state.input.keys);
- let matched = Object.keys(keys.defaultKeymap).filter((keyStr) => {
+ let matched = Object.keys(state.input.keymaps).filter((keyStr) => {
return keyStr.startsWith(prefix);
});
if (matched.length === 0) {
@@ -51,11 +51,19 @@ const keyQueueChanged = (state, sender) => {
matched.length === 1 && prefix !== matched[0]) {
return Promise.resolve();
}
- let action = keys.defaultKeymap[matched];
+ let action = state.input.keymaps[matched];
backgroundStore.dispatch(operationActions.exec(action, sender.tab), sender);
backgroundStore.dispatch(inputActions.clearKeys(), sender);
};
+const reloadSettings = () => {
+ browser.storage.local.get('settings').then((value) => {
+ let settings = JSON.parse(value.settings.json);
+ let action = inputActions.setKeymaps(settings.keymaps);
+ backgroundStore.dispatch(action);
+ }, console.error);
+};
+
const handleMessage = (message, sender) => {
switch (message.type) {
case messages.KEYDOWN:
@@ -77,6 +85,8 @@ const handleMessage = (message, sender) => {
case messages.CONSOLE_CHANGEED:
return backgroundStore.dispatch(
commandActions.complete(message.text), sender);
+ case messages.SETTINGS_RELOAD:
+ return reloadSettings();
}
};
@@ -87,3 +97,9 @@ browser.runtime.onMessage.addListener((message, sender) => {
backgroundStore.dispatch(consoleActions.showError(e.message), sender);
}
});
+
+const initializeSettings = () => {
+ reloadSettings();
+};
+
+initializeSettings();
diff --git a/src/background/keys.js b/src/background/keys.js
index e4a8b19..aca050e 100644
--- a/src/background/keys.js
+++ b/src/background/keys.js
@@ -1,43 +1,3 @@
-import operations from '../operations';
-
-const defaultKeymap = {
- ':': { type: operations.COMMAND_OPEN },
- 'o': { type: operations.COMMAND_TABS_OPEN, alter: false },
- 'O': { type: operations.COMMAND_TABS_OPEN, alter: true },
- 't': { type: operations.COMMAND_TABS_NEW, alter: false },
- 'T': { type: operations.COMMAND_TABS_NEW, alter: true },
- 'b': { type: operations.COMMAND_BUFFER },
- 'k': { type: operations.SCROLL_LINES, count: -1 },
- 'j': { type: operations.SCROLL_LINES, count: 1 },
- '<C-E>': { type: operations.SCROLL_LINES, count: -1 },
- '<C-Y>': { type: operations.SCROLL_LINES, count: 1 },
- '<C-U>': { type: operations.SCROLL_PAGES, count: -0.5 },
- '<C-D>': { type: operations.SCROLL_PAGES, count: 0.5 },
- '<C-B>': { type: operations.SCROLL_PAGES, count: -1 },
- '<C-F>': { type: operations.SCROLL_PAGES, count: 1 },
- 'gg': { type: operations.SCROLL_TOP },
- 'G': { type: operations.SCROLL_BOTTOM },
- '0': { type: operations.SCROLL_LEFT },
- '$': { type: operations.SCROLL_RIGHT },
- 'd': { type: operations.TABS_CLOSE },
- 'u': { type: operations.TABS_REOPEN },
- 'h': { type: operations.TABS_PREV, count: 1 },
- 'l': { type: operations.TABS_NEXT, count: 1 },
- 'r': { type: operations.TABS_RELOAD, cache: false },
- 'R': { type: operations.TABS_RELOAD, cache: true },
- 'zi': { type: operations.ZOOM_IN },
- 'zo': { type: operations.ZOOM_OUT },
- 'zz': { type: operations.ZOOM_NEUTRAL },
- 'f': { type: operations.FOLLOW_START, newTab: false },
- 'F': { type: operations.FOLLOW_START, newTab: true },
- 'H': { type: operations.NAVIGATE_HISTORY_PREV },
- 'L': { type: operations.NAVIGATE_HISTORY_NEXT },
- '[[': { type: operations.NAVIGATE_LINK_PREV },
- ']]': { type: operations.NAVIGATE_LINK_NEXT },
- 'gu': { type: operations.NAVIGATE_PARENT },
- 'gU': { type: operations.NAVIGATE_ROOT },
-};
-
const asKeymapChars = (keys) => {
return keys.map((k) => {
let c = String.fromCharCode(k.code);
@@ -58,4 +18,4 @@ const asCaretChars = (keys) => {
}).join('');
};
-export { defaultKeymap, asKeymapChars, asCaretChars };
+export { asKeymapChars, asCaretChars };
diff --git a/src/content/index.js b/src/content/index.js
index 80acd2d..812fbc5 100644
--- a/src/content/index.js
+++ b/src/content/index.js
@@ -85,9 +85,9 @@ const execOperation = (operation) => {
return scrolls.scrollTop(window);
case operations.SCROLL_BOTTOM:
return scrolls.scrollBottom(window);
- case operations.SCROLL_LEFT:
+ case operations.SCROLL_HOME:
return scrolls.scrollLeft(window);
- case operations.SCROLL_RIGHT:
+ case operations.SCROLL_END:
return scrolls.scrollRight(window);
case operations.FOLLOW_START:
return startFollows(operation.newTab);
diff --git a/src/messages/index.js b/src/messages/index.js
index 4e34436..df9fba2 100644
--- a/src/messages/index.js
+++ b/src/messages/index.js
@@ -8,5 +8,7 @@ export default {
KEYDOWN: 'keydown',
- OPEN_URL: 'open.url'
+ OPEN_URL: 'open.url',
+
+ SETTINGS_RELOAD: 'settings.reload',
};
diff --git a/src/operations/index.js b/src/operations/index.js
index d6ffc42..b68f59d 100644
--- a/src/operations/index.js
+++ b/src/operations/index.js
@@ -1,17 +1,22 @@
export default {
// Command
- COMMAND_OPEN: 'cmd.open',
- COMMAND_TABS_OPEN: 'cmd.tabs.open',
- COMMAND_TABS_NEW: 'cmd.tabs.new',
- COMMAND_BUFFER: 'cmd.buffer',
+ COMMAND_SHOW: 'command.show',
+ COMMAND_SHOW_OPEN: 'command.show.open',
+ COMMAND_SHOW_TABOPEN: 'command.show.tabopen',
+ COMMAND_SHOW_BUFFER: 'command.show.buffer',
+ // Scrolls
SCROLL_LINES: 'scroll.lines',
SCROLL_PAGES: 'scroll.pages',
SCROLL_TOP: 'scroll.top',
SCROLL_BOTTOM: 'scroll.bottom',
- SCROLL_LEFT: 'scroll.left',
- SCROLL_RIGHT: 'scroll.right',
+ SCROLL_HOME: 'scroll.home',
+ SCROLL_END: 'scroll.end',
+
+ // Follows
FOLLOW_START: 'follow.start',
+
+ // Navigations
NAVIGATE_HISTORY_PREV: 'navigate.history.prev',
NAVIGATE_HISTORY_NEXT: 'navigate.history.next',
NAVIGATE_LINK_PREV: 'navigate.link.prev',
@@ -19,12 +24,14 @@ export default {
NAVIGATE_PARENT: 'navigate.parent',
NAVIGATE_ROOT: 'navigate.root',
- // Background
- TABS_CLOSE: 'tabs.close',
- TABS_REOPEN: 'tabs.reopen',
- TABS_PREV: 'tabs.prev',
- TABS_NEXT: 'tabs.next',
- TABS_RELOAD: 'tabs.reload',
+ // Tabs
+ TAB_CLOSE: 'tabs.close',
+ TAB_REOPEN: 'tabs.reopen',
+ TAB_PREV: 'tabs.prev',
+ TAB_NEXT: 'tabs.next',
+ TAB_RELOAD: 'tabs.reload',
+
+ // Zooms
ZOOM_IN: 'zoom.in',
ZOOM_OUT: 'zoom.out',
ZOOM_NEUTRAL: 'zoom.neutral',
diff --git a/src/reducers/input.js b/src/reducers/input.js
index eb7ff24..dca26e2 100644
--- a/src/reducers/input.js
+++ b/src/reducers/input.js
@@ -2,6 +2,7 @@ import actions from '../actions';
const defaultState = {
keys: [],
+ keymaps: {}
};
export default function reducer(state = defaultState, action = {}) {
@@ -19,6 +20,11 @@ export default function reducer(state = defaultState, action = {}) {
return Object.assign({}, state, {
keys: [],
});
+ case actions.INPUT_SET_KEYMAPS:
+ return Object.assign({}, state, {
+ keymaps: action.keymaps,
+ keys: [],
+ });
default:
return state;
}
diff --git a/src/settings/index.js b/src/settings/index.js
new file mode 100644
index 0000000..2ed060c
--- /dev/null
+++ b/src/settings/index.js
@@ -0,0 +1,22 @@
+import './settings.scss';
+import messages from '../messages';
+
+document.addEventListener('DOMContentLoaded', () => {
+ let form = document.getElementById('vimvixen-settings-form');
+ form.addEventListener('submit', (e) => {
+ e.preventDefault();
+ browser.storage.local.set({
+ settings: {
+ json: e.target.elements['plain-json'].value
+ }
+ }).then(() => {
+ return browser.runtime.sendMessage({
+ type: messages.SETTINGS_RELOAD
+ });
+ });
+ });
+
+ browser.storage.local.get('settings').then((value) => {
+ form.elements['plain-json'].value = value.settings.json;
+ }, console.error);
+});
diff --git a/src/settings/settings.html b/src/settings/settings.html
new file mode 100644
index 0000000..99d6c6b
--- /dev/null
+++ b/src/settings/settings.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset='utf-8'>
+ </head>
+ <body>
+ <h1>Configure</h1>
+
+ <h2>Home page</h2>
+ <form id='vimvixen-settings-form' class='vimvixen-settings-form'>
+ <label for='load-from-json'>Load from JSON:</label>
+ <textarea name='plain-json' spellcheck='false'></textarea>
+
+ <button type='submit'>Save</button>
+ </form>
+ <script src='settings.js'></script>
+ </body>
+</html>
diff --git a/src/settings/settings.scss b/src/settings/settings.scss
new file mode 100644
index 0000000..5707c8a
--- /dev/null
+++ b/src/settings/settings.scss
@@ -0,0 +1,8 @@
+.vimvixen-settings-form {
+ textarea[name=plain-json] {
+ font-family: monospace;
+ width: 100%;
+ min-height: 64ex;
+ resize: vertical;
+ }
+}
diff --git a/webpack.config.js b/webpack.config.js
index ba08975..bf121d1 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -7,6 +7,7 @@ const dist = path.resolve(__dirname, 'build');
module.exports = {
entry: {
index: path.join(src, 'content'),
+ settings: path.join(src, 'settings'),
background: path.join(src, 'background'),
console: path.join(src, 'console', 'console.js')
},
@@ -46,6 +47,11 @@ module.exports = {
template: path.join(src, 'console', 'console.html'),
filename: path.join(dist, 'console.html'),
inject: false
+ }),
+ new HtmlWebpackPlugin({
+ template: path.join(src, 'settings', 'settings.html'),
+ filename: path.join(dist, 'settings.html'),
+ inject: false
})
]
};