diff options
Diffstat (limited to 'src/background')
| -rw-r--r-- | src/background/clients/FindClient.ts | 15 | ||||
| -rw-r--r-- | src/background/operators/impls/FindPrevOperator.ts | 86 | 
2 files changed, 95 insertions, 6 deletions
| diff --git a/src/background/clients/FindClient.ts b/src/background/clients/FindClient.ts index 863c5ad..b46b964 100644 --- a/src/background/clients/FindClient.ts +++ b/src/background/clients/FindClient.ts @@ -3,6 +3,8 @@ import * as messages from "../../shared/messages";  export default interface FindClient {    findNext(tabId: number, frameId: number, keyword: string): Promise<boolean>; +  findPrev(tabId: number, frameId: number, keyword: string): Promise<boolean>; +    clearSelection(tabId: number, frameId: number): Promise<void>;  } @@ -20,6 +22,19 @@ export class FindClientImpl implements FindClient {      return found;    } +  async findPrev( +    tabId: number, +    frameId: number, +    keyword: string +  ): Promise<boolean> { +    const found = (await browser.tabs.sendMessage( +      tabId, +      { type: messages.FIND_PREV, keyword }, +      { frameId } +    )) as boolean; +    return found; +  } +    clearSelection(tabId: number, frameId: number): Promise<void> {      return browser.tabs.sendMessage(        tabId, diff --git a/src/background/operators/impls/FindPrevOperator.ts b/src/background/operators/impls/FindPrevOperator.ts index 28238f6..822c386 100644 --- a/src/background/operators/impls/FindPrevOperator.ts +++ b/src/background/operators/impls/FindPrevOperator.ts @@ -7,14 +7,88 @@ import FramePresenter from "../../presenters/FramePresenter";  export default class FindPrevOperator implements Operator {    constructor( -    _tabPresenter: TabPresenter, -    _findRepository: FindRepository, -    _findClient: FindClient, -    _consoleClient: ConsoleClient, -    _framePresenter: FramePresenter +    private readonly tabPresenter: TabPresenter, +    private readonly findRepository: FindRepository, +    private readonly findClient: FindClient, +    private readonly consoleClient: ConsoleClient, +    private readonly framePresenter: FramePresenter    ) {}    async run(): Promise<void> { -    throw new Error("not implemented"); +    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 = targetFrameIds.length - 1; i >= 0; --i) { +        const found = await this.findClient.findPrev( +          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 = frameIds.length - 1; framePos >= 0; --framePos) { +        const found = await this.findClient.findPrev( +          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");    }  } | 
