diff options
Diffstat (limited to 'src/console')
-rw-r--r-- | src/console/actions/console.ts (renamed from src/console/actions/console.js) | 34 | ||||
-rw-r--r-- | src/console/actions/index.js | 13 | ||||
-rw-r--r-- | src/console/actions/index.ts | 63 | ||||
-rw-r--r-- | src/console/components/Console.tsx (renamed from src/console/components/Console.jsx) | 72 | ||||
-rw-r--r-- | src/console/components/console/Completion.tsx (renamed from src/console/components/console/Completion.jsx) | 45 | ||||
-rw-r--r-- | src/console/components/console/CompletionItem.tsx (renamed from src/console/components/console/CompletionItem.jsx) | 9 | ||||
-rw-r--r-- | src/console/components/console/CompletionTitle.tsx (renamed from src/console/components/console/CompletionTitle.jsx) | 11 | ||||
-rw-r--r-- | src/console/components/console/Input.tsx (renamed from src/console/components/console/Input.jsx) | 33 | ||||
-rw-r--r-- | src/console/components/console/Message.tsx (renamed from src/console/components/console/Message.jsx) | 13 | ||||
-rw-r--r-- | src/console/index.tsx (renamed from src/console/index.jsx) | 19 | ||||
-rw-r--r-- | src/console/reducers/index.ts (renamed from src/console/reducers/index.js) | 23 |
11 files changed, 216 insertions, 119 deletions
diff --git a/src/console/actions/console.js b/src/console/actions/console.ts index 3713a76..b1494b0 100644 --- a/src/console/actions/console.js +++ b/src/console/actions/console.ts @@ -1,40 +1,40 @@ -import messages from 'shared/messages'; -import actions from 'console/actions'; +import * as messages from '../../shared/messages'; +import * as actions from './index'; -const hide = () => { +const hide = (): actions.ConsoleAction => { return { type: actions.CONSOLE_HIDE, }; }; -const showCommand = (text) => { +const showCommand = (text: string): actions.ConsoleAction => { return { type: actions.CONSOLE_SHOW_COMMAND, text: text }; }; -const showFind = () => { +const showFind = (): actions.ConsoleAction => { return { type: actions.CONSOLE_SHOW_FIND, }; }; -const showError = (text) => { +const showError = (text: string): actions.ConsoleAction => { return { type: actions.CONSOLE_SHOW_ERROR, text: text }; }; -const showInfo = (text) => { +const showInfo = (text: string): actions.ConsoleAction => { return { type: actions.CONSOLE_SHOW_INFO, text: text }; }; -const hideCommand = () => { +const hideCommand = (): actions.ConsoleAction => { window.top.postMessage(JSON.stringify({ type: messages.CONSOLE_UNFOCUS, }), '*'); @@ -43,15 +43,17 @@ const hideCommand = () => { }; }; -const enterCommand = async(text) => { +const enterCommand = async( + text: string, +): Promise<actions.ConsoleAction> => { await browser.runtime.sendMessage({ type: messages.CONSOLE_ENTER_COMMAND, text, }); - return hideCommand(text); + return hideCommand(); }; -const enterFind = (text) => { +const enterFind = (text: string): actions.ConsoleAction => { window.top.postMessage(JSON.stringify({ type: messages.CONSOLE_ENTER_FIND, text, @@ -59,14 +61,14 @@ const enterFind = (text) => { return hideCommand(); }; -const setConsoleText = (consoleText) => { +const setConsoleText = (consoleText: string): actions.ConsoleAction => { return { type: actions.CONSOLE_SET_CONSOLE_TEXT, consoleText, }; }; -const getCompletions = async(text) => { +const getCompletions = async(text: string): Promise<actions.ConsoleAction> => { let completions = await browser.runtime.sendMessage({ type: messages.CONSOLE_QUERY_COMPLETIONS, text, @@ -78,13 +80,13 @@ const getCompletions = async(text) => { }; }; -const completionNext = () => { +const completionNext = (): actions.ConsoleAction => { return { type: actions.CONSOLE_COMPLETION_NEXT, }; }; -const completionPrev = () => { +const completionPrev = (): actions.ConsoleAction => { return { type: actions.CONSOLE_COMPLETION_PREV, }; @@ -92,5 +94,5 @@ const completionPrev = () => { export { hide, showCommand, showFind, showError, showInfo, hideCommand, setConsoleText, - enterCommand, enterFind, getCompletions, completionNext, completionPrev + enterCommand, enterFind, getCompletions, completionNext, completionPrev, }; diff --git a/src/console/actions/index.js b/src/console/actions/index.js deleted file mode 100644 index b394179..0000000 --- a/src/console/actions/index.js +++ /dev/null @@ -1,13 +0,0 @@ -export default { - // console commands - CONSOLE_HIDE: 'console.hide', - CONSOLE_SHOW_COMMAND: 'console.show.command', - CONSOLE_SHOW_ERROR: 'console.show.error', - CONSOLE_SHOW_INFO: 'console.show.info', - CONSOLE_HIDE_COMMAND: 'console.hide.command', - CONSOLE_SET_CONSOLE_TEXT: 'console.set.command', - CONSOLE_SET_COMPLETIONS: 'console.set.completions', - CONSOLE_COMPLETION_NEXT: 'console.completion.next', - CONSOLE_COMPLETION_PREV: 'console.completion.prev', - CONSOLE_SHOW_FIND: 'console.show.find', -}; diff --git a/src/console/actions/index.ts b/src/console/actions/index.ts new file mode 100644 index 0000000..3770496 --- /dev/null +++ b/src/console/actions/index.ts @@ -0,0 +1,63 @@ +// console commands +export const CONSOLE_HIDE = 'console.hide'; +export const CONSOLE_SHOW_COMMAND = 'console.show.command'; +export const CONSOLE_SHOW_ERROR = 'console.show.error'; +export const CONSOLE_SHOW_INFO = 'console.show.info'; +export const CONSOLE_HIDE_COMMAND = 'console.hide.command'; +export const CONSOLE_SET_CONSOLE_TEXT = 'console.set.command'; +export const CONSOLE_SET_COMPLETIONS = 'console.set.completions'; +export const CONSOLE_COMPLETION_NEXT = 'console.completion.next'; +export const CONSOLE_COMPLETION_PREV = 'console.completion.prev'; +export const CONSOLE_SHOW_FIND = 'console.show.find'; + +interface HideAction { + type: typeof CONSOLE_HIDE; +} + +interface ShowCommand { + type: typeof CONSOLE_SHOW_COMMAND; + text: string; +} + +interface ShowFindAction { + type: typeof CONSOLE_SHOW_FIND; +} + +interface ShowErrorAction { + type: typeof CONSOLE_SHOW_ERROR; + text: string; +} + +interface ShowInfoAction { + type: typeof CONSOLE_SHOW_INFO; + text: string; +} + +interface HideCommandAction { + type: typeof CONSOLE_HIDE_COMMAND; +} + +interface SetConsoleTextAction { + type: typeof CONSOLE_SET_CONSOLE_TEXT; + consoleText: string; +} + +interface SetCompletionsAction { + type: typeof CONSOLE_SET_COMPLETIONS; + completions: any[]; + completionSource: string; +} + +interface CompletionNextAction { + type: typeof CONSOLE_COMPLETION_NEXT; +} + +interface CompletionPrevAction { + type: typeof CONSOLE_COMPLETION_PREV; +} + +export type ConsoleAction = + HideAction | ShowCommand | ShowFindAction | ShowErrorAction | + ShowInfoAction | HideCommandAction | SetConsoleTextAction | + SetCompletionsAction | CompletionNextAction | CompletionPrevAction; + diff --git a/src/console/components/Console.jsx b/src/console/components/Console.tsx index 5427e43..3274047 100644 --- a/src/console/components/Console.jsx +++ b/src/console/components/Console.tsx @@ -1,26 +1,40 @@ import './console.scss'; import { connect } from 'react-redux'; import React from 'react'; -import PropTypes from 'prop-types'; 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; -class Console extends React.Component { +type StateProps = ReturnType<typeof mapStateToProps>; +interface DispatchProps { + dispatch: (action: any) => void, +} +type Props = StateProps & DispatchProps + +class Console extends React.Component<Props> { + private input: React.RefObject<Input>; + + constructor(props: Props) { + super(props); + + this.input = React.createRef(); + } + onBlur() { if (this.props.mode === 'command' || this.props.mode === 'find') { return this.props.dispatch(consoleActions.hideCommand()); } } - doEnter(e) { + doEnter(e: React.KeyboardEvent<HTMLInputElement>) { 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') { @@ -28,28 +42,25 @@ class Console extends React.Component { } } - selectNext(e) { + selectNext(e: React.KeyboardEvent<HTMLInputElement>) { this.props.dispatch(consoleActions.completionNext()); e.stopPropagation(); e.preventDefault(); } - selectPrev(e) { + selectPrev(e: React.KeyboardEvent<HTMLInputElement>) { this.props.dispatch(consoleActions.completionPrev()); e.stopPropagation(); e.preventDefault(); } - onKeyDown(e) { - if (e.keyCode === KeyboardEvent.DOM_VK_ESCAPE && e.ctrlKey) { - this.props.dispatch(consoleActions.hideCommand()); - } - switch (e.keyCode) { - case KeyboardEvent.DOM_VK_ESCAPE: + onKeyDown(e: React.KeyboardEvent<HTMLInputElement>) { + 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 { @@ -58,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); } @@ -81,7 +92,7 @@ class Console extends React.Component { } } - onChange(e) { + onChange(e: React.ChangeEvent<HTMLInputElement>) { let text = e.target.value; this.props.dispatch(consoleActions.setConsoleText(text)); if (this.props.mode === 'command') { @@ -90,10 +101,7 @@ class Console extends React.Component { } - componentDidUpdate(prevProps) { - if (!this.input) { - return; - } + componentDidUpdate(prevProps: Props) { if (prevProps.mode !== 'command' && this.props.mode === 'command') { this.props.dispatch( consoleActions.getCompletions(this.props.consoleText)); @@ -114,7 +122,7 @@ class Console extends React.Component { select={this.props.select} /> <Input - ref={(c) => { this.input = c; }} + ref={this.input} mode={this.props.mode} onBlur={this.onBlur.bind(this)} onKeyDown={this.onKeyDown.bind(this)} @@ -134,16 +142,14 @@ class Console extends React.Component { focus() { window.focus(); - this.input.focus(); + if (this.input.current) { + this.input.current.focus(); + } } } -Console.propTypes = { - mode: PropTypes.string, - consoleText: PropTypes.string, - messageText: PropTypes.string, - children: PropTypes.string, -}; +const mapStateToProps = (state: AppState) => ({ ...state }); -const mapStateToProps = state => state; -export default connect(mapStateToProps)(Console); +export default connect( + mapStateToProps, +)(Console); diff --git a/src/console/components/console/Completion.jsx b/src/console/components/console/Completion.tsx index 5477cb6..169a39c 100644 --- a/src/console/components/console/Completion.jsx +++ b/src/console/components/console/Completion.tsx @@ -1,15 +1,36 @@ import React from 'react'; -import PropTypes from 'prop-types'; import CompletionItem from './CompletionItem'; import CompletionTitle from './CompletionTitle'; -class Completion extends React.Component { - constructor() { - super(); +interface Item { + icon?: string; + caption?: string; + url?: string; +} + +interface Group { + name: string; + items: Item[]; +} + +interface Props { + select: number; + size: number; + completions: Group[]; +} + +interface State { + viewOffset: number; + select: number; +} + +class Completion extends React.Component<Props, State> { + constructor(props: Props) { + super(props); this.state = { viewOffset: 0, select: -1 }; } - static getDerivedStateFromProps(nextProps, prevState) { + static getDerivedStateFromProps(nextProps: Props, prevState: State) { if (prevState.select === nextProps.select) { return null; } @@ -24,6 +45,7 @@ class Completion extends React.Component { } index += g.items.length; } + return -1; })(); let viewOffset = 0; @@ -70,17 +92,4 @@ class Completion extends React.Component { } } -Completion.propTypes = { - select: PropTypes.number, - size: PropTypes.number, - completions: PropTypes.arrayOf(PropTypes.shape({ - name: PropTypes.string, - items: PropTypes.arrayOf(PropTypes.shape({ - icon: PropTypes.string, - caption: PropTypes.string, - url: PropTypes.string, - })), - })), -}; - export default Completion; diff --git a/src/console/components/console/CompletionItem.jsx b/src/console/components/console/CompletionItem.tsx index 3dc552b..1cbf3de 100644 --- a/src/console/components/console/CompletionItem.jsx +++ b/src/console/components/console/CompletionItem.tsx @@ -1,7 +1,14 @@ import React from 'react'; import PropTypes from 'prop-types'; -const CompletionItem = (props) => { +interface Props { + highlight: boolean; + caption?: string; + url?: string; + icon?: string; +} + +const CompletionItem = (props: Props) => { let className = 'vimvixen-console-completion-item'; if (props.highlight) { className += ' vimvixen-completion-selected'; diff --git a/src/console/components/console/CompletionTitle.jsx b/src/console/components/console/CompletionTitle.tsx index 4fcba3f..2543619 100644 --- a/src/console/components/console/CompletionTitle.jsx +++ b/src/console/components/console/CompletionTitle.tsx @@ -1,14 +1,13 @@ import React from 'react'; -import PropTypes from 'prop-types'; -const CompletionTitle = (props) => { +interface Props { + title: string; +} + +const CompletionTitle = (props: Props) => { return <li className='vimvixen-console-completion-title'> {props.title} </li>; }; -CompletionTitle.propTypes = { - title: PropTypes.string, -}; - export default CompletionTitle; diff --git a/src/console/components/console/Input.jsx b/src/console/components/console/Input.tsx index cbd3348..54ea251 100644 --- a/src/console/components/console/Input.jsx +++ b/src/console/components/console/Input.tsx @@ -1,9 +1,26 @@ import React from 'react'; -import PropTypes from 'prop-types'; -class Input extends React.Component { +interface Props { + mode: string; + value: string; + onBlur: (e: React.FocusEvent<HTMLInputElement>) => void; + onKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void; + onChange: (e: React.ChangeEvent<HTMLInputElement>) => void; +} + +class Input extends React.Component<Props> { + private input: React.RefObject<HTMLInputElement>; + + constructor(props: Props) { + super(props); + + this.input = React.createRef(); + } + focus() { - this.input.focus(); + if (this.input.current) { + this.input.current.focus(); + } } render() { @@ -21,7 +38,7 @@ class Input extends React.Component { </i> <input className='vimvixen-console-command-input' - ref={(c) => { this.input = c; }} + ref={this.input} onBlur={this.props.onBlur} onKeyDown={this.props.onKeyDown} onChange={this.props.onChange} @@ -32,12 +49,4 @@ class Input extends React.Component { } } -Input.propTypes = { - mode: PropTypes.string, - value: PropTypes.string, - onBlur: PropTypes.func, - onKeyDown: PropTypes.func, - onChange: PropTypes.func, -}; - export default Input; diff --git a/src/console/components/console/Message.jsx b/src/console/components/console/Message.tsx index dd96248..9fa2788 100644 --- a/src/console/components/console/Message.jsx +++ b/src/console/components/console/Message.tsx @@ -1,7 +1,11 @@ import React from 'react'; -import PropTypes from 'prop-types'; -const Message = (props) => { +interface Props { + mode: string; + children: string; +} + +const Message = (props: Props) => { switch (props.mode) { case 'error': return ( @@ -16,10 +20,7 @@ const Message = (props) => { </p> ); } -}; - -Message.propTypes = { - children: PropTypes.string, + return null; }; export default Message; diff --git a/src/console/index.jsx b/src/console/index.tsx index 3190a9a..b655154 100644 --- a/src/console/index.jsx +++ b/src/console/index.tsx @@ -1,8 +1,8 @@ -import messages from 'shared/messages'; -import reducers from 'console/reducers'; +import * as messages from '../shared/messages'; +import reducers from './reducers'; import { createStore, applyMiddleware } from 'redux'; import promise from 'redux-promise'; -import * as consoleActions from 'console/actions/console'; +import * as consoleActions from './actions/console'; import { Provider } from 'react-redux'; import Console from './components/Console'; import React from 'react'; @@ -22,21 +22,22 @@ window.addEventListener('load', () => { wrapper); }); -const onMessage = (message) => { - switch (message.type) { +const onMessage = (message: any): any => { + let msg = messages.valueOf(message); + switch (msg.type) { case messages.CONSOLE_SHOW_COMMAND: - return store.dispatch(consoleActions.showCommand(message.command)); + return store.dispatch(consoleActions.showCommand(msg.command)); case messages.CONSOLE_SHOW_FIND: return store.dispatch(consoleActions.showFind()); case messages.CONSOLE_SHOW_ERROR: - return store.dispatch(consoleActions.showError(message.text)); + return store.dispatch(consoleActions.showError(msg.text)); case messages.CONSOLE_SHOW_INFO: - return store.dispatch(consoleActions.showInfo(message.text)); + return store.dispatch(consoleActions.showInfo(msg.text)); case messages.CONSOLE_HIDE: return store.dispatch(consoleActions.hide()); } }; browser.runtime.onMessage.addListener(onMessage); -let port = browser.runtime.connect({ name: 'vimvixen-console' }); +let port = browser.runtime.connect(undefined, { name: 'vimvixen-console' }); port.onMessage.addListener(onMessage); diff --git a/src/console/reducers/index.js b/src/console/reducers/index.ts index 614a72f..b6be483 100644 --- a/src/console/reducers/index.js +++ b/src/console/reducers/index.ts @@ -1,4 +1,14 @@ -import actions from 'console/actions'; +import * as actions from '../actions'; + +export interface State { + mode: string; + messageText: string; + consoleText: string; + completionSource: string; + completions: any[], + select: number; + viewIndex: number; +} const defaultState = { mode: '', @@ -10,7 +20,7 @@ const defaultState = { viewIndex: 0, }; -const nextSelection = (state) => { +const nextSelection = (state: State): number => { if (state.completions.length === 0) { return -1; } @@ -27,7 +37,7 @@ const nextSelection = (state) => { return -1; }; -const prevSelection = (state) => { +const prevSelection = (state: State): number => { let length = state.completions .map(g => g.items.length) .reduce((x, y) => x + y); @@ -37,7 +47,7 @@ const prevSelection = (state) => { return state.select - 1; }; -const nextConsoleText = (completions, select, defaults) => { +const nextConsoleText = (completions: any[], select: number, defaults: any) => { if (select < 0) { return defaults; } @@ -46,7 +56,10 @@ const nextConsoleText = (completions, select, defaults) => { }; // eslint-disable-next-line max-lines-per-function -export default function reducer(state = defaultState, action = {}) { +export default function reducer( + state: State = defaultState, + action: actions.ConsoleAction, +): State { switch (action.type) { case actions.CONSOLE_HIDE: return { ...state, |