aboutsummaryrefslogtreecommitdiff
path: root/src/content/controllers/KeymapController.ts
blob: 092e55ce81d6c1865c03f294361b925c4ecf7218 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { injectable, inject } from "tsyringe";
import * as operations from "../../shared/operations";
import KeymapUseCase from "../usecases/KeymapUseCase";
import AddonEnabledUseCase from "../usecases/AddonEnabledUseCase";
import FindSlaveUseCase from "../usecases/FindSlaveUseCase";
import ScrollUseCase from "../usecases/ScrollUseCase";
import FocusUseCase from "../usecases/FocusUseCase";
import ClipboardUseCase from "../usecases/ClipboardUseCase";
import OperationClient from "../client/OperationClient";
import MarkKeyyUseCase from "../usecases/MarkKeyUseCase";
import FollowMasterClient from "../client/FollowMasterClient";
import Key from "../../shared/settings/Key";

@injectable()
export default class KeymapController {
  constructor(
    private keymapUseCase: KeymapUseCase,
    private addonEnabledUseCase: AddonEnabledUseCase,
    private findSlaveUseCase: FindSlaveUseCase,
    private scrollUseCase: ScrollUseCase,
    private focusUseCase: FocusUseCase,
    private clipbaordUseCase: ClipboardUseCase,
    private markKeyUseCase: MarkKeyyUseCase,

    @inject("OperationClient")
    private operationClient: OperationClient,

    @inject("FollowMasterClient")
    private followMasterClient: FollowMasterClient
  ) {}

  // eslint-disable-next-line complexity, max-lines-per-function
  press(key: Key): boolean {
    const nextOp = this.keymapUseCase.nextOps(key);
    if (nextOp === null) {
      return false;
    }

    if (!operations.isNRepeatable(nextOp.op.type)) {
      nextOp.repeat = 1;
    }

    const doFunc = ((op: operations.Operation) => {
      switch (op.type) {
        case operations.ADDON_ENABLE:
          return () => this.addonEnabledUseCase.enable();
        case operations.ADDON_DISABLE:
          return () => this.addonEnabledUseCase.disable();
        case operations.ADDON_TOGGLE_ENABLED:
          return () => this.addonEnabledUseCase.toggle();
        case operations.FIND_NEXT:
          return () => this.findSlaveUseCase.findNext();
        case operations.FIND_PREV:
          return () => this.findSlaveUseCase.findPrev();
        case operations.SCROLL_VERTICALLY:
          return () => this.scrollUseCase.scrollVertically(op.count);
        case operations.SCROLL_HORIZONALLY:
          return () => this.scrollUseCase.scrollHorizonally(op.count);
        case operations.SCROLL_PAGES:
          return () => this.scrollUseCase.scrollPages(op.count);
        case operations.SCROLL_TOP:
          return () => this.scrollUseCase.scrollToTop();
        case operations.SCROLL_BOTTOM:
          return () => this.scrollUseCase.scrollToBottom();
        case operations.SCROLL_HOME:
          return () => this.scrollUseCase.scrollToHome();
        case operations.SCROLL_END:
          return () => this.scrollUseCase.scrollToEnd();
        case operations.FOLLOW_START:
          return () =>
            this.followMasterClient.startFollow(op.newTab, op.background);
        case operations.MARK_SET_PREFIX:
          return () => this.markKeyUseCase.enableSetMode();
        case operations.MARK_JUMP_PREFIX:
          return () => this.markKeyUseCase.enableJumpMode();
        case operations.FOCUS_INPUT:
          return () => this.focusUseCase.focusFirstInput();
        case operations.URLS_YANK:
          return () => this.clipbaordUseCase.yankCurrentURL();
        case operations.URLS_PASTE:
          return () =>
            this.clipbaordUseCase.openOrSearch(op.newTab ? op.newTab : false);
        default:
          return null;
      }
    })(nextOp.op);

    if (doFunc === null) {
      // Do not await asynchronous methods to return a boolean immidiately. The
      // caller requires the synchronous response from the callback to identify
      // to continue of abandon the event propagations.
      this.operationClient.execBackgroundOp(nextOp.repeat, nextOp.op);
    } else {
      for (let i = 0; i < nextOp.repeat; ++i) {
        doFunc();
      }
    }
    return true;
  }

  onBlurWindow() {
    this.keymapUseCase.cancel();
  }
}