From b002d70070a1b691b635220bc694c48df36faca5 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 6 May 2019 22:17:01 +0900 Subject: [PATCH] src/content --- .../repositories/BrowserSettingRepository.ts | 16 ++++++ src/background/usecases/MarkUseCase.ts | 17 +++---- src/background/usecases/VersionUseCase.ts | 2 +- src/background/usecases/filters.ts | 6 ++- src/console/components/Console.tsx | 51 +++++++++---------- src/console/components/console/Input.tsx | 16 +++--- src/console/components/console/Message.tsx | 2 +- src/console/reducers/index.ts | 2 +- src/content/Mark.ts | 6 +++ src/content/actions/find.ts | 18 ++++++- src/content/actions/index.ts | 3 +- src/content/actions/input.ts | 3 +- src/content/components/common/index.ts | 2 +- src/content/components/common/mark.ts | 41 ++++++++------- src/content/index.ts | 2 +- src/content/reducers/input.ts | 3 +- src/content/reducers/mark.ts | 6 +-- src/content/site-style.ts | 2 +- test/content/reducers/setting.test.ts | 1 - 19 files changed, 119 insertions(+), 80 deletions(-) create mode 100644 src/content/Mark.ts diff --git a/src/background/repositories/BrowserSettingRepository.ts b/src/background/repositories/BrowserSettingRepository.ts index 48c72a5..33b35dd 100644 --- a/src/background/repositories/BrowserSettingRepository.ts +++ b/src/background/repositories/BrowserSettingRepository.ts @@ -1,5 +1,21 @@ import * as urls from '../../shared/urls'; +declare namespace browser.browserSettings.homepageOverride { + + type BrowserSettings = { + value: string; + levelOfControl: LevelOfControlType; + }; + + type LevelOfControlType = + 'not_controllable' | + 'controlled_by_other_extensions' | + 'controllable_by_this_extension' | + 'controlled_by_this_extension'; + + function get(param: object): Promise; +} + export default class BrowserSettingRepository { async getHomepageUrls(): Promise { let { value } = await browser.browserSettings.homepageOverride.get({}); diff --git a/src/background/usecases/MarkUseCase.ts b/src/background/usecases/MarkUseCase.ts index 8b544aa..e376c55 100644 --- a/src/background/usecases/MarkUseCase.ts +++ b/src/background/usecases/MarkUseCase.ts @@ -21,7 +21,7 @@ export default class MarkUseCase { async setGlobal(key: string, x: number, y: number): Promise { let tab = await this.tabPresenter.getCurrent(); - let mark = { tabId: tab.id, url: tab.url, x, y }; + let mark = { tabId: tab.id as number, url: tab.url as string, x, y }; return this.markRepository.setMark(key, mark); } @@ -33,15 +33,14 @@ export default class MarkUseCase { return this.consoleClient.showError( current.id as number, 'Mark is not set'); } - - return this.contentMessageClient.scrollTo( - mark.tabId, mark.x, mark.y - ).then(() => { + try { + await this.contentMessageClient.scrollTo(mark.tabId, mark.x, mark.y); return this.tabPresenter.select(mark.tabId); - }).catch(async() => { + } catch (e) { let tab = await this.tabPresenter.create(mark.url); - let mark2 = { tabId: tab.id, url: mark.url, x: mark.x, y: mark.y }; - return this.markRepository.setMark(key, mark2); - }); + return this.markRepository.setMark(key, { + tabId: tab.id as number, url: mark.url, x: mark.x, y: mark.y, + }); + } } } diff --git a/src/background/usecases/VersionUseCase.ts b/src/background/usecases/VersionUseCase.ts index 3a3cc2e..8154eba 100644 --- a/src/background/usecases/VersionUseCase.ts +++ b/src/background/usecases/VersionUseCase.ts @@ -1,4 +1,3 @@ -import manifest from '../../../manifest.json'; import TabPresenter from '../presenters/TabPresenter'; import NotifyPresenter from '../presenters/NotifyPresenter'; @@ -13,6 +12,7 @@ export default class VersionUseCase { } notify(): Promise { + let manifest = browser.runtime.getManifest(); let title = `Vim Vixen ${manifest.version} has been installed`; let message = 'Click here to see release notes'; let url = this.releaseNoteUrl(manifest.version); diff --git a/src/background/usecases/filters.ts b/src/background/usecases/filters.ts index 44eb56f..84a42fb 100644 --- a/src/background/usecases/filters.ts +++ b/src/background/usecases/filters.ts @@ -40,7 +40,8 @@ const filterByPathname = (items: Item[], min: number): Item[] => { let pathname = url.origin + url.pathname; if (!hash[pathname]) { hash[pathname] = item; - } else if (hash[pathname].url.length > item.url.length) { + } else if ((hash[pathname].url as string).length > + (item.url as string).length) { hash[pathname] = item; } } @@ -57,7 +58,8 @@ const filterByOrigin = (items: Item[], min: number): Item[] => { let origin = new URL(item.url as string).origin; if (!hash[origin]) { hash[origin] = item; - } else if (hash[origin].url.length > item.url.length) { + } else if ((hash[origin].url as string).length > + (item.url as string).length) { hash[origin] = item; } } diff --git a/src/console/components/Console.tsx b/src/console/components/Console.tsx index 09c0f50..3274047 100644 --- a/src/console/components/Console.tsx +++ b/src/console/components/Console.tsx @@ -5,23 +5,23 @@ import Input from './console/Input'; import Completion from './console/Completion'; import Message from './console/Message'; import * as consoleActions from '../../console/actions/console'; +import { State as AppState } from '../reducers'; const COMPLETION_MAX_ITEMS = 33; -interface Props { - mode?: string; - consoleText?: string; - messageText?: string; - children?: string; +type StateProps = ReturnType; +interface DispatchProps { + dispatch: (action: any) => void, } +type Props = StateProps & DispatchProps class Console extends React.Component { - private input: HTMLInputElement | null; + private input: React.RefObject; constructor(props: Props) { super(props); - this.input = null; + this.input = React.createRef(); } onBlur() { @@ -34,7 +34,7 @@ class Console extends React.Component { e.stopPropagation(); e.preventDefault(); - let value = e.target.value; + let value = (e.target as HTMLInputElement).value; if (this.props.mode === 'command') { return this.props.dispatch(consoleActions.enterCommand(value)); } else if (this.props.mode === 'find') { @@ -55,15 +55,12 @@ class Console extends React.Component { } onKeyDown(e: React.KeyboardEvent) { - if (e.keyCode === KeyboardEvent.DOM_VK_ESCAPE && e.ctrlKey) { - this.props.dispatch(consoleActions.hideCommand()); - } - switch (e.keyCode) { - case KeyboardEvent.DOM_VK_ESCAPE: + switch (e.key) { + case 'Escape': return this.props.dispatch(consoleActions.hideCommand()); - case KeyboardEvent.DOM_VK_RETURN: + case 'Enter': return this.doEnter(e); - case KeyboardEvent.DOM_VK_TAB: + case 'Tab': if (e.shiftKey) { this.props.dispatch(consoleActions.completionPrev()); } else { @@ -72,22 +69,22 @@ class Console extends React.Component { e.stopPropagation(); e.preventDefault(); break; - case KeyboardEvent.DOM_VK_OPEN_BRACKET: + case '[': if (e.ctrlKey) { return this.props.dispatch(consoleActions.hideCommand()); } break; - case KeyboardEvent.DOM_VK_M: + case 'm': if (e.ctrlKey) { return this.doEnter(e); } break; - case KeyboardEvent.DOM_VK_N: + case 'n': if (e.ctrlKey) { this.selectNext(e); } break; - case KeyboardEvent.DOM_VK_P: + case 'p': if (e.ctrlKey) { this.selectPrev(e); } @@ -105,9 +102,6 @@ class Console extends React.Component { componentDidUpdate(prevProps: Props) { - if (!this.input) { - return; - } if (prevProps.mode !== 'command' && this.props.mode === 'command') { this.props.dispatch( consoleActions.getCompletions(this.props.consoleText)); @@ -128,7 +122,7 @@ class Console extends React.Component { select={this.props.select} /> { this.input = c; }} + ref={this.input} mode={this.props.mode} onBlur={this.onBlur.bind(this)} onKeyDown={this.onKeyDown.bind(this)} @@ -148,11 +142,14 @@ class Console extends React.Component { focus() { window.focus(); - if (this.input) { - this.input.focus(); + if (this.input.current) { + this.input.current.focus(); } } } -const mapStateToProps = (state: any) => state; -export default connect(mapStateToProps)(Console); +const mapStateToProps = (state: AppState) => ({ ...state }); + +export default connect( + mapStateToProps, +)(Console); diff --git a/src/console/components/console/Input.tsx b/src/console/components/console/Input.tsx index d0348bd..54ea251 100644 --- a/src/console/components/console/Input.tsx +++ b/src/console/components/console/Input.tsx @@ -3,23 +3,23 @@ import React from 'react'; interface Props { mode: string; value: string; - onBlur: (e: React.FocusEvent) => void; - onKeyDown: (e: React.KeyboardEvent) => void; - onChange: (e: React.ChangeEvent) => void; + onBlur: (e: React.FocusEvent) => void; + onKeyDown: (e: React.KeyboardEvent) => void; + onChange: (e: React.ChangeEvent) => void; } class Input extends React.Component { - private input: HTMLInputElement | null; + private input: React.RefObject; constructor(props: Props) { super(props); - this.input = null; + this.input = React.createRef(); } focus() { - if (this.input) { - this.input.focus(); + if (this.input.current) { + this.input.current.focus(); } } @@ -38,7 +38,7 @@ class Input extends React.Component { { this.input = c; }} + ref={this.input} onBlur={this.props.onBlur} onKeyDown={this.props.onKeyDown} onChange={this.props.onChange} diff --git a/src/console/components/console/Message.tsx b/src/console/components/console/Message.tsx index 07a929e..9fa2788 100644 --- a/src/console/components/console/Message.tsx +++ b/src/console/components/console/Message.tsx @@ -2,7 +2,7 @@ import React from 'react'; interface Props { mode: string; - children: string[]; + children: string; } const Message = (props: Props) => { diff --git a/src/console/reducers/index.ts b/src/console/reducers/index.ts index 37ed715..b6be483 100644 --- a/src/console/reducers/index.ts +++ b/src/console/reducers/index.ts @@ -1,6 +1,6 @@ import * as actions from '../actions'; -interface State { +export interface State { mode: string; messageText: string; consoleText: string; diff --git a/src/content/Mark.ts b/src/content/Mark.ts new file mode 100644 index 0000000..f1282fc --- /dev/null +++ b/src/content/Mark.ts @@ -0,0 +1,6 @@ +export default interface Mark { + x: number; + y: number; + // eslint-disable-next-line semi +} + diff --git a/src/content/actions/find.ts b/src/content/actions/find.ts index 6dd2ae6..53e03ae 100644 --- a/src/content/actions/find.ts +++ b/src/content/actions/find.ts @@ -9,6 +9,20 @@ import * as messages from '../../shared/messages'; import * as actions from './index'; import * as consoleFrames from '../console-frames'; +interface MyWindow extends Window { + find( + aString: string, + aCaseSensitive?: boolean, + aBackwards?: boolean, + aWrapAround?: boolean, + aWholeWord?: boolean, + aSearchInFrames?: boolean, + aShowDialog?: boolean): boolean; +} + +// eslint-disable-next-line no-var, vars-on-top, init-declarations +declare var window: MyWindow; + const find = (str: string, backwards: boolean): boolean => { let caseSensitive = false; let wrapScan = true; @@ -18,7 +32,7 @@ const find = (str: string, backwards: boolean): boolean => { // because of same origin policy // eslint-disable-next-line no-extra-parens - let found = (window).find(str, caseSensitive, backwards, wrapScan); + let found = window.find(str, caseSensitive, backwards, wrapScan); if (found) { return found; } @@ -28,7 +42,7 @@ const find = (str: string, backwards: boolean): boolean => { } // eslint-disable-next-line no-extra-parens - return (window).find(str, caseSensitive, backwards, wrapScan); + return window.find(str, caseSensitive, backwards, wrapScan); }; // eslint-disable-next-line max-statements diff --git a/src/content/actions/index.ts b/src/content/actions/index.ts index a259211..8aa9c23 100644 --- a/src/content/actions/index.ts +++ b/src/content/actions/index.ts @@ -1,5 +1,6 @@ import Redux from 'redux'; import Settings from '../../shared/Settings'; +import * as keyUtils from '../../shared/utils/keys'; // Enable/disable export const ADDON_SET_ENABLED = 'addon.set.enabled'; @@ -51,7 +52,7 @@ export interface SettingSetAction extends Redux.Action { export interface InputKeyPressAction extends Redux.Action { type: typeof INPUT_KEY_PRESS; - key: string; + key: keyUtils.Key; } export interface InputClearKeysAction extends Redux.Action { diff --git a/src/content/actions/input.ts b/src/content/actions/input.ts index 21c912e..1df6452 100644 --- a/src/content/actions/input.ts +++ b/src/content/actions/input.ts @@ -1,6 +1,7 @@ import * as actions from './index'; +import * as keyUtils from '../../shared/utils/keys'; -const keyPress = (key: string): actions.InputAction => { +const keyPress = (key: keyUtils.Key): actions.InputAction => { return { type: actions.INPUT_KEY_PRESS, key, diff --git a/src/content/components/common/index.ts b/src/content/components/common/index.ts index 8bd697f..5b097b6 100644 --- a/src/content/components/common/index.ts +++ b/src/content/components/common/index.ts @@ -18,7 +18,7 @@ export default class Common { constructor(win: Window, store: any) { const input = new InputComponent(win.document.body); const follow = new FollowComponent(win); - const mark = new MarkComponent(win.document.body, store); + const mark = new MarkComponent(store); const keymapper = new KeymapperComponent(store); input.onKey((key: keys.Key) => follow.key(key)); diff --git a/src/content/components/common/mark.ts b/src/content/components/common/mark.ts index 686116c..1237385 100644 --- a/src/content/components/common/mark.ts +++ b/src/content/components/common/mark.ts @@ -1,27 +1,30 @@ import * as markActions from '../../actions/mark'; import * as scrolls from '../..//scrolls'; import * as consoleFrames from '../..//console-frames'; +import * as keyUtils from '../../../shared/utils/keys'; +import Mark from '../../Mark'; -const cancelKey = (key): boolean => { - return key.key === 'Esc' || key.key === '[' && key.ctrlKey; +const cancelKey = (key: keyUtils.Key): boolean => { + return key.key === 'Esc' || key.key === '[' && Boolean(key.ctrlKey); }; -const globalKey = (key) => { +const globalKey = (key: string): boolean => { return (/^[A-Z0-9]$/).test(key); }; export default class MarkComponent { - constructor(body, store) { - this.body = body; + private store: any; + + constructor(store: any) { this.store = store; } // eslint-disable-next-line max-statements - key(key) { - let { mark: markStage, setting } = this.store.getState(); + key(key: keyUtils.Key) { + let { mark: markState, setting } = this.store.getState(); let smoothscroll = setting.properties.smoothscroll; - if (!markStage.setMode && !markStage.jumpMode) { + if (!markState.setMode && !markState.jumpMode) { return false; } @@ -32,26 +35,30 @@ export default class MarkComponent { if (key.ctrlKey || key.metaKey || key.altKey) { consoleFrames.postError('Unknown mark'); - } else if (globalKey(key.key) && markStage.setMode) { + } else if (globalKey(key.key) && markState.setMode) { this.doSetGlobal(key); - } else if (globalKey(key.key) && markStage.jumpMode) { + } else if (globalKey(key.key) && markState.jumpMode) { this.doJumpGlobal(key); - } else if (markStage.setMode) { + } else if (markState.setMode) { this.doSet(key); - } else if (markStage.jumpMode) { - this.doJump(markStage.marks, key, smoothscroll); + } else if (markState.jumpMode) { + this.doJump(markState.marks, key, smoothscroll); } this.store.dispatch(markActions.cancel()); return true; } - doSet(key) { + doSet(key: keyUtils.Key) { let { x, y } = scrolls.getScroll(); this.store.dispatch(markActions.setLocal(key.key, x, y)); } - doJump(marks, key, smoothscroll) { + doJump( + marks: { [key: string]: Mark }, + key: keyUtils.Key, + smoothscroll: boolean, + ) { if (!marks[key.key]) { consoleFrames.postError('Mark is not set'); return; @@ -61,12 +68,12 @@ export default class MarkComponent { scrolls.scrollTo(x, y, smoothscroll); } - doSetGlobal(key) { + doSetGlobal(key: keyUtils.Key) { let { x, y } = scrolls.getScroll(); this.store.dispatch(markActions.setGlobal(key.key, x, y)); } - doJumpGlobal(key) { + doJumpGlobal(key: keyUtils.Key) { this.store.dispatch(markActions.jumpGlobal(key.key)); } } diff --git a/src/content/index.ts b/src/content/index.ts index 309f27f..9d791fc 100644 --- a/src/content/index.ts +++ b/src/content/index.ts @@ -12,5 +12,5 @@ if (window.self === window.top) { } let style = window.document.createElement('style'); -style.textContent = consoleFrameStyle.default; +style.textContent = consoleFrameStyle; window.document.head.appendChild(style); diff --git a/src/content/reducers/input.ts b/src/content/reducers/input.ts index 6257e49..35b9075 100644 --- a/src/content/reducers/input.ts +++ b/src/content/reducers/input.ts @@ -1,7 +1,8 @@ import * as actions from '../actions'; +import * as keyUtils from '../../shared/utils/keys'; export interface State { - keys: string[]; + keys: keyUtils.Key[], } const defaultState: State = { diff --git a/src/content/reducers/mark.ts b/src/content/reducers/mark.ts index e78b7b9..7409938 100644 --- a/src/content/reducers/mark.ts +++ b/src/content/reducers/mark.ts @@ -1,10 +1,6 @@ +import Mark from '../Mark'; import * as actions from '../actions'; -interface Mark { - x: number; - y: number; -} - export interface State { setMode: boolean; jumpMode: boolean; diff --git a/src/content/site-style.ts b/src/content/site-style.ts index e7a82a5..0c335fc 100644 --- a/src/content/site-style.ts +++ b/src/content/site-style.ts @@ -1,4 +1,4 @@ -exports.default = ` +export default ` .vimvixen-console-frame { margin: 0; padding: 0; diff --git a/test/content/reducers/setting.test.ts b/test/content/reducers/setting.test.ts index fe23006..9b332aa 100644 --- a/test/content/reducers/setting.test.ts +++ b/test/content/reducers/setting.test.ts @@ -20,7 +20,6 @@ describe("content setting reducer", () => { } } let state = settingReducer(undefined, action); - console.log(JSON.stringify(state.keymaps)); expect(state.keymaps).to.have.deep.all.members([ { key: [{ key: 'z', shiftKey: false, ctrlKey: false, altKey: false, metaKey: false }, { key: 'z', shiftKey: false, ctrlKey: false, altKey: false, metaKey: false }],