commit
df9094e520
12 changed files with 128 additions and 17 deletions
23
QA.md
23
QA.md
|
@ -4,12 +4,6 @@
|
||||||
|
|
||||||
Test operations with default key maps.
|
Test operations with default key maps.
|
||||||
|
|
||||||
#### Scrolling
|
|
||||||
|
|
||||||
- [ ] Smooth scroll by `:set smoothscroll`
|
|
||||||
- [ ] Non-smooth scroll by `:set nosmoothscroll`
|
|
||||||
- [ ] Configure custom hint character by settings `"smoothscroll": true`, `"smoothscroll": false`
|
|
||||||
|
|
||||||
#### Console
|
#### Console
|
||||||
|
|
||||||
The behaviors of the console are tested in [Console section](#consoles).
|
The behaviors of the console are tested in [Console section](#consoles).
|
||||||
|
@ -48,9 +42,6 @@ The behaviors of the console are tested in [Console section](#consoles).
|
||||||
- [ ] Select link and open it in new tab in `<iframe>`/`<frame`> on following by <kbd>F</kbd>
|
- [ ] Select link and open it in new tab in `<iframe>`/`<frame`> on following by <kbd>F</kbd>
|
||||||
- [ ] Select link and open it in `<area>` tags, for <kbd>f</kbd> and <kbd>F</kbd>
|
- [ ] Select link and open it in `<area>` tags, for <kbd>f</kbd> and <kbd>F</kbd>
|
||||||
- [ ] Open new tab in background by `"background": true`
|
- [ ] Open new tab in background by `"background": true`
|
||||||
- [ ] Configure custom hint character by `:set hintchars=012345678`
|
|
||||||
- [ ] Configure custom hint character by settings `"hintchars": "012345678"` in add-on preferences
|
|
||||||
- [ ] Opened tabs is in child on Tree Style Tab
|
|
||||||
|
|
||||||
### Consoles
|
### Consoles
|
||||||
|
|
||||||
|
@ -122,6 +113,20 @@ The behaviors of the console are tested in [Console section](#consoles).
|
||||||
- [ ] Select next item by <kbd>Tab</kbd> and previous item by <kbd>Shift</kbd>+<kbd>Tab</kbd>
|
- [ ] Select next item by <kbd>Tab</kbd> and previous item by <kbd>Shift</kbd>+<kbd>Tab</kbd>
|
||||||
- [ ] Reopen tab on *only current window* by <kbd>u</kbd>
|
- [ ] Reopen tab on *only current window* by <kbd>u</kbd>
|
||||||
|
|
||||||
|
### Properties
|
||||||
|
|
||||||
|
- [ ] Configure custom hint character by `:set hintchars=012345678`
|
||||||
|
- [ ] Configure custom hint character by settings `"hintchars": "012345678"` in add-on preferences
|
||||||
|
- [ ] Opened tabs is in child on Tree Style Tab
|
||||||
|
|
||||||
|
- [ ] Smooth scroll by `:set smoothscroll`
|
||||||
|
- [ ] Non-smooth scroll by `:set nosmoothscroll`
|
||||||
|
- [ ] Configure smooth scroll by settings `"smoothscroll": true`, `"smoothscroll": false`
|
||||||
|
|
||||||
|
- [ ] Show search engine, bookmark and history items in order by `:set complete=sbh`
|
||||||
|
- [ ] Show bookmark, search engine, and search engine items in order by `:set complete=bss`
|
||||||
|
- [ ] Configure completion items by setting `"complete": "sbh"`, `"complete": "bss"`
|
||||||
|
|
||||||
### Settings
|
### Settings
|
||||||
|
|
||||||
#### JSON Settings
|
#### JSON Settings
|
||||||
|
|
17
README.md
17
README.md
|
@ -56,6 +56,10 @@ See [console commands](#console-commands) section for more detailed description
|
||||||
- <kbd>G</kbd>: scroll to bottom of a page
|
- <kbd>G</kbd>: scroll to bottom of a page
|
||||||
- <kbd>0</kbd>: scroll to the leftmost part of a page
|
- <kbd>0</kbd>: scroll to the leftmost part of a page
|
||||||
- <kbd>$</kbd>: scroll to the rightmost part of a page
|
- <kbd>$</kbd>: scroll to the rightmost part of a page
|
||||||
|
- <kbd>m</kbd>: set a mark from current position
|
||||||
|
- <kbd>'</kbd>: jump to position by the mark
|
||||||
|
|
||||||
|
Lowercase alphabet mark (`[a-z]`) stores position on the current tab. Upper alphabet and numeric mark (`[A-Z0-9]`) stores position and tab.
|
||||||
|
|
||||||
#### Zoom
|
#### Zoom
|
||||||
|
|
||||||
|
@ -219,6 +223,19 @@ Set hint characters
|
||||||
:set hintchars=0123456789
|
:set hintchars=0123456789
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `complete` property
|
||||||
|
|
||||||
|
Set completion items on `open`, `tabopen` `winopen` commands.
|
||||||
|
The allowed value is character sequence of `s`, `b`, or `n`.
|
||||||
|
Each character presents as following:
|
||||||
|
- `s`: search engines
|
||||||
|
- `b`: bookmark items
|
||||||
|
- `h`: history items.
|
||||||
|
|
||||||
|
```
|
||||||
|
:set complete=sbn
|
||||||
|
```
|
||||||
|
|
||||||
### Search engines
|
### Search engines
|
||||||
|
|
||||||
Vim Vixen supports search by search engines like Google and Yahoo.
|
Vim Vixen supports search by search engines like Google and Yahoo.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {
|
import {
|
||||||
WINDOWS_CREATE, WINDOWS_REMOVE, WINDOWS_GET,
|
WINDOWS_CREATE, WINDOWS_REMOVE, WINDOWS_GET,
|
||||||
TABS_CREATE, TABS_SELECT_AT, TABS_GET, TABS_UPDATE,
|
TABS_CREATE, TABS_SELECT_AT, TABS_GET, TABS_UPDATE, TABS_REMOVE,
|
||||||
TABS_GET_ZOOM, TABS_SET_ZOOM,
|
TABS_GET_ZOOM, TABS_SET_ZOOM,
|
||||||
EVENT_KEYPRESS, EVENT_KEYDOWN, EVENT_KEYUP,
|
EVENT_KEYPRESS, EVENT_KEYDOWN, EVENT_KEYUP,
|
||||||
SCROLL_GET, SCROLL_SET,
|
SCROLL_GET, SCROLL_SET,
|
||||||
|
@ -30,6 +30,8 @@ receiveContentMessage((message) => {
|
||||||
return browser.tabs.get(message.tabId);
|
return browser.tabs.get(message.tabId);
|
||||||
case TABS_UPDATE:
|
case TABS_UPDATE:
|
||||||
return browser.tabs.update(message.tabId, message.properties);
|
return browser.tabs.update(message.tabId, message.properties);
|
||||||
|
case TABS_REMOVE:
|
||||||
|
return browser.tabs.remove(message.tabId);
|
||||||
case TABS_GET_ZOOM:
|
case TABS_GET_ZOOM:
|
||||||
return browser.tabs.getZoom(message.tabId);
|
return browser.tabs.getZoom(message.tabId);
|
||||||
case TABS_SET_ZOOM:
|
case TABS_SET_ZOOM:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import {
|
import {
|
||||||
TABS_CREATE, TABS_SELECT_AT, TABS_GET, TABS_UPDATE,
|
TABS_CREATE, TABS_SELECT_AT, TABS_GET, TABS_UPDATE, TABS_REMOVE,
|
||||||
TABS_GET_ZOOM, TABS_SET_ZOOM,
|
TABS_GET_ZOOM, TABS_SET_ZOOM,
|
||||||
} from '../shared/messages';
|
} from '../shared/messages';
|
||||||
import * as ipc from './ipc';
|
import * as ipc from './ipc';
|
||||||
|
@ -35,6 +35,13 @@ const update = (tabId, properties) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const remove = (tabId) => {
|
||||||
|
return ipc.send({
|
||||||
|
type: TABS_REMOVE,
|
||||||
|
tabId
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const getZoom = (tabId) => {
|
const getZoom = (tabId) => {
|
||||||
return ipc.send({
|
return ipc.send({
|
||||||
tabId,
|
tabId,
|
||||||
|
@ -50,4 +57,4 @@ const setZoom = (tabId, factor) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export { create, selectAt, get, update, getZoom, setZoom };
|
export { create, selectAt, get, update, remove, getZoom, setZoom };
|
||||||
|
|
|
@ -7,6 +7,7 @@ const TABS_CREATE = 'tabs.create';
|
||||||
const TABS_SELECT_AT = 'tabs.selectAt';
|
const TABS_SELECT_AT = 'tabs.selectAt';
|
||||||
const TABS_GET = 'tabs.get';
|
const TABS_GET = 'tabs.get';
|
||||||
const TABS_UPDATE = 'tabs.update';
|
const TABS_UPDATE = 'tabs.update';
|
||||||
|
const TABS_REMOVE = 'tabs.remove';
|
||||||
const TABS_GET_ZOOM = 'tabs.get.zoom';
|
const TABS_GET_ZOOM = 'tabs.get.zoom';
|
||||||
const TABS_SET_ZOOM = 'tabs.set.zoom';
|
const TABS_SET_ZOOM = 'tabs.set.zoom';
|
||||||
const EVENT_KEYPRESS = 'event.keypress';
|
const EVENT_KEYPRESS = 'event.keypress';
|
||||||
|
@ -29,6 +30,7 @@ export {
|
||||||
TABS_SELECT_AT,
|
TABS_SELECT_AT,
|
||||||
TABS_GET_ZOOM,
|
TABS_GET_ZOOM,
|
||||||
TABS_SET_ZOOM,
|
TABS_SET_ZOOM,
|
||||||
|
TABS_REMOVE,
|
||||||
|
|
||||||
EVENT_KEYPRESS,
|
EVENT_KEYPRESS,
|
||||||
EVENT_KEYDOWN,
|
EVENT_KEYDOWN,
|
||||||
|
|
71
e2e/contents/mark.test.js
Normal file
71
e2e/contents/mark.test.js
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
import * as windows from "../ambassador/src/client/windows";
|
||||||
|
import * as tabs from "../ambassador/src/client/tabs";
|
||||||
|
import * as keys from "../ambassador/src/client/keys";
|
||||||
|
import * as scrolls from "../ambassador/src/client/scrolls";
|
||||||
|
import { CLIENT_URL } from '../web-server/url';
|
||||||
|
|
||||||
|
describe("mark test", () => {
|
||||||
|
let targetWindow;
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
targetWindow = await windows.create();
|
||||||
|
});
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
await windows.remove(targetWindow.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('set a local mark and jump to it', async () => {
|
||||||
|
let tab = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#local');
|
||||||
|
await scrolls.set(tab.id, 100, 100);
|
||||||
|
await keys.press(tab.id, 'm');
|
||||||
|
await keys.press(tab.id, 'a');
|
||||||
|
|
||||||
|
await scrolls.set(tab.id, 200, 200);
|
||||||
|
await keys.press(tab.id, "'");
|
||||||
|
await keys.press(tab.id, 'a');
|
||||||
|
|
||||||
|
let scroll = await scrolls.get(tab.id);
|
||||||
|
expect(scroll.x).to.be.equals(100);
|
||||||
|
expect(scroll.y).to.be.equals(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('set a global mark and jump to it', async () => {
|
||||||
|
let tab1 = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#global1');
|
||||||
|
await scrolls.set(tab1.id, 100, 100);
|
||||||
|
await keys.press(tab1.id, 'm');
|
||||||
|
await keys.press(tab1.id, 'A');
|
||||||
|
await new Promise(resolve => { setTimeout(() => resolve(), 100) });
|
||||||
|
await scrolls.set(tab1.id, 200, 200);
|
||||||
|
|
||||||
|
let tab2 = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#global2');
|
||||||
|
await keys.press(tab2.id, "'");
|
||||||
|
await keys.press(tab2.id, 'A');
|
||||||
|
await new Promise(resolve => { setTimeout(() => resolve(), 100) });
|
||||||
|
|
||||||
|
tab1 = await tabs.get(tab1.id);
|
||||||
|
expect(tab1.active).to.be.true;
|
||||||
|
let scroll = await scrolls.get(tab1.id);
|
||||||
|
expect(scroll.x).to.be.equals(100);
|
||||||
|
expect(scroll.y).to.be.equals(100);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('set a global mark and creates new tab from gone', async () => {
|
||||||
|
let tab1 = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#gone');
|
||||||
|
await scrolls.set(tab1.id, 100, 100);
|
||||||
|
await keys.press(tab1.id, 'm');
|
||||||
|
await keys.press(tab1.id, 'A');
|
||||||
|
await tabs.remove(tab1.id);
|
||||||
|
await new Promise(resolve => { setTimeout(() => resolve(), 100) });
|
||||||
|
|
||||||
|
let tab2 = await tabs.create(targetWindow.id, CLIENT_URL + '/mark#newtab');
|
||||||
|
await keys.press(tab2.id, "'");
|
||||||
|
await keys.press(tab2.id, 'A');
|
||||||
|
await new Promise(resolve => { setTimeout(() => resolve(), 100) });
|
||||||
|
|
||||||
|
let win = await windows.get(targetWindow.id);
|
||||||
|
let found = win.tabs.find(tab => tab.url === CLIENT_URL + '/mark#gone')
|
||||||
|
expect(found).to.be.an('object');
|
||||||
|
expect(found.id).to.not.equal(tab1.id);
|
||||||
|
});
|
||||||
|
});
|
|
@ -23,6 +23,7 @@ describe("zoom test", () => {
|
||||||
let before = await tabs.getZoom(targetTab.id);
|
let before = await tabs.getZoom(targetTab.id);
|
||||||
await keys.press(targetTab.id, 'z');
|
await keys.press(targetTab.id, 'z');
|
||||||
await keys.press(targetTab.id, 'i');
|
await keys.press(targetTab.id, 'i');
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
let actual = await tabs.getZoom(targetTab.id);
|
let actual = await tabs.getZoom(targetTab.id);
|
||||||
expect(actual).to.be.greaterThan(before);
|
expect(actual).to.be.greaterThan(before);
|
||||||
|
@ -32,6 +33,7 @@ describe("zoom test", () => {
|
||||||
let before = await tabs.getZoom(targetTab.id);
|
let before = await tabs.getZoom(targetTab.id);
|
||||||
await keys.press(targetTab.id, 'z');
|
await keys.press(targetTab.id, 'z');
|
||||||
await keys.press(targetTab.id, 'o');
|
await keys.press(targetTab.id, 'o');
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
let actual = await tabs.getZoom(targetTab.id);
|
let actual = await tabs.getZoom(targetTab.id);
|
||||||
expect(actual).to.be.lessThan(before);
|
expect(actual).to.be.lessThan(before);
|
||||||
|
@ -42,6 +44,7 @@ describe("zoom test", () => {
|
||||||
let before = await tabs.getZoom(targetTab.id);
|
let before = await tabs.getZoom(targetTab.id);
|
||||||
await keys.press(targetTab.id, 'z');
|
await keys.press(targetTab.id, 'z');
|
||||||
await keys.press(targetTab.id, 'z');
|
await keys.press(targetTab.id, 'z');
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
let actual = await tabs.getZoom(targetTab.id);
|
let actual = await tabs.getZoom(targetTab.id);
|
||||||
expect(actual).to.be.lessThan(before);
|
expect(actual).to.be.lessThan(before);
|
||||||
|
|
|
@ -72,7 +72,7 @@ http.createServer(function (req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let u = url.parse(req.url);
|
let u = url.parse(req.url);
|
||||||
if (u.pathname === '/scroll') {
|
if (u.pathname === '/scroll' || u.pathname === '/mark') {
|
||||||
handleScroll(req, res);
|
handleScroll(req, res);
|
||||||
} else if (u.pathname === '/a-pagenation') {
|
} else if (u.pathname === '/a-pagenation') {
|
||||||
handleAPagenation(req, res);
|
handleAPagenation(req, res);
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
"sass-loader": "^7.1.0",
|
"sass-loader": "^7.1.0",
|
||||||
"sinon-chrome": "^2.3.2",
|
"sinon-chrome": "^2.3.2",
|
||||||
"style-loader": "^0.22.0",
|
"style-loader": "^0.22.0",
|
||||||
"web-ext": "github:ueokande/web-ext#patched-2.7.0",
|
"web-ext": "github:ueokande/web-ext#patched-2.9.1",
|
||||||
"webextensions-api-fake": "^0.5.1",
|
"webextensions-api-fake": "^0.5.1",
|
||||||
"webpack": "^4.20.2",
|
"webpack": "^4.20.2",
|
||||||
"webpack-cli": "^3.1.2"
|
"webpack-cli": "^3.1.2"
|
||||||
|
|
|
@ -39,7 +39,8 @@ export default class CompletionsInteractor {
|
||||||
let settings = await this.settingRepository.get();
|
let settings = await this.settingRepository.get();
|
||||||
let groups = [];
|
let groups = [];
|
||||||
|
|
||||||
for (let c of settings.properties.complete) {
|
let complete = settings.properties.complete || properties.defaults.complete;
|
||||||
|
for (let c of complete) {
|
||||||
if (c === 's') {
|
if (c === 's') {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
let engines = await this.querySearchEngineItems(name, keywords);
|
let engines = await this.querySearchEngineItems(name, keywords);
|
||||||
|
|
|
@ -97,9 +97,12 @@ export default class ConsoleComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
onInput(e) {
|
onInput(e) {
|
||||||
|
let state = this.store.getState();
|
||||||
let text = e.target.value;
|
let text = e.target.value;
|
||||||
this.store.dispatch(consoleActions.setConsoleText(text));
|
this.store.dispatch(consoleActions.setConsoleText(text));
|
||||||
this.store.dispatch(consoleActions.getCompletions(text));
|
if (state.mode === 'command') {
|
||||||
|
this.store.dispatch(consoleActions.getCompletions(text));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onInputShown(state) {
|
onInputShown(state) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ const types = {
|
||||||
const defaults = {
|
const defaults = {
|
||||||
hintchars: 'abcdefghijklmnopqrstuvwxyz',
|
hintchars: 'abcdefghijklmnopqrstuvwxyz',
|
||||||
smoothscroll: false,
|
smoothscroll: false,
|
||||||
complete: 'sbn',
|
complete: 'sbh',
|
||||||
};
|
};
|
||||||
|
|
||||||
const docs = {
|
const docs = {
|
||||||
|
|
Reference in a new issue