aboutsummaryrefslogtreecommitdiff
path: root/src/content
diff options
context:
space:
mode:
Diffstat (limited to 'src/content')
-rw-r--r--src/content/client/OperationClient.ts6
-rw-r--r--src/content/controllers/KeymapController.ts83
-rw-r--r--src/content/usecases/KeymapUseCase.ts12
3 files changed, 49 insertions, 52 deletions
diff --git a/src/content/client/OperationClient.ts b/src/content/client/OperationClient.ts
index 5dbe555..06077dc 100644
--- a/src/content/client/OperationClient.ts
+++ b/src/content/client/OperationClient.ts
@@ -2,7 +2,7 @@ import * as operations from '../../shared/operations';
import * as messages from '../../shared/messages';
export default interface OperationClient {
- execBackgroundOp(op: operations.Operation): Promise<void>;
+ execBackgroundOp(count: number, op: operations.Operation): Promise<void>;
internalOpenUrl(
url: string, newTab?: boolean, background?: boolean,
@@ -10,9 +10,10 @@ export default interface OperationClient {
}
export class OperationClientImpl implements OperationClient {
- execBackgroundOp(op: operations.Operation): Promise<void> {
+ execBackgroundOp(count: number, op: operations.Operation): Promise<void> {
return browser.runtime.sendMessage({
type: messages.BACKGROUND_OPERATION,
+ count,
operation: op,
});
}
@@ -22,6 +23,7 @@ export class OperationClientImpl implements OperationClient {
): Promise<void> {
return browser.runtime.sendMessage({
type: messages.BACKGROUND_OPERATION,
+ count: 1,
operation: {
type: operations.INTERNAL_OPEN_URL,
url,
diff --git a/src/content/controllers/KeymapController.ts b/src/content/controllers/KeymapController.ts
index cf59ae5..b8069f9 100644
--- a/src/content/controllers/KeymapController.ts
+++ b/src/content/controllers/KeymapController.ts
@@ -23,7 +23,7 @@ export default class KeymapController {
private markKeyUseCase: MarkKeyyUseCase,
@inject('OperationClient')
- private backgroundClient: OperationClient,
+ private operationClient: OperationClient,
@inject('FollowMasterClient')
private followMasterClient: FollowMasterClient,
@@ -32,74 +32,69 @@ export default class KeymapController {
// eslint-disable-next-line complexity, max-lines-per-function
press(key: Key): boolean {
- let ops = this.keymapUseCase.nextOps(key);
- if (ops.length === 0) {
+ let nextOp = this.keymapUseCase.nextOps(key);
+ if (nextOp === null) {
return false;
}
- // 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.
- for (let op of ops) {
+ if (!operations.isNRepeatable(nextOp.op.type)) {
+ nextOp.count = 1;
+ }
+
+ const doFunc = ((op: operations.Operation) => {
switch (op.type) {
case operations.ADDON_ENABLE:
- this.addonEnabledUseCase.enable();
- break;
+ return () => this.addonEnabledUseCase.enable();
case operations.ADDON_DISABLE:
- this.addonEnabledUseCase.disable();
- break;
+ return () => this.addonEnabledUseCase.disable();
case operations.ADDON_TOGGLE_ENABLED:
- this.addonEnabledUseCase.toggle();
- break;
+ return () => this.addonEnabledUseCase.toggle();
case operations.FIND_NEXT:
- this.findSlaveUseCase.findNext();
- break;
+ return () => this.findSlaveUseCase.findNext();
case operations.FIND_PREV:
- this.findSlaveUseCase.findPrev();
- break;
+ return () => this.findSlaveUseCase.findPrev();
case operations.SCROLL_VERTICALLY:
- this.scrollUseCase.scrollVertically(op.count);
- break;
+ return () => this.scrollUseCase.scrollVertically(op.count);
case operations.SCROLL_HORIZONALLY:
- this.scrollUseCase.scrollHorizonally(op.count);
- break;
+ return () => this.scrollUseCase.scrollHorizonally(op.count);
case operations.SCROLL_PAGES:
- this.scrollUseCase.scrollPages(op.count);
- break;
+ return () => this.scrollUseCase.scrollPages(op.count);
case operations.SCROLL_TOP:
- this.scrollUseCase.scrollToTop();
- break;
+ return () => this.scrollUseCase.scrollToTop();
case operations.SCROLL_BOTTOM:
- this.scrollUseCase.scrollToBottom();
- break;
+ return () => this.scrollUseCase.scrollToBottom();
case operations.SCROLL_HOME:
- this.scrollUseCase.scrollToHome();
- break;
+ return () => this.scrollUseCase.scrollToHome();
case operations.SCROLL_END:
- this.scrollUseCase.scrollToEnd();
- break;
+ return () => this.scrollUseCase.scrollToEnd();
case operations.FOLLOW_START:
- this.followMasterClient.startFollow(op.newTab, op.background);
- break;
+ return () => this.followMasterClient.startFollow(
+ op.newTab, op.background);
case operations.MARK_SET_PREFIX:
- this.markKeyUseCase.enableSetMode();
- break;
+ return () => this.markKeyUseCase.enableSetMode();
case operations.MARK_JUMP_PREFIX:
- this.markKeyUseCase.enableJumpMode();
- break;
+ return () => this.markKeyUseCase.enableJumpMode();
case operations.FOCUS_INPUT:
- this.focusUseCase.focusFirstInput();
- break;
+ return () => this.focusUseCase.focusFirstInput();
case operations.URLS_YANK:
- this.clipbaordUseCase.yankCurrentURL();
- break;
+ return () => this.clipbaordUseCase.yankCurrentURL();
case operations.URLS_PASTE:
- this.clipbaordUseCase.openOrSearch(
+ return () => this.clipbaordUseCase.openOrSearch(
op.newTab ? op.newTab : false,
);
- break;
default:
- this.backgroundClient.execBackgroundOp(op);
+ 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.count, nextOp.op);
+ } else {
+ for (let i = 0; i < nextOp.count; ++i) {
+ doFunc();
}
}
return true;
diff --git a/src/content/usecases/KeymapUseCase.ts b/src/content/usecases/KeymapUseCase.ts
index f7de334..fab13f5 100644
--- a/src/content/usecases/KeymapUseCase.ts
+++ b/src/content/usecases/KeymapUseCase.ts
@@ -36,13 +36,13 @@ export default class KeymapUseCase {
}
// eslint-disable-next-line max-statements
- nextOps(key: Key): operations.Operation[] {
+ nextOps(key: Key): { count: number, op: operations.Operation } | null {
let sequence = this.repository.enqueueKey(key);
let baseSequence = sequence.trimNumericPrefix();
if (baseSequence.length() === 1 && this.blacklistKey(key)) {
// ignore if the input starts with black list keys
this.repository.clear();
- return [];
+ return null;
}
let keymaps = this.keymapEntityMap();
@@ -53,21 +53,21 @@ export default class KeymapUseCase {
sequence.length() === matched[0][0].length()) {
// keys are matched with an operation
this.repository.clear();
- return [matched[0][1]];
+ return { count: 1, op: matched[0][1] };
} else if (
baseMatched.length === 1 &&
baseSequence.length() === baseMatched[0][0].length()) {
// keys are matched with an operation with a numeric prefix
this.repository.clear();
- return Array(sequence.repeatCount()).fill(baseMatched[0][1]);
+ return { count: sequence.repeatCount(), op: baseMatched[0][1] };
} else if (matched.length >= 1 || baseMatched.length >= 1) {
// keys are matched with an operation's prefix
- return [];
+ return null;
}
// matched with no operations
this.repository.clear();
- return [];
+ return null;
}
private keymapEntityMap(): [KeySequence, operations.Operation][] {