From c60d0e7392fc708e961614d6b756a045de74f458 Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka 
Date: Tue, 30 Apr 2019 14:00:07 +0900
Subject: Rename .js/.jsx to .ts/.tsx
---
 src/console/components/Console.jsx                 | 149 ---------------------
 src/console/components/Console.tsx                 | 149 +++++++++++++++++++++
 src/console/components/console/Completion.jsx      |  86 ------------
 src/console/components/console/Completion.tsx      |  86 ++++++++++++
 src/console/components/console/CompletionItem.jsx  |  28 ----
 src/console/components/console/CompletionItem.tsx  |  28 ++++
 src/console/components/console/CompletionTitle.jsx |  14 --
 src/console/components/console/CompletionTitle.tsx |  14 ++
 src/console/components/console/Input.jsx           |  43 ------
 src/console/components/console/Input.tsx           |  43 ++++++
 src/console/components/console/Message.jsx         |  25 ----
 src/console/components/console/Message.tsx         |  25 ++++
 12 files changed, 345 insertions(+), 345 deletions(-)
 delete mode 100644 src/console/components/Console.jsx
 create mode 100644 src/console/components/Console.tsx
 delete mode 100644 src/console/components/console/Completion.jsx
 create mode 100644 src/console/components/console/Completion.tsx
 delete mode 100644 src/console/components/console/CompletionItem.jsx
 create mode 100644 src/console/components/console/CompletionItem.tsx
 delete mode 100644 src/console/components/console/CompletionTitle.jsx
 create mode 100644 src/console/components/console/CompletionTitle.tsx
 delete mode 100644 src/console/components/console/Input.jsx
 create mode 100644 src/console/components/console/Input.tsx
 delete mode 100644 src/console/components/console/Message.jsx
 create mode 100644 src/console/components/console/Message.tsx
