aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/background/controllers/OperationController.ts3
-rw-r--r--src/background/usecases/CommandUseCase.ts17
-rw-r--r--src/background/usecases/RepeatUseCase.ts1
-rw-r--r--src/background/usecases/TabUseCase.ts15
-rw-r--r--src/content/client/OperationClient.ts18
-rw-r--r--src/content/usecases/ClipboardUseCase.ts10
-rw-r--r--src/shared/operations.ts33
7 files changed, 93 insertions, 4 deletions
diff --git a/src/background/controllers/OperationController.ts b/src/background/controllers/OperationController.ts
index 7233c0e..51cff28 100644
--- a/src/background/controllers/OperationController.ts
+++ b/src/background/controllers/OperationController.ts
@@ -105,6 +105,9 @@ export default class OperationController {
}
return Promise.resolve();
}
+ case operations.INTERNAL_OPEN_URL:
+ return this.tabUseCase.openURL(
+ operation.url, operation.newTab, operation.newWindow);
}
throw new Error('unknown operation: ' + operation.type);
}
diff --git a/src/background/usecases/CommandUseCase.ts b/src/background/usecases/CommandUseCase.ts
index 921a779..a526cfc 100644
--- a/src/background/usecases/CommandUseCase.ts
+++ b/src/background/usecases/CommandUseCase.ts
@@ -1,4 +1,5 @@
import { injectable } from 'tsyringe';
+import * as operations from '../../shared/operations';
import * as parsers from './parsers';
import * as urls from '../../shared/urls';
import TabPresenter from '../presenters/TabPresenter';
@@ -7,6 +8,7 @@ import SettingRepository from '../repositories/SettingRepository';
import BookmarkRepository from '../repositories/BookmarkRepository';
import ConsoleClient from '../infrastructures/ConsoleClient';
import ContentMessageClient from '../infrastructures/ContentMessageClient';
+import RepeatUseCase from '../usecases/RepeatUseCase';
@injectable()
export default class CommandIndicator {
@@ -17,21 +19,36 @@ export default class CommandIndicator {
private bookmarkRepository: BookmarkRepository,
private consoleClient: ConsoleClient,
private contentMessageClient: ContentMessageClient,
+ private repeatUseCase: RepeatUseCase,
) {
}
async open(keywords: string): Promise<browser.tabs.Tab> {
let url = await this.urlOrSearch(keywords);
+ this.repeatUseCase.storeLastOperation({
+ type: operations.INTERNAL_OPEN_URL,
+ url,
+ });
return this.tabPresenter.open(url);
}
async tabopen(keywords: string): Promise<browser.tabs.Tab> {
let url = await this.urlOrSearch(keywords);
+ this.repeatUseCase.storeLastOperation({
+ type: operations.INTERNAL_OPEN_URL,
+ url,
+ newTab: true,
+ });
return this.tabPresenter.create(url);
}
async winopen(keywords: string): Promise<browser.windows.Window> {
let url = await this.urlOrSearch(keywords);
+ this.repeatUseCase.storeLastOperation({
+ type: operations.INTERNAL_OPEN_URL,
+ url,
+ newWindow: true,
+ });
return this.windowPresenter.create(url);
}
diff --git a/src/background/usecases/RepeatUseCase.ts b/src/background/usecases/RepeatUseCase.ts
index a005682..d78de34 100644
--- a/src/background/usecases/RepeatUseCase.ts
+++ b/src/background/usecases/RepeatUseCase.ts
@@ -42,6 +42,7 @@ export default class RepeatUseCase {
case operations.ZOOM_IN:
case operations.ZOOM_OUT:
case operations.ZOOM_NEUTRAL:
+ case operations.INTERNAL_OPEN_URL:
return true;
}
return false;
diff --git a/src/background/usecases/TabUseCase.ts b/src/background/usecases/TabUseCase.ts
index 0239a87..31112a9 100644
--- a/src/background/usecases/TabUseCase.ts
+++ b/src/background/usecases/TabUseCase.ts
@@ -1,11 +1,13 @@
import { injectable } from 'tsyringe';
import TabPresenter from '../presenters/TabPresenter';
+import WindowPresenter from '../presenters/WindowPresenter';
import BrowserSettingRepository from '../repositories/BrowserSettingRepository';
@injectable()
export default class TabUseCase {
constructor(
private tabPresenter: TabPresenter,
+ private windowPresenter: WindowPresenter,
private browserSettingRepository: BrowserSettingRepository,
) {
}
@@ -77,4 +79,17 @@ export default class TabUseCase {
this.tabPresenter.create(url);
}
}
+
+ async openURL(
+ url: string, newTab?: boolean, newWindow?: boolean,
+ ): Promise<void> {
+ if (newWindow) {
+ await this.windowPresenter.create(url);
+ } else if (newTab) {
+ await this.tabPresenter.create(url);
+ } else {
+ let tab = await this.tabPresenter.getCurrent();
+ await this.tabPresenter.open(url, tab.id);
+ }
+ }
}
diff --git a/src/content/client/OperationClient.ts b/src/content/client/OperationClient.ts
index d699fec..5dbe555 100644
--- a/src/content/client/OperationClient.ts
+++ b/src/content/client/OperationClient.ts
@@ -3,6 +3,10 @@ import * as messages from '../../shared/messages';
export default interface OperationClient {
execBackgroundOp(op: operations.Operation): Promise<void>;
+
+ internalOpenUrl(
+ url: string, newTab?: boolean, background?: boolean,
+ ): Promise<void>;
}
export class OperationClientImpl implements OperationClient {
@@ -12,4 +16,18 @@ export class OperationClientImpl implements OperationClient {
operation: op,
});
}
+
+ internalOpenUrl(
+ url: string, newTab?: boolean, background?: boolean,
+ ): Promise<void> {
+ return browser.runtime.sendMessage({
+ type: messages.BACKGROUND_OPERATION,
+ operation: {
+ type: operations.INTERNAL_OPEN_URL,
+ url,
+ newTab,
+ background,
+ },
+ });
+ }
}
diff --git a/src/content/usecases/ClipboardUseCase.ts b/src/content/usecases/ClipboardUseCase.ts
index 8c4d621..c8fe719 100644
--- a/src/content/usecases/ClipboardUseCase.ts
+++ b/src/content/usecases/ClipboardUseCase.ts
@@ -2,16 +2,16 @@ import { injectable, inject } from 'tsyringe';
import * as urls from '../../shared/urls';
import ClipboardRepository from '../repositories/ClipboardRepository';
import SettingRepository from '../repositories/SettingRepository';
-import TabsClient from '../client/TabsClient';
import ConsoleClient from '../client/ConsoleClient';
+import OperationClient from '../client/OperationClient';
@injectable()
export default class ClipboardUseCase {
constructor(
@inject('ClipboardRepository') private repository: ClipboardRepository,
@inject('SettingRepository') private settingRepository: SettingRepository,
- @inject('TabsClient') private client: TabsClient,
@inject('ConsoleClient') private consoleClient: ConsoleClient,
+ @inject('OperationClient') private operationClinet: OperationClient,
) {
}
@@ -26,6 +26,10 @@ export default class ClipboardUseCase {
let search = this.settingRepository.get().search;
let text = this.repository.read();
let url = urls.searchUrl(text, search);
- await this.client.openUrl(url, newTab);
+
+ // TODO: Repeat pasting from clipboard instead of opening a certain url.
+ // 'Repeat last' command is implemented in the background script and cannot
+ // access to clipboard until Firefox 63.
+ await this.operationClinet.internalOpenUrl(url, newTab);
}
}
diff --git a/src/shared/operations.ts b/src/shared/operations.ts
index 0f0d0c0..2b03d9d 100644
--- a/src/shared/operations.ts
+++ b/src/shared/operations.ts
@@ -78,6 +78,9 @@ export const MARK_JUMP_PREFIX = 'mark.jump.prefix';
// Repeat
export const REPEAT_LAST = 'repeat.last';
+// Internal
+export const INTERNAL_OPEN_URL = 'internal.open.url';
+
export interface CancelOperation {
type: typeof CANCEL;
}
@@ -298,6 +301,14 @@ export interface RepeatLastOperation {
type: typeof REPEAT_LAST;
}
+export interface InternalOpenUrl {
+ type: typeof INTERNAL_OPEN_URL;
+ url: string;
+ newTab?: boolean;
+ newWindow?: boolean;
+ background?: boolean;
+}
+
export type Operation =
CancelOperation |
AddonEnableOperation |
@@ -350,7 +361,8 @@ export type Operation =
FindPrevOperation |
MarkSetPrefixOperation |
MarkJumpPrefixOperation |
- RepeatLastOperation;
+ RepeatLastOperation |
+ InternalOpenUrl;
const assertOptionalBoolean = (obj: any, name: string) => {
if (Object.prototype.hasOwnProperty.call(obj, name) &&
@@ -366,6 +378,13 @@ const assertRequiredNumber = (obj: any, name: string) => {
}
};
+const assertRequiredString = (obj: any, name: string) => {
+ if (!Object.prototype.hasOwnProperty.call(obj, name) ||
+ typeof obj[name] !== 'string') {
+ 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')) {
@@ -409,6 +428,18 @@ export const valueOf = (o: any): Operation => {
type: URLS_PASTE,
newTab: Boolean(typeof o.newTab === undefined ? false : o.newTab),
};
+ case INTERNAL_OPEN_URL:
+ assertOptionalBoolean(o, 'newTab');
+ assertOptionalBoolean(o, 'newWindow');
+ assertOptionalBoolean(o, 'background');
+ assertRequiredString(o, 'url');
+ return {
+ type: INTERNAL_OPEN_URL,
+ url: o.url,
+ newTab: Boolean(typeof o.newTab === undefined ? false : o.newTab),
+ newWindow: Boolean(typeof o.newWindow === undefined ? false : o.newWindow), // eslint-disable-line max-len
+ background: Boolean(typeof o.background === undefined ? true : o.background), // eslint-disable-line max-len
+ };
case CANCEL:
case ADDON_ENABLE:
case ADDON_DISABLE: