more strict lint
This commit is contained in:
parent
c5529958d5
commit
9ae814dfe4
21 changed files with 211 additions and 157 deletions
33
.eslintrc
33
.eslintrc
|
@ -11,28 +11,47 @@
|
|||
"jsx": true
|
||||
}
|
||||
},
|
||||
"extends": [ "eslint:recommended" ],
|
||||
"extends": [ "eslint:all" ],
|
||||
"rules": {
|
||||
"array-bracket-newline": ["error", { "multiline": true }],
|
||||
"arrow-body-style": "off",
|
||||
"array-element-newline": "off",
|
||||
"arrow-parens": ["error", "as-needed", { "requireForBlockBody": true }],
|
||||
"brace-style": ["error", "1tbs", { "allowSingleLine": true }],
|
||||
"comma-dangle": "off",
|
||||
"consistent-return": "off",
|
||||
"default-case": "off",
|
||||
"id-length": "off",
|
||||
"indent": ["error", 2],
|
||||
"max-statements": ["error", 15],
|
||||
"multiline-ternary": "off",
|
||||
"newline-after-var": "off",
|
||||
"newline-before-return": "off",
|
||||
"multiline-ternary": "off",
|
||||
"max-statements": ["error", 15],
|
||||
"no-console": "off",
|
||||
"no-param-reassign": "off",
|
||||
"no-magic-numbers": "off",
|
||||
"no-bitwise": "off",
|
||||
"no-use-before-define": "off",
|
||||
"no-warning-comments": "off",
|
||||
"no-console": ["error", { "allow": ["warn", "error"] }],
|
||||
"no-empty-function": "off",
|
||||
"no-mixed-operators": "off",
|
||||
"no-plusplus": "off",
|
||||
"capitalized-comments": "off",
|
||||
"no-ternary": "off",
|
||||
"no-undefined": "off",
|
||||
"object-curly-spacing": [
|
||||
"error",
|
||||
"always", { "arraysInObjects": false, "objectsInObjects": false }
|
||||
],
|
||||
"object-curly-newline": "off",
|
||||
"object-property-newline": "off",
|
||||
"object-curly-newline": ["error", { "consistent": true }],
|
||||
"object-property-newline": ["error", { "allowMultiplePropertiesPerLine": true }],
|
||||
"object-shorthand": "off",
|
||||
"one-var": "off",
|
||||
"padded-blocks": "off",
|
||||
"prefer-const": "off",
|
||||
"prefer-destructuring": ["error", { "AssignmentExpression": {"array": false}}],
|
||||
"prefer-template": "off",
|
||||
"quotes": ["error", "single", { "allowTemplateLiterals": true }],
|
||||
"quote-props": "off",
|
||||
"require-jsdoc": "off",
|
||||
"sort-imports": "off",
|
||||
"sort-keys": "off",
|
||||
|
|
|
@ -3,36 +3,39 @@ import * as consoleActions from './console';
|
|||
|
||||
const normalizeUrl = (string) => {
|
||||
try {
|
||||
return new URL(string).href
|
||||
return new URL(string).href;
|
||||
} catch (e) {
|
||||
return 'http://' + string;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const openCommand = (url) => {
|
||||
return browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => {
|
||||
if (tabs.length > 0) {
|
||||
return browser.tabs.update(tabs[0].id, { url: url });
|
||||
return browser.tabs.query({
|
||||
active: true, currentWindow: true
|
||||
}).then((gotTabs) => {
|
||||
if (gotTabs.length > 0) {
|
||||
return browser.tabs.update(gotTabs[0].id, { url: url });
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const tabopenCommand = (url) => {
|
||||
return browser.tabs.create({ url: url });
|
||||
}
|
||||
};
|
||||
|
||||
const bufferCommand = (keywords) => {
|
||||
return browser.tabs.query({ active: true, currentWindow: true }).then((tabss) => {
|
||||
if (tabss.length > 0) {
|
||||
return browser.tabs.query({
|
||||
active: true, currentWindow: true
|
||||
}).then((gotTabs) => {
|
||||
if (gotTabs.length > 0) {
|
||||
if (isNaN(keywords)) {
|
||||
return tabs.selectByKeyword(tabss[0], keywords);
|
||||
} else {
|
||||
let index = parseInt(keywords, 10) - 1;
|
||||
return tabs.selectAt(index);
|
||||
return tabs.selectByKeyword(gotTabs[0], keywords);
|
||||
}
|
||||
let index = parseInt(keywords, 10) - 1;
|
||||
return tabs.selectAt(index);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const doCommand = (name, remaining) => {
|
||||
switch (name) {
|
||||
|
@ -46,39 +49,43 @@ const doCommand = (name, remaining) => {
|
|||
return bufferCommand(remaining);
|
||||
}
|
||||
throw new Error(name + ' command is not defined');
|
||||
}
|
||||
};
|
||||
|
||||
const getCompletions = (command, keywords) => {
|
||||
switch (command) {
|
||||
case 'buffer':
|
||||
return tabs.getCompletions(keywords).then((tabs) => {
|
||||
let items = tabs.map((tab) => {
|
||||
return tabs.getCompletions(keywords).then((gotTabs) => {
|
||||
let items = gotTabs.map((tab) => {
|
||||
return {
|
||||
caption: tab.title,
|
||||
content: tab.title,
|
||||
url: tab.url,
|
||||
icon: tab.favIconUrl
|
||||
}
|
||||
};
|
||||
});
|
||||
return [{
|
||||
name: "Buffers",
|
||||
items: items
|
||||
}];
|
||||
return [
|
||||
{
|
||||
name: 'Buffers',
|
||||
items: items
|
||||
}
|
||||
];
|
||||
});
|
||||
}
|
||||
return Promise.resolve([]);
|
||||
};
|
||||
|
||||
export function exec(line) {
|
||||
const exec = (line) => {
|
||||
let name = line.split(' ')[0];
|
||||
let remaining = line.replace(name + ' ', '');
|
||||
return doCommand(name, remaining).then(() => {
|
||||
return consoleActions.hide();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export function complete(line) {
|
||||
const complete = (line) => {
|
||||
let command = line.split(' ', 1)[0];
|
||||
let keywords = line.replace(command + ' ', '');
|
||||
return getCompletions(command, keywords).then(consoleActions.setCompletions);
|
||||
}
|
||||
};
|
||||
|
||||
export { exec, complete };
|
||||
|
|
|
@ -1,28 +1,30 @@
|
|||
import actions from '../actions';
|
||||
|
||||
export function showCommand(text) {
|
||||
const showCommand = (text) => {
|
||||
return {
|
||||
type: actions.CONSOLE_SHOW_COMMAND,
|
||||
text: text
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export function setCompletions(completions) {
|
||||
const setCompletions = (completions) => {
|
||||
return {
|
||||
type: actions.CONSOLE_SET_COMPLETIONS,
|
||||
completions: completions
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export function showError(text) {
|
||||
const showError = (text) => {
|
||||
return {
|
||||
type: actions.CONSOLE_SHOW_ERROR,
|
||||
text: text
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export function hide() {
|
||||
const hide = () => {
|
||||
return {
|
||||
type: actions.CONSOLE_HIDE
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export { showCommand, setCompletions, showError, hide };
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import actions from '../actions';
|
||||
|
||||
export function keyPress(code, ctrl) {
|
||||
const keyPress = (code, ctrl) => {
|
||||
return {
|
||||
type: actions.INPUT_KEY_PRESS,
|
||||
code,
|
||||
ctrl
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export function clearKeys() {
|
||||
const clearKeys = () => {
|
||||
return {
|
||||
type: actions.INPUT_CLEAR_KEYS
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export { keyPress, clearKeys };
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import operations from '../operations';
|
||||
import messages from '../messages';
|
||||
import messages from '../messages';
|
||||
import * as consoleActions from './console';
|
||||
import * as tabs from '../background/tabs';
|
||||
import * as zooms from '../background/zooms';
|
||||
|
||||
export function exec(operation, tab) {
|
||||
const exec = (operation, tab) => {
|
||||
switch (operation.type) {
|
||||
case operations.TABS_CLOSE:
|
||||
return tabs.closeTab(tab.id);
|
||||
|
@ -28,9 +28,8 @@ export function exec(operation, tab) {
|
|||
if (operations.alter) {
|
||||
// alter url
|
||||
return consoleActions.showCommand('open ' + tab.url);
|
||||
} else {
|
||||
return consoleActions.showCommand('open ');
|
||||
}
|
||||
return consoleActions.showCommand('open ');
|
||||
case operations.COMMAND_BUFFER:
|
||||
return consoleActions.showCommand('buffer ');
|
||||
default:
|
||||
|
@ -39,5 +38,6 @@ export function exec(operation, tab) {
|
|||
operation
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export { exec };
|
||||
|
|
|
@ -5,9 +5,10 @@ import * as commandActions from '../actions/command';
|
|||
import * as consoleActions from '../actions/console';
|
||||
import reducers from '../reducers';
|
||||
import messages from '../messages';
|
||||
import * as store from '../store'
|
||||
import * as store from '../store';
|
||||
|
||||
let prevInput = [];
|
||||
|
||||
const backgroundStore = store.createStore(reducers, (e, sender) => {
|
||||
console.error('Vim-Vixen:', e);
|
||||
if (sender) {
|
||||
|
@ -15,9 +16,9 @@ const backgroundStore = store.createStore(reducers, (e, sender) => {
|
|||
}
|
||||
});
|
||||
backgroundStore.subscribe((sender) => {
|
||||
let currentInput = backgroundStore.getState().input
|
||||
let currentInput = backgroundStore.getState().input;
|
||||
if (JSON.stringify(prevInput) === JSON.stringify(currentInput)) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
prevInput = currentInput;
|
||||
|
||||
|
@ -39,13 +40,14 @@ backgroundStore.subscribe((sender) => {
|
|||
|
||||
const keyQueueChanged = (state, sender) => {
|
||||
let prefix = keys.asKeymapChars(state.input.keys);
|
||||
let matched = Object.keys(keys.defaultKeymap).filter((keys) => {
|
||||
return keys.startsWith(prefix);
|
||||
let matched = Object.keys(keys.defaultKeymap).filter((keyStr) => {
|
||||
return keyStr.startsWith(prefix);
|
||||
});
|
||||
if (matched.length == 0) {
|
||||
if (matched.length === 0) {
|
||||
backgroundStore.dispatch(inputActions.clearKeys(), sender);
|
||||
return Promise.resolve();
|
||||
} else if (matched.length > 1 || matched.length === 1 && prefix !== matched[0]) {
|
||||
} else if (matched.length > 1 ||
|
||||
matched.length === 1 && prefix !== matched[0]) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
let action = keys.defaultKeymap[matched];
|
||||
|
@ -56,15 +58,19 @@ const keyQueueChanged = (state, sender) => {
|
|||
const handleMessage = (message, sender) => {
|
||||
switch (message.type) {
|
||||
case messages.KEYDOWN:
|
||||
return backgroundStore.dispatch(inputActions.keyPress(message.code, message.ctrl), sender);
|
||||
return backgroundStore.dispatch(
|
||||
inputActions.keyPress(message.code, message.ctrl), sender);
|
||||
case messages.CONSOLE_BLURRED:
|
||||
return backgroundStore.dispatch(consoleActions.hide(), sender);
|
||||
return backgroundStore.dispatch(
|
||||
consoleActions.hide(), sender);
|
||||
case messages.CONSOLE_ENTERED:
|
||||
return backgroundStore.dispatch(commandActions.exec(message.text), sender);
|
||||
return backgroundStore.dispatch(
|
||||
commandActions.exec(message.text), sender);
|
||||
case messages.CONSOLE_CHANGEED:
|
||||
return backgroundStore.dispatch(commandActions.complete(message.text), sender);
|
||||
return backgroundStore.dispatch(
|
||||
commandActions.complete(message.text), sender);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
browser.runtime.onMessage.addListener((message, sender) => {
|
||||
try {
|
||||
|
|
|
@ -30,28 +30,26 @@ const defaultKeymap = {
|
|||
'F': { type: operations.FOLLOW_START, newTab: true },
|
||||
'H': { type: operations.HISTORY_PREV },
|
||||
'L': { type: operations.HISTORY_NEXT },
|
||||
}
|
||||
};
|
||||
|
||||
const asKeymapChars = (keys) => {
|
||||
return keys.map((k) => {
|
||||
let c = String.fromCharCode(k.code);
|
||||
if (k.ctrl) {
|
||||
return '<C-' + c.toUpperCase() + '>';
|
||||
} else {
|
||||
return c
|
||||
}
|
||||
return c;
|
||||
}).join('');
|
||||
}
|
||||
};
|
||||
|
||||
const asCaretChars = (keys) => {
|
||||
return keys.map((k) => {
|
||||
let c = String.fromCharCode(k.code);
|
||||
if (k.ctrl) {
|
||||
return '^' + c.toUpperCase();
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
return c;
|
||||
}).join('');
|
||||
}
|
||||
};
|
||||
|
||||
export { defaultKeymap, asKeymapChars, asCaretChars };
|
||||
|
|
|
@ -12,9 +12,8 @@ const reopenTab = () => {
|
|||
let session = sessions[0];
|
||||
if (session.tab) {
|
||||
return browser.sessions.restore(session.tab.sessionId);
|
||||
} else {
|
||||
return browser.sessions.restore(session.window.sessionId);
|
||||
}
|
||||
return browser.sessions.restore(session.window.sessionId);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -24,20 +23,20 @@ const selectAt = (index) => {
|
|||
return;
|
||||
}
|
||||
if (index < 0 || tabs.length <= index) {
|
||||
throw new RangeError(`tab ${index} does not exist`)
|
||||
throw new RangeError(`tab ${index} does not exist`);
|
||||
}
|
||||
let id = tabs[index].id;
|
||||
return browser.tabs.update(id, { active: true })
|
||||
return browser.tabs.update(id, { active: true });
|
||||
});
|
||||
};
|
||||
|
||||
const selectByKeyword = (current, keyword) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then((tabs) => {
|
||||
let matched = tabs.filter((t) => {
|
||||
return t.url.includes(keyword) || t.title.includes(keyword)
|
||||
})
|
||||
return t.url.includes(keyword) || t.title.includes(keyword);
|
||||
});
|
||||
|
||||
if (matched.length == 0) {
|
||||
if (matched.length === 0) {
|
||||
throw new RangeError('No matching buffer for ' + keyword);
|
||||
}
|
||||
for (let tab of matched) {
|
||||
|
@ -47,13 +46,13 @@ const selectByKeyword = (current, keyword) => {
|
|||
}
|
||||
return browser.tabs.update(matched[0].id, { active: true });
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getCompletions = (keyword) => {
|
||||
return browser.tabs.query({ currentWindow: true }).then((tabs) => {
|
||||
let matched = tabs.filter((t) => {
|
||||
return t.url.includes(keyword) || t.title.includes(keyword)
|
||||
})
|
||||
return t.url.includes(keyword) || t.title.includes(keyword);
|
||||
});
|
||||
return matched;
|
||||
});
|
||||
};
|
||||
|
@ -63,9 +62,9 @@ const selectPrevTab = (current, count) => {
|
|||
if (tabs.length < 2) {
|
||||
return;
|
||||
}
|
||||
let select = (current - count) % tabs.length
|
||||
let select = (current - count) % tabs.length;
|
||||
let id = tabs[select].id;
|
||||
return browser.tabs.update(id, { active: true })
|
||||
return browser.tabs.update(id, { active: true });
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -74,9 +73,9 @@ const selectNextTab = (current, count) => {
|
|||
if (tabs.length < 2) {
|
||||
return;
|
||||
}
|
||||
let select = (current + count + tabs.length) % tabs.length
|
||||
let select = (current + count + tabs.length) % tabs.length;
|
||||
let id = tabs[select].id;
|
||||
return browser.tabs.update(id, { active: true })
|
||||
return browser.tabs.update(id, { active: true });
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -87,4 +86,7 @@ const reload = (current, cache) => {
|
|||
);
|
||||
};
|
||||
|
||||
export { closeTab, reopenTab, selectAt, selectByKeyword, getCompletions, selectPrevTab, selectNextTab, reload };
|
||||
export {
|
||||
closeTab, reopenTab, selectAt, selectByKeyword, getCompletions,
|
||||
selectPrevTab, selectNextTab, reload
|
||||
};
|
||||
|
|
|
@ -3,15 +3,16 @@ export default class Completion {
|
|||
if (typeof completions.length !== 'number') {
|
||||
throw new TypeError('completions does not have a length in number');
|
||||
}
|
||||
this.completions = completions
|
||||
this.completions = completions;
|
||||
this.index = 0;
|
||||
}
|
||||
|
||||
prev() {
|
||||
if (this.completions.length === 0) {
|
||||
let length = this.completions.length;
|
||||
if (length === 0) {
|
||||
return null;
|
||||
}
|
||||
this.index = (this.index + this.completions.length - 1) % this.completions.length
|
||||
this.index = (this.index + length - 1) % length;
|
||||
return this.completions[this.index];
|
||||
}
|
||||
|
||||
|
@ -20,7 +21,7 @@ export default class Completion {
|
|||
return null;
|
||||
}
|
||||
let item = this.completions[this.index];
|
||||
this.index = (this.index + 1) % this.completions.length
|
||||
this.index = (this.index + 1) % this.completions.length;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@ import Completion from './completion';
|
|||
import messages from '../messages';
|
||||
|
||||
// TODO consider object-oriented
|
||||
var prevValue = "";
|
||||
var completion = null;
|
||||
var completionOrigin = "";
|
||||
var prevState = {};
|
||||
let prevValue = '';
|
||||
let completion = null;
|
||||
let completionOrigin = '';
|
||||
let prevState = {};
|
||||
|
||||
const handleBlur = () => {
|
||||
return browser.runtime.sendMessage({
|
||||
|
@ -14,6 +14,20 @@ const handleBlur = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const selectCompletion = (target) => {
|
||||
let container = window.document.querySelector('#vimvixen-console-completion');
|
||||
Array.prototype.forEach.call(container.children, (ele) => {
|
||||
if (!ele.classList.contains('vimvixen-console-completion-item')) {
|
||||
return;
|
||||
}
|
||||
if (ele === target) {
|
||||
ele.classList.add('vimvixen-completion-selected');
|
||||
} else {
|
||||
ele.classList.remove('vimvixen-completion-selected');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const completeNext = () => {
|
||||
if (!completion) {
|
||||
return;
|
||||
|
@ -27,7 +41,7 @@ const completeNext = () => {
|
|||
input.value = completionOrigin + ' ' + item[0].content;
|
||||
|
||||
selectCompletion(item[1]);
|
||||
}
|
||||
};
|
||||
|
||||
const completePrev = () => {
|
||||
if (!completion) {
|
||||
|
@ -42,12 +56,12 @@ const completePrev = () => {
|
|||
input.value = completionOrigin + ' ' + item[0].content;
|
||||
|
||||
selectCompletion(item[1]);
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeydown = (e) => {
|
||||
let input = window.document.querySelector('#vimvixen-console-command-input');
|
||||
|
||||
switch(e.keyCode) {
|
||||
switch (e.keyCode) {
|
||||
case KeyboardEvent.DOM_VK_ESCAPE:
|
||||
return input.blur();
|
||||
case KeyboardEvent.DOM_VK_RETURN:
|
||||
|
@ -92,17 +106,17 @@ const createCompletionTitle = (text) => {
|
|||
let li = document.createElement('li');
|
||||
li.className = 'vimvixen-console-completion-title';
|
||||
li.textContent = text;
|
||||
return li
|
||||
}
|
||||
return li;
|
||||
};
|
||||
|
||||
const createCompletionItem = (icon, caption, url) => {
|
||||
let captionEle = document.createElement('span');
|
||||
captionEle.className = 'vimvixen-console-completion-item-caption';
|
||||
captionEle.textContent = caption
|
||||
captionEle.textContent = caption;
|
||||
|
||||
let urlEle = document.createElement('span');
|
||||
urlEle.className = 'vimvixen-console-completion-item-url';
|
||||
urlEle.textContent = url
|
||||
urlEle.textContent = url;
|
||||
|
||||
let li = document.createElement('li');
|
||||
li.style.backgroundImage = 'url(' + icon + ')';
|
||||
|
@ -110,24 +124,11 @@ const createCompletionItem = (icon, caption, url) => {
|
|||
li.append(captionEle);
|
||||
li.append(urlEle);
|
||||
return li;
|
||||
}
|
||||
|
||||
const selectCompletion = (target) => {
|
||||
let container = window.document.querySelector('#vimvixen-console-completion');
|
||||
Array.prototype.forEach.call(container.children, (ele) => {
|
||||
if (!ele.classList.contains('vimvixen-console-completion-item')) {
|
||||
return;
|
||||
}
|
||||
if (ele === target) {
|
||||
ele.classList.add('vimvixen-completion-selected');
|
||||
} else {
|
||||
ele.classList.remove('vimvixen-completion-selected');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const updateCompletions = (completions) => {
|
||||
let completionsContainer = window.document.querySelector('#vimvixen-console-completion');
|
||||
let completionsContainer =
|
||||
window.document.querySelector('#vimvixen-console-completion');
|
||||
let input = window.document.querySelector('#vimvixen-console-command-input');
|
||||
|
||||
completionsContainer.innerHTML = '';
|
||||
|
@ -148,7 +149,7 @@ const updateCompletions = (completions) => {
|
|||
|
||||
completion = new Completion(pairs);
|
||||
completionOrigin = input.value.split(' ')[0];
|
||||
}
|
||||
};
|
||||
|
||||
const update = (state) => {
|
||||
let error = window.document.querySelector('#vimvixen-console-error');
|
||||
|
@ -163,12 +164,13 @@ const update = (state) => {
|
|||
input.value = state.commandText;
|
||||
input.focus();
|
||||
}
|
||||
if (JSON.stringify(state.completions) !== JSON.stringify(prevState.completions)) {
|
||||
if (JSON.stringify(state.completions) !==
|
||||
JSON.stringify(prevState.completions)) {
|
||||
updateCompletions(state.completions);
|
||||
}
|
||||
|
||||
prevState = state;
|
||||
}
|
||||
};
|
||||
|
||||
browser.runtime.onMessage.addListener((action) => {
|
||||
if (action.type === messages.STATE_UPDATE) {
|
||||
|
|
|
@ -8,11 +8,11 @@ const initialize = (doc) => {
|
|||
doc.body.append(iframe);
|
||||
|
||||
return iframe;
|
||||
}
|
||||
};
|
||||
|
||||
const blur = (doc) => {
|
||||
let iframe = doc.getElementById('vimvixen-console-frame');
|
||||
iframe.blur();
|
||||
}
|
||||
};
|
||||
|
||||
export { initialize, blur };
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Hint from './hint';
|
||||
import HintKeyProducer from './hint-key-producer';
|
||||
|
||||
const DEFAULT_HINT_CHARSET = 'abcdefghijklmnopqrstuvwxyz'
|
||||
const DEFAULT_HINT_CHARSET = 'abcdefghijklmnopqrstuvwxyz';
|
||||
|
||||
export default class Follow {
|
||||
constructor(doc) {
|
||||
|
@ -22,14 +22,14 @@ export default class Follow {
|
|||
let producer = new HintKeyProducer(DEFAULT_HINT_CHARSET);
|
||||
Array.prototype.forEach.call(elements, (ele) => {
|
||||
let keys = producer.produce();
|
||||
let hint = new Hint(ele, keys)
|
||||
let hint = new Hint(ele, keys);
|
||||
|
||||
this.hintElements[keys] = hint;
|
||||
});
|
||||
}
|
||||
|
||||
handleKeydown(e) {
|
||||
let keyCode = e.keyCode;
|
||||
let { keyCode } = e;
|
||||
if (keyCode === KeyboardEvent.DOM_VK_ESCAPE) {
|
||||
this.remove();
|
||||
return;
|
||||
|
@ -56,10 +56,10 @@ export default class Follow {
|
|||
let hidden = Object.keys(this.hintElements).filter((key) => {
|
||||
return !key.startsWith(chars);
|
||||
});
|
||||
if (shown.length == 0) {
|
||||
if (shown.length === 0) {
|
||||
this.remove();
|
||||
return;
|
||||
} else if (shown.length == 1) {
|
||||
} else if (shown.length === 1) {
|
||||
this.remove();
|
||||
this.hintElements[chars].activate();
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ export default class Follow {
|
|||
|
||||
|
||||
remove() {
|
||||
this.doc.removeEventListener("keydown", this.boundKeydown);
|
||||
this.doc.removeEventListener('keydown', this.boundKeydown);
|
||||
Object.keys(this.hintElements).forEach((key) => {
|
||||
this.hintElements[key].remove();
|
||||
});
|
||||
|
@ -87,6 +87,14 @@ export default class Follow {
|
|||
);
|
||||
}
|
||||
|
||||
static isNumericKey(code) {
|
||||
return KeyboardEvent.DOM_VK_0 <= code && code <= KeyboardEvent.DOM_VK_9;
|
||||
}
|
||||
|
||||
static isAlphabeticKey(code) {
|
||||
return KeyboardEvent.DOM_VK_A <= code && code <= KeyboardEvent.DOM_VK_Z;
|
||||
}
|
||||
|
||||
static codeChars(codes) {
|
||||
const CHARCODE_ZERO = '0'.charCodeAt(0);
|
||||
const CHARCODE_A = 'a'.charCodeAt(0);
|
||||
|
@ -94,10 +102,12 @@ export default class Follow {
|
|||
let chars = '';
|
||||
|
||||
for (let code of codes) {
|
||||
if (KeyboardEvent.DOM_VK_0 <= code && code <= KeyboardEvent.DOM_VK_9) {
|
||||
chars += String.fromCharCode(code - KeyboardEvent.DOM_VK_0 + CHARCODE_ZERO);
|
||||
} else if (KeyboardEvent.DOM_VK_A <= code && code <= KeyboardEvent.DOM_VK_Z) {
|
||||
chars += String.fromCharCode(code - KeyboardEvent.DOM_VK_A + CHARCODE_A);
|
||||
if (Follow.isNumericKey(code)) {
|
||||
chars += String.fromCharCode(
|
||||
code - KeyboardEvent.DOM_VK_0 + CHARCODE_ZERO);
|
||||
} else if (Follow.isAlphabeticKey(code)) {
|
||||
chars += String.fromCharCode(
|
||||
code - KeyboardEvent.DOM_VK_A + CHARCODE_A);
|
||||
}
|
||||
}
|
||||
return chars;
|
||||
|
@ -112,7 +122,7 @@ export default class Follow {
|
|||
}
|
||||
|
||||
static isVisibleElement(element) {
|
||||
var style = window.getComputedStyle(element);
|
||||
let style = window.getComputedStyle(element);
|
||||
if (style.display === 'none') {
|
||||
return false;
|
||||
} else if (style.visibility === 'hidden') {
|
||||
|
|
|
@ -11,19 +11,19 @@ export default class HintKeyProducer {
|
|||
produce() {
|
||||
this.increment();
|
||||
|
||||
return this.counter.map((x) => this.charset[x]).join('');
|
||||
return this.counter.map(x => this.charset[x]).join('');
|
||||
}
|
||||
|
||||
increment() {
|
||||
let max = this.charset.length - 1;
|
||||
if (this.counter.every((x) => x == max)) {
|
||||
if (this.counter.every(x => x === max)) {
|
||||
this.counter = new Array(this.counter.length + 1).fill(0);
|
||||
return;
|
||||
}
|
||||
|
||||
this.counter.reverse();
|
||||
let len = this.charset.length;
|
||||
let num = this.counter.reduce((x,y,index) => x + y * (len ** index)) + 1;
|
||||
let num = this.counter.reduce((x, y, index) => x + y * len ** index) + 1;
|
||||
for (let i = 0; i < this.counter.length; ++i) {
|
||||
this.counter[i] = num % len;
|
||||
num = ~~(num / len);
|
||||
|
|
|
@ -8,10 +8,9 @@ export default class Hint {
|
|||
|
||||
this.target = target;
|
||||
|
||||
let doc = target.ownerDocument
|
||||
let doc = target.ownerDocument;
|
||||
let { top, left } = target.getBoundingClientRect();
|
||||
let scrollX = window.scrollX;
|
||||
let scrollY = window.scrollY;
|
||||
let { scrollX, scrollY } = window;
|
||||
|
||||
this.element = doc.createElement('span');
|
||||
this.element.className = 'vimvixen-hint';
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const prev = (win) => {
|
||||
win.history.back()
|
||||
win.history.back();
|
||||
};
|
||||
const next = (win) => {
|
||||
win.history.forward()
|
||||
win.history.forward();
|
||||
};
|
||||
|
||||
export { prev, next };
|
||||
|
|
|
@ -4,11 +4,11 @@ import * as scrolls from '../content/scrolls';
|
|||
import * as histories from '../content/histories';
|
||||
import Follow from '../content/follow';
|
||||
import operations from '../operations';
|
||||
import messages from '../messages';
|
||||
import messages from '../messages';
|
||||
|
||||
consoleFrames.initialize(window.document);
|
||||
|
||||
window.addEventListener("keypress", (e) => {
|
||||
window.addEventListener('keypress', (e) => {
|
||||
if (e.target instanceof HTMLInputElement) {
|
||||
return;
|
||||
}
|
||||
|
@ -40,14 +40,14 @@ const execOperation = (operation) => {
|
|||
case operations.HISTORY_NEXT:
|
||||
return histories.next(window);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const update = (state) => {
|
||||
if (!state.console.commandShown) {
|
||||
window.focus();
|
||||
consoleFrames.blur(window.document);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
browser.runtime.onMessage.addListener((action) => {
|
||||
switch (action.type) {
|
||||
|
|
|
@ -37,4 +37,6 @@ const scrollRight = (page) => {
|
|||
page.scrollTo(x, y);
|
||||
};
|
||||
|
||||
export { scrollLines, scrollPages, scrollTop, scrollBottom, scrollLeft, scrollRight }
|
||||
export {
|
||||
scrollLines, scrollPages, scrollTop, scrollBottom, scrollLeft, scrollRight
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
export default {
|
||||
// command
|
||||
// Command
|
||||
COMMAND_OPEN: 'cmd.open',
|
||||
COMMAND_TABS_OPEN: 'cmd.tabs.open',
|
||||
COMMAND_BUFFER: 'cmd.buffer',
|
||||
|
@ -14,7 +14,7 @@ export default {
|
|||
HISTORY_PREV: 'history.prev',
|
||||
HISTORY_NEXT: 'history.next',
|
||||
|
||||
// background
|
||||
// Background
|
||||
TABS_CLOSE: 'tabs.close',
|
||||
TABS_REOPEN: 'tabs.reopen',
|
||||
TABS_PREV: 'tabs.prev',
|
||||
|
@ -23,4 +23,4 @@ export default {
|
|||
ZOOM_IN: 'zoom.in',
|
||||
ZOOM_OUT: 'zoom.out',
|
||||
ZOOM_NEUTRAL: 'zoom.neutral',
|
||||
}
|
||||
};
|
||||
|
|
|
@ -8,10 +8,12 @@ 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.concat([
|
||||
{
|
||||
code: action.code,
|
||||
ctrl: action.ctrl
|
||||
}
|
||||
])
|
||||
});
|
||||
case actions.INPUT_CLEAR_KEYS:
|
||||
return Object.assign({}, state, {
|
||||
|
|
|
@ -24,7 +24,7 @@ class Store {
|
|||
this.catcher(e, sender);
|
||||
}
|
||||
}
|
||||
return action
|
||||
return action;
|
||||
}
|
||||
|
||||
getState() {
|
||||
|
@ -46,6 +46,8 @@ class Store {
|
|||
|
||||
const empty = () => {};
|
||||
|
||||
export function createStore(reducer, catcher = empty) {
|
||||
const createStore = (reducer, catcher = empty) => {
|
||||
return new Store(reducer, catcher);
|
||||
}
|
||||
};
|
||||
|
||||
export { createStore };
|
||||
|
|
Reference in a new issue