diff options
Diffstat (limited to 'src/background/operators/impls')
41 files changed, 869 insertions, 0 deletions
diff --git a/src/background/operators/impls/CancelOperator.ts b/src/background/operators/impls/CancelOperator.ts new file mode 100644 index 0000000..7ab09fb --- /dev/null +++ b/src/background/operators/impls/CancelOperator.ts @@ -0,0 +1,15 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; + +export default class CancelOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly consoleClient: ConsoleClient + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + return this.consoleClient.hide(tab.id as number); + } +} diff --git a/src/background/operators/impls/CloseTabOperator.ts b/src/background/operators/impls/CloseTabOperator.ts new file mode 100644 index 0000000..5d8e80b --- /dev/null +++ b/src/background/operators/impls/CloseTabOperator.ts @@ -0,0 +1,22 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class CloseTabOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly force: boolean = false, + private readonly selectLeft: boolean = false + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + if (!this.force && tab.pinned) { + return Promise.resolve(); + } + if (this.selectLeft && tab.index > 0) { + const 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/background/operators/impls/CloseTabRightOperator.ts b/src/background/operators/impls/CloseTabRightOperator.ts new file mode 100644 index 0000000..f36930e --- /dev/null +++ b/src/background/operators/impls/CloseTabRightOperator.ts @@ -0,0 +1,21 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class CloseTabRightOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tabs = await this.tabPresenter.getAll(); + tabs.sort((t1, t2) => t1.index - t2.index); + const index = tabs.findIndex((t) => t.active); + if (index < 0) { + return; + } + for (let i = index + 1; i < tabs.length; ++i) { + const tab = tabs[i]; + if (!tab.pinned) { + await this.tabPresenter.remove([tab.id as number]); + } + } + } +} diff --git a/src/background/operators/impls/CommandOperatorFactoryChain.ts b/src/background/operators/impls/CommandOperatorFactoryChain.ts new file mode 100644 index 0000000..680a384 --- /dev/null +++ b/src/background/operators/impls/CommandOperatorFactoryChain.ts @@ -0,0 +1,63 @@ +import { inject, injectable } from "tsyringe"; +import Operator from "../Operator"; +import OperatorFactoryChain from "../OperatorFactoryChain"; +import ShowCommandOperator from "./ShowCommandOperator"; +import ShowOpenCommandOperator from "./ShowOpenCommandOperator"; +import ShowTabOpenCommandOperator from "./ShowTabOpenCommandOperator"; +import ShowWinOpenCommandOperator from "./ShowWinOpenCommandOperator"; +import ShowBufferCommandOperator from "./ShowBufferCommandOperator"; +import ShowAddBookmarkOperator from "./ShowAddBookmarkOperator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; +import * as operations from "../../../shared/operations"; +import StartFindOperator from "./StartFindOperator"; + +@injectable() +export default class CommandOperatorFactoryChain + implements OperatorFactoryChain { + constructor( + @inject("TabPresenter") + private readonly tabPresenter: TabPresenter, + @inject("ConsoleClient") + private readonly consoleClient: ConsoleClient + ) {} + + create(op: operations.Operation): Operator | null { + switch (op.type) { + case operations.COMMAND_SHOW: + return new ShowCommandOperator(this.tabPresenter, this.consoleClient); + case operations.COMMAND_SHOW_OPEN: + return new ShowOpenCommandOperator( + this.tabPresenter, + this.consoleClient, + op.alter + ); + case operations.COMMAND_SHOW_TABOPEN: + return new ShowTabOpenCommandOperator( + this.tabPresenter, + this.consoleClient, + op.alter + ); + case operations.COMMAND_SHOW_WINOPEN: + return new ShowWinOpenCommandOperator( + this.tabPresenter, + this.consoleClient, + op.alter + ); + case operations.COMMAND_SHOW_BUFFER: + return new ShowBufferCommandOperator( + this.tabPresenter, + this.consoleClient + ); + case operations.COMMAND_SHOW_ADDBOOKMARK: + return new ShowAddBookmarkOperator( + this.tabPresenter, + this.consoleClient, + op.alter + ); + case operations.FIND_START: + return new StartFindOperator(this.tabPresenter, this.consoleClient); + } + return null; + } +} diff --git a/src/background/operators/impls/DuplicateTabOperator.ts b/src/background/operators/impls/DuplicateTabOperator.ts new file mode 100644 index 0000000..7737cfa --- /dev/null +++ b/src/background/operators/impls/DuplicateTabOperator.ts @@ -0,0 +1,11 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class DuplicateTabOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + await this.tabPresenter.duplicate(tab.id as number); + } +} diff --git a/src/background/operators/impls/InternalOpenURLOperator.ts b/src/background/operators/impls/InternalOpenURLOperator.ts new file mode 100644 index 0000000..6bf513b --- /dev/null +++ b/src/background/operators/impls/InternalOpenURLOperator.ts @@ -0,0 +1,24 @@ +import Operator from "../Operator"; +import WindowPresenter from "../../presenters/WindowPresenter"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class InternalOpenURLOperator implements Operator { + constructor( + private readonly windowPresenter: WindowPresenter, + private readonly tabPresenter: TabPresenter, + private readonly url: string, + private readonly newTab?: boolean, + private readonly newWindow?: boolean + ) {} + + async run(): Promise<void> { + if (this.newWindow) { + await this.windowPresenter.create(this.url); + } else if (this.newTab) { + await this.tabPresenter.create(this.url); + } else { + const tab = await this.tabPresenter.getCurrent(); + await this.tabPresenter.open(this.url, tab.id); + } + } +} diff --git a/src/background/operators/impls/InternalOperatorFactoryChain.ts b/src/background/operators/impls/InternalOperatorFactoryChain.ts new file mode 100644 index 0000000..05615f6 --- /dev/null +++ b/src/background/operators/impls/InternalOperatorFactoryChain.ts @@ -0,0 +1,38 @@ +import { inject, injectable } from "tsyringe"; +import Operator from "../Operator"; +import OperatorFactoryChain from "../OperatorFactoryChain"; +import CancelOperator from "./CancelOperator"; +import InternalOpenURLOperator from "./InternalOpenURLOperator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; +import WindowPresenter from "../../presenters/WindowPresenter"; +import * as operations from "../../../shared/operations"; + +@injectable() +export default class InternalOperatorFactoryChain + implements OperatorFactoryChain { + constructor( + @inject("WindowPresenter") + private readonly windowPresenter: WindowPresenter, + @inject("TabPresenter") + private readonly tabPresenter: TabPresenter, + @inject("ConsoleClient") + private readonly consoleClient: ConsoleClient + ) {} + + create(op: operations.Operation): Operator | null { + switch (op.type) { + case operations.CANCEL: + return new CancelOperator(this.tabPresenter, this.consoleClient); + case operations.INTERNAL_OPEN_URL: + return new InternalOpenURLOperator( + this.windowPresenter, + this.tabPresenter, + op.url, + op.newTab, + op.newWindow + ); + } + return null; + } +} diff --git a/src/background/operators/impls/NavigateHistoryNextOperator.ts b/src/background/operators/impls/NavigateHistoryNextOperator.ts new file mode 100644 index 0000000..b092c48 --- /dev/null +++ b/src/background/operators/impls/NavigateHistoryNextOperator.ts @@ -0,0 +1,15 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import NavigateClient from "../../clients/NavigateClient"; + +export default class NavigateHistoryNextOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly navigateClient: NavigateClient + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + await this.navigateClient.historyNext(tab.id!); + } +} diff --git a/src/background/operators/impls/NavigateHistoryPrevOperator.ts b/src/background/operators/impls/NavigateHistoryPrevOperator.ts new file mode 100644 index 0000000..27d4ee9 --- /dev/null +++ b/src/background/operators/impls/NavigateHistoryPrevOperator.ts @@ -0,0 +1,15 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import NavigateClient from "../../clients/NavigateClient"; + +export default class NavigateHistoryPrevOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly navigateClient: NavigateClient + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + await this.navigateClient.historyPrev(tab.id!); + } +} diff --git a/src/background/operators/impls/NavigateLinkNextOperator.ts b/src/background/operators/impls/NavigateLinkNextOperator.ts new file mode 100644 index 0000000..dbbcc45 --- /dev/null +++ b/src/background/operators/impls/NavigateLinkNextOperator.ts @@ -0,0 +1,15 @@ +import Operator from "../Operator"; +import NavigateClient from "../../clients/NavigateClient"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class NavigateLinkNextOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly navigateClient: NavigateClient + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + await this.navigateClient.linkNext(tab.id!); + } +} diff --git a/src/background/operators/impls/NavigateLinkPrevOperator.ts b/src/background/operators/impls/NavigateLinkPrevOperator.ts new file mode 100644 index 0000000..fe41ee6 --- /dev/null +++ b/src/background/operators/impls/NavigateLinkPrevOperator.ts @@ -0,0 +1,15 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import NavigateClient from "../../clients/NavigateClient"; + +export default class NavigateLinkPrevOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly navigateClient: NavigateClient + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + await this.navigateClient.linkPrev(tab.id!); + } +} diff --git a/src/background/operators/impls/NavigateOperatorFactoryChain.ts b/src/background/operators/impls/NavigateOperatorFactoryChain.ts new file mode 100644 index 0000000..618db45 --- /dev/null +++ b/src/background/operators/impls/NavigateOperatorFactoryChain.ts @@ -0,0 +1,66 @@ +import { inject, injectable } from "tsyringe"; +import Operator from "../Operator"; +import OperatorFactoryChain from "../OperatorFactoryChain"; +import NavigateHistoryPrevOperator from "./NavigateHistoryPrevOperator"; +import NavigateHistoryNextOperator from "./NavigateHistoryNextOperator"; +import NavigateLinkPrevOperator from "./NavigateLinkPrevOperator"; +import NavigateLinkNextOperator from "./NavigateLinkNextOperator"; +import NavigateParentOperator from "./NavigateParentOperator"; +import NavigateRootOperator from "./NavigateRootOperator"; +import OpenSourceOperator from "./OpenSourceOperator"; +import OpenHomeOperator from "./OpenHomeOperator"; +import TabPresenter from "../../presenters/TabPresenter"; +import NavigateClient from "../../clients/NavigateClient"; +import BrowserSettingRepository from "../../repositories/BrowserSettingRepository"; +import * as operations from "../../../shared/operations"; + +@injectable() +export default class NavigateOperatorFactoryChain + implements OperatorFactoryChain { + constructor( + @inject("TabPresenter") + private readonly tabPresenter: TabPresenter, + @inject("NavigateClient") + private readonly navigateClient: NavigateClient, + @inject("BrowserSettingRepository") + private readonly browserSettingRepository: BrowserSettingRepository + ) {} + + create(op: operations.Operation): Operator | null { + switch (op.type) { + case operations.NAVIGATE_HISTORY_PREV: + return new NavigateHistoryPrevOperator( + this.tabPresenter, + this.navigateClient + ); + case operations.NAVIGATE_HISTORY_NEXT: + return new NavigateHistoryNextOperator( + this.tabPresenter, + this.navigateClient + ); + case operations.NAVIGATE_LINK_PREV: + return new NavigateLinkPrevOperator( + this.tabPresenter, + this.navigateClient + ); + case operations.NAVIGATE_LINK_NEXT: + return new NavigateLinkNextOperator( + this.tabPresenter, + this.navigateClient + ); + case operations.NAVIGATE_PARENT: + return new NavigateParentOperator(this.tabPresenter); + case operations.NAVIGATE_ROOT: + return new NavigateRootOperator(this.tabPresenter); + case operations.PAGE_SOURCE: + return new OpenSourceOperator(this.tabPresenter); + case operations.PAGE_HOME: + return new OpenHomeOperator( + this.tabPresenter, + this.browserSettingRepository, + op.newTab + ); + } + return null; + } +} diff --git a/src/background/operators/impls/NavigateParentOperator.ts b/src/background/operators/impls/NavigateParentOperator.ts new file mode 100644 index 0000000..652cfb8 --- /dev/null +++ b/src/background/operators/impls/NavigateParentOperator.ts @@ -0,0 +1,25 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class NavigateParentOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + const url = new URL(tab.url!); + if (url.hash.length > 0) { + url.hash = ""; + } else if (url.search.length > 0) { + url.search = ""; + } else { + const basenamePattern = /\/[^/]+$/; + const lastDirPattern = /\/[^/]+\/$/; + if (basenamePattern.test(url.pathname)) { + url.pathname = url.pathname.replace(basenamePattern, "/"); + } else if (lastDirPattern.test(url.pathname)) { + url.pathname = url.pathname.replace(lastDirPattern, "/"); + } + } + await this.tabPresenter.open(url.href); + } +} diff --git a/src/background/operators/impls/NavigateRootOperator.ts b/src/background/operators/impls/NavigateRootOperator.ts new file mode 100644 index 0000000..b140156 --- /dev/null +++ b/src/background/operators/impls/NavigateRootOperator.ts @@ -0,0 +1,12 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class NavigateRootOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + const url = new URL(tab.url!); + await this.tabPresenter.open(url.origin); + } +} diff --git a/src/background/operators/impls/OpenHomeOperator.ts b/src/background/operators/impls/OpenHomeOperator.ts new file mode 100644 index 0000000..4773be6 --- /dev/null +++ b/src/background/operators/impls/OpenHomeOperator.ts @@ -0,0 +1,29 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import BrowserSettingRepository from "../../repositories/BrowserSettingRepository"; + +export default class OpenHomeOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly browserSettingRepository: BrowserSettingRepository, + private readonly newTab: boolean + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + const urls = await this.browserSettingRepository.getHomepageUrls(); + if (urls.length === 1 && urls[0] === "about:home") { + // eslint-disable-next-line max-len + throw new Error( + "Cannot open Firefox Home (about:home) by WebExtensions, set your custom URLs" + ); + } + if (urls.length === 1 && !this.newTab) { + await this.tabPresenter.open(urls[0], tab.id); + return; + } + for (const url of urls) { + await this.tabPresenter.create(url); + } + } +} diff --git a/src/background/operators/impls/OpenSourceOperator.ts b/src/background/operators/impls/OpenSourceOperator.ts new file mode 100644 index 0000000..9185ba5 --- /dev/null +++ b/src/background/operators/impls/OpenSourceOperator.ts @@ -0,0 +1,12 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class OpenSourceOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + const url = "view-source:" + tab.url; + await this.tabPresenter.create(url); + } +} diff --git a/src/background/operators/impls/OperatorFactoryImpl.ts b/src/background/operators/impls/OperatorFactoryImpl.ts new file mode 100644 index 0000000..34e7bb5 --- /dev/null +++ b/src/background/operators/impls/OperatorFactoryImpl.ts @@ -0,0 +1,45 @@ +import { inject, delay, injectable } from "tsyringe"; +import Operator from "../Operator"; +import OperatorFactory from "../OperatorFactory"; +import OperatorFactoryChain from "../OperatorFactoryChain"; +import CommandOperatorFactoryChain from "./CommandOperatorFactoryChain"; +import InternalOperatorFactoryChain from "./InternalOperatorFactoryChain"; +import NavigateOperatorFactoryChain from "./NavigateOperatorFactoryChain"; +import RepeatOperatorFactoryChain from "./RepeatOperatorFactoryChain"; +import TabOperatorFactoryChain from "./TabOperatorFactoryChain"; +import ZoomOperatorFactoryChain from "./ZoomOperatorFactoryChain"; +import * as operations from "../../../shared/operations"; + +@injectable() +export class OperatorFactoryImpl implements OperatorFactory { + private readonly factoryChains: OperatorFactoryChain[]; + + constructor( + commandOperatorFactoryChain: CommandOperatorFactoryChain, + internalOperatorFactoryChain: InternalOperatorFactoryChain, + navigateOperatorFactoryChain: NavigateOperatorFactoryChain, + tabOperatorFactoryChain: TabOperatorFactoryChain, + zoomOperatorFactoryChain: ZoomOperatorFactoryChain, + @inject(delay(() => RepeatOperatorFactoryChain)) + repeatOperatorFactoryChain: RepeatOperatorFactoryChain + ) { + this.factoryChains = [ + commandOperatorFactoryChain, + internalOperatorFactoryChain, + navigateOperatorFactoryChain, + repeatOperatorFactoryChain, + tabOperatorFactoryChain, + zoomOperatorFactoryChain, + ]; + } + + create(op: operations.Operation): Operator { + for (const chain of this.factoryChains) { + const operator = chain.create(op); + if (operator !== null) { + return operator; + } + } + throw new Error("unknown operation: " + op.type); + } +} diff --git a/src/background/operators/impls/PinTabOperator.ts b/src/background/operators/impls/PinTabOperator.ts new file mode 100644 index 0000000..8121725 --- /dev/null +++ b/src/background/operators/impls/PinTabOperator.ts @@ -0,0 +1,11 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class PinTabOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + return this.tabPresenter.setPinned(tab.id as number, true); + } +} diff --git a/src/background/operators/impls/ReloadTabOperator.ts b/src/background/operators/impls/ReloadTabOperator.ts new file mode 100644 index 0000000..db3389e --- /dev/null +++ b/src/background/operators/impls/ReloadTabOperator.ts @@ -0,0 +1,14 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class ReloadTabOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly cache: boolean + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + return this.tabPresenter.reload(tab.id as number, this.cache); + } +} diff --git a/src/background/operators/impls/ReopenTabOperator.ts b/src/background/operators/impls/ReopenTabOperator.ts new file mode 100644 index 0000000..507b4a8 --- /dev/null +++ b/src/background/operators/impls/ReopenTabOperator.ts @@ -0,0 +1,10 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class ReopenTabOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + run(): Promise<void> { + return this.tabPresenter.reopen(); + } +} diff --git a/src/background/operators/impls/RepeatLastOperator.ts b/src/background/operators/impls/RepeatLastOperator.ts new file mode 100644 index 0000000..d46daab --- /dev/null +++ b/src/background/operators/impls/RepeatLastOperator.ts @@ -0,0 +1,18 @@ +import Operator from "../Operator"; +import RepeatRepository from "../../repositories/RepeatRepository"; +import OperatorFactory from "../OperatorFactory"; + +export default class RepeatLastOperator implements Operator { + constructor( + private readonly repeatRepository: RepeatRepository, + private readonly operatorFactory: OperatorFactory + ) {} + + run(): Promise<void> { + const op = this.repeatRepository.getLastOperation(); + if (typeof op === "undefined") { + return Promise.resolve(); + } + return this.operatorFactory.create(op).run(); + } +} diff --git a/src/background/operators/impls/RepeatOperatorFactoryChain.ts b/src/background/operators/impls/RepeatOperatorFactoryChain.ts new file mode 100644 index 0000000..5038d48 --- /dev/null +++ b/src/background/operators/impls/RepeatOperatorFactoryChain.ts @@ -0,0 +1,29 @@ +import { inject, injectable } from "tsyringe"; +import Operator from "../Operator"; +import OperatorFactoryChain from "../OperatorFactoryChain"; +import RepeatLastOperator from "./RepeatLastOperator"; +import RepeatRepository from "../../repositories/RepeatRepository"; +import OperatorFactory from "../OperatorFactory"; +import * as operations from "../../../shared/operations"; + +@injectable() +export default class RepeatOperatorFactoryChain + implements OperatorFactoryChain { + constructor( + @inject("RepeatRepository") + private readonly repeatRepository: RepeatRepository, + @inject("OperatorFactory") + private readonly operatorFactory: OperatorFactory + ) {} + + create(op: operations.Operation): Operator | null { + switch (op.type) { + case operations.REPEAT_LAST: + return new RepeatLastOperator( + this.repeatRepository, + this.operatorFactory + ); + } + return null; + } +} diff --git a/src/background/operators/impls/ResetZoomOperator.ts b/src/background/operators/impls/ResetZoomOperator.ts new file mode 100644 index 0000000..96af733 --- /dev/null +++ b/src/background/operators/impls/ResetZoomOperator.ts @@ -0,0 +1,10 @@ +import Operator from "../Operator"; +import ZoomPresenter from "../../presenters/ZoomPresenter"; + +export default class ResetZoomOperator implements Operator { + constructor(private readonly zoomPresenter: ZoomPresenter) {} + + run(): Promise<void> { + return this.zoomPresenter.resetZoom(); + } +} diff --git a/src/background/operators/impls/SelectFirstTabOperator.ts b/src/background/operators/impls/SelectFirstTabOperator.ts new file mode 100644 index 0000000..c04b8a9 --- /dev/null +++ b/src/background/operators/impls/SelectFirstTabOperator.ts @@ -0,0 +1,11 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class SelectFirstTabOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tabs = await this.tabPresenter.getAll(); + return this.tabPresenter.select(tabs[0].id as number); + } +} diff --git a/src/background/operators/impls/SelectLastTabOperator.ts b/src/background/operators/impls/SelectLastTabOperator.ts new file mode 100644 index 0000000..e16d406 --- /dev/null +++ b/src/background/operators/impls/SelectLastTabOperator.ts @@ -0,0 +1,11 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class SelectLastTabOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tabs = await this.tabPresenter.getAll(); + return this.tabPresenter.select(tabs[tabs.length - 1].id as number); + } +} diff --git a/src/background/operators/impls/SelectPreviousSelectedTabOperator.ts b/src/background/operators/impls/SelectPreviousSelectedTabOperator.ts new file mode 100644 index 0000000..03a778d --- /dev/null +++ b/src/background/operators/impls/SelectPreviousSelectedTabOperator.ts @@ -0,0 +1,14 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class SelectPreviousSelectedTabOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tabId = await this.tabPresenter.getLastSelectedId(); + if (tabId === null || typeof tabId === "undefined") { + return Promise.resolve(); + } + return this.tabPresenter.select(tabId); + } +} diff --git a/src/background/operators/impls/SelectTabNextOperator.ts b/src/background/operators/impls/SelectTabNextOperator.ts new file mode 100644 index 0000000..34d37ff --- /dev/null +++ b/src/background/operators/impls/SelectTabNextOperator.ts @@ -0,0 +1,19 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class SelectTabNextOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tabs = await this.tabPresenter.getAll(); + if (tabs.length < 2) { + return; + } + const tab = tabs.find((t) => t.active); + if (!tab) { + return; + } + const select = (tab.index + 1) % tabs.length; + return this.tabPresenter.select(tabs[select].id as number); + } +} diff --git a/src/background/operators/impls/SelectTabPrevOperator.ts b/src/background/operators/impls/SelectTabPrevOperator.ts new file mode 100644 index 0000000..3776c1a --- /dev/null +++ b/src/background/operators/impls/SelectTabPrevOperator.ts @@ -0,0 +1,19 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class SelectTabPrevOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tabs = await this.tabPresenter.getAll(); + if (tabs.length < 2) { + return; + } + const tab = tabs.find((t) => t.active); + if (!tab) { + return; + } + const select = (tab.index - 1 + tabs.length) % tabs.length; + return this.tabPresenter.select(tabs[select].id as number); + } +} diff --git a/src/background/operators/impls/ShowAddBookmarkOperator.ts b/src/background/operators/impls/ShowAddBookmarkOperator.ts new file mode 100644 index 0000000..cce4879 --- /dev/null +++ b/src/background/operators/impls/ShowAddBookmarkOperator.ts @@ -0,0 +1,20 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; + +export default class ShowAddBookmarkOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly consoleClient: ConsoleClient, + private readonly alter: boolean + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + let command = "addbookmark "; + if (this.alter) { + command += tab.title || ""; + } + return this.consoleClient.showCommand(tab.id as number, command); + } +} diff --git a/src/background/operators/impls/ShowBufferCommandOperator.ts b/src/background/operators/impls/ShowBufferCommandOperator.ts new file mode 100644 index 0000000..e1246e4 --- /dev/null +++ b/src/background/operators/impls/ShowBufferCommandOperator.ts @@ -0,0 +1,16 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; + +export default class ShowBufferCommandOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly consoleClient: ConsoleClient + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + const command = "buffer "; + return this.consoleClient.showCommand(tab.id as number, command); + } +} diff --git a/src/background/operators/impls/ShowCommandOperator.ts b/src/background/operators/impls/ShowCommandOperator.ts new file mode 100644 index 0000000..a5e1765 --- /dev/null +++ b/src/background/operators/impls/ShowCommandOperator.ts @@ -0,0 +1,15 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; + +export default class ShowCommandOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly consoleClient: ConsoleClient + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + return this.consoleClient.showCommand(tab.id as number, ""); + } +} diff --git a/src/background/operators/impls/ShowOpenCommandOperator.ts b/src/background/operators/impls/ShowOpenCommandOperator.ts new file mode 100644 index 0000000..1e78e5f --- /dev/null +++ b/src/background/operators/impls/ShowOpenCommandOperator.ts @@ -0,0 +1,20 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; + +export default class ShowOpenCommandOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly consoleClient: ConsoleClient, + private readonly alter: boolean + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + let command = "open "; + if (this.alter) { + command += tab.url || ""; + } + return this.consoleClient.showCommand(tab.id as number, command); + } +} diff --git a/src/background/operators/impls/ShowTabOpenCommandOperator.ts b/src/background/operators/impls/ShowTabOpenCommandOperator.ts new file mode 100644 index 0000000..d734da1 --- /dev/null +++ b/src/background/operators/impls/ShowTabOpenCommandOperator.ts @@ -0,0 +1,20 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; + +export default class ShowTabOpenCommandOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly consoleClient: ConsoleClient, + private readonly alter: boolean + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + let command = "tabopen "; + if (this.alter) { + command += tab.url || ""; + } + return this.consoleClient.showCommand(tab.id as number, command); + } +} diff --git a/src/background/operators/impls/ShowWinOpenCommandOperator.ts b/src/background/operators/impls/ShowWinOpenCommandOperator.ts new file mode 100644 index 0000000..3c5e639 --- /dev/null +++ b/src/background/operators/impls/ShowWinOpenCommandOperator.ts @@ -0,0 +1,20 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; + +export default class ShowWinOpenCommandOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly consoleClient: ConsoleClient, + private readonly alter: boolean + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + let command = "winopen "; + if (this.alter) { + command += tab.url || ""; + } + return this.consoleClient.showCommand(tab.id as number, command); + } +} diff --git a/src/background/operators/impls/StartFindOperator.ts b/src/background/operators/impls/StartFindOperator.ts new file mode 100644 index 0000000..284ac9b --- /dev/null +++ b/src/background/operators/impls/StartFindOperator.ts @@ -0,0 +1,15 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import ConsoleClient from "../../infrastructures/ConsoleClient"; + +export default class StartFindOperator implements Operator { + constructor( + private readonly tabPresenter: TabPresenter, + private readonly consoleClient: ConsoleClient + ) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + return this.consoleClient.showFind(tab.id as number); + } +} diff --git a/src/background/operators/impls/TabOperatorFactoryChain.ts b/src/background/operators/impls/TabOperatorFactoryChain.ts new file mode 100644 index 0000000..edd3eaf --- /dev/null +++ b/src/background/operators/impls/TabOperatorFactoryChain.ts @@ -0,0 +1,64 @@ +import { inject, injectable } from "tsyringe"; +import OperatorFactoryChain from "../OperatorFactoryChain"; +import * as operations from "../../../shared/operations"; +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; +import CloseTabOperator from "./CloseTabOperator"; +import CloseTabRightOperator from "./CloseTabRightOperator"; +import ReopenTabOperator from "./ReopenTabOperator"; +import SelectTabPrevOperator from "./SelectTabPrevOperator"; +import SelectTabNextOperator from "./SelectTabNextOperator"; +import SelectFirstTabOperator from "./SelectFirstTabOperator"; +import SelectLastTabOperator from "./SelectLastTabOperator"; +import SelectPreviousSelectedTabOperator from "./SelectPreviousSelectedTabOperator"; +import ReloadTabOperator from "./ReloadTabOperator"; +import PinTabOperator from "./PinTabOperator"; +import UnpinTabOperator from "./UnpinTabOperator"; +import TogglePinnedTabOperator from "./TogglePinnedTabOperator"; +import DuplicateTabOperator from "./DuplicateTabOperator"; + +@injectable() +export default class TabOperatorFactoryChain implements OperatorFactoryChain { + constructor( + @inject("TabPresenter") + private readonly tabPresenter: TabPresenter + ) {} + + create(op: operations.Operation): Operator | null { + switch (op.type) { + case operations.TAB_CLOSE: + return new CloseTabOperator( + this.tabPresenter, + false, + op.select === "left" + ); + case operations.TAB_CLOSE_RIGHT: + return new CloseTabRightOperator(this.tabPresenter); + case operations.TAB_CLOSE_FORCE: + return new CloseTabOperator(this.tabPresenter, true, false); + case operations.TAB_REOPEN: + return new ReopenTabOperator(this.tabPresenter); + case operations.TAB_PREV: + return new SelectTabPrevOperator(this.tabPresenter); + case operations.TAB_NEXT: + return new SelectTabNextOperator(this.tabPresenter); + case operations.TAB_FIRST: + return new SelectFirstTabOperator(this.tabPresenter); + case operations.TAB_LAST: + return new SelectLastTabOperator(this.tabPresenter); + case operations.TAB_PREV_SEL: + return new SelectPreviousSelectedTabOperator(this.tabPresenter); + case operations.TAB_RELOAD: + return new ReloadTabOperator(this.tabPresenter, op.cache); + case operations.TAB_PIN: + return new PinTabOperator(this.tabPresenter); + case operations.TAB_UNPIN: + return new UnpinTabOperator(this.tabPresenter); + case operations.TAB_TOGGLE_PINNED: + return new TogglePinnedTabOperator(this.tabPresenter); + case operations.TAB_DUPLICATE: + return new DuplicateTabOperator(this.tabPresenter); + } + return null; + } +} diff --git a/src/background/operators/impls/TogglePinnedTabOperator.ts b/src/background/operators/impls/TogglePinnedTabOperator.ts new file mode 100644 index 0000000..c4fd4ba --- /dev/null +++ b/src/background/operators/impls/TogglePinnedTabOperator.ts @@ -0,0 +1,11 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class TogglePinnedTabOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + return this.tabPresenter.setPinned(tab.id as number, !tab.pinned); + } +} diff --git a/src/background/operators/impls/UnpinTabOperator.ts b/src/background/operators/impls/UnpinTabOperator.ts new file mode 100644 index 0000000..fa50145 --- /dev/null +++ b/src/background/operators/impls/UnpinTabOperator.ts @@ -0,0 +1,11 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class UnpinTabOperator implements Operator { + constructor(private readonly tabPresenter: TabPresenter) {} + + async run(): Promise<void> { + const tab = await this.tabPresenter.getCurrent(); + return this.tabPresenter.setPinned(tab.id as number, false); + } +} diff --git a/src/background/operators/impls/ZoomInOperator.ts b/src/background/operators/impls/ZoomInOperator.ts new file mode 100644 index 0000000..e900f0d --- /dev/null +++ b/src/background/operators/impls/ZoomInOperator.ts @@ -0,0 +1,10 @@ +import Operator from "../Operator"; +import ZoomPresenter from "../../presenters/ZoomPresenter"; + +export default class ZoomInOperator implements Operator { + constructor(private readonly zoomPresenter: ZoomPresenter) {} + + run(): Promise<void> { + return this.zoomPresenter.zoomIn(); + } +} diff --git a/src/background/operators/impls/ZoomOperatorFactoryChain.ts b/src/background/operators/impls/ZoomOperatorFactoryChain.ts new file mode 100644 index 0000000..bf930a7 --- /dev/null +++ b/src/background/operators/impls/ZoomOperatorFactoryChain.ts @@ -0,0 +1,28 @@ +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 ZoomPresenter from "../../presenters/ZoomPresenter"; +import * as operations from "../../../shared/operations"; + +@injectable() +export default class ZoomOperatorFactoryChain implements OperatorFactoryChain { + constructor( + @inject("ZoomPresenter") + private readonly zoomPresenter: ZoomPresenter + ) {} + + create(op: operations.Operation): Operator | null { + switch (op.type) { + case operations.ZOOM_IN: + return new ZoomInOperator(this.zoomPresenter); + case operations.ZOOM_OUT: + return new ZoomOutOperator(this.zoomPresenter); + case operations.ZOOM_NEUTRAL: + return new ResetZoomOperator(this.zoomPresenter); + } + return null; + } +} diff --git a/src/background/operators/impls/ZoomOutOperator.ts b/src/background/operators/impls/ZoomOutOperator.ts new file mode 100644 index 0000000..0c0389e --- /dev/null +++ b/src/background/operators/impls/ZoomOutOperator.ts @@ -0,0 +1,10 @@ +import Operator from "../Operator"; +import ZoomPresenter from "../../presenters/ZoomPresenter"; + +export default class ZoomOutOperator implements Operator { + constructor(private readonly zoomPresenter: ZoomPresenter) {} + + run(): Promise<void> { + return this.zoomPresenter.zoomOut(); + } +} |