aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShin'ya Ueoka <ueokande@i-beam.org>2020-12-02 22:40:10 +0900
committerShin'ya Ueoka <ueokande@i-beam.org>2020-12-09 23:09:34 +0900
commitca804b1b335df0e7a316d12ed9246beec55ff7f2 (patch)
tree6265d1d0b4e7637a10ae9e68e0f2949d11fcd0e4
parentddf912804fc4cb26d388283eacca63a0aeddf779 (diff)
Make background operator as an operator
-rw-r--r--src/background/clients/NavigateClient.ts14
-rw-r--r--src/background/di.ts12
-rw-r--r--src/background/infrastructures/ConsoleClient.ts14
-rw-r--r--src/background/operators/impls/CommandOperatorFactoryChain.ts1
-rw-r--r--src/background/operators/impls/InternalOperatorFactoryChain.ts1
-rw-r--r--src/background/operators/impls/NavigateOperatorFactoryChain.ts2
-rw-r--r--src/background/operators/impls/RepeatOperatorFactoryChain.ts1
-rw-r--r--src/background/operators/impls/ResetZoomOperator.ts7
-rw-r--r--src/background/operators/impls/ShowAddBookmarkOperator.ts2
-rw-r--r--src/background/operators/impls/ZoomInOperator.ts6
-rw-r--r--src/background/operators/impls/ZoomOperatorFactoryChain.ts15
-rw-r--r--src/background/operators/impls/ZoomOutOperator.ts6
-rw-r--r--src/background/repositories/BrowserSettingRepository.ts6
-rw-r--r--src/background/repositories/RepeatRepository.ts8
-rw-r--r--src/background/usecases/CommandUseCase.ts18
-rw-r--r--src/background/usecases/ConsoleUseCase.ts6
-rw-r--r--src/background/usecases/FindUseCase.ts8
-rw-r--r--src/background/usecases/MarkUseCase.ts12
-rw-r--r--src/background/usecases/NavigateUseCase.ts6
-rw-r--r--src/background/usecases/RepeatUseCase.ts7
-rw-r--r--src/background/usecases/TabUseCase.ts8
-rw-r--r--src/background/usecases/ZoomPresenter.ts60
-rw-r--r--test/background/usecases/NavigateUseCase.test.ts6
23 files changed, 177 insertions, 49 deletions
diff --git a/src/background/clients/NavigateClient.ts b/src/background/clients/NavigateClient.ts
index 40ceb45..af8688e 100644
--- a/src/background/clients/NavigateClient.ts
+++ b/src/background/clients/NavigateClient.ts
@@ -1,8 +1,16 @@
-import { injectable } from "tsyringe";
import * as messages from "../../shared/messages";
-@injectable()
-export default class NavigateClient {
+export default interface NavigateClient {
+ historyNext(tabId: number): Promise<void>;
+
+ historyPrev(tabId: number): Promise<void>;
+
+ linkNext(tabId: number): Promise<void>;
+
+ linkPrev(tabId: number): Promise<void>;
+}
+
+export class NavigateClientImpl implements NavigateClient {
async historyNext(tabId: number): Promise<void> {
await browser.tabs.sendMessage(tabId, {
type: messages.NAVIGATE_HISTORY_NEXT,
diff --git a/src/background/di.ts b/src/background/di.ts
index 44bf427..8623f95 100644
--- a/src/background/di.ts
+++ b/src/background/di.ts
@@ -12,6 +12,11 @@ import BookmarkRepositoryImpl from "./completion/impl/BookmarkRepositoryImpl";
import TabRepositoryImpl from "./completion/impl/TabRepositoryImpl";
import { TabPresenterImpl } from "./presenters/TabPresenter";
import { OperatorFactoryImpl } from "./operators/impls/OperatorFactoryImpl";
+import { NavigateClientImpl } from "./clients/NavigateClient";
+import { ConsoleClientImpl } from "./infrastructures/ConsoleClient";
+import { BrowserSettingRepositoryImpl } from "./repositories/BrowserSettingRepository";
+import { RepeatRepositoryImpl } from "./repositories/RepeatRepository";
+import { ZoomPresenterImpl } from "./usecases/ZoomPresenter";
container.register("LocalSettingRepository", {
useValue: LocalSettingRepository,
@@ -25,6 +30,13 @@ container.register("CachedSettingRepository", {
container.register("Notifier", { useClass: NotifierImpl });
container.register("HistoryRepository", { useClass: HistoryRepositoryImpl });
container.register("BookmarkRepository", { useClass: BookmarkRepositoryImpl });
+container.register("BrowserSettingRepository", {
+ useClass: BrowserSettingRepositoryImpl,
+});
+container.register("RepeatRepository", { useClass: RepeatRepositoryImpl });
container.register("TabRepository", { useClass: TabRepositoryImpl });
+container.register("ZoomPresenter", { useClass: ZoomPresenterImpl });
container.register("TabPresenter", { useClass: TabPresenterImpl });
+container.register("NavigateClient", { useClass: NavigateClientImpl });
+container.register("ConsoleClient", { useClass: ConsoleClientImpl });
container.register("OperatorFactory", { useClass: OperatorFactoryImpl });
diff --git a/src/background/infrastructures/ConsoleClient.ts b/src/background/infrastructures/ConsoleClient.ts
index 8d0af89..2a1df5b 100644
--- a/src/background/infrastructures/ConsoleClient.ts
+++ b/src/background/infrastructures/ConsoleClient.ts
@@ -1,8 +1,20 @@
import { injectable } from "tsyringe";
import * as messages from "../../shared/messages";
+export default interface ConsoleClient {
+ showCommand(tabId: number, command: string): Promise<any>;
+
+ showFind(tabId: number): Promise<any>;
+
+ showInfo(tabId: number, message: string): Promise<any>;
+
+ showError(tabId: number, message: string): Promise<any>;
+
+ hide(tabId: number): Promise<any>;
+}
+
@injectable()
-export default class ConsoleClient {
+export class ConsoleClientImpl implements ConsoleClient {
showCommand(tabId: number, command: string): Promise<any> {
return browser.tabs.sendMessage(tabId, {
type: messages.CONSOLE_SHOW_COMMAND,
diff --git a/src/background/operators/impls/CommandOperatorFactoryChain.ts b/src/background/operators/impls/CommandOperatorFactoryChain.ts
index 7432153..680a384 100644
--- a/src/background/operators/impls/CommandOperatorFactoryChain.ts
+++ b/src/background/operators/impls/CommandOperatorFactoryChain.ts
@@ -18,6 +18,7 @@ export default class CommandOperatorFactoryChain
constructor(
@inject("TabPresenter")
private readonly tabPresenter: TabPresenter,
+ @inject("ConsoleClient")
private readonly consoleClient: ConsoleClient
) {}
diff --git a/src/background/operators/impls/InternalOperatorFactoryChain.ts b/src/background/operators/impls/InternalOperatorFactoryChain.ts
index 607dbfa..fd3e010 100644
--- a/src/background/operators/impls/InternalOperatorFactoryChain.ts
+++ b/src/background/operators/impls/InternalOperatorFactoryChain.ts
@@ -15,6 +15,7 @@ export default class InternalOperatorFactoryChain
private readonly windowPresenter: WindowPresenter,
@inject("TabPresenter")
private readonly tabPresenter: TabPresenter,
+ @inject("ConsoleClient")
private readonly consoleClient: ConsoleClient
) {}
diff --git a/src/background/operators/impls/NavigateOperatorFactoryChain.ts b/src/background/operators/impls/NavigateOperatorFactoryChain.ts
index d9b1619..618db45 100644
--- a/src/background/operators/impls/NavigateOperatorFactoryChain.ts
+++ b/src/background/operators/impls/NavigateOperatorFactoryChain.ts
@@ -20,7 +20,9 @@ export default class NavigateOperatorFactoryChain
constructor(
@inject("TabPresenter")
private readonly tabPresenter: TabPresenter,
+ @inject("NavigateClient")
private readonly navigateClient: NavigateClient,
+ @inject("BrowserSettingRepository")
private readonly browserSettingRepository: BrowserSettingRepository
) {}
diff --git a/src/background/operators/impls/RepeatOperatorFactoryChain.ts b/src/background/operators/impls/RepeatOperatorFactoryChain.ts
index 9d67b75..5038d48 100644
--- a/src/background/operators/impls/RepeatOperatorFactoryChain.ts
+++ b/src/background/operators/impls/RepeatOperatorFactoryChain.ts
@@ -10,6 +10,7 @@ import * as operations from "../../../shared/operations";
export default class RepeatOperatorFactoryChain
implements OperatorFactoryChain {
constructor(
+ @inject("RepeatRepository")
private readonly repeatRepository: RepeatRepository,
@inject("OperatorFactory")
private readonly operatorFactory: OperatorFactory
diff --git a/src/background/operators/impls/ResetZoomOperator.ts b/src/background/operators/impls/ResetZoomOperator.ts
index 66cf245..48db1d5 100644
--- a/src/background/operators/impls/ResetZoomOperator.ts
+++ b/src/background/operators/impls/ResetZoomOperator.ts
@@ -1,9 +1,10 @@
import Operator from "../Operator";
-import ZoomUseCase from "../../usecases/ZoomUseCase";
+import ZoomPresenter from "../../usecases/ZoomPresenter";
export default class ResetZoomOperator implements Operator {
- constructor(private readonly zoomUseCase: ZoomUseCase) {}
+ constructor(private readonly zoomPresenter: ZoomPresenter) {}
+
run(): Promise<void> {
- return this.zoomUseCase.zoomNutoral();
+ return this.zoomPresenter.resetZoom();
}
}
diff --git a/src/background/operators/impls/ShowAddBookmarkOperator.ts b/src/background/operators/impls/ShowAddBookmarkOperator.ts
index a1752eb..cce4879 100644
--- a/src/background/operators/impls/ShowAddBookmarkOperator.ts
+++ b/src/background/operators/impls/ShowAddBookmarkOperator.ts
@@ -11,7 +11,7 @@ export default class ShowAddBookmarkOperator implements Operator {
async run(): Promise<void> {
const tab = await this.tabPresenter.getCurrent();
- let command = "addookmark ";
+ let command = "addbookmark ";
if (this.alter) {
command += tab.title || "";
}
diff --git a/src/background/operators/impls/ZoomInOperator.ts b/src/background/operators/impls/ZoomInOperator.ts
index 0c44c6f..9ed1861 100644
--- a/src/background/operators/impls/ZoomInOperator.ts
+++ b/src/background/operators/impls/ZoomInOperator.ts
@@ -1,10 +1,10 @@
import Operator from "../Operator";
-import ZoomUseCase from "../../usecases/ZoomUseCase";
+import ZoomPresenter from "../../usecases/ZoomPresenter";
export default class ZoomInOperator implements Operator {
- constructor(private readonly zoomUseCase: ZoomUseCase) {}
+ constructor(private readonly zoomPresenter: ZoomPresenter) {}
run(): Promise<void> {
- return this.zoomUseCase.zoomIn();
+ return this.zoomPresenter.zoomIn();
}
}
diff --git a/src/background/operators/impls/ZoomOperatorFactoryChain.ts b/src/background/operators/impls/ZoomOperatorFactoryChain.ts
index b8858ab..ebcf2a5 100644
--- a/src/background/operators/impls/ZoomOperatorFactoryChain.ts
+++ b/src/background/operators/impls/ZoomOperatorFactoryChain.ts
@@ -1,24 +1,27 @@
-import { injectable } from "tsyringe";
+import { inject, injectable } from "tsyringe";
import Operator from "../Operator";
import OperatorFactoryChain from "../OperatorFactoryChain";
import ZoomInOperator from "./ZoomInOperator";
import ZoomOutOperator from "./ZoomOutOperator";
import ResetZoomOperator from "./ResetZoomOperator";
-import ZoomUseCase from "../../usecases/ZoomUseCase";
+import ZoomPresenter from "../../usecases/ZoomPresenter";
import * as operations from "../../../shared/operations";
@injectable()
export default class ZoomOperatorFactoryChain implements OperatorFactoryChain {
- constructor(private readonly zoomUseCase: ZoomUseCase) {}
+ constructor(
+ @inject("ZoomPresenter")
+ private readonly zoomPresenter: ZoomPresenter
+ ) {}
create(op: operations.Operation): Operator | null {
switch (op.type) {
case operations.ZOOM_IN:
- return new ZoomInOperator(this.zoomUseCase);
+ return new ZoomInOperator(this.zoomPresenter);
case operations.ZOOM_OUT:
- return new ZoomOutOperator(this.zoomUseCase);
+ return new ZoomOutOperator(this.zoomPresenter);
case operations.ZOOM_NEUTRAL:
- return new ResetZoomOperator(this.zoomUseCase);
+ return new ResetZoomOperator(this.zoomPresenter);
}
return null;
}
diff --git a/src/background/operators/impls/ZoomOutOperator.ts b/src/background/operators/impls/ZoomOutOperator.ts
index 7f9cb6b..35f5d3d 100644
--- a/src/background/operators/impls/ZoomOutOperator.ts
+++ b/src/background/operators/impls/ZoomOutOperator.ts
@@ -1,10 +1,10 @@
import Operator from "../Operator";
-import ZoomUseCase from "../../usecases/ZoomUseCase";
+import ZoomPresenter from "../../usecases/ZoomPresenter";
export default class ZoomOutOperator implements Operator {
- constructor(private readonly zoomUseCase: ZoomUseCase) {}
+ constructor(private readonly zoomPresenter: ZoomPresenter) {}
run(): Promise<void> {
- return this.zoomUseCase.zoomOut();
+ return this.zoomPresenter.zoomOut();
}
}
diff --git a/src/background/repositories/BrowserSettingRepository.ts b/src/background/repositories/BrowserSettingRepository.ts
index e24874b..1dde190 100644
--- a/src/background/repositories/BrowserSettingRepository.ts
+++ b/src/background/repositories/BrowserSettingRepository.ts
@@ -1,8 +1,12 @@
import { injectable } from "tsyringe";
import * as urls from "../../shared/urls";
+export default interface BrowserSettingRepository {
+ getHomepageUrls(): Promise<string[]>;
+}
+
@injectable()
-export default class BrowserSettingRepository {
+export class BrowserSettingRepositoryImpl implements BrowserSettingRepository {
async getHomepageUrls(): Promise<string[]> {
const { value } = await browser.browserSettings.homepageOverride.get({});
return value.split("|").map(urls.normalizeUrl);
diff --git a/src/background/repositories/RepeatRepository.ts b/src/background/repositories/RepeatRepository.ts
index e3ab43d..00098d3 100644
--- a/src/background/repositories/RepeatRepository.ts
+++ b/src/background/repositories/RepeatRepository.ts
@@ -4,8 +4,14 @@ import MemoryStorage from "../infrastructures/MemoryStorage";
const REPEAT_KEY = "repeat";
+export default interface RepeatRepository {
+ getLastOperation(): Operation | undefined;
+
+ setLastOperation(op: Operation): void;
+}
+
@injectable()
-export default class RepeatRepository {
+export class RepeatRepositoryImpl implements RepeatRepository {
private cache: MemoryStorage;
constructor() {
diff --git a/src/background/usecases/CommandUseCase.ts b/src/background/usecases/CommandUseCase.ts
index 811ec77..69ef3ea 100644
--- a/src/background/usecases/CommandUseCase.ts
+++ b/src/background/usecases/CommandUseCase.ts
@@ -14,15 +14,17 @@ import RepeatUseCase from "../usecases/RepeatUseCase";
@injectable()
export default class CommandIndicator {
constructor(
- @inject("TabPresenter") private tabPresenter: TabPresenter,
- private windowPresenter: WindowPresenter,
- private helpPresenter: HelpPresenter,
+ @inject("TabPresenter")
+ private readonly tabPresenter: TabPresenter,
+ private readonly windowPresenter: WindowPresenter,
+ private readonly helpPresenter: HelpPresenter,
@inject("CachedSettingRepository")
- private cachedSettingRepository: CachedSettingRepository,
- private bookmarkRepository: BookmarkRepository,
- private consoleClient: ConsoleClient,
- private contentMessageClient: ContentMessageClient,
- private repeatUseCase: RepeatUseCase
+ private readonly cachedSettingRepository: CachedSettingRepository,
+ private readonly bookmarkRepository: BookmarkRepository,
+ @inject("ConsoleClient")
+ private readonly consoleClient: ConsoleClient,
+ private readonly contentMessageClient: ContentMessageClient,
+ private readonly repeatUseCase: RepeatUseCase
) {}
async open(keywords: string): Promise<browser.tabs.Tab> {
diff --git a/src/background/usecases/ConsoleUseCase.ts b/src/background/usecases/ConsoleUseCase.ts
index 195c70f..4adba65 100644
--- a/src/background/usecases/ConsoleUseCase.ts
+++ b/src/background/usecases/ConsoleUseCase.ts
@@ -5,8 +5,10 @@ import ConsoleClient from "../infrastructures/ConsoleClient";
@injectable()
export default class ConsoleUseCase {
constructor(
- @inject("TabPresenter") private tabPresenter: TabPresenter,
- private consoleClient: ConsoleClient
+ @inject("TabPresenter")
+ private readonly tabPresenter: TabPresenter,
+ @inject("ConsoleClient")
+ private readonly consoleClient: ConsoleClient
) {}
async showCommand(): Promise<any> {
diff --git a/src/background/usecases/FindUseCase.ts b/src/background/usecases/FindUseCase.ts
index facc461..404fb48 100644
--- a/src/background/usecases/FindUseCase.ts
+++ b/src/background/usecases/FindUseCase.ts
@@ -6,9 +6,11 @@ import ConsoleClient from "../infrastructures/ConsoleClient";
@injectable()
export default class FindUseCase {
constructor(
- @inject("TabPresenter") private tabPresenter: TabPresenter,
- private findRepository: FindRepository,
- private consoleClient: ConsoleClient
+ @inject("TabPresenter")
+ private readonly tabPresenter: TabPresenter,
+ private readonly findRepository: FindRepository,
+ @inject("ConsoleClient")
+ private readonly consoleClient: ConsoleClient
) {}
getKeyword(): Promise<string> {
diff --git a/src/background/usecases/MarkUseCase.ts b/src/background/usecases/MarkUseCase.ts
index 9da9a21..57e04b4 100644
--- a/src/background/usecases/MarkUseCase.ts
+++ b/src/background/usecases/MarkUseCase.ts
@@ -1,16 +1,18 @@
import { inject, injectable } from "tsyringe";
import TabPresenter from "../presenters/TabPresenter";
import MarkRepository from "../repositories/MarkRepository";
-import ConsoleClient from "../infrastructures/ConsoleClient";
import ContentMessageClient from "../infrastructures/ContentMessageClient";
+import ConsoleClient from "../infrastructures/ConsoleClient";
@injectable()
export default class MarkUseCase {
constructor(
- @inject("TabPresenter") private tabPresenter: TabPresenter,
- private markRepository: MarkRepository,
- private consoleClient: ConsoleClient,
- private contentMessageClient: ContentMessageClient
+ @inject("TabPresenter")
+ private readonly tabPresenter: TabPresenter,
+ private readonly markRepository: MarkRepository,
+ @inject("ConsoleClient")
+ private readonly consoleClient: ConsoleClient,
+ private readonly contentMessageClient: ContentMessageClient
) {}
async setGlobal(key: string, x: number, y: number): Promise<any> {
diff --git a/src/background/usecases/NavigateUseCase.ts b/src/background/usecases/NavigateUseCase.ts
index 974606c..29e629a 100644
--- a/src/background/usecases/NavigateUseCase.ts
+++ b/src/background/usecases/NavigateUseCase.ts
@@ -5,8 +5,10 @@ import TabPresenter from "../presenters/TabPresenter";
@injectable()
export default class NavigateUseCase {
constructor(
- @inject("TabPresenter") private tabPresenter: TabPresenter,
- private navigateClient: NavigateClient
+ @inject("TabPresenter")
+ private readonly tabPresenter: TabPresenter,
+ @inject("NavigateClient")
+ private readonly navigateClient: NavigateClient
) {}
async openHistoryNext(): Promise<void> {
diff --git a/src/background/usecases/RepeatUseCase.ts b/src/background/usecases/RepeatUseCase.ts
index d7235ee..992e76b 100644
--- a/src/background/usecases/RepeatUseCase.ts
+++ b/src/background/usecases/RepeatUseCase.ts
@@ -1,4 +1,4 @@
-import { injectable } from "tsyringe";
+import { inject, injectable } from "tsyringe";
import * as operations from "../../shared/operations";
import RepeatRepository from "../repositories/RepeatRepository";
@@ -6,7 +6,10 @@ type Operation = operations.Operation;
@injectable()
export default class RepeatUseCase {
- constructor(private repeatRepository: RepeatRepository) {}
+ constructor(
+ @inject("RepeatRepository")
+ private readonly repeatRepository: RepeatRepository
+ ) {}
storeLastOperation(op: Operation): void {
this.repeatRepository.setLastOperation(op);
diff --git a/src/background/usecases/TabUseCase.ts b/src/background/usecases/TabUseCase.ts
index 1439107..900c305 100644
--- a/src/background/usecases/TabUseCase.ts
+++ b/src/background/usecases/TabUseCase.ts
@@ -6,9 +6,11 @@ import BrowserSettingRepository from "../repositories/BrowserSettingRepository";
@injectable()
export default class TabUseCase {
constructor(
- @inject("TabPresenter") private tabPresenter: TabPresenter,
- private windowPresenter: WindowPresenter,
- private browserSettingRepository: BrowserSettingRepository
+ @inject("TabPresenter")
+ private readonly tabPresenter: TabPresenter,
+ private readonly windowPresenter: WindowPresenter,
+ @inject("BrowserSettingRepository")
+ private readonly browserSettingRepository: BrowserSettingRepository
) {}
async close(force: boolean, selectLeft = false): Promise<any> {
diff --git a/src/background/usecases/ZoomPresenter.ts b/src/background/usecases/ZoomPresenter.ts
new file mode 100644
index 0000000..5a3c64d
--- /dev/null
+++ b/src/background/usecases/ZoomPresenter.ts
@@ -0,0 +1,60 @@
+const ZOOM_SETTINGS = [
+ 0.33,
+ 0.5,
+ 0.66,
+ 0.75,
+ 0.8,
+ 0.9,
+ 1.0,
+ 1.1,
+ 1.25,
+ 1.5,
+ 1.75,
+ 2.0,
+ 2.5,
+ 3.0,
+] as const;
+
+export default interface ZoomPresenter {
+ zoomIn(): Promise<void>;
+ zoomOut(): Promise<void>;
+ resetZoom(): Promise<void>;
+}
+
+export class ZoomPresenterImpl implements ZoomPresenter {
+ async zoomIn(): Promise<void> {
+ const tab = await browser.tabs.query({
+ active: true,
+ currentWindow: true,
+ });
+ const tabId = tab[0].id as number;
+ const current = await browser.tabs.getZoom(tabId);
+ const factor = ZOOM_SETTINGS.find((f) => f > current);
+ if (factor) {
+ return browser.tabs.setZoom(tabId, factor);
+ }
+ }
+
+ async zoomOut(): Promise<void> {
+ const tab = await browser.tabs.query({
+ active: true,
+ currentWindow: true,
+ });
+ const tabId = tab[0].id as number;
+ const current = await browser.tabs.getZoom(tabId);
+ const factor = ZOOM_SETTINGS.slice(0)
+ .reverse()
+ .find((f) => f < current);
+ if (factor) {
+ return browser.tabs.setZoom(tabId, factor);
+ }
+ }
+
+ async resetZoom(): Promise<void> {
+ const tab = await browser.tabs.query({
+ active: true,
+ currentWindow: true,
+ });
+ return browser.tabs.setZoom(tab[0].id, 1);
+ }
+}
diff --git a/test/background/usecases/NavigateUseCase.test.ts b/test/background/usecases/NavigateUseCase.test.ts
index 086d6cd..f1b94a7 100644
--- a/test/background/usecases/NavigateUseCase.test.ts
+++ b/test/background/usecases/NavigateUseCase.test.ts
@@ -1,7 +1,9 @@
import "reflect-metadata";
import TabPresenter from "../../../src/background/presenters/TabPresenter";
import NavigateUseCase from "../../../src/background/usecases/NavigateUseCase";
-import NavigateClient from "../../../src/background/clients/NavigateClient";
+import NavigateClient, {
+ NavigateClientImpl,
+} from "../../../src/background/clients/NavigateClient";
import * as sinon from "sinon";
class MockTabPresenter implements TabPresenter {
@@ -78,7 +80,7 @@ describe("NavigateUseCase", () => {
beforeEach(() => {
tabPresenter = new MockTabPresenter();
- navigateClient = new NavigateClient();
+ navigateClient = new NavigateClientImpl();
sut = new NavigateUseCase(tabPresenter, navigateClient);
});