aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/background/controllers/OperationController.ts2
-rw-r--r--src/background/usecases/TabUseCase.ts6
-rw-r--r--src/content/presenters/ScrollPresenter.ts2
-rw-r--r--src/settings/keymaps.ts12
-rw-r--r--src/shared/SettingData.ts3
-rw-r--r--src/shared/Settings.ts3
-rw-r--r--src/shared/operations.ts31
7 files changed, 42 insertions, 17 deletions
diff --git a/src/background/controllers/OperationController.ts b/src/background/controllers/OperationController.ts
index 51cff28..7a10ad6 100644
--- a/src/background/controllers/OperationController.ts
+++ b/src/background/controllers/OperationController.ts
@@ -32,7 +32,7 @@ export default class OperationController {
doOperation(operation: operations.Operation): Promise<any> {
switch (operation.type) {
case operations.TAB_CLOSE:
- return this.tabUseCase.close(false);
+ return this.tabUseCase.close(false, operation.select === 'left');
case operations.TAB_CLOSE_RIGHT:
return this.tabUseCase.closeRight();
case operations.TAB_CLOSE_FORCE:
diff --git a/src/background/usecases/TabUseCase.ts b/src/background/usecases/TabUseCase.ts
index 31112a9..386307e 100644
--- a/src/background/usecases/TabUseCase.ts
+++ b/src/background/usecases/TabUseCase.ts
@@ -12,11 +12,15 @@ export default class TabUseCase {
) {
}
- async close(force: boolean): Promise<any> {
+ async close(force: boolean, selectLeft = false): Promise<any> {
let tab = await this.tabPresenter.getCurrent();
if (!force && tab.pinned) {
return Promise.resolve();
}
+ if (selectLeft && tab.index > 0) {
+ let tabs = await this.tabPresenter.getAll();
+ await this.tabPresenter.select(tabs[tab.index - 1].id as number);
+ }
return this.tabPresenter.remove([tab.id as number]);
}
diff --git a/src/content/presenters/ScrollPresenter.ts b/src/content/presenters/ScrollPresenter.ts
index c06efca..e83f172 100644
--- a/src/content/presenters/ScrollPresenter.ts
+++ b/src/content/presenters/ScrollPresenter.ts
@@ -90,7 +90,7 @@ class Scroller {
clearTimeout(lastTimeoutId);
lastTimeoutId = null;
}
- lastTimeoutId = setTimeout(resetScrolling, 100);
+ lastTimeoutId = window.setTimeout(resetScrolling, 100);
}
}
diff --git a/src/settings/keymaps.ts b/src/settings/keymaps.ts
index 33ad26d..24ba1a5 100644
--- a/src/settings/keymaps.ts
+++ b/src/settings/keymaps.ts
@@ -18,11 +18,11 @@ const fields = [
['mark.set.prefix', 'Set mark at current position'],
['mark.jump.prefix', 'Jump to the mark'],
], [
- ['tabs.close', 'Close a tab'],
- ['tabs.close.right', 'Close tabs to the right'],
+ ['tabs.close?{"select":"right"}', 'Close a tab'],
+ ['tabs.close.right', 'Close all tabs to the right'],
['tabs.reopen', 'Reopen closed tab'],
- ['tabs.next', 'Select next Tab'],
- ['tabs.prev', 'Select prev Tab'],
+ ['tabs.next', 'Select next tab'],
+ ['tabs.prev', 'Select prev tab'],
['tabs.first', 'Select first tab'],
['tabs.last', 'Select last tab'],
['tabs.reload?{"cache":false}', 'Reload current tab'],
@@ -50,8 +50,8 @@ const fields = [
['command.show', 'Open console'],
['command.show.open?{"alter":false}', 'Open URL'],
['command.show.open?{"alter":true}', 'Alter URL'],
- ['command.show.tabopen?{"alter":false}', 'Open URL in new Tab'],
- ['command.show.tabopen?{"alter":true}', 'Alter URL in new Tab'],
+ ['command.show.tabopen?{"alter":false}', 'Open URL in new tab'],
+ ['command.show.tabopen?{"alter":true}', 'Alter URL in new tab'],
['command.show.winopen?{"alter":false}', 'Open URL in new window'],
['command.show.winopen?{"alter":true}', 'Alter URL in new window'],
['command.show.buffer', 'Open buffer command'],
diff --git a/src/shared/SettingData.ts b/src/shared/SettingData.ts
index 1c085cf..14a7d35 100644
--- a/src/shared/SettingData.ts
+++ b/src/shared/SettingData.ts
@@ -353,7 +353,8 @@ export const DefaultSettingData: SettingData = SettingData.valueOf({
"G": { "type": "scroll.bottom" },
"$": { "type": "scroll.end" },
"d": { "type": "tabs.close" },
- "D": { "type": "tabs.close.right" },
+ "D": { "type": "tabs.close", "select": "left" },
+ "x$": { "type": "tabs.close.right" },
"!d": { "type": "tabs.close.force" },
"u": { "type": "tabs.reopen" },
"K": { "type": "tabs.prev" },
diff --git a/src/shared/Settings.ts b/src/shared/Settings.ts
index 0bef342..2a392df 100644
--- a/src/shared/Settings.ts
+++ b/src/shared/Settings.ts
@@ -146,7 +146,8 @@ export const DefaultSetting: Settings = {
'G': { 'type': 'scroll.bottom' },
'$': { 'type': 'scroll.end' },
'd': { 'type': 'tabs.close' },
- 'D': { 'type': 'tabs.close.right' },
+ 'D': { 'type': 'tabs.close', 'select': 'left' },
+ 'x$': { 'type': 'tabs.close.right' },
'!d': { 'type': 'tabs.close.force' },
'u': { 'type': 'tabs.reopen' },
'K': { 'type': 'tabs.prev' },
diff --git a/src/shared/operations.ts b/src/shared/operations.ts
index 2b03d9d..2df2e67 100644
--- a/src/shared/operations.ts
+++ b/src/shared/operations.ts
@@ -201,6 +201,7 @@ export interface PageHomeOperation {
export interface TabCloseOperation {
type: typeof TAB_CLOSE;
+ select?: 'left' | 'right';
}
export interface TabCloseForceOperation {
@@ -367,28 +368,41 @@ export type Operation =
const assertOptionalBoolean = (obj: any, name: string) => {
if (Object.prototype.hasOwnProperty.call(obj, name) &&
typeof obj[name] !== 'boolean') {
- throw new TypeError(`Not a boolean parameter '${name}'`);
+ throw new TypeError(`Not a boolean parameter: '${name}'`);
+ }
+};
+
+const assertOptionalString = (obj: any, name: string, values?: string[]) => {
+ if (Object.prototype.hasOwnProperty.call(obj, name)) {
+ let value = obj[name];
+ if (typeof value !== 'string') {
+ throw new TypeError(`Not a string parameter: '${name}'`);
+ }
+ if (values && values.length && values.indexOf(value) === -1) {
+ // eslint-disable-next-line max-len
+ throw new TypeError(`Invalid parameter for '${name}': '${value}'`);
+ }
}
};
const assertRequiredNumber = (obj: any, name: string) => {
if (!Object.prototype.hasOwnProperty.call(obj, name) ||
typeof obj[name] !== 'number') {
- throw new TypeError(`Missing number parameter '${name}`);
+ throw new TypeError(`Missing number parameter: '${name}`);
}
};
const assertRequiredString = (obj: any, name: string) => {
if (!Object.prototype.hasOwnProperty.call(obj, name) ||
typeof obj[name] !== 'string') {
- throw new TypeError(`Missing string parameter '${name}`);
+ throw new TypeError(`Missing string parameter: '${name}`);
}
};
// eslint-disable-next-line complexity, max-lines-per-function
export const valueOf = (o: any): Operation => {
if (!Object.prototype.hasOwnProperty.call(o, 'type')) {
- throw new TypeError(`missing 'type' field`);
+ throw new TypeError(`Missing 'type' field`);
}
switch (o.type) {
case COMMAND_SHOW_OPEN:
@@ -416,6 +430,12 @@ export const valueOf = (o: any): Operation => {
type: PAGE_HOME,
newTab: Boolean(typeof o.newTab === undefined ? false : o.newTab),
};
+ case TAB_CLOSE:
+ assertOptionalString(o, 'select', ['left', 'right']);
+ return {
+ type: TAB_CLOSE,
+ select: (typeof o.select === undefined ? 'right' : o.select),
+ };
case TAB_RELOAD:
assertOptionalBoolean(o, 'cache');
return {
@@ -458,7 +478,6 @@ export const valueOf = (o: any): Operation => {
case NAVIGATE_ROOT:
case FOCUS_INPUT:
case PAGE_SOURCE:
- case TAB_CLOSE:
case TAB_CLOSE_FORCE:
case TAB_CLOSE_RIGHT:
case TAB_REOPEN:
@@ -483,5 +502,5 @@ export const valueOf = (o: any): Operation => {
case REPEAT_LAST:
return { type: o.type };
}
- throw new TypeError('unknown operation type: ' + o.type);
+ throw new TypeError('Unknown operation type: ' + o.type);
};