aboutsummaryrefslogtreecommitdiff
path: root/src/background/operators/impls/FindNextOperator.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/background/operators/impls/FindNextOperator.ts')
-rw-r--r--src/background/operators/impls/FindNextOperator.ts94
1 files changed, 94 insertions, 0 deletions
diff --git a/src/background/operators/impls/FindNextOperator.ts b/src/background/operators/impls/FindNextOperator.ts
new file mode 100644
index 0000000..241f71d
--- /dev/null
+++ b/src/background/operators/impls/FindNextOperator.ts
@@ -0,0 +1,94 @@
+import Operator from "../Operator";
+import TabPresenter from "../../presenters/TabPresenter";
+import FindRepository from "../../repositories/FindRepository";
+import FindClient from "../../clients/FindClient";
+import ConsoleClient from "../../infrastructures/ConsoleClient";
+import FramePresenter from "../../presenters/FramePresenter";
+
+export default class FindNextOperator implements Operator {
+ constructor(
+ private readonly tabPresenter: TabPresenter,
+ private readonly findRepository: FindRepository,
+ private readonly findClient: FindClient,
+ private readonly consoleClient: ConsoleClient,
+ private readonly framePresenter: FramePresenter
+ ) {}
+
+ async run(): Promise<void> {
+ const tab = await this.tabPresenter.getCurrent();
+ const tabId = tab?.id;
+ if (tabId == null) {
+ return;
+ }
+
+ const state = await this.findRepository.getLocalState(tabId);
+ if (state) {
+ // Start to find the keyword from the current frame which last found on,
+ // and concat it to end of frame ids to perform a wrap-search
+ //
+ // ,- keyword should be in this frame
+ // |
+ // [100, 101, 0, 100]
+ // |
+ // `- continue from frame id 100
+ //
+ const targetFrameIds = state.frameIds
+ .slice(state.framePos)
+ .concat(
+ state.frameIds.slice(0, state.framePos),
+ state.frameIds[state.framePos]
+ );
+
+ for (let i = 0; i < targetFrameIds.length; ++i) {
+ const found = await this.findClient.findNext(
+ tabId,
+ targetFrameIds[i],
+ state.keyword
+ );
+ if (found) {
+ this.findRepository.setLocalState(tabId, {
+ ...state,
+ framePos: (i + state.framePos) % state.frameIds.length, // save current frame position or first
+ });
+ return;
+ }
+ this.findClient.clearSelection(tabId, targetFrameIds[i]);
+ }
+
+ // The keyword is gone.
+ this.consoleClient.showError(
+ tabId,
+ "Pattern not found: " + state.keyword
+ );
+ return;
+ }
+
+ const keyword = await this.findRepository.getGlobalKeyword();
+ if (keyword) {
+ const frameIds = await this.framePresenter.getAllFrameIds(tabId);
+ for (const frameId of frameIds) {
+ await this.findClient.clearSelection(tabId, frameId);
+ }
+
+ for (let framePos = 0; framePos < frameIds.length; ++framePos) {
+ const found = await this.findClient.findNext(
+ tabId,
+ frameIds[framePos],
+ keyword
+ );
+ if (found) {
+ await this.findRepository.setLocalState(tabId, {
+ frameIds,
+ framePos,
+ keyword,
+ });
+ await this.consoleClient.showInfo(tabId, "Pattern found: " + keyword);
+ return;
+ }
+ }
+ this.consoleClient.showError(tabId, "Pattern not found: " + keyword);
+ return;
+ }
+ await this.consoleClient.showError(tabId, "No previous search keywords");
+ }
+}