diff options
Diffstat (limited to 'src/background/operators')
44 files changed, 882 insertions, 0 deletions
| diff --git a/src/background/operators/Operator.ts b/src/background/operators/Operator.ts new file mode 100644 index 0000000..3b1fe03 --- /dev/null +++ b/src/background/operators/Operator.ts @@ -0,0 +1,5 @@ +interface Operator { +  run(): Promise<void>; +} + +export default Operator; diff --git a/src/background/operators/OperatorFactory.ts b/src/background/operators/OperatorFactory.ts new file mode 100644 index 0000000..9a5234c --- /dev/null +++ b/src/background/operators/OperatorFactory.ts @@ -0,0 +1,6 @@ +import Operator from "./Operator"; +import { Operation } from "../../shared/operations"; + +export default interface OperatorFactory { +  create(op: Operation): Operator; +} diff --git a/src/background/operators/OperatorFactoryChain.ts b/src/background/operators/OperatorFactoryChain.ts new file mode 100644 index 0000000..046ed42 --- /dev/null +++ b/src/background/operators/OperatorFactoryChain.ts @@ -0,0 +1,6 @@ +import Operator from "./Operator"; +import { Operation } from "../../shared/operations"; + +export default interface OperatorFactoryChain { +  create(op: Operation): Operator | null; +} 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..7432153 --- /dev/null +++ b/src/background/operators/impls/CommandOperatorFactoryChain.ts @@ -0,0 +1,62 @@ +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, +    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..607dbfa --- /dev/null +++ b/src/background/operators/impls/InternalOperatorFactoryChain.ts @@ -0,0 +1,36 @@ +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( +    private readonly windowPresenter: WindowPresenter, +    @inject("TabPresenter") +    private readonly tabPresenter: TabPresenter, +    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..d9b1619 --- /dev/null +++ b/src/background/operators/impls/NavigateOperatorFactoryChain.ts @@ -0,0 +1,64 @@ +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, +    private readonly navigateClient: NavigateClient, +    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..9d67b75 --- /dev/null +++ b/src/background/operators/impls/RepeatOperatorFactoryChain.ts @@ -0,0 +1,28 @@ +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( +    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..66cf245 --- /dev/null +++ b/src/background/operators/impls/ResetZoomOperator.ts @@ -0,0 +1,9 @@ +import Operator from "../Operator"; +import ZoomUseCase from "../../usecases/ZoomUseCase"; + +export default class ResetZoomOperator implements Operator { +  constructor(private readonly zoomUseCase: ZoomUseCase) {} +  run(): Promise<void> { +    return this.zoomUseCase.zoomNutoral(); +  } +} 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..37482fe --- /dev/null +++ b/src/background/operators/impls/SelectTabNextOperator.ts @@ -0,0 +1,22 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class SelectTabNextOperator implements Operator { +  constructor( +    private readonly tabPresenter: TabPresenter, +    private readonly count: number +  ) {} + +  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 + this.count) % 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..93a0d6d --- /dev/null +++ b/src/background/operators/impls/SelectTabPrevOperator.ts @@ -0,0 +1,22 @@ +import Operator from "../Operator"; +import TabPresenter from "../../presenters/TabPresenter"; + +export default class SelectTabPrevOperator implements Operator { +  constructor( +    private readonly tabPresenter: TabPresenter, +    private readonly count: number +  ) {} + +  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 - this.count + 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..a1752eb --- /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 = "addookmark "; +    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..b4cb401 --- /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 "./SelectTabPrevOperator"; +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, 1); +      case operations.TAB_NEXT: +        return new SelectTabNextOperator(this.tabPresenter, 1); +      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..0c44c6f --- /dev/null +++ b/src/background/operators/impls/ZoomInOperator.ts @@ -0,0 +1,10 @@ +import Operator from "../Operator"; +import ZoomUseCase from "../../usecases/ZoomUseCase"; + +export default class ZoomInOperator implements Operator { +  constructor(private readonly zoomUseCase: ZoomUseCase) {} + +  run(): Promise<void> { +    return this.zoomUseCase.zoomIn(); +  } +} diff --git a/src/background/operators/impls/ZoomOperatorFactoryChain.ts b/src/background/operators/impls/ZoomOperatorFactoryChain.ts new file mode 100644 index 0000000..b8858ab --- /dev/null +++ b/src/background/operators/impls/ZoomOperatorFactoryChain.ts @@ -0,0 +1,25 @@ +import { 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 * as operations from "../../../shared/operations"; + +@injectable() +export default class ZoomOperatorFactoryChain implements OperatorFactoryChain { +  constructor(private readonly zoomUseCase: ZoomUseCase) {} + +  create(op: operations.Operation): Operator | null { +    switch (op.type) { +      case operations.ZOOM_IN: +        return new ZoomInOperator(this.zoomUseCase); +      case operations.ZOOM_OUT: +        return new ZoomOutOperator(this.zoomUseCase); +      case operations.ZOOM_NEUTRAL: +        return new ResetZoomOperator(this.zoomUseCase); +    } +    return null; +  } +} diff --git a/src/background/operators/impls/ZoomOutOperator.ts b/src/background/operators/impls/ZoomOutOperator.ts new file mode 100644 index 0000000..7f9cb6b --- /dev/null +++ b/src/background/operators/impls/ZoomOutOperator.ts @@ -0,0 +1,10 @@ +import Operator from "../Operator"; +import ZoomUseCase from "../../usecases/ZoomUseCase"; + +export default class ZoomOutOperator implements Operator { +  constructor(private readonly zoomUseCase: ZoomUseCase) {} + +  run(): Promise<void> { +    return this.zoomUseCase.zoomOut(); +  } +} | 
