diff --git a/.eslintrc b/.eslintrc index 80fc259..fa283fd 100644 --- a/.eslintrc +++ b/.eslintrc @@ -33,7 +33,6 @@ "object-shorthand": "off", "padded-blocks": "off", "prefer-template": "off", - "quote-props": ["error", "as-needed"], "require-jsdoc": "off", "sort-imports": "off", "sort-keys": "off", diff --git a/src/background/key-queue.js b/src/background/key-queue.js index 3c1ffbb..8af776e 100644 --- a/src/background/key-queue.js +++ b/src/background/key-queue.js @@ -1,62 +1,79 @@ -import * as keys from './keys'; import * as actions from '../shared/actions'; -const DEFAULT_KEYMAP = [ - { keys: [{ code: KeyboardEvent.DOM_VK_SEMICOLON, shift: true }], action: [ actions.CMD_OPEN ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_O }], action: [ actions.CMD_TABS_OPEN, false ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_O, shift: true }], action: [ actions.CMD_TABS_OPEN, true ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_K }], action: [ actions.SCROLL_LINES, -1 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_J }], action: [ actions.SCROLL_LINES, 1 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_E, ctrl: true }], action: [ actions.SCROLL_LINES, -1 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_Y, ctrl: true }], action: [ actions.SCROLL_LINES, 1 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_U, ctrl: true }], action: [ actions.SCROLL_PAGES, -0.5 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_D, ctrl: true }], action: [ actions.SCROLL_PAGES, 0.5 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_B, ctrl: true }], action: [ actions.SCROLL_PAGES, -1 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_F, ctrl: true }], action: [ actions.SCROLL_PAGES, 1 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_G }, { code: KeyboardEvent.DOM_VK_G }], action: [ actions.SCROLL_TOP ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_G, shift: true }], action: [ actions.SCROLL_BOTTOM ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_D }], action: [ actions.TABS_CLOSE ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_U }], action: [ actions.TABS_REOPEN]}, - { keys: [{ code: KeyboardEvent.DOM_VK_H }], action: [ actions.TABS_PREV, 1 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_L }], action: [ actions.TABS_NEXT, 1 ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_R }], action: [ actions.TABS_RELOAD, false ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_R, shift: true }], action: [ actions.TABS_RELOAD, true ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_Z }, { code: KeyboardEvent.DOM_VK_I }], action: [ actions.ZOOM_IN ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_Z }, { code: KeyboardEvent.DOM_VK_O }], action: [ actions.ZOOM_OUT ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_Z }, { code: KeyboardEvent.DOM_VK_Z }], action: [ actions.ZOOM_NEUTRAL]}, - { keys: [{ code: KeyboardEvent.DOM_VK_F }], action: [ actions.FOLLOW_START, false ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_F, shift: true }], action: [ actions.FOLLOW_START, true ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_H, shift: true }], action: [ actions.HISTORY_PREV ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_L, shift: true }], action: [ actions.HISTORY_NEXT ]}, -] +const DEFAULT_KEYMAP = { + ':': [ actions.CMD_OPEN ], + 'o': [ actions.CMD_TABS_OPEN, false ], + 'O': [ actions.CMD_TABS_OPEN, true ], + 'k': [ actions.SCROLL_LINES, -1 ], + 'j': [ actions.SCROLL_LINES, 1 ], + '': [ actions.SCROLL_LINES, -1 ], + '': [ actions.SCROLL_LINES, 1 ], + '': [ actions.SCROLL_PAGES, -0.5 ], + '': [ actions.SCROLL_PAGES, 0.5 ], + '': [ actions.SCROLL_PAGES, -1 ], + '': [ actions.SCROLL_PAGES, 1 ], + 'gg': [ actions.SCROLL_TOP ], + 'G': [ actions.SCROLL_BOTTOM ], + 'd': [ actions.TABS_CLOSE ], + 'u': [ actions.TABS_REOPEN], + 'h': [ actions.TABS_PREV, 1 ], + 'l': [ actions.TABS_NEXT, 1 ], + 'r': [ actions.TABS_RELOAD, false ], + 'R': [ actions.TABS_RELOAD, true ], + 'zi': [ actions.ZOOM_IN ], + 'zo': [ actions.ZOOM_OUT ], + 'zz': [ actions.ZOOM_NEUTRAL], + 'f': [ actions.FOLLOW_START, false ], + 'F': [ actions.FOLLOW_START, true ], + 'H': [ actions.HISTORY_PREV ], + 'L': [ actions.HISTORY_NEXT ], +} export default class KeyQueue { - constructor() { + constructor(keymap = DEFAULT_KEYMAP) { this.data = []; - this.keymap = DEFAULT_KEYMAP; + this.keymap = keymap; } push(key) { this.data.push(key); - let filtered = this.keymap.filter((map) => { - return keys.hasPrefix(map.keys, this.data) + + let current = this.asKeymapChars(); + let filtered = Object.keys(this.keymap).filter((keys) => { + return keys.startsWith(current); }); if (filtered.length == 0) { this.data = []; return null; - } else if (filtered.length == 1) { - let map = filtered[0]; - if (map.keys.length == this.data.length) { - this.data = []; - return map.action; - } + } else if (filtered.length === 1 && current === filtered[0]) { + let action = this.keymap[filtered[0]]; + this.data = []; + return action; } return null; } - queuedKeys() { - return this.data; + asKeymapChars() { + return this.data.map((k) => { + let c = String.fromCharCode(k.code); + if (k.ctrl) { + return ''; + } else { + return c + } + }).join(''); + } + + asCaretChars() { + return this.data.map((k) => { + let c = String.fromCharCode(k.code); + if (k.ctrl) { + return '^' + c.toUpperCase(); + } else { + return c; + } + }).join(''); } } diff --git a/test/background/key-queue.test.js b/test/background/key-queue.test.js index 7b0db9b..ac43228 100644 --- a/test/background/key-queue.test.js +++ b/test/background/key-queue.test.js @@ -1,47 +1,50 @@ import { expect } from "chai"; import KeyQueue from '../../src/background/key-queue'; -import * as actions from '../../src/shared/actions'; describe("keyQueue class", () => { - const KEYMAP = [ - { keys: [{ code: KeyboardEvent.DOM_VK_G }, { code: KeyboardEvent.DOM_VK_G }], - action: [ actions.SCROLL_TOP ]}, - { keys: [{ code: KeyboardEvent.DOM_VK_J }], - action: [ actions.SCROLL_DOWN ]}, - ] + const KEYMAP = { + 'gGG': [], + 'gg': [ 'scroll.top' ], + }; + + const g = 'g'.charCodeAt(0); + const G = 'G'.charCodeAt(0); + const x = 'x'.charCodeAt(0); describe("#push", () => { it("returns matched action", () => { let queue = new KeyQueue(KEYMAP); - queue.push({ code: KeyboardEvent.DOM_VK_G }); - let action = queue.push({ code: KeyboardEvent.DOM_VK_G }); + queue.push({ code: g }); + let action = queue.push({ code: g }); - expect(action).to.deep.equal([ actions.SCROLL_TOP ]); + expect(action).to.deep.equal([ 'scroll.top' ]); }); it("returns null on no actions matched", () => { let queue = new KeyQueue(KEYMAP); - queue.push({ code: KeyboardEvent.DOM_VK_G }); - let action = queue.push({ code: KeyboardEvent.DOM_VK_X }); + queue.push({ code: g }); + let action = queue.push({ code: G }); expect(action).to.be.null; + expect(queue.asKeymapChars()).to.be.empty; }); }); - describe("#queuedKeys", () => { - it("queues keys on matched actions exist", () => { - let queue = new KeyQueue(KEYMAP); - queue.push({ code: KeyboardEvent.DOM_VK_G }); + describe('#asKeymapChars', () => { + let queue = new KeyQueue(KEYMAP); + queue.push({ code: g }); + queue.push({ code: x, ctrl: true }); + queue.push({ code: G }); - expect(queue.queuedKeys()).to.have.lengthOf(1); - }); + expect(queue.asKeymapChars()).to.equal('gG'); + }); - it("flushs keys on no actions matched", () => { - let queue = new KeyQueue(KEYMAP); - queue.push({ code: KeyboardEvent.DOM_VK_G }); - queue.push({ code: KeyboardEvent.DOM_VK_Z }); + describe('#asCaretChars', () => { + let queue = new KeyQueue(KEYMAP); + queue.push({ code: g }); + queue.push({ code: x, ctrl: true }); + queue.push({ code: G }); - expect(queue.queuedKeys()).to.be.empty; - }); + expect(queue.asCaretChars()).to.equal('g^XG'); }); });