(limited to 'src/console/components')
diff --git a/src/console/components/Console.jsx b/src/console/components/Console.jsx
deleted file mode 100644
index 5427e43..0000000
--- a/src/console/components/Console.jsx
+++ /dev/null
@@ -1,149 +0,0 @@
-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';
-
-const COMPLETION_MAX_ITEMS = 33;
-
-class Console extends React.Component {
-  onBlur() {
-    if (this.props.mode === 'command' || this.props.mode === 'find') {
-      return this.props.dispatch(consoleActions.hideCommand());
-    }
-  }
-
-  doEnter(e) {
-    e.stopPropagation();
-    e.preventDefault();
-
-    let value = e.target.value;
-    if (this.props.mode === 'command') {
-      return this.props.dispatch(consoleActions.enterCommand(value));
-    } else if (this.props.mode === 'find') {
-      return this.props.dispatch(consoleActions.enterFind(value));
-    }
-  }
-
-  selectNext(e) {
-    this.props.dispatch(consoleActions.completionNext());
-    e.stopPropagation();
-    e.preventDefault();
-  }
-
-  selectPrev(e) {
-    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:
-      return this.props.dispatch(consoleActions.hideCommand());
-    case KeyboardEvent.DOM_VK_RETURN:
-      return this.doEnter(e);
-    case KeyboardEvent.DOM_VK_TAB:
-      if (e.shiftKey) {
-        this.props.dispatch(consoleActions.completionPrev());
-      } else {
-        this.props.dispatch(consoleActions.completionNext());
-      }
-      e.stopPropagation();
-      e.preventDefault();
-      break;
-    case KeyboardEvent.DOM_VK_OPEN_BRACKET:
-      if (e.ctrlKey) {
-        return this.props.dispatch(consoleActions.hideCommand());
-      }
-      break;
-    case KeyboardEvent.DOM_VK_M:
-      if (e.ctrlKey) {
-        return this.doEnter(e);
-      }
-      break;
-    case KeyboardEvent.DOM_VK_N:
-      if (e.ctrlKey) {
-        this.selectNext(e);
-      }
-      break;
-    case KeyboardEvent.DOM_VK_P:
-      if (e.ctrlKey) {
-        this.selectPrev(e);
-      }
-      break;
-    }
-  }
-
-  onChange(e) {
-    let text = e.target.value;
-    this.props.dispatch(consoleActions.setConsoleText(text));
-    if (this.props.mode === 'command') {
-      this.props.dispatch(consoleActions.getCompletions(text));
-    }
-  }
-
-
-  componentDidUpdate(prevProps) {
-    if (!this.input) {
-      return;
-    }
-    if (prevProps.mode !== 'command' && this.props.mode === 'command') {
-      this.props.dispatch(
-        consoleActions.getCompletions(this.props.consoleText));
-      this.focus();
-    } else if (prevProps.mode !== 'find' && this.props.mode === 'find') {
-      this.focus();
-    }
-  }
-
-  render() {
-    switch (this.props.mode) {
-    case 'command':
-    case 'find':
-      return 
-        
-         { this.input = c; }}
-          mode={this.props.mode}
-          onBlur={this.onBlur.bind(this)}
-          onKeyDown={this.onKeyDown.bind(this)}
-          onChange={this.onChange.bind(this)}
-          value={this.props.consoleText}
-        />
-      
;
-    case 'info':
-    case 'error':
-      return 
-        { this.props.messageText }
-      ;
-    default:
-      return null;
-    }
-  }
-
-  focus() {
-    window.focus();
-    this.input.focus();
-  }
-}
-
-Console.propTypes = {
-  mode: PropTypes.string,
-  consoleText: PropTypes.string,
-  messageText: PropTypes.string,
-  children: PropTypes.string,
-};
-
-const mapStateToProps = state => state;
-export default connect(mapStateToProps)(Console);
diff --git a/src/console/components/Console.tsx b/src/console/components/Console.tsx
new file mode 100644
index 0000000..5427e43
--- /dev/null
+++ b/src/console/components/Console.tsx
@@ -0,0 +1,149 @@
+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';
+
+const COMPLETION_MAX_ITEMS = 33;
+
+class Console extends React.Component {
+  onBlur() {
+    if (this.props.mode === 'command' || this.props.mode === 'find') {
+      return this.props.dispatch(consoleActions.hideCommand());
+    }
+  }
+
+  doEnter(e) {
+    e.stopPropagation();
+    e.preventDefault();
+
+    let value = e.target.value;
+    if (this.props.mode === 'command') {
+      return this.props.dispatch(consoleActions.enterCommand(value));
+    } else if (this.props.mode === 'find') {
+      return this.props.dispatch(consoleActions.enterFind(value));
+    }
+  }
+
+  selectNext(e) {
+    this.props.dispatch(consoleActions.completionNext());
+    e.stopPropagation();
+    e.preventDefault();
+  }
+
+  selectPrev(e) {
+    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:
+      return this.props.dispatch(consoleActions.hideCommand());
+    case KeyboardEvent.DOM_VK_RETURN:
+      return this.doEnter(e);
+    case KeyboardEvent.DOM_VK_TAB:
+      if (e.shiftKey) {
+        this.props.dispatch(consoleActions.completionPrev());
+      } else {
+        this.props.dispatch(consoleActions.completionNext());
+      }
+      e.stopPropagation();
+      e.preventDefault();
+      break;
+    case KeyboardEvent.DOM_VK_OPEN_BRACKET:
+      if (e.ctrlKey) {
+        return this.props.dispatch(consoleActions.hideCommand());
+      }
+      break;
+    case KeyboardEvent.DOM_VK_M:
+      if (e.ctrlKey) {
+        return this.doEnter(e);
+      }
+      break;
+    case KeyboardEvent.DOM_VK_N:
+      if (e.ctrlKey) {
+        this.selectNext(e);
+      }
+      break;
+    case KeyboardEvent.DOM_VK_P:
+      if (e.ctrlKey) {
+        this.selectPrev(e);
+      }
+      break;
+    }
+  }
+
+  onChange(e) {
+    let text = e.target.value;
+    this.props.dispatch(consoleActions.setConsoleText(text));
+    if (this.props.mode === 'command') {
+      this.props.dispatch(consoleActions.getCompletions(text));
+    }
+  }
+
+
+  componentDidUpdate(prevProps) {
+    if (!this.input) {
+      return;
+    }
+    if (prevProps.mode !== 'command' && this.props.mode === 'command') {
+      this.props.dispatch(
+        consoleActions.getCompletions(this.props.consoleText));
+      this.focus();
+    } else if (prevProps.mode !== 'find' && this.props.mode === 'find') {
+      this.focus();
+    }
+  }
+
+  render() {
+    switch (this.props.mode) {
+    case 'command':
+    case 'find':
+      return 
+        
+         { this.input = c; }}
+          mode={this.props.mode}
+          onBlur={this.onBlur.bind(this)}
+          onKeyDown={this.onKeyDown.bind(this)}
+          onChange={this.onChange.bind(this)}
+          value={this.props.consoleText}
+        />
+      
;
+    case 'info':
+    case 'error':
+      return 
+        { this.props.messageText }
+      ;
+    default:
+      return null;
+    }
+  }
+
+  focus() {
+    window.focus();
+    this.input.focus();
+  }
+}
+
+Console.propTypes = {
+  mode: PropTypes.string,
+  consoleText: PropTypes.string,
+  messageText: PropTypes.string,
+  children: PropTypes.string,
+};
+
+const mapStateToProps = state => state;
+export default connect(mapStateToProps)(Console);
diff --git a/src/console/components/console/Completion.jsx b/src/console/components/console/Completion.jsx
deleted file mode 100644
index 5477cb6..0000000
--- a/src/console/components/console/Completion.jsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import CompletionItem from './CompletionItem';
-import CompletionTitle from './CompletionTitle';
-
-class Completion extends React.Component {
-  constructor() {
-    super();
-    this.state = { viewOffset: 0, select: -1 };
-  }
-
-  static getDerivedStateFromProps(nextProps, prevState) {
-    if (prevState.select === nextProps.select) {
-      return null;
-    }
-
-    let viewSelect = (() => {
-      let index = 0;
-      for (let i = 0; i < nextProps.completions.length; ++i) {
-        ++index;
-        let g = nextProps.completions[i];
-        if (nextProps.select + i + 1 < index + g.items.length) {
-          return nextProps.select + i + 1;
-        }
-        index += g.items.length;
-      }
-    })();
-
-    let viewOffset = 0;
-    if (nextProps.select < 0) {
-      viewOffset = 0;
-    } else if (prevState.select < nextProps.select) {
-      viewOffset = Math.max(prevState.viewOffset,
-        viewSelect - nextProps.size + 1);
-    } else if (prevState.select > nextProps.select) {
-      viewOffset = Math.min(prevState.viewOffset, viewSelect);
-    }
-    return { viewOffset, select: nextProps.select };
-  }
-
-  render() {
-    let eles = [];
-    let index = 0;
-
-    for (let group of this.props.completions) {
-      eles.push();
-      for (let item of group.items) {
-        eles.push();
-        ++index;
-      }
-    }
-
-    let viewOffset = this.state.viewOffset;
-    eles = eles.slice(viewOffset, viewOffset + this.props.size);
-
-    return (
-      
-    );
-  }
-}
-
-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/Completion.tsx b/src/console/components/console/Completion.tsx
new file mode 100644
index 0000000..5477cb6
--- /dev/null
+++ b/src/console/components/console/Completion.tsx
@@ -0,0 +1,86 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import CompletionItem from './CompletionItem';
+import CompletionTitle from './CompletionTitle';
+
+class Completion extends React.Component {
+  constructor() {
+    super();
+    this.state = { viewOffset: 0, select: -1 };
+  }
+
+  static getDerivedStateFromProps(nextProps, prevState) {
+    if (prevState.select === nextProps.select) {
+      return null;
+    }
+
+    let viewSelect = (() => {
+      let index = 0;
+      for (let i = 0; i < nextProps.completions.length; ++i) {
+        ++index;
+        let g = nextProps.completions[i];
+        if (nextProps.select + i + 1 < index + g.items.length) {
+          return nextProps.select + i + 1;
+        }
+        index += g.items.length;
+      }
+    })();
+
+    let viewOffset = 0;
+    if (nextProps.select < 0) {
+      viewOffset = 0;
+    } else if (prevState.select < nextProps.select) {
+      viewOffset = Math.max(prevState.viewOffset,
+        viewSelect - nextProps.size + 1);
+    } else if (prevState.select > nextProps.select) {
+      viewOffset = Math.min(prevState.viewOffset, viewSelect);
+    }
+    return { viewOffset, select: nextProps.select };
+  }
+
+  render() {
+    let eles = [];
+    let index = 0;
+
+    for (let group of this.props.completions) {
+      eles.push();
+      for (let item of group.items) {
+        eles.push();
+        ++index;
+      }
+    }
+
+    let viewOffset = this.state.viewOffset;
+    eles = eles.slice(viewOffset, viewOffset + this.props.size);
+
+    return (
+      
+    );
+  }
+}
+
+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.jsx
deleted file mode 100644
index 3dc552b..0000000
--- a/src/console/components/console/CompletionItem.jsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-const CompletionItem = (props) => {
-  let className = 'vimvixen-console-completion-item';
-  if (props.highlight) {
-    className += ' vimvixen-completion-selected';
-  }
-  return 
-    {props.caption}
-    {props.url}
-  ;
-};
-
-CompletionItem.propTypes = {
-  highlight: PropTypes.bool,
-  caption: PropTypes.string,
-  url: PropTypes.string,
-};
-
-export default CompletionItem;
diff --git a/src/console/components/console/CompletionItem.tsx b/src/console/components/console/CompletionItem.tsx
new file mode 100644
index 0000000..3dc552b
--- /dev/null
+++ b/src/console/components/console/CompletionItem.tsx
@@ -0,0 +1,28 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const CompletionItem = (props) => {
+  let className = 'vimvixen-console-completion-item';
+  if (props.highlight) {
+    className += ' vimvixen-completion-selected';
+  }
+  return 
+    {props.caption}
+    {props.url}
+  ;
+};
+
+CompletionItem.propTypes = {
+  highlight: PropTypes.bool,
+  caption: PropTypes.string,
+  url: PropTypes.string,
+};
+
+export default CompletionItem;
diff --git a/src/console/components/console/CompletionTitle.jsx b/src/console/components/console/CompletionTitle.jsx
deleted file mode 100644
index 4fcba3f..0000000
--- a/src/console/components/console/CompletionTitle.jsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-const CompletionTitle = (props) => {
-  return 
-    {props.title}
-  ;
-};
-
-CompletionTitle.propTypes = {
-  title: PropTypes.string,
-};
-
-export default CompletionTitle;
diff --git a/src/console/components/console/CompletionTitle.tsx b/src/console/components/console/CompletionTitle.tsx
new file mode 100644
index 0000000..4fcba3f
--- /dev/null
+++ b/src/console/components/console/CompletionTitle.tsx
@@ -0,0 +1,14 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const CompletionTitle = (props) => {
+  return 
+    {props.title}
+  ;
+};
+
+CompletionTitle.propTypes = {
+  title: PropTypes.string,
+};
+
+export default CompletionTitle;
diff --git a/src/console/components/console/Input.jsx b/src/console/components/console/Input.jsx
deleted file mode 100644
index cbd3348..0000000
--- a/src/console/components/console/Input.jsx
+++ /dev/null
@@ -1,43 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-class Input extends React.Component {
-  focus() {
-    this.input.focus();
-  }
-
-  render() {
-    let prompt = '';
-    if (this.props.mode === 'command') {
-      prompt = ':';
-    } else if (this.props.mode === 'find') {
-      prompt = '/';
-    }
-
-    return (
-      
-        
-          { prompt }
-        
-         { this.input = c; }}
-          onBlur={this.props.onBlur}
-          onKeyDown={this.props.onKeyDown}
-          onChange={this.props.onChange}
-          value={this.props.value}
-        />
-      
-    );
-  }
-}
-
-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/Input.tsx b/src/console/components/console/Input.tsx
new file mode 100644
index 0000000..cbd3348
--- /dev/null
+++ b/src/console/components/console/Input.tsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+class Input extends React.Component {
+  focus() {
+    this.input.focus();
+  }
+
+  render() {
+    let prompt = '';
+    if (this.props.mode === 'command') {
+      prompt = ':';
+    } else if (this.props.mode === 'find') {
+      prompt = '/';
+    }
+
+    return (
+      
+        
+          { prompt }
+        
+         { this.input = c; }}
+          onBlur={this.props.onBlur}
+          onKeyDown={this.props.onKeyDown}
+          onChange={this.props.onChange}
+          value={this.props.value}
+        />
+      
+    );
+  }
+}
+
+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.jsx
deleted file mode 100644
index dd96248..0000000
--- a/src/console/components/console/Message.jsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-const Message = (props) => {
-  switch (props.mode) {
-  case 'error':
-    return (
-      
-        { props.children }
-      
-    );
-  case 'info':
-    return (
-      
-        { props.children }
-      
-    );
-  }
-};
-
-Message.propTypes = {
-  children: PropTypes.string,
-};
-
-export default Message;
diff --git a/src/console/components/console/Message.tsx b/src/console/components/console/Message.tsx
new file mode 100644
index 0000000..dd96248
--- /dev/null
+++ b/src/console/components/console/Message.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+const Message = (props) => {
+  switch (props.mode) {
+  case 'error':
+    return (
+      
+        { props.children }
+      
+    );
+  case 'info':
+    return (
+      
+        { props.children }
+      
+    );
+  }
+};
+
+Message.propTypes = {
+  children: PropTypes.string,
+};
+
+export default Message;
-- 
cgit v1.2.3
From 0452370df43cc4263f268e7064f824d7e6e489b3 Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka 
Date: Wed, 1 May 2019 23:10:37 +0900
Subject: Types on src/console
---
 src/background/usecases/CompletionsUseCase.ts      | 12 ++--
 src/console/actions/console.ts                     | 34 +++++-----
 src/console/actions/index.ts                       | 76 ++++++++++++++++++----
 src/console/components/Console.tsx                 | 43 +++++++-----
 src/console/components/console/Completion.tsx      | 45 ++++++++-----
 src/console/components/console/CompletionItem.tsx  |  9 ++-
 src/console/components/console/CompletionTitle.tsx | 11 ++--
 src/console/components/console/Input.tsx           | 31 +++++----
 src/console/components/console/Message.tsx         | 13 ++--
 src/console/index.tsx                              | 10 +--
 src/console/reducers/index.ts                      | 23 +++++--
 test/console/actions/console.test.ts               |  2 +-
 test/console/reducers/console.test.ts              |  2 +-
 13 files changed, 206 insertions(+), 105 deletions(-)
(limited to 'src/console/components')
diff --git a/src/background/usecases/CompletionsUseCase.ts b/src/background/usecases/CompletionsUseCase.ts
index 037d6eb..f3a808b 100644
--- a/src/background/usecases/CompletionsUseCase.ts
+++ b/src/background/usecases/CompletionsUseCase.ts
@@ -1,4 +1,3 @@
-import Completions from '../domains/Completions';
 import CompletionGroup from '../domains/CompletionGroup';
 import CommandDocs from '../domains/CommandDocs';
 import CompletionsRepository from '../repositories/CompletionsRepository';
@@ -25,7 +24,7 @@ export default class CompletionsUseCase {
     this.settingRepository = new SettingRepository();
   }
 
-  queryConsoleCommand(prefix: string): Promise {
+  queryConsoleCommand(prefix: string): Promise {
     let keys = Object.keys(CommandDocs);
     let items = keys
       .filter(name => name.startsWith(prefix))
@@ -38,10 +37,10 @@ export default class CompletionsUseCase {
     if (items.length === 0) {
       return Promise.resolve([]);
     }
-    return Promise.resolve([{ name: 'Console CompletionGroup', items }]);
+    return Promise.resolve([{ name: 'Console Command', items }]);
   }
 
-  async queryOpen(name: string, keywords: string): Promise {
+  async queryOpen(name: string, keywords: string): Promise {
     let settings = await this.settingRepository.get();
     let groups: CompletionGroup[] = [];
 
@@ -71,7 +70,10 @@ export default class CompletionsUseCase {
   }
 
   // eslint-disable-next-line max-statements
-  async queryBuffer(name: string, keywords: string): Promise {
+  async queryBuffer(
+    name: string,
+    keywords: string,
+  ): Promise {
     let lastId = await this.tabPresenter.getLastSelectedId();
     let trimmed = keywords.trim();
     let tabs: Tab[] = [];
diff --git a/src/console/actions/console.ts b/src/console/actions/console.ts
index 3713a76..ceb419c 100644
--- a/src/console/actions/console.ts
+++ b/src/console/actions/console.ts
@@ -1,40 +1,40 @@
-import messages from 'shared/messages';
-import actions from 'console/actions';
+import 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 => {
   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 => {
   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.ts b/src/console/actions/index.ts
index b394179..3770496 100644
--- a/src/console/actions/index.ts
+++ b/src/console/actions/index.ts
@@ -1,13 +1,63 @@
-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',
-};
+// 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.tsx b/src/console/components/Console.tsx
index 5427e43..09c0f50 100644
--- a/src/console/components/Console.tsx
+++ b/src/console/components/Console.tsx
@@ -1,7 +1,6 @@
 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';
@@ -9,14 +8,29 @@ import * as consoleActions from '../../console/actions/console';
 
 const COMPLETION_MAX_ITEMS = 33;
 
-class Console extends React.Component {
+interface Props {
+  mode?: string;
+  consoleText?: string;
+  messageText?: string;
+  children?: string;
+}
+
+class Console extends React.Component {
+  private input: HTMLInputElement | null;
+
+  constructor(props: Props) {
+    super(props);
+
+    this.input = null;
+  }
+
   onBlur() {
     if (this.props.mode === 'command' || this.props.mode === 'find') {
       return this.props.dispatch(consoleActions.hideCommand());
     }
   }
 
-  doEnter(e) {
+  doEnter(e: React.KeyboardEvent) {
     e.stopPropagation();
     e.preventDefault();
 
@@ -28,19 +42,19 @@ class Console extends React.Component {
     }
   }
 
-  selectNext(e) {
+  selectNext(e: React.KeyboardEvent) {
     this.props.dispatch(consoleActions.completionNext());
     e.stopPropagation();
     e.preventDefault();
   }
 
-  selectPrev(e) {
+  selectPrev(e: React.KeyboardEvent) {
     this.props.dispatch(consoleActions.completionPrev());
     e.stopPropagation();
     e.preventDefault();
   }
 
-  onKeyDown(e) {
+  onKeyDown(e: React.KeyboardEvent) {
     if (e.keyCode === KeyboardEvent.DOM_VK_ESCAPE && e.ctrlKey) {
       this.props.dispatch(consoleActions.hideCommand());
     }
@@ -81,7 +95,7 @@ class Console extends React.Component {
     }
   }
 
-  onChange(e) {
+  onChange(e: React.ChangeEvent) {
     let text = e.target.value;
     this.props.dispatch(consoleActions.setConsoleText(text));
     if (this.props.mode === 'command') {
@@ -90,7 +104,7 @@ class Console extends React.Component {
   }
 
 
-  componentDidUpdate(prevProps) {
+  componentDidUpdate(prevProps: Props) {
     if (!this.input) {
       return;
     }
@@ -134,16 +148,11 @@ class Console extends React.Component {
 
   focus() {
     window.focus();
-    this.input.focus();
+    if (this.input) {
+      this.input.focus();
+    }
   }
 }
 
-Console.propTypes = {
-  mode: PropTypes.string,
-  consoleText: PropTypes.string,
-  messageText: PropTypes.string,
-  children: PropTypes.string,
-};
-
-const mapStateToProps = state => state;
+const mapStateToProps = (state: any) => state;
 export default connect(mapStateToProps)(Console);
diff --git a/src/console/components/console/Completion.tsx b/src/console/components/console/Completion.tsx
index 5477cb6..169a39c 100644
--- a/src/console/components/console/Completion.tsx
+++ 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 {
+  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.tsx b/src/console/components/console/CompletionItem.tsx
index 3dc552b..1cbf3de 100644
--- a/src/console/components/console/CompletionItem.tsx
+++ 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.tsx b/src/console/components/console/CompletionTitle.tsx
index 4fcba3f..2543619 100644
--- a/src/console/components/console/CompletionTitle.tsx
+++ 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 
     {props.title}
   ;
 };
 
-CompletionTitle.propTypes = {
-  title: PropTypes.string,
-};
-
 export default CompletionTitle;
diff --git a/src/console/components/console/Input.tsx b/src/console/components/console/Input.tsx
index cbd3348..d0348bd 100644
--- a/src/console/components/console/Input.tsx
+++ 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) => void;
+  onKeyDown: (e: React.KeyboardEvent) => void;
+  onChange: (e: React.ChangeEvent) => void;
+}
+
+class Input extends React.Component {
+  private input: HTMLInputElement | null;
+
+  constructor(props: Props) {
+    super(props);
+
+    this.input = null;
+  }
+
   focus() {
-    this.input.focus();
+    if (this.input) {
+      this.input.focus();
+    }
   }
 
   render() {
@@ -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.tsx b/src/console/components/console/Message.tsx
index dd96248..07a929e 100644
--- a/src/console/components/console/Message.tsx
+++ 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) => {
       
     );
   }
-};
-
-Message.propTypes = {
-  children: PropTypes.string,
+  return null;
 };
 
 export default Message;
diff --git a/src/console/index.tsx b/src/console/index.tsx
index 3190a9a..ee3a8ee 100644
--- a/src/console/index.tsx
+++ b/src/console/index.tsx
@@ -1,8 +1,8 @@
-import messages from 'shared/messages';
-import reducers from 'console/reducers';
+import 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,7 +22,7 @@ window.addEventListener('load', () => {
     wrapper);
 });
 
-const onMessage = (message) => {
+const onMessage = (message: any): any => {
   switch (message.type) {
   case messages.CONSOLE_SHOW_COMMAND:
     return store.dispatch(consoleActions.showCommand(message.command));
@@ -38,5 +38,5 @@ const onMessage = (message) => {
 };
 
 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.ts b/src/console/reducers/index.ts
index 614a72f..37ed715 100644
--- a/src/console/reducers/index.ts
+++ b/src/console/reducers/index.ts
@@ -1,4 +1,14 @@
-import actions from 'console/actions';
+import * as actions from '../actions';
+
+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,
diff --git a/test/console/actions/console.test.ts b/test/console/actions/console.test.ts
index 10cd9fe..e45d008 100644
--- a/test/console/actions/console.test.ts
+++ b/test/console/actions/console.test.ts
@@ -1,4 +1,4 @@
-import actions from 'console/actions';
+import * as actions from 'console/actions';
 import * as consoleActions from 'console/actions/console';
 
 describe("console actions", () => {
diff --git a/test/console/reducers/console.test.ts b/test/console/reducers/console.test.ts
index d5a38cf..47e7daf 100644
--- a/test/console/reducers/console.test.ts
+++ b/test/console/reducers/console.test.ts
@@ -1,4 +1,4 @@
-import actions from 'console/actions';
+import * as actions from 'console/actions';
 import reducer from 'console/reducers';
 
 describe("console reducer", () => {
-- 
cgit v1.2.3
From b002d70070a1b691b635220bc694c48df36faca5 Mon Sep 17 00:00:00 2001
From: Shin'ya Ueoka 
Date: Mon, 6 May 2019 22:17:01 +0900
Subject: 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
(limited to 'src/console/components')
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 }],
-- 
cgit v1.2.